1 #include "config.h"
2 
3 #include "phosphor-ldap-config/ldap_config.hpp"
4 #include "phosphor-ldap-config/ldap_config_mgr.hpp"
5 
6 #include <sys/types.h>
7 
8 #include <phosphor-logging/elog-errors.hpp>
9 #include <phosphor-logging/log.hpp>
10 #include <sdbusplus/bus.hpp>
11 #include <xyz/openbmc_project/Common/error.hpp>
12 #include <xyz/openbmc_project/User/Common/error.hpp>
13 
14 #include <filesystem>
15 #include <fstream>
16 #include <string>
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 namespace phosphor
22 {
23 namespace ldap
24 {
25 namespace fs = std::filesystem;
26 namespace ldap_base = sdbusplus::xyz::openbmc_project::User::Ldap::server;
27 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
28 using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
29 
30 using Config = phosphor::ldap::Config;
31 static constexpr const char* dbusPersistFile = "Config";
32 using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common::
33     Error::PrivilegeMappingExists;
34 
35 class TestLDAPConfig : public testing::Test
36 {
37   public:
38     TestLDAPConfig() : bus(sdbusplus::bus::new_default())
39     {}
40     void SetUp() override
41     {
42         using namespace phosphor::ldap;
43         char tmpldap[] = "/tmp/ldap_test.XXXXXX";
44         dir = fs::path(mkdtemp(tmpldap));
45         fs::path tlsCacertFilePath{TLS_CACERT_PATH};
46         tlsCacertFile = tlsCacertFilePath.filename().c_str();
47         fs::path tlsCertFilePath{TLS_CERT_FILE};
48         tlsCertFile = tlsCertFilePath.filename().c_str();
49 
50         fs::path confFilePath{LDAP_CONFIG_FILE};
51         ldapconfFile = confFilePath.filename().c_str();
52         std::fstream fs;
53         fs.open(dir / defaultNslcdFile, std::fstream::out);
54         fs.close();
55         fs.open(dir / nsSwitchFile, std::fstream::out);
56         fs.close();
57         fs.open(dir / tlsCacertFile, std::fstream::out);
58         fs.close();
59         fs.open(dir / tlsCertFile, std::fstream::out);
60         fs.close();
61     }
62 
63     void TearDown() override
64     {
65         fs::remove_all(dir);
66     }
67 
68   protected:
69     fs::path dir;
70     std::string tlsCacertFile;
71     std::string tlsCertFile;
72     std::string ldapconfFile;
73     sdbusplus::bus::bus bus;
74 };
75 
76 class MockConfigMgr : public phosphor::ldap::ConfigMgr
77 {
78   public:
79     MockConfigMgr(sdbusplus::bus::bus& bus, const char* path,
80                   const char* filePath, const char* dbusPersistentFile,
81                   const char* caCertFile, const char* certFile) :
82         phosphor::ldap::ConfigMgr(bus, path, filePath, dbusPersistentFile,
83                                   caCertFile, certFile)
84     {}
85     MOCK_METHOD1(restartService, void(const std::string& service));
86     MOCK_METHOD1(stopService, void(const std::string& service));
87     std::unique_ptr<Config>& getOpenLdapConfigPtr()
88     {
89         return openLDAPConfigPtr;
90     }
91 
92     std::string configBindPassword()
93     {
94         return getADConfigPtr()->ldapBindPassword;
95     }
96 
97     std::unique_ptr<Config>& getADConfigPtr()
98     {
99         return ADConfigPtr;
100     }
101     void restore()
102     {
103         phosphor::ldap::ConfigMgr::restore();
104         return;
105     }
106 
107     void createDefaultObjects()
108     {
109         phosphor::ldap::ConfigMgr::createDefaultObjects();
110     }
111 
112     bool secureLDAP()
113     {
114         return ADConfigPtr->secureLDAP;
115     }
116 
117     friend class TestLDAPConfig;
118 };
119 
120 TEST_F(TestLDAPConfig, testCreate)
121 {
122     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
123     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
124     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
125     auto dbusPersistentFilePath = std::string(dir.c_str());
126 
127     if (fs::exists(configFilePath))
128     {
129         fs::remove(configFilePath);
130     }
131     EXPECT_FALSE(fs::exists(configFilePath));
132     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
133                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
134                           tlsCertfile.c_str());
135 
136     EXPECT_CALL(manager, stopService("nslcd.service")).Times(2);
137     EXPECT_CALL(manager, restartService("nslcd.service")).Times(2);
138     EXPECT_CALL(manager, restartService("nscd.service")).Times(2);
139 
140     manager.createConfig(
141         "ldap://9.194.251.136/", "cn=Users,dc=com", "cn=Users,dc=corp",
142         "MyLdap12", ldap_base::Create::SearchScope::sub,
143         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
144     manager.getADConfigPtr()->enabled(true);
145 
146     manager.createConfig("ldap://9.194.251.137/", "cn=Users",
147                          "cn=Users,dc=test", "MyLdap123",
148                          ldap_base::Create::SearchScope::sub,
149                          ldap_base::Create::Type::OpenLdap, "uid", "gid");
150     manager.getOpenLdapConfigPtr()->enabled(false);
151 
152     // Below setting of username/groupname attr is to make sure
153     // that in-active config should not call the start/stop service.
154     manager.getOpenLdapConfigPtr()->userNameAttribute("abc");
155     EXPECT_EQ(manager.getOpenLdapConfigPtr()->userNameAttribute(), "abc");
156 
157     manager.getOpenLdapConfigPtr()->groupNameAttribute("def");
158     EXPECT_EQ(manager.getOpenLdapConfigPtr()->groupNameAttribute(), "def");
159 
160     EXPECT_TRUE(fs::exists(configFilePath));
161     EXPECT_EQ(manager.getADConfigPtr()->ldapServerURI(),
162               "ldap://9.194.251.136/");
163     EXPECT_EQ(manager.getADConfigPtr()->ldapBindDN(), "cn=Users,dc=com");
164     EXPECT_EQ(manager.getADConfigPtr()->ldapBaseDN(), "cn=Users,dc=corp");
165     EXPECT_EQ(manager.getADConfigPtr()->ldapSearchScope(),
166               ldap_base::Config::SearchScope::sub);
167     EXPECT_EQ(manager.getADConfigPtr()->ldapType(),
168               ldap_base::Config::Type::ActiveDirectory);
169 
170     EXPECT_EQ(manager.getADConfigPtr()->userNameAttribute(), "uid");
171     EXPECT_EQ(manager.getADConfigPtr()->groupNameAttribute(), "gid");
172     EXPECT_EQ(manager.getADConfigPtr()->ldapBindDNPassword(), "");
173     EXPECT_EQ(manager.configBindPassword(), "MyLdap12");
174     // change the password
175     manager.getADConfigPtr()->ldapBindDNPassword("MyLdap14");
176     EXPECT_EQ(manager.getADConfigPtr()->ldapBindDNPassword(), "");
177     EXPECT_EQ(manager.configBindPassword(), "MyLdap14");
178 }
179 
180 TEST_F(TestLDAPConfig, testDefaultObject)
181 {
182     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
183     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
184     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
185     auto dbusPersistentFilePath = std::string(dir.c_str());
186 
187     if (fs::exists(configFilePath))
188     {
189         fs::remove(configFilePath);
190     }
191     EXPECT_FALSE(fs::exists(configFilePath));
192 
193     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
194                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
195                           tlsCertfile.c_str());
196 
197     manager.createDefaultObjects();
198 
199     EXPECT_NE(nullptr, manager.getADConfigPtr());
200     EXPECT_NE(nullptr, manager.getOpenLdapConfigPtr());
201     EXPECT_EQ(manager.getADConfigPtr()->ldapType(),
202               ldap_base::Config::Type::ActiveDirectory);
203     EXPECT_EQ(manager.getOpenLdapConfigPtr()->ldapType(),
204               ldap_base::Config::Type::OpenLdap);
205 }
206 
207 TEST_F(TestLDAPConfig, testRestoresDefault)
208 {
209     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
210     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
211     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
212     auto dbusPersistentFilePath = std::string(dir.c_str());
213 
214     if (fs::exists(configFilePath))
215     {
216         fs::remove(configFilePath);
217     }
218     EXPECT_FALSE(fs::exists(configFilePath));
219 
220     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
221                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
222                           tlsCertfile.c_str());
223 
224     EXPECT_CALL(manager, stopService("nslcd.service")).Times(1);
225     EXPECT_CALL(manager, restartService("nslcd.service")).Times(0);
226     EXPECT_CALL(manager, restartService("nscd.service")).Times(0);
227 
228     manager.restore();
229 
230     EXPECT_NE(nullptr, manager.getADConfigPtr());
231     EXPECT_NE(nullptr, manager.getOpenLdapConfigPtr());
232     EXPECT_EQ(manager.getADConfigPtr()->ldapType(),
233               ldap_base::Config::Type::ActiveDirectory);
234     EXPECT_EQ(manager.getOpenLdapConfigPtr()->ldapType(),
235               ldap_base::Config::Type::OpenLdap);
236     EXPECT_FALSE(manager.getADConfigPtr()->enabled());
237     EXPECT_FALSE(manager.getOpenLdapConfigPtr()->enabled());
238 }
239 
240 TEST_F(TestLDAPConfig, testRestores)
241 {
242     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
243     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
244     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
245     auto dbusPersistentFilePath = std::string(dir.c_str());
246 
247     if (fs::exists(configFilePath))
248     {
249         fs::remove(configFilePath);
250     }
251     EXPECT_FALSE(fs::exists(configFilePath));
252     MockConfigMgr* managerPtr =
253         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
254                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
255                           tlsCertfile.c_str());
256     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
257     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
258     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
259     managerPtr->createConfig(
260         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
261         "MyLdap12", ldap_base::Create::SearchScope::sub,
262         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
263     managerPtr->getADConfigPtr()->enabled(false);
264     EXPECT_FALSE(fs::exists(configFilePath));
265     EXPECT_FALSE(managerPtr->getADConfigPtr()->enabled());
266     managerPtr->getADConfigPtr()->enabled(true);
267 
268     EXPECT_TRUE(fs::exists(configFilePath));
269     // Restore from configFilePath
270     managerPtr->restore();
271     // validate restored properties
272     EXPECT_TRUE(managerPtr->getADConfigPtr()->enabled());
273     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapServerURI(),
274               "ldap://9.194.251.138/");
275     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBindDN(), "cn=Users,dc=com");
276     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBaseDN(), "cn=Users,dc=corp");
277     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapSearchScope(),
278               ldap_base::Config::SearchScope::sub);
279     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapType(),
280               ldap_base::Config::Type::ActiveDirectory);
281     EXPECT_EQ(managerPtr->getADConfigPtr()->userNameAttribute(), "uid");
282     EXPECT_EQ(managerPtr->getADConfigPtr()->groupNameAttribute(), "gid");
283     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBindDNPassword(), "");
284     EXPECT_EQ(managerPtr->configBindPassword(), "MyLdap12");
285     delete managerPtr;
286 }
287 
288 TEST_F(TestLDAPConfig, testLDAPServerURI)
289 {
290     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
291     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
292     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
293     auto dbusPersistentFilePath = std::string(dir.c_str());
294 
295     if (fs::exists(configFilePath))
296     {
297         fs::remove(configFilePath);
298     }
299     EXPECT_FALSE(fs::exists(configFilePath));
300     MockConfigMgr* managerPtr =
301         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
302                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
303                           tlsCertfile.c_str());
304 
305     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
306     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
307     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
308 
309     managerPtr->createConfig(
310         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
311         "MyLdap12", ldap_base::Create::SearchScope::sub,
312         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
313     managerPtr->getADConfigPtr()->enabled(true);
314 
315     // Change LDAP Server URI
316     managerPtr->getADConfigPtr()->ldapServerURI("ldap://9.194.251.139/");
317     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapServerURI(),
318               "ldap://9.194.251.139/");
319 
320     fs::remove(tlsCacertfile.c_str());
321     // Change LDAP Server URI to make it secure
322     EXPECT_THROW(
323         managerPtr->getADConfigPtr()->ldapServerURI("ldaps://9.194.251.139/"),
324         NoCACertificate);
325 
326     // check once again
327     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapServerURI(),
328               "ldap://9.194.251.139/");
329 
330     managerPtr->restore();
331     // Check LDAP Server URI
332     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapServerURI(),
333               "ldap://9.194.251.139/");
334     delete managerPtr;
335 }
336 
337 TEST_F(TestLDAPConfig, testLDAPBindDN)
338 {
339     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
340     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
341     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
342     auto dbusPersistentFilePath = std::string(dir.c_str());
343 
344     if (fs::exists(configFilePath))
345     {
346         fs::remove(configFilePath);
347     }
348     EXPECT_FALSE(fs::exists(configFilePath));
349     MockConfigMgr* managerPtr =
350         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
351                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
352                           tlsCertfile.c_str());
353 
354     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
355     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
356     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
357 
358     managerPtr->createConfig(
359         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
360         "MyLdap12", ldap_base::Create::SearchScope::sub,
361         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
362     managerPtr->getADConfigPtr()->enabled(true);
363 
364     // Change LDAP BindDN
365     managerPtr->getADConfigPtr()->ldapBindDN(
366         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
367     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBindDN(),
368               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
369     // Change LDAP BindDN
370     EXPECT_THROW(
371         {
372             try
373             {
374                 managerPtr->getADConfigPtr()->ldapBindDN("");
375             }
376             catch (const InvalidArgument& e)
377             {
378                 throw;
379             }
380         },
381         InvalidArgument);
382 
383     managerPtr->restore();
384     // Check LDAP BindDN after restoring
385     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBindDN(),
386               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
387     delete managerPtr;
388 }
389 
390 TEST_F(TestLDAPConfig, testLDAPBaseDN)
391 {
392     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
393     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
394     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
395     auto dbusPersistentFilePath = std::string(dir.c_str());
396 
397     if (fs::exists(configFilePath))
398     {
399         fs::remove(configFilePath);
400     }
401     EXPECT_FALSE(fs::exists(configFilePath));
402     MockConfigMgr* managerPtr =
403         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
404                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
405                           tlsCertfile.c_str());
406     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
407     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
408     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
409     managerPtr->createConfig(
410         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
411         "MyLdap12", ldap_base::Create::SearchScope::sub,
412         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
413     managerPtr->getADConfigPtr()->enabled(true);
414     // Change LDAP BaseDN
415     managerPtr->getADConfigPtr()->ldapBaseDN(
416         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
417     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBaseDN(),
418               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
419     // Change LDAP BaseDN
420     EXPECT_THROW(
421         {
422             try
423             {
424                 managerPtr->getADConfigPtr()->ldapBaseDN("");
425             }
426             catch (const InvalidArgument& e)
427             {
428                 throw;
429             }
430         },
431         InvalidArgument);
432 
433     managerPtr->restore();
434     // Check LDAP BaseDN after restoring
435     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapBaseDN(),
436               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
437     delete managerPtr;
438 }
439 
440 TEST_F(TestLDAPConfig, testSearchScope)
441 {
442     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
443     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
444     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
445     auto dbusPersistentFilePath = std::string(dir.c_str());
446 
447     if (fs::exists(configFilePath))
448     {
449         fs::remove(configFilePath);
450     }
451     EXPECT_FALSE(fs::exists(configFilePath));
452     MockConfigMgr* managerPtr =
453         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
454                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
455                           tlsCertfile.c_str());
456     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
457     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
458     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
459     managerPtr->createConfig(
460         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
461         "MyLdap12", ldap_base::Create::SearchScope::sub,
462         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
463     managerPtr->getADConfigPtr()->enabled(true);
464 
465     // Change LDAP SearchScope
466     managerPtr->getADConfigPtr()->ldapSearchScope(
467         ldap_base::Config::SearchScope::one);
468     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapSearchScope(),
469               ldap_base::Config::SearchScope::one);
470 
471     managerPtr->restore();
472     // Check LDAP SearchScope after restoring
473     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapSearchScope(),
474               ldap_base::Config::SearchScope::one);
475     delete managerPtr;
476 }
477 
478 TEST_F(TestLDAPConfig, testLDAPType)
479 {
480     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
481     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
482     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
483     auto dbusPersistentFilePath = std::string(dir.c_str());
484 
485     if (fs::exists(configFilePath))
486     {
487         fs::remove(configFilePath);
488     }
489     EXPECT_FALSE(fs::exists(configFilePath));
490     MockConfigMgr* managerPtr =
491         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
492                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
493                           tlsCertfile.c_str());
494     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
495     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
496     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
497     managerPtr->createConfig(
498         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
499         "MyLdap12", ldap_base::Create::SearchScope::sub,
500         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
501     managerPtr->getADConfigPtr()->enabled(true);
502 
503     // Change LDAP type
504     // will not be changed
505     EXPECT_THROW(managerPtr->getADConfigPtr()->ldapType(
506                      ldap_base::Config::Type::OpenLdap),
507                  NotAllowed);
508     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapType(),
509               ldap_base::Config::Type::ActiveDirectory);
510 
511     managerPtr->restore();
512     // Check LDAP type after restoring
513     EXPECT_EQ(managerPtr->getADConfigPtr()->ldapType(),
514               ldap_base::Config::Type::ActiveDirectory);
515     delete managerPtr;
516 }
517 
518 TEST_F(TestLDAPConfig, testsecureLDAPRestore)
519 {
520     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
521     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
522     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
523     auto dbusPersistentFilePath = std::string(dir.c_str());
524 
525     if (fs::exists(configFilePath))
526     {
527         fs::remove(configFilePath);
528     }
529     EXPECT_FALSE(fs::exists(configFilePath));
530     MockConfigMgr* managerPtr =
531         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
532                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
533                           tlsCertfile.c_str());
534     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
535     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
536     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
537     managerPtr->createConfig(
538         "ldaps://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
539         "MyLdap12", ldap_base::Create::SearchScope::sub,
540         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
541     managerPtr->getADConfigPtr()->enabled(true);
542     EXPECT_TRUE(managerPtr->secureLDAP());
543     managerPtr->restore();
544     // Check secureLDAP variable value after restoring
545     EXPECT_TRUE(managerPtr->secureLDAP());
546 
547     delete managerPtr;
548 }
549 
550 TEST_F(TestLDAPConfig, filePermission)
551 {
552     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
553     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
554     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
555     auto dbusPersistentFilePath = std::string(dir.c_str());
556 
557     if (fs::exists(configFilePath))
558     {
559         fs::remove(configFilePath);
560     }
561     EXPECT_FALSE(fs::exists(configFilePath));
562     MockConfigMgr* managerPtr =
563         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
564                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
565                           tlsCertfile.c_str());
566     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
567     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
568     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
569     managerPtr->createConfig(
570         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
571         "MyLdap12", ldap_base::Create::SearchScope::sub,
572         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
573     managerPtr->getADConfigPtr()->enabled(true);
574 
575     // Permission of the persistent file should be 640
576     // Others should not be allowed to read.
577     auto permission =
578         fs::perms::owner_read | fs::perms::owner_write | fs::perms::group_read;
579     auto persistFilepath = std::string(dir.c_str());
580     persistFilepath += ADDbusObjectPath;
581     persistFilepath += "/config";
582 
583     EXPECT_EQ(fs::status(persistFilepath).permissions(), permission);
584     delete managerPtr;
585 }
586 
587 TEST_F(TestLDAPConfig, ConditionalEnableConfig)
588 {
589     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
590     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
591     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
592     auto dbusPersistentFilePath = std::string(dir.c_str());
593 
594     if (fs::exists(configFilePath))
595     {
596         fs::remove(configFilePath);
597     }
598     EXPECT_FALSE(fs::exists(configFilePath));
599     MockConfigMgr* managerPtr =
600         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
601                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
602                           tlsCertfile.c_str());
603     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(3);
604     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
605     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
606     managerPtr->createConfig(
607         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
608         "MyLdap12", ldap_base::Create::SearchScope::sub,
609         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
610 
611     managerPtr->createConfig(
612         "ldap://9.194.251.139/", "cn=Users,dc=com, dc=ldap", "cn=Users,dc=corp",
613         "MyLdap123", ldap_base::Create::SearchScope::sub,
614         ldap_base::Create::Type::OpenLdap, "attr1", "attr2");
615 
616     // Enable the AD configuration
617     managerPtr->getADConfigPtr()->enabled(true);
618 
619     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), true);
620     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
621 
622     // AS AD is already enabled so openldap can't be enabled.
623     EXPECT_THROW(
624         {
625             try
626             {
627                 managerPtr->getOpenLdapConfigPtr()->enabled(true);
628             }
629             catch (const NotAllowed& e)
630             {
631                 throw;
632             }
633         },
634         NotAllowed);
635     // Check the values
636     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), true);
637     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
638     // Let's disable the AD.
639     managerPtr->getADConfigPtr()->enabled(false);
640     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), false);
641     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
642     // Now enable the openldap
643     managerPtr->getOpenLdapConfigPtr()->enabled(true);
644     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), true);
645     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), false);
646 
647     delete managerPtr;
648 }
649 
650 TEST_F(TestLDAPConfig, createPrivMapping)
651 {
652     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
653     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
654     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
655     auto dbusPersistentFilePath = std::string(dir.c_str());
656 
657     if (fs::exists(configFilePath))
658     {
659         fs::remove(configFilePath);
660     }
661     EXPECT_FALSE(fs::exists(configFilePath));
662     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
663                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
664                           tlsCertfile.c_str());
665     manager.createDefaultObjects();
666     // Create the priv-mapping under the config.
667     manager.getADConfigPtr()->create("admin", "priv-admin");
668     // Check whether the entry has been created.
669     EXPECT_THROW(
670         {
671             try
672             {
673                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
674             }
675             catch (const PrivilegeMappingExists& e)
676             {
677                 throw;
678             }
679         },
680         PrivilegeMappingExists);
681 }
682 
683 TEST_F(TestLDAPConfig, deletePrivMapping)
684 {
685     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
686     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
687     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
688     auto dbusPersistentFilePath = std::string(dir.c_str());
689 
690     if (fs::exists(configFilePath))
691     {
692         fs::remove(configFilePath);
693     }
694     EXPECT_FALSE(fs::exists(configFilePath));
695     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
696                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
697                           tlsCertfile.c_str());
698     manager.createDefaultObjects();
699     // Create the priv-mapping under the config.
700     manager.getADConfigPtr()->create("admin", "priv-admin");
701     manager.getADConfigPtr()->create("user", "priv-user");
702     // Check whether the entry has been created.
703     EXPECT_THROW(
704         {
705             try
706             {
707                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
708                 manager.getADConfigPtr()->checkPrivilegeMapper("user");
709             }
710             catch (const PrivilegeMappingExists& e)
711             {
712                 throw;
713             }
714         },
715         PrivilegeMappingExists);
716 
717     // This would delete the admin privilege
718     manager.getADConfigPtr()->deletePrivilegeMapper(1);
719     EXPECT_NO_THROW(manager.getADConfigPtr()->checkPrivilegeMapper("admin"));
720     manager.getADConfigPtr()->deletePrivilegeMapper(2);
721     EXPECT_NO_THROW(manager.getADConfigPtr()->checkPrivilegeMapper("user"));
722 }
723 
724 TEST_F(TestLDAPConfig, restorePrivMapping)
725 {
726     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
727     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
728     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
729     auto dbusPersistentFilePath = std::string(dir.c_str());
730 
731     if (fs::exists(configFilePath))
732     {
733         fs::remove(configFilePath);
734     }
735     EXPECT_FALSE(fs::exists(configFilePath));
736     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
737                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
738                           tlsCertfile.c_str());
739     manager.createDefaultObjects();
740     // Create the priv-mapping under the config.
741     manager.getADConfigPtr()->create("admin", "priv-admin");
742     manager.getOpenLdapConfigPtr()->create("user", "priv-user");
743     manager.restore();
744     EXPECT_THROW(
745         {
746             try
747             {
748                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
749             }
750             catch (const PrivilegeMappingExists& e)
751             {
752                 throw;
753             }
754         },
755         PrivilegeMappingExists);
756 
757     EXPECT_THROW(
758         {
759             try
760             {
761                 manager.getOpenLdapConfigPtr()->checkPrivilegeMapper("user");
762             }
763             catch (const PrivilegeMappingExists& e)
764             {
765                 throw;
766             }
767         },
768         PrivilegeMappingExists);
769 }
770 
771 TEST_F(TestLDAPConfig, testPrivileges)
772 {
773     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
774     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
775     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
776     auto dbusPersistentFilePath = std::string(dir.c_str());
777 
778     if (fs::exists(configFilePath))
779     {
780         fs::remove(configFilePath);
781     }
782     EXPECT_FALSE(fs::exists(configFilePath));
783     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
784                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
785                           tlsCertfile.c_str());
786     manager.createDefaultObjects();
787 
788     std::string groupName = "admin";
789     std::string privilege = "priv-admin";
790     size_t entryId = 1;
791     auto dbusPath = std::string(LDAP_CONFIG_ROOT) +
792                     "/active_directory/role_map/" + std::to_string(entryId);
793     dbusPersistentFilePath += dbusPath;
794 
795     auto entry = std::make_unique<LDAPMapperEntry>(
796         bus, dbusPath.c_str(), dbusPersistentFilePath.c_str(), groupName,
797         privilege, *(manager.getADConfigPtr()));
798 
799     EXPECT_NO_THROW(entry->privilege("priv-operator"));
800     EXPECT_NO_THROW(entry->privilege("priv-user"));
801 }
802 
803 } // namespace ldap
804 } // namespace phosphor
805