blob: f0630f6cac028e71eae1cbcdaf00ca23e9cd5a6a [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
Ravi Tejaaf1594c2024-04-27 13:11:54 -050020constexpr auto systemdBusname = "org.freedesktop.systemd1";
21constexpr auto systemdObjPath = "/org/freedesktop/systemd1";
22constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
23
Alexander Filippov372c5662021-06-30 20:23:39 +030024constexpr auto nslcdService = "nslcd.service";
Ratan Guptae1f4db62019-04-11 18:57:42 +053025constexpr auto nscdService = "nscd.service";
Nan Zhou78d85042022-08-29 17:50:22 +000026constexpr auto ldapScheme = "ldap";
27constexpr auto ldapsScheme = "ldaps";
Ratan Guptae1f4db62019-04-11 18:57:42 +053028
Jiaqing Zhaoe8d664d2022-07-05 21:22:54 +080029using namespace phosphor::logging;
Ratan Guptae1f4db62019-04-11 18:57:42 +053030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
31namespace fs = std::filesystem;
32using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Guptac5481d12019-04-12 18:31:05 +053033using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
Ratan Guptae1f4db62019-04-11 18:57:42 +053034
35using Line = std::string;
36using Key = std::string;
37using Val = std::string;
38using ConfigInfo = std::map<Key, Val>;
39
40void ConfigMgr::startOrStopService(const std::string& service, bool start)
41{
42 if (start)
43 {
44 restartService(service);
45 }
46 else
47 {
48 stopService(service);
49 }
50}
51
52void ConfigMgr::restartService(const std::string& service)
53{
54 try
55 {
Ravi Tejaaf1594c2024-04-27 13:11:54 -050056 auto method = bus.new_method_call(systemdBusname, systemdObjPath,
57 systemdInterface, "RestartUnit");
Ratan Guptae1f4db62019-04-11 18:57:42 +053058 method.append(service.c_str(), "replace");
59 bus.call_noreply(method);
60 }
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050061 catch (const sdbusplus::exception_t& ex)
Ratan Guptae1f4db62019-04-11 18:57:42 +053062 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080063 lg2::error("Failed to restart service {SERVICE}: {ERR}", "SERVICE",
64 service, "ERR", ex);
Ratan Guptae1f4db62019-04-11 18:57:42 +053065 elog<InternalFailure>();
66 }
67}
68void ConfigMgr::stopService(const std::string& service)
69{
70 try
71 {
Ravi Tejaaf1594c2024-04-27 13:11:54 -050072 auto method = bus.new_method_call(systemdBusname, systemdObjPath,
73 systemdInterface, "StopUnit");
Ratan Guptae1f4db62019-04-11 18:57:42 +053074 method.append(service.c_str(), "replace");
75 bus.call_noreply(method);
76 }
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050077 catch (const sdbusplus::exception_t& ex)
Ratan Guptae1f4db62019-04-11 18:57:42 +053078 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080079 lg2::error("Failed to stop service {SERVICE}: {ERR}", "SERVICE",
80 service, "ERR", ex);
Ratan Guptae1f4db62019-04-11 18:57:42 +053081 elog<InternalFailure>();
82 }
83}
84
Ratan Guptae1f4db62019-04-11 18:57:42 +053085std::string ConfigMgr::createConfig(
Patrick Williamse6500a42021-05-01 05:58:23 -050086 std::string ldapServerURI, std::string ldapBindDN, std::string ldapBaseDN,
87 std::string ldapBindDNPassword, CreateIface::SearchScope ldapSearchScope,
88 CreateIface::Create::Type ldapType, std::string groupNameAttribute,
Ratan Guptae1f4db62019-04-11 18:57:42 +053089 std::string userNameAttribute)
90{
91 bool secureLDAP = false;
92
Nan Zhou78d85042022-08-29 17:50:22 +000093 if (isValidLDAPURI(ldapServerURI, ldapsScheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053094 {
95 secureLDAP = true;
96 }
Nan Zhou78d85042022-08-29 17:50:22 +000097 else if (isValidLDAPURI(ldapServerURI, ldapScheme))
Ratan Guptae1f4db62019-04-11 18:57:42 +053098 {
99 secureLDAP = false;
100 }
101 else
102 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800103 lg2::error("Bad LDAP Server URI {URI}", "URI", ldapServerURI);
Patrick Williamse6500a42021-05-01 05:58:23 -0500104 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"),
105 Argument::ARGUMENT_VALUE(ldapServerURI.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530106 }
107
108 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
109 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800110 lg2::error("LDAP server CA certificate not found at {PATH}", "PATH",
111 tlsCacertFile);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530112 elog<NoCACertificate>();
113 }
114
Patrick Williamse6500a42021-05-01 05:58:23 -0500115 if (ldapBindDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530116 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800117 lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN",
118 ldapBindDN);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530119 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500120 Argument::ARGUMENT_VALUE(ldapBindDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530121 }
122
Patrick Williamse6500a42021-05-01 05:58:23 -0500123 if (ldapBaseDN.empty())
Ratan Guptae1f4db62019-04-11 18:57:42 +0530124 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800125 lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN",
126 ldapBaseDN);
Ratan Guptae1f4db62019-04-11 18:57:42 +0530127 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
Patrick Williamse6500a42021-05-01 05:58:23 -0500128 Argument::ARGUMENT_VALUE(ldapBaseDN.c_str()));
Ratan Guptae1f4db62019-04-11 18:57:42 +0530129 }
130
Ratan Gupta27d4c012019-04-12 13:03:35 +0530131 // With current implementation we support only two default LDAP server.
132 // which will be always there but when the support comes for additional
133 // account providers then the create config would be used to create the
134 // additional config.
Ratan Guptae1f4db62019-04-11 18:57:42 +0530135
Ratan Gupta27d4c012019-04-12 13:03:35 +0530136 std::string objPath;
Ratan Guptae1f4db62019-04-11 18:57:42 +0530137
Patrick Williamse6500a42021-05-01 05:58:23 -0500138 if (static_cast<ConfigIface::Type>(ldapType) == ConfigIface::Type::OpenLdap)
Ratan Gupta27d4c012019-04-12 13:03:35 +0530139 {
140 openLDAPConfigPtr.reset(nullptr);
141 objPath = openLDAPDbusObjectPath;
142 openLDAPConfigPtr = std::make_unique<Config>(
143 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500144 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
145 ldapBaseDN, std::move(ldapBindDNPassword),
146 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
147 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530148 userNameAttribute, *this);
149 }
150 else
151 {
152 ADConfigPtr.reset(nullptr);
Nan Zhou78d85042022-08-29 17:50:22 +0000153 objPath = adDbusObjectPath;
Ratan Gupta27d4c012019-04-12 13:03:35 +0530154 ADConfigPtr = std::make_unique<Config>(
155 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Patrick Williamse6500a42021-05-01 05:58:23 -0500156 tlsCertFile.c_str(), secureLDAP, ldapServerURI, ldapBindDN,
157 ldapBaseDN, std::move(ldapBindDNPassword),
158 static_cast<ConfigIface::SearchScope>(ldapSearchScope),
159 static_cast<ConfigIface::Type>(ldapType), false, groupNameAttribute,
Ratan Gupta27d4c012019-04-12 13:03:35 +0530160 userNameAttribute, *this);
161 }
Ratan Guptae1f4db62019-04-11 18:57:42 +0530162 restartService(nscdService);
163 return objPath;
164}
165
Ratan Gupta27d4c012019-04-12 13:03:35 +0530166void ConfigMgr::createDefaultObjects()
Ratan Guptae1f4db62019-04-11 18:57:42 +0530167{
Ratan Gupta27d4c012019-04-12 13:03:35 +0530168 if (!openLDAPConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530169 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530170 openLDAPConfigPtr = std::make_unique<Config>(
171 bus, openLDAPDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530172 tlsCacertFile.c_str(), tlsCertFile.c_str(),
173 ConfigIface::Type::OpenLdap, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530174 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530175 }
Ratan Gupta27d4c012019-04-12 13:03:35 +0530176 if (!ADConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530177 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530178 ADConfigPtr = std::make_unique<Config>(
Nan Zhou78d85042022-08-29 17:50:22 +0000179 bus, adDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Guptaab4fcb42019-04-29 19:39:51 +0530180 tlsCacertFile.c_str(), tlsCertFile.c_str(),
181 ConfigIface::Type::ActiveDirectory, *this);
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530182 ADConfigPtr->emit_object_added();
183 }
184}
185
Ratan Guptac5481d12019-04-12 18:31:05 +0530186bool ConfigMgr::enableService(Config& config, bool value)
187{
188 if (value)
189 {
190 if (openLDAPConfigPtr && openLDAPConfigPtr->enabled())
191 {
192 elog<NotAllowed>(NotAllowedArgument::REASON(
193 "OpenLDAP service is already active"));
194 }
195 if (ADConfigPtr && ADConfigPtr->enabled())
196 {
197 elog<NotAllowed>(NotAllowedArgument::REASON(
198 "ActiveDirectory service is already active"));
199 }
200 }
201 return config.enableService(value);
202}
203
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530204void ConfigMgr::restore()
205{
206 createDefaultObjects();
207 // Restore the ldap config and their mappings
208 if (ADConfigPtr->deserialize())
209 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530210 // Restore the role mappings
211 ADConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530212 ADConfigPtr->emit_object_added();
213 }
214 if (openLDAPConfigPtr->deserialize())
215 {
Ratan Gupta7b04c352019-04-12 21:46:29 +0530216 // Restore the role mappings
217 openLDAPConfigPtr->restoreRoleMapping();
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530218 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530219 }
Alexander Filippov372c5662021-06-30 20:23:39 +0300220
221 startOrStopService(phosphor::ldap::nslcdService,
222 ADConfigPtr->enabled() || openLDAPConfigPtr->enabled());
Ratan Guptae1f4db62019-04-11 18:57:42 +0530223}
Ratan Gupta27d4c012019-04-12 13:03:35 +0530224
Ratan Guptae1f4db62019-04-11 18:57:42 +0530225} // namespace ldap
226} // namespace phosphor