blob: 914253876d5899980a48afdfe8c24b0f6e6a2092 [file] [log] [blame]
Ratan Guptae1f4db62019-04-11 18:57:42 +05301#include "ldap_config_mgr.hpp"
Ratan Gupta37fb3fe2019-04-13 12:54:18 +05302#include "ldap_config.hpp"
Ratan Guptae1f4db62019-04-11 18:57:42 +05303
4#include "utils.hpp"
5#include <filesystem>
6#include <fstream>
7#include <sstream>
8
9namespace phosphor
10{
11namespace ldap
12{
13
14constexpr auto nscdService = "nscd.service";
15constexpr auto LDAPscheme = "ldap";
16constexpr auto LDAPSscheme = "ldaps";
17
18using namespace phosphor::logging;
19using namespace sdbusplus::xyz::openbmc_project::Common::Error;
20namespace fs = std::filesystem;
21using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Guptac5481d12019-04-12 18:31:05 +053022using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
23using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
Ratan Guptae1f4db62019-04-11 18:57:42 +053024
25using Line = std::string;
26using Key = std::string;
27using Val = std::string;
28using ConfigInfo = std::map<Key, Val>;
29
30void ConfigMgr::startOrStopService(const std::string& service, bool start)
31{
32 if (start)
33 {
34 restartService(service);
35 }
36 else
37 {
38 stopService(service);
39 }
40}
41
42void ConfigMgr::restartService(const std::string& service)
43{
44 try
45 {
46 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
47 SYSTEMD_INTERFACE, "RestartUnit");
48 method.append(service.c_str(), "replace");
49 bus.call_noreply(method);
50 }
51 catch (const sdbusplus::exception::SdBusError& ex)
52 {
53 log<level::ERR>("Failed to restart service",
54 entry("SERVICE=%s", service.c_str()),
55 entry("ERR=%s", ex.what()));
56 elog<InternalFailure>();
57 }
58}
59void ConfigMgr::stopService(const std::string& service)
60{
61 try
62 {
63 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
64 SYSTEMD_INTERFACE, "StopUnit");
65 method.append(service.c_str(), "replace");
66 bus.call_noreply(method);
67 }
68 catch (const sdbusplus::exception::SdBusError& ex)
69 {
70 log<level::ERR>("Failed to stop service",
71 entry("SERVICE=%s", service.c_str()),
72 entry("ERR=%s", ex.what()));
73 elog<InternalFailure>();
74 }
75}
76
Ratan Guptae1f4db62019-04-11 18:57:42 +053077std::string ConfigMgr::createConfig(
78 std::string lDAPServerURI, std::string lDAPBindDN, std::string lDAPBaseDN,
79 std::string lDAPBindDNPassword, CreateIface::SearchScope lDAPSearchScope,
80 CreateIface::Create::Type lDAPType, std::string groupNameAttribute,
81 std::string userNameAttribute)
82{
83 bool secureLDAP = false;
84
85 if (isValidLDAPURI(lDAPServerURI, LDAPSscheme))
86 {
87 secureLDAP = true;
88 }
89 else if (isValidLDAPURI(lDAPServerURI, LDAPscheme))
90 {
91 secureLDAP = false;
92 }
93 else
94 {
95 log<level::ERR>("bad LDAP Server URI",
96 entry("LDAPSERVERURI=%s", lDAPServerURI.c_str()));
97 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
98 Argument::ARGUMENT_VALUE(lDAPServerURI.c_str()));
99 }
100
101 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
102 {
103 log<level::ERR>("LDAP server's CA certificate not provided",
104 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
105 elog<NoCACertificate>();
106 }
107
108 if (lDAPBindDN.empty())
109 {
110 log<level::ERR>("Not a valid LDAP BINDDN",
111 entry("LDAPBINDDN=%s", lDAPBindDN.c_str()));
112 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
113 Argument::ARGUMENT_VALUE(lDAPBindDN.c_str()));
114 }
115
116 if (lDAPBaseDN.empty())
117 {
118 log<level::ERR>("Not a valid LDAP BASEDN",
119 entry("LDAPBASEDN=%s", lDAPBaseDN.c_str()));
120 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
121 Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str()));
122 }
123
Ratan Gupta27d4c012019-04-12 13:03:35 +0530124 // With current implementation we support only two default LDAP server.
125 // which will be always there but when the support comes for additional
126 // account providers then the create config would be used to create the
127 // additional config.
Ratan Guptae1f4db62019-04-11 18:57:42 +0530128
Ratan Gupta27d4c012019-04-12 13:03:35 +0530129 std::string objPath;
Ratan Guptae1f4db62019-04-11 18:57:42 +0530130
Ratan Gupta27d4c012019-04-12 13:03:35 +0530131 if (static_cast<ConfigIface::Type>(lDAPType) == ConfigIface::Type::OpenLdap)
132 {
133 openLDAPConfigPtr.reset(nullptr);
134 objPath = openLDAPDbusObjectPath;
135 openLDAPConfigPtr = std::make_unique<Config>(
136 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
137 secureLDAP, lDAPServerURI, lDAPBindDN, lDAPBaseDN,
138 std::move(lDAPBindDNPassword),
139 static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
140 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
141 userNameAttribute, *this);
142 }
143 else
144 {
145 ADConfigPtr.reset(nullptr);
146 objPath = ADDbusObjectPath;
147 ADConfigPtr = std::make_unique<Config>(
148 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
149 secureLDAP, lDAPServerURI, lDAPBindDN, lDAPBaseDN,
150 std::move(lDAPBindDNPassword),
151 static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
152 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
153 userNameAttribute, *this);
154 }
Ratan Guptae1f4db62019-04-11 18:57:42 +0530155 restartService(nscdService);
156 return objPath;
157}
158
Ratan Gupta27d4c012019-04-12 13:03:35 +0530159void ConfigMgr::createDefaultObjects()
Ratan Guptae1f4db62019-04-11 18:57:42 +0530160{
Ratan Gupta27d4c012019-04-12 13:03:35 +0530161 if (!openLDAPConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530162 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530163 openLDAPConfigPtr = std::make_unique<Config>(
164 bus, openLDAPDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530165 tlsCacertFile.c_str(), ConfigIface::Type::OpenLdap, *this);
166 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530167 }
Ratan Gupta27d4c012019-04-12 13:03:35 +0530168 if (!ADConfigPtr)
Ratan Guptae1f4db62019-04-11 18:57:42 +0530169 {
Ratan Gupta27d4c012019-04-12 13:03:35 +0530170 ADConfigPtr = std::make_unique<Config>(
171 bus, ADDbusObjectPath.c_str(), configFilePath.c_str(),
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530172 tlsCacertFile.c_str(), ConfigIface::Type::ActiveDirectory, *this);
173 ADConfigPtr->emit_object_added();
174 }
175}
176
Ratan Guptac5481d12019-04-12 18:31:05 +0530177bool ConfigMgr::enableService(Config& config, bool value)
178{
179 if (value)
180 {
181 if (openLDAPConfigPtr && openLDAPConfigPtr->enabled())
182 {
183 elog<NotAllowed>(NotAllowedArgument::REASON(
184 "OpenLDAP service is already active"));
185 }
186 if (ADConfigPtr && ADConfigPtr->enabled())
187 {
188 elog<NotAllowed>(NotAllowedArgument::REASON(
189 "ActiveDirectory service is already active"));
190 }
191 }
192 return config.enableService(value);
193}
194
Ratan Gupta21e88cb2019-04-12 17:15:52 +0530195void ConfigMgr::restore()
196{
197 createDefaultObjects();
198 // Restore the ldap config and their mappings
199 if (ADConfigPtr->deserialize())
200 {
201 // Restore the role mappings in later commit
202 ADConfigPtr->emit_object_added();
203 }
204 if (openLDAPConfigPtr->deserialize())
205 {
206 // Restore the role mappings in later commit
207 openLDAPConfigPtr->emit_object_added();
Ratan Guptae1f4db62019-04-11 18:57:42 +0530208 }
209}
Ratan Gupta27d4c012019-04-12 13:03:35 +0530210
Ratan Guptae1f4db62019-04-11 18:57:42 +0530211} // namespace ldap
212} // namespace phosphor