blob: 30217931db98ba51df40cb5cc2fdab63ef536645 [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(
79 std::string lDAPServerURI, std::string lDAPBindDN, std::string lDAPBaseDN,
80 std::string lDAPBindDNPassword, CreateIface::SearchScope lDAPSearchScope,
81 CreateIface::Create::Type lDAPType, std::string groupNameAttribute,
82 std::string userNameAttribute)
83{
84 bool secureLDAP = false;
85
86 if (isValidLDAPURI(lDAPServerURI, LDAPSscheme))
87 {
88 secureLDAP = true;
89 }
90 else if (isValidLDAPURI(lDAPServerURI, LDAPscheme))
91 {
92 secureLDAP = false;
93 }
94 else
95 {
96 log<level::ERR>("bad LDAP Server URI",
97 entry("LDAPSERVERURI=%s", lDAPServerURI.c_str()));
98 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
99 Argument::ARGUMENT_VALUE(lDAPServerURI.c_str()));
100 }
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
109 if (lDAPBindDN.empty())
110 {
111 log<level::ERR>("Not a valid LDAP BINDDN",
112 entry("LDAPBINDDN=%s", lDAPBindDN.c_str()));
113 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
114 Argument::ARGUMENT_VALUE(lDAPBindDN.c_str()));
115 }
116
117 if (lDAPBaseDN.empty())
118 {
119 log<level::ERR>("Not a valid LDAP BASEDN",
120 entry("LDAPBASEDN=%s", lDAPBaseDN.c_str()));
121 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
122 Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str()));
123 }
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
Ratan Gupta27d4c012019-04-12 13:03:35 +0530132 if (static_cast<ConfigIface::Type>(lDAPType) == ConfigIface::Type::OpenLdap)
133 {
134 openLDAPConfigPtr.reset(nullptr);
135 objPath = openLDAPDbusObjectPath;
136 openLDAPConfigPtr = std::make_unique<Config>(
137 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
Ratan Gupta22f13f12019-04-29 15:36:40 +0530138 tlsCertFile.c_str(), secureLDAP, lDAPServerURI, lDAPBindDN,
139 lDAPBaseDN, std::move(lDAPBindDNPassword),
Ratan Gupta27d4c012019-04-12 13:03:35 +0530140 static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
141 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
142 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(),
Ratan Gupta22f13f12019-04-29 15:36:40 +0530150 tlsCertFile.c_str(), secureLDAP, lDAPServerURI, lDAPBindDN,
151 lDAPBaseDN, std::move(lDAPBindDNPassword),
Ratan Gupta27d4c012019-04-12 13:03:35 +0530152 static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
153 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
154 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