blob: 5dea8e84f65bb0a3458c0c0d85031143acc528e8 [file] [log] [blame]
Ratan Guptae1f4db62019-04-11 18:57:42 +05301#include "ldap_config_mgr.hpp"
Ratan Guptae1f4db62019-04-11 18:57:42 +05302
Patrick Williams9638afb2021-02-22 17:16:24 -06003#include "ldap_config.hpp"
Ratan Guptae1f4db62019-04-11 18:57:42 +05304#include "utils.hpp"
Patrick Williams9638afb2021-02-22 17:16:24 -06005
Ratan Guptae1f4db62019-04-11 18:57:42 +05306#include <filesystem>
7#include <fstream>
8#include <sstream>
9
10namespace phosphor
11{
12namespace ldap
13{
14
15constexpr auto nscdService = "nscd.service";
16constexpr auto LDAPscheme = "ldap";
17constexpr auto LDAPSscheme = "ldaps";
18
19using namespace phosphor::logging;
20using namespace sdbusplus::xyz::openbmc_project::Common::Error;
21namespace fs = std::filesystem;
22using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Guptac5481d12019-04-12 18:31:05 +053023using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
24using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
Ratan Guptae1f4db62019-04-11 18:57:42 +053025
26using Line = std::string;
27using Key = std::string;
28using Val = std::string;
29using ConfigInfo = std::map<Key, Val>;
30
31void ConfigMgr::startOrStopService(const std::string& service, bool start)
32{
33 if (start)
34 {
35 restartService(service);
36 }
37 else
38 {
39 stopService(service);
40 }
41}
42
43void ConfigMgr::restartService(const std::string& service)
44{
45 try
46 {
47 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
48 SYSTEMD_INTERFACE, "RestartUnit");
49 method.append(service.c_str(), "replace");
50 bus.call_noreply(method);
51 }
52 catch (const sdbusplus::exception::SdBusError& ex)
53 {
54 log<level::ERR>("Failed to restart service",
55 entry("SERVICE=%s", service.c_str()),
56 entry("ERR=%s", ex.what()));
57 elog<InternalFailure>();
58 }
59}
60void ConfigMgr::stopService(const std::string& service)
61{
62 try
63 {
64 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
65 SYSTEMD_INTERFACE, "StopUnit");
66 method.append(service.c_str(), "replace");
67 bus.call_noreply(method);
68 }
69 catch (const sdbusplus::exception::SdBusError& ex)
70 {
71 log<level::ERR>("Failed to stop service",
72 entry("SERVICE=%s", service.c_str()),
73 entry("ERR=%s", ex.what()));
74 elog<InternalFailure>();
75 }
76}
77
Ratan Guptae1f4db62019-04-11 18:57:42 +053078std::string ConfigMgr::createConfig(
Patrick Williamse6500a42021-05-01 05:58:23 -050079 std::string ldapServerURI, std::string ldapBindDN, std::string ldapBaseDN,
80 std::string ldapBindDNPassword, CreateIface::SearchScope ldapSearchScope,
81 CreateIface::Create::Type ldapType, std::string groupNameAttribute,
Ratan Guptae1f4db62019-04-11 18:57:42 +053082 std::string userNameAttribute)
83{
84 bool secureLDAP = false;
85
Patrick Williamse6500a42021-05-01 05:58:23 -050086 if (isValidLDAPURI(ldapServerURI, LDAPSscheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053087 {
88 secureLDAP = true;
89 }
Patrick Williamse6500a42021-05-01 05:58:23 -050090 else if (isValidLDAPURI(ldapServerURI, LDAPscheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053091 {
92 secureLDAP = false;
93 }
94 else
95 {
96 log<level::ERR>("bad LDAP Server URI",
Patrick Williamse6500a42021-05-01 05:58:23 -050097 entry("LDAPSERVERURI=%s", ldapServerURI.c_str()));
98 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"),
99 Argument::ARGUMENT_VALUE(ldapServerURI.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530100 }
101
102 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
103 {
104 log<level::ERR>("LDAP server's CA certificate not provided",
105 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
106 elog<NoCACertificate>();
107 }
108
Patrick Williamse6500a42021-05-01 05:58:23 -0500109 if (ldapBindDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530110 {
111 log<level::ERR>("Not a valid LDAP BINDDN",
Patrick Williamse6500a42021-05-01 05:58:23 -0500112 entry("LDAPBINDDN=%s", ldapBindDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530113 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500114 Argument::ARGUMENT_VALUE(ldapBindDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530115 }
116
Patrick Williamse6500a42021-05-01 05:58:23 -0500117 if (ldapBaseDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530118 {
119 log<level::ERR>("Not a valid LDAP BASEDN",
Patrick Williamse6500a42021-05-01 05:58:23 -0500120 entry("LDAPBASEDN=%s", ldapBaseDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530121 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500122 Argument::ARGUMENT_VALUE(ldapBaseDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530123 }
124
Ratan Gupta27d4c012019-04-12 13:03:35 +0530125 // With current implementation we support only two default LDAP server.
126 // which will be always there but when the support comes for additional
127 // account providers then the create config would be used to create the
128 // additional config.
Ratan Guptae1f4db62019-04-11 18:57:42 +0530129
Ratan Gupta27d4c012019-04-12 13:03:35 +0530130 std::string objPath;
Ratan Guptae1f4db62019-04-11 18:57:42 +0530131
Patrick Williamse6500a42021-05-01 05:58:23 -0500132 if (static_cast<ConfigIface::Type>(ldapType) == ConfigIface::Type::OpenLdap)
Ratan Gupta27d4c012019-04-12 13:03:35 +0530133 {
134 openLDAPConfigPtr.reset(nullptr);
135 objPath = openLDAPDbusObjectPath;
136 openLDAPConfigPtr = std::make_unique<Config>(
137 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500138 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
139 ldapBaseDN, std::move(ldapBindDNPassword),
140 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
141 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530142 userNameAttribute, *this);
143 }
144 else
145 {
146 ADConfigPtr.reset(nullptr);
147 objPath = ADDbusObjectPath;
148 ADConfigPtr = std::make_unique<Config>(
149 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500150 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
151 ldapBaseDN, std::move(ldapBindDNPassword),
152 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
153 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530154 userNameAttribute, *this);
155 }
Ratan Guptae1f4db62019-04-11 18:57:42 +0530156 restartService(nscdService);
157 return objPath;
158}
159
Ratan Gupta27d4c012019-04-12 13:03:35 +0530160void ConfigMgr::createDefaultObjects()
Ratan Guptae1f4db62019-04-11 18:57:42 +0530161{
Ratan Gupta27d4c012019-04-12 13:03:35 +0530162 if (!openLDAPConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530163 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530164 openLDAPConfigPtr = std::make_unique<Config>(
165 bus, openLDAPDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530166 tlsCacertFile.c_str(), tlsCertFile.c_str(),
167 ConfigIface::Type::OpenLdap, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530168 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530169 }
Ratan Gupta27d4c012019-04-12 13:03:35 +0530170 if (!ADConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530171 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530172 ADConfigPtr = std::make_unique<Config>(
173 bus, ADDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530174 tlsCacertFile.c_str(), tlsCertFile.c_str(),
175 ConfigIface::Type::ActiveDirectory, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530176 ADConfigPtr->emit_object_added();
177 }
178}
179
Ratan Guptac5481d12019-04-12 18:31:05 +0530180bool ConfigMgr::enableService(Config& config, bool value)
181{
182 if (value)
183 {
184 if (openLDAPConfigPtr && openLDAPConfigPtr->enabled())
185 {
186 elog<NotAllowed>(NotAllowedArgument::REASON(
187 "OpenLDAP service is already active"));
188 }
189 if (ADConfigPtr && ADConfigPtr->enabled())
190 {
191 elog<NotAllowed>(NotAllowedArgument::REASON(
192 "ActiveDirectory service is already active"));
193 }
194 }
195 return config.enableService(value);
196}
197
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530198void ConfigMgr::restore()
199{
200 createDefaultObjects();
201 // Restore the ldap config and their mappings
202 if (ADConfigPtr->deserialize())
203 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530204 // Restore the role mappings
205 ADConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530206 ADConfigPtr->emit_object_added();
207 }
208 if (openLDAPConfigPtr->deserialize())
209 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530210 // Restore the role mappings
211 openLDAPConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530212 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530213 }
214}
Ratan Gupta27d4c012019-04-12 13:03:35 +0530215
Ratan Guptae1f4db62019-04-11 18:57:42 +0530216} // namespace ldap
217} // namespace phosphor