blob: 0ce4c61046a826c5e53ff8afbc7297bcbe1f3f25 [file] [log] [blame]
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -05001#include "ldap_configuration.hpp"
Nagaraju Goruganti59287f02018-10-12 07:00:20 -05002#include "utils.hpp"
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -05003#include <experimental/filesystem>
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -05004#include <fstream>
5#include <sstream>
6
7namespace phosphor
8{
9namespace ldap
10{
11constexpr auto nslcdService = "nslcd.service";
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -050012constexpr auto nscdService = "nscd.service";
Nagaraju Goruganti59287f02018-10-12 07:00:20 -050013constexpr auto LDAPscheme = "ldap";
14constexpr auto LDAPSscheme = "ldaps";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050015
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -050016using namespace phosphor::logging;
17using namespace sdbusplus::xyz::openbmc_project::Common::Error;
18namespace fs = std::experimental::filesystem;
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -050019using Argument = xyz::openbmc_project::Common::InvalidArgument;
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -050020
21using Line = std::string;
22using Key = std::string;
23using Val = std::string;
24using ConfigInfo = std::map<Key, Val>;
25
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050026Config::Config(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -060027 const char* caCertFile, bool secureLDAP,
28 std::string lDAPServerURI, std::string lDAPBindDN,
29 std::string lDAPBaseDN, std::string&& lDAPBindDNPassword,
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050030 ldap_base::Config::SearchScope lDAPSearchScope,
31 ldap_base::Config::Type lDAPType, ConfigMgr& parent) :
32 ConfigIface(bus, path, true),
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -060033 secureLDAP(secureLDAP), configFilePath(filePath), tlsCacertFile(caCertFile),
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -060034 lDAPBindDNPassword(std::move(lDAPBindDNPassword)), bus(bus), parent(parent)
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050035{
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050036 ConfigIface::lDAPServerURI(lDAPServerURI);
37 ConfigIface::lDAPBindDN(lDAPBindDN);
38 ConfigIface::lDAPBaseDN(lDAPBaseDN);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050039 ConfigIface::lDAPSearchScope(lDAPSearchScope);
40 ConfigIface::lDAPType(lDAPType);
41 writeConfig();
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050042 // Emit deferred signal.
43 this->emit_object_added();
44}
45
Nagaraju Goruganti24194bd2018-09-18 09:55:09 -050046void Config::delete_()
47{
48 parent.deleteObject();
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -050049 try
50 {
Nagaraju Gorugantid514e5d2018-11-08 03:07:25 -060051 fs::path configDir = fs::path(configFilePath.c_str()).parent_path();
52
53 fs::copy_file(configDir / defaultNslcdFile, LDAP_CONFIG_FILE,
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -050054 fs::copy_options::overwrite_existing);
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -050055 }
56 catch (const std::exception& e)
57 {
58 log<level::ERR>("Failed to rename Config Files while deleting Object",
59 entry("ERR=%s", e.what()));
60 elog<InternalFailure>();
61 }
62
63 parent.restartService(nscdService);
64 parent.stopService(nslcdService);
Nagaraju Goruganti24194bd2018-09-18 09:55:09 -050065}
66
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050067void Config::writeConfig()
68{
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050069 std::stringstream confData;
Ratan Gupta9891f2f2018-10-06 12:07:35 +053070 auto isPwdTobeWritten = false;
71
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050072 confData << "uid root\n";
73 confData << "gid root\n\n";
74 confData << "ldap_version 3\n\n";
75 confData << "timelimit 30\n";
76 confData << "bind_timelimit 30\n";
77 confData << "pagesize 1000\n";
78 confData << "referrals off\n\n";
79 confData << "uri " << lDAPServerURI() << "\n\n";
80 confData << "base " << lDAPBaseDN() << "\n\n";
81 confData << "binddn " << lDAPBindDN() << "\n";
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -060082 if (!lDAPBindDNPassword.empty())
Nagaraju Goruganti15675472018-10-05 07:03:05 -050083 {
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -060084 confData << "bindpw " << lDAPBindDNPassword << "\n";
Ratan Gupta9891f2f2018-10-06 12:07:35 +053085 isPwdTobeWritten = true;
Nagaraju Goruganti15675472018-10-05 07:03:05 -050086 }
87 confData << "\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -050088 switch (lDAPSearchScope())
89 {
90 case ldap_base::Config::SearchScope::sub:
91 confData << "scope sub\n\n";
92 break;
93 case ldap_base::Config::SearchScope::one:
94 confData << "scope one\n\n";
95 break;
96 case ldap_base::Config::SearchScope::base:
97 confData << "scope base\n\n";
98 break;
99 }
100 confData << "base passwd " << lDAPBaseDN() << "\n";
101 confData << "base shadow " << lDAPBaseDN() << "\n\n";
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600102 if (secureLDAP == true)
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500103 {
104 confData << "ssl on\n";
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600105 confData << "tls_reqcert hard\n";
106 confData << "tls_cacertFile " << tlsCacertFile.c_str() << "\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500107 }
108 else
109 {
Nagaraju Goruganti15675472018-10-05 07:03:05 -0500110 confData << "ssl off\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500111 }
Nagaraju Goruganti15675472018-10-05 07:03:05 -0500112 confData << "\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500113 if (lDAPType() == ldap_base::Config::Type::ActiveDirectory)
114 {
115 confData << "filter passwd (&(objectClass=user)(objectClass=person)"
116 "(!(objectClass=computer)))\n";
117 confData
118 << "filter group (|(objectclass=group)(objectclass=groupofnames) "
119 "(objectclass=groupofuniquenames))\n";
120 confData << "map passwd uid sAMAccountName\n";
121 confData << "map passwd uidNumber "
122 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
123 confData << "map passwd gidNumber primaryGroupID\n";
124 confData << "map passwd homeDirectory \"/home/$sAMAccountName\"\n";
125 confData << "map passwd gecos displayName\n";
126 confData << "map passwd loginShell \"/bin/bash\"\n";
127 confData << "map group gidNumber primaryGroupID\n";
128 confData << "map group gidNumber "
129 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
130 confData << "map group cn sAMAccountName\n";
131 }
132 else if (lDAPType() == ldap_base::Config::Type::OpenLdap)
133 {
134 confData << "filter passwd (objectclass=*)\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500135 confData << "map passwd gecos displayName\n";
Nagaraju Goruganti808eda42018-10-10 08:48:12 -0500136 confData << "filter group (objectclass=posixGroup)\n";
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500137 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500138 try
139 {
140 std::fstream stream(configFilePath.c_str(), std::fstream::out);
Ratan Gupta9891f2f2018-10-06 12:07:35 +0530141 // remove the read permission from others if password is being written.
142 // nslcd forces this behaviour.
143 auto permission = fs::perms::owner_read | fs::perms::owner_write |
144 fs::perms::group_read;
145 if (isPwdTobeWritten)
146 {
147 fs::permissions(configFilePath, permission);
148 }
149 else
150 {
151 fs::permissions(configFilePath,
152 permission | fs::perms::others_read);
153 }
154
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500155 stream << confData.str();
156 stream.flush();
157 stream.close();
158 }
159 catch (const std::exception& e)
160 {
161 log<level::ERR>(e.what());
162 elog<InternalFailure>();
163 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500164 return;
165}
166
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500167std::string Config::lDAPServerURI(std::string value)
168{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500169 std::string val;
170 try
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500171 {
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500172 if (value == lDAPServerURI())
173 {
174 return value;
175 }
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500176 if (isValidLDAPURI(value, LDAPSscheme))
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500177 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500178 secureLDAP = true;
179 }
180 else if (isValidLDAPURI(value, LDAPscheme))
181 {
182 secureLDAP = false;
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600183 }
184 else
185 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500186 log<level::ERR>("bad LDAP Server URI",
187 entry("LDAPSERVERURI=%s", value.c_str()));
188 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
189 Argument::ARGUMENT_VALUE(value.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500190 }
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600191
192 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
193 {
194 log<level::ERR>("LDAP server's CA certificate not provided",
195 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
196 elog<NoCACertificate>();
197 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500198 val = ConfigIface::lDAPServerURI(value);
199 writeConfig();
200 parent.restartService(nslcdService);
201 }
202 catch (const InternalFailure& e)
203 {
204 throw;
205 }
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500206 catch (const InvalidArgument& e)
207 {
208 throw;
209 }
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600210 catch (const NoCACertificate& e)
211 {
212 throw;
213 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500214 catch (const std::exception& e)
215 {
216 log<level::ERR>(e.what());
217 elog<InternalFailure>();
218 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500219 return val;
220}
221
222std::string Config::lDAPBindDN(std::string value)
223{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500224 std::string val;
225 try
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500226 {
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500227 if (value == lDAPBindDN())
228 {
229 return value;
230 }
231
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500232 if (value.empty())
233 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500234 log<level::ERR>("Not a valid LDAP BINDDN",
235 entry("LDAPBINDDN=%s", value.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500236 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBindDN"),
237 Argument::ARGUMENT_VALUE(value.c_str()));
238 }
239
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500240 val = ConfigIface::lDAPBindDN(value);
241 writeConfig();
242 parent.restartService(nslcdService);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500243 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500244 catch (const InternalFailure& e)
245 {
246 throw;
247 }
Nagaraju Gorugantid514e5d2018-11-08 03:07:25 -0600248 catch (const InvalidArgument& e)
249 {
250 throw;
251 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500252 catch (const std::exception& e)
253 {
254 log<level::ERR>(e.what());
255 elog<InternalFailure>();
256 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500257 return val;
258}
259
260std::string Config::lDAPBaseDN(std::string value)
261{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500262 std::string val;
263 try
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500264 {
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500265 if (value == lDAPBaseDN())
266 {
267 return value;
268 }
269
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500270 if (value.empty())
271 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500272 log<level::ERR>("Not a valid LDAP BASEDN",
273 entry("BASEDN=%s", value.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500274 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBaseDN"),
275 Argument::ARGUMENT_VALUE(value.c_str()));
276 }
277
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500278 val = ConfigIface::lDAPBaseDN(value);
279 writeConfig();
280 parent.restartService(nslcdService);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500281 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500282 catch (const InternalFailure& e)
283 {
284 throw;
285 }
Nagaraju Gorugantid514e5d2018-11-08 03:07:25 -0600286 catch (const InvalidArgument& e)
287 {
288 throw;
289 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500290 catch (const std::exception& e)
291 {
292 log<level::ERR>(e.what());
293 elog<InternalFailure>();
294 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500295 return val;
296}
297
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500298ldap_base::Config::SearchScope
299 Config::lDAPSearchScope(ldap_base::Config::SearchScope value)
300{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500301 ldap_base::Config::SearchScope val;
302 try
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500303 {
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500304 if (value == lDAPSearchScope())
305 {
306 return value;
307 }
308
309 val = ConfigIface::lDAPSearchScope(value);
310 writeConfig();
311 parent.restartService(nslcdService);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500312 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500313 catch (const InternalFailure& e)
314 {
315 throw;
316 }
317 catch (const std::exception& e)
318 {
319 log<level::ERR>(e.what());
320 elog<InternalFailure>();
321 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500322 return val;
323}
324
325ldap_base::Config::Type Config::lDAPType(ldap_base::Config::Type value)
326{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500327 ldap_base::Config::Type val;
328 try
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500329 {
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500330 if (value == lDAPType())
331 {
332 return value;
333 }
334
335 val = ConfigIface::lDAPType(value);
336 writeConfig();
337 parent.restartService(nslcdService);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500338 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500339 catch (const InternalFailure& e)
340 {
341 throw;
342 }
343 catch (const std::exception& e)
344 {
345 log<level::ERR>(e.what());
346 elog<InternalFailure>();
347 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500348 return val;
349}
350
351void ConfigMgr::restartService(const std::string& service)
352{
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500353 try
354 {
355 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
356 SYSTEMD_INTERFACE, "RestartUnit");
357 method.append(service.c_str(), "replace");
358 bus.call_noreply(method);
359 }
360 catch (const sdbusplus::exception::SdBusError& ex)
361 {
362 log<level::ERR>("Failed to restart nslcd service",
363 entry("ERR=%s", ex.what()));
364 elog<InternalFailure>();
365 }
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500366}
367
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -0500368void ConfigMgr::stopService(const std::string& service)
369{
370 try
371 {
372 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
373 SYSTEMD_INTERFACE, "StopUnit");
374 method.append(service.c_str(), "replace");
375 bus.call_noreply(method);
376 }
377 catch (const sdbusplus::exception::SdBusError& ex)
378 {
379 log<level::ERR>("Failed to stop nslcd service",
380 entry("ERR=%s", ex.what()));
381 elog<InternalFailure>();
382 }
383}
384
Nagaraju Goruganti24194bd2018-09-18 09:55:09 -0500385void ConfigMgr::deleteObject()
386{
387 configPtr.reset(nullptr);
388}
389
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500390std::string
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600391 ConfigMgr::createConfig(std::string lDAPServerURI, std::string lDAPBindDN,
392 std::string lDAPBaseDN,
393 std::string lDAPBindDNPassword,
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500394 ldap_base::Create::SearchScope lDAPSearchScope,
395 ldap_base::Create::Type lDAPType)
396{
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600397 bool secureLDAP = false;
398
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500399 if (isValidLDAPURI(lDAPServerURI, LDAPSscheme))
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500400 {
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600401 secureLDAP = true;
402 }
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500403 else if (isValidLDAPURI(lDAPServerURI, LDAPscheme))
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600404 {
405 secureLDAP = false;
406 }
407 else
408 {
409 log<level::ERR>("bad LDAP Server URI",
410 entry("LDAPSERVERURI=%s", lDAPServerURI.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500411 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
412 Argument::ARGUMENT_VALUE(lDAPServerURI.c_str()));
413 }
414
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600415 if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
416 {
417 log<level::ERR>("LDAP server's CA certificate not provided",
418 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
419 elog<NoCACertificate>();
420 }
421
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500422 if (lDAPBindDN.empty())
423 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500424 log<level::ERR>("Not a valid LDAP BINDDN",
425 entry("LDAPBINDDN=%s", lDAPBindDN.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500426 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
427 Argument::ARGUMENT_VALUE(lDAPBindDN.c_str()));
428 }
429
430 if (lDAPBaseDN.empty())
431 {
Nagaraju Goruganti59287f02018-10-12 07:00:20 -0500432 log<level::ERR>("Not a valid LDAP BASEDN",
433 entry("LDAPBASEDN=%s", lDAPBaseDN.c_str()));
Nagaraju Gorugantib26799a2018-09-28 13:12:19 -0500434 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
435 Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str()));
436 }
437
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500438 // With current implementation we support only one LDAP server.
Nagaraju Goruganti24194bd2018-09-18 09:55:09 -0500439 deleteObject();
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500440
441 auto objPath = std::string(LDAP_CONFIG_DBUS_OBJ_PATH);
442 configPtr = std::make_unique<Config>(
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600443 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
444 secureLDAP, lDAPServerURI, lDAPBindDN, lDAPBaseDN,
445 std::move(lDAPBindDNPassword),
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500446 static_cast<ldap_base::Config::SearchScope>(lDAPSearchScope),
447 static_cast<ldap_base::Config::Type>(lDAPType), *this);
448
Nagaraju Gorugantidccee2b2018-09-25 08:51:06 -0500449 restartService(nslcdService);
450 restartService(nscdService);
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500451 return objPath;
452}
453
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500454void ConfigMgr::restore(const char* filePath)
455{
456 if (!fs::exists(filePath))
457 {
458 log<level::ERR>("Config file doesn't exists",
Nagaraju Gorugantid514e5d2018-11-08 03:07:25 -0600459 entry("LDAP_CONFIG_FILE=%s", configFilePath.c_str()));
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500460 return;
461 }
462
463 ConfigInfo configValues;
464
465 try
466 {
467 std::fstream stream(filePath, std::fstream::in);
468 Line line;
469 // read characters from stream and places them into line
470 while (std::getline(stream, line))
471 {
472 // remove leading and trailing extra spaces
473 auto firstScan = line.find_first_not_of(' ');
474 auto first =
475 (firstScan == std::string::npos ? line.length() : firstScan);
476 auto last = line.find_last_not_of(' ');
477 line = line.substr(first, last - first + 1);
478 // reduce multiple spaces between two words to a single space
479 auto pred = [](char a, char b) {
480 return (a == b && a == ' ') ? true : false;
481 };
482
483 auto lastPos = std::unique(line.begin(), line.end(), pred);
484
485 line.erase(lastPos, line.end());
486
487 // Ignore if line is empty or starts with '#'
488 if (line.empty() || line.at(0) == '#')
489 {
490 continue;
491 }
492
493 Key key;
494 std::istringstream isLine(line);
495 // extract characters from isLine and stores them into
496 // key until the delimitation character ' ' is found.
497 // If the delimiter is found, it is extracted and discarded
498 // the next input operation will begin after it.
499 if (std::getline(isLine, key, ' '))
500 {
501 Val value;
502 // extract characters after delimitation character ' '
503 if (std::getline(isLine, value, ' '))
504 {
505 // skip line if it starts with "base shadow" or
506 // "base passwd" because we would have 3 entries
507 // ("base lDAPBaseDN" , "base passwd lDAPBaseDN" and
508 // "base shadow lDAPBaseDN") for the property "lDAPBaseDN",
509 // one is enough to restore it.
510
511 if ((key == "base") &&
512 (value == "passwd" || value == "shadow"))
513 {
514 continue;
515 }
516 // skip the line if it starts with "map passwd".
517 // if config type is AD "map group" entry would be add to
518 // the map configValues. For OpenLdap config file no map
519 // entry would be there.
520 if ((key == "map") && (value == "passwd"))
521 {
522 continue;
523 }
524 configValues[key] = value;
525 }
526 }
527 }
528
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500529 ldap_base::Create::SearchScope lDAPSearchScope;
530 if (configValues["scope"] == "sub")
531 {
532 lDAPSearchScope = ldap_base::Create::SearchScope::sub;
533 }
534 else if (configValues["scope"] == "one")
535 {
536 lDAPSearchScope = ldap_base::Create::SearchScope::one;
537 }
538 else
539 {
540 lDAPSearchScope = ldap_base::Create::SearchScope::base;
541 }
542
543 ldap_base::Create::Type lDAPType;
544 // If the file is having a line which starts with "map group"
545 if (configValues["map"] == "group")
546 {
547 lDAPType = ldap_base::Create::Type::ActiveDirectory;
548 }
549 else
550 {
551 lDAPType = ldap_base::Create::Type::OpenLdap;
552 }
553
Ratan Guptac9c86a22018-10-18 00:47:01 +0530554 // Don't create the config object if either of the field is empty.
555 if (configValues["uri"] == "" || configValues["binddn"] == "" ||
556 configValues["base"] == "")
557 {
558 log<level::INFO>(
559 "LDAP config parameter value missing",
560 entry("URI=%s", configValues["uri"].c_str()),
561 entry("BASEDN=%s", configValues["base"].c_str()),
562 entry("BINDDN=%s", configValues["binddn"].c_str()));
563 return;
564 }
565
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500566 createConfig(
Nagaraju Gorugantidb60f582018-11-08 03:14:48 -0600567 std::move(configValues["uri"]), std::move(configValues["binddn"]),
568 std::move(configValues["base"]), std::move(configValues["bindpw"]),
569 lDAPSearchScope, lDAPType);
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500570 }
571 catch (const InvalidArgument& e)
572 {
573 // Don't throw - we don't want to create a D-Bus
574 // object upon finding empty values in config, as
575 // this can be a default config.
576 }
Nagaraju Goruganti3b4d06a2018-11-08 03:13:38 -0600577 catch (const NoCACertificate& e)
578 {
579 // Don't throw - we don't want to create a D-Bus
580 // object upon finding "ssl on" without having tls_cacertFile in place,
581 // as this can be a default config.
582 }
Nagaraju Gorugantif1940d92018-09-18 05:05:50 -0500583 catch (const InternalFailure& e)
584 {
585 throw;
586 }
587 catch (const std::exception& e)
588 {
589 log<level::ERR>(e.what());
590 elog<InternalFailure>();
591 }
592}
Nagaraju Goruganti997f5e02018-08-30 03:05:11 -0500593} // namespace ldap
594} // namespace phosphor