blob: eec8579ef5a17a5f113d3a27cfb637ab864459b5 [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
Jiaqing Zhaoe8d664d2022-07-05 21:22:54 +08006#include <phosphor-logging/elog-errors.hpp>
7#include <phosphor-logging/elog.hpp>
8#include <phosphor-logging/lg2.hpp>
9#include <xyz/openbmc_project/Common/error.hpp>
10
Ratan Guptae1f4db62019-04-11 18:57:42 +053011#include <filesystem>
12#include <fstream>
13#include <sstream>
14
15namespace phosphor
16{
17namespace ldap
18{
19
Alexander Filippov372c5662021-06-30 20:23:39 +030020constexpr auto nslcdService = "nslcd.service";
Ratan Guptae1f4db62019-04-11 18:57:42 +053021constexpr auto nscdService = "nscd.service";
Nan Zhou78d85042022-08-29 17:50:22 +000022constexpr auto ldapScheme = "ldap";
23constexpr auto ldapsScheme = "ldaps";
Ratan Guptae1f4db62019-04-11 18:57:42 +053024
Jiaqing Zhaoe8d664d2022-07-05 21:22:54 +080025using namespace phosphor::logging;
Ratan Guptae1f4db62019-04-11 18:57:42 +053026using namespace sdbusplus::xyz::openbmc_project::Common::Error;
27namespace fs = std::filesystem;
28using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Guptac5481d12019-04-12 18:31:05 +053029using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
Ratan Guptae1f4db62019-04-11 18:57:42 +053030
31using Line = std::string;
32using Key = std::string;
33using Val = std::string;
34using ConfigInfo = std::map<Key, Val>;
35
36void ConfigMgr::startOrStopService(const std::string& service, bool start)
37{
38 if (start)
39 {
40 restartService(service);
41 }
42 else
43 {
44 stopService(service);
45 }
46}
47
48void ConfigMgr::restartService(const std::string& service)
49{
50 try
51 {
52 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
53 SYSTEMD_INTERFACE, "RestartUnit");
54 method.append(service.c_str(), "replace");
55 bus.call_noreply(method);
56 }
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050057 catch (const sdbusplus::exception_t& ex)
Ratan Guptae1f4db62019-04-11 18:57:42 +053058 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080059 lg2::error("Failed to restart service {SERVICE}: {ERR}", "SERVICE",
60 service, "ERR", ex);
Ratan Guptae1f4db62019-04-11 18:57:42 +053061 elog<InternalFailure>();
62 }
63}
64void ConfigMgr::stopService(const std::string& service)
65{
66 try
67 {
68 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
69 SYSTEMD_INTERFACE, "StopUnit");
70 method.append(service.c_str(), "replace");
71 bus.call_noreply(method);
72 }
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050073 catch (const sdbusplus::exception_t& ex)
Ratan Guptae1f4db62019-04-11 18:57:42 +053074 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080075 lg2::error("Failed to stop service {SERVICE}: {ERR}", "SERVICE",
76 service, "ERR", ex);
Ratan Guptae1f4db62019-04-11 18:57:42 +053077 elog<InternalFailure>();
78 }
79}
80
Ratan Guptae1f4db62019-04-11 18:57:42 +053081std::string ConfigMgr::createConfig(
Patrick Williamse6500a42021-05-01 05:58:23 -050082 std::string ldapServerURI, std::string ldapBindDN, std::string ldapBaseDN,
83 std::string ldapBindDNPassword, CreateIface::SearchScope ldapSearchScope,
84 CreateIface::Create::Type ldapType, std::string groupNameAttribute,
Ratan Guptae1f4db62019-04-11 18:57:42 +053085 std::string userNameAttribute)
86{
87 bool secureLDAP = false;
88
Nan Zhou78d85042022-08-29 17:50:22 +000089 if (isValidLDAPURI(ldapServerURI, ldapsScheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053090 {
91 secureLDAP = true;
92 }
Nan Zhou78d85042022-08-29 17:50:22 +000093 else if (isValidLDAPURI(ldapServerURI, ldapScheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053094 {
95 secureLDAP = false;
96 }
97 else
98 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080099 lg2::error("Bad LDAP Server URI {URI}", "URI", ldapServerURI);
Patrick Williamse6500a42021-05-01 05:58:23 -0500100 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"),
101 Argument::ARGUMENT_VALUE(ldapServerURI.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530102 }
103
104 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
105 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800106 lg2::error("LDAP server CA certificate not found at {PATH}", "PATH",
107 tlsCacertFile);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530108 elog<NoCACertificate>();
109 }
110
Patrick Williamse6500a42021-05-01 05:58:23 -0500111 if (ldapBindDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530112 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800113 lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN",
114 ldapBindDN);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530115 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500116 Argument::ARGUMENT_VALUE(ldapBindDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530117 }
118
Patrick Williamse6500a42021-05-01 05:58:23 -0500119 if (ldapBaseDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530120 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800121 lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN",
122 ldapBaseDN);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530123 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500124 Argument::ARGUMENT_VALUE(ldapBaseDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530125 }
126
Ratan Gupta27d4c012019-04-12 13:03:35 +0530127 // With current implementation we support only two default LDAP server.
128 // which will be always there but when the support comes for additional
129 // account providers then the create config would be used to create the
130 // additional config.
Ratan Guptae1f4db62019-04-11 18:57:42 +0530131
Ratan Gupta27d4c012019-04-12 13:03:35 +0530132 std::string objPath;
Ratan Guptae1f4db62019-04-11 18:57:42 +0530133
Patrick Williamse6500a42021-05-01 05:58:23 -0500134 if (static_cast<ConfigIface::Type>(ldapType) == ConfigIface::Type::OpenLdap)
Ratan Gupta27d4c012019-04-12 13:03:35 +0530135 {
136 openLDAPConfigPtr.reset(nullptr);
137 objPath = openLDAPDbusObjectPath;
138 openLDAPConfigPtr = std::make_unique<Config>(
139 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500140 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
141 ldapBaseDN, std::move(ldapBindDNPassword),
142 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
143 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530144 userNameAttribute, *this);
145 }
146 else
147 {
148 ADConfigPtr.reset(nullptr);
Nan Zhou78d85042022-08-29 17:50:22 +0000149 objPath = adDbusObjectPath;
Ratan Gupta27d4c012019-04-12 13:03:35 +0530150 ADConfigPtr = std::make_unique<Config>(
151 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500152 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
153 ldapBaseDN, std::move(ldapBindDNPassword),
154 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
155 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530156 userNameAttribute, *this);
157 }
Ratan Guptae1f4db62019-04-11 18:57:42 +0530158 restartService(nscdService);
159 return objPath;
160}
161
Ratan Gupta27d4c012019-04-12 13:03:35 +0530162void ConfigMgr::createDefaultObjects()
Ratan Guptae1f4db62019-04-11 18:57:42 +0530163{
Ratan Gupta27d4c012019-04-12 13:03:35 +0530164 if (!openLDAPConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530165 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530166 openLDAPConfigPtr = std::make_unique<Config>(
167 bus, openLDAPDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530168 tlsCacertFile.c_str(), tlsCertFile.c_str(),
169 ConfigIface::Type::OpenLdap, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530170 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530171 }
Ratan Gupta27d4c012019-04-12 13:03:35 +0530172 if (!ADConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530173 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530174 ADConfigPtr = std::make_unique<Config>(
Nan Zhou78d85042022-08-29 17:50:22 +0000175 bus, adDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530176 tlsCacertFile.c_str(), tlsCertFile.c_str(),
177 ConfigIface::Type::ActiveDirectory, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530178 ADConfigPtr->emit_object_added();
179 }
180}
181
Ratan Guptac5481d12019-04-12 18:31:05 +0530182bool ConfigMgr::enableService(Config& config, bool value)
183{
184 if (value)
185 {
186 if (openLDAPConfigPtr && openLDAPConfigPtr->enabled())
187 {
188 elog<NotAllowed>(NotAllowedArgument::REASON(
189 "OpenLDAP service is already active"));
190 }
191 if (ADConfigPtr && ADConfigPtr->enabled())
192 {
193 elog<NotAllowed>(NotAllowedArgument::REASON(
194 "ActiveDirectory service is already active"));
195 }
196 }
197 return config.enableService(value);
198}
199
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530200void ConfigMgr::restore()
201{
202 createDefaultObjects();
203 // Restore the ldap config and their mappings
204 if (ADConfigPtr->deserialize())
205 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530206 // Restore the role mappings
207 ADConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530208 ADConfigPtr->emit_object_added();
209 }
210 if (openLDAPConfigPtr->deserialize())
211 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530212 // Restore the role mappings
213 openLDAPConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530214 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530215 }
Alexander Filippov372c5662021-06-30 20:23:39 +0300216
217 startOrStopService(phosphor::ldap::nslcdService,
218 ADConfigPtr->enabled() || openLDAPConfigPtr->enabled());
Ratan Guptae1f4db62019-04-11 18:57:42 +0530219}
Ratan Gupta27d4c012019-04-12 13:03:35 +0530220
Ratan Guptae1f4db62019-04-11 18:57:42 +0530221} // namespace ldap
222} // namespace phosphor