1 #include "config.h"
2 #include "phosphor-ldap-config/ldap_config.hpp"
3 #include "phosphor-ldap-config/ldap_config_mgr.hpp"
4 
5 #include <phosphor-logging/log.hpp>
6 #include <phosphor-logging/elog-errors.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <xyz/openbmc_project/Common/error.hpp>
9 #include <xyz/openbmc_project/User/Common/error.hpp>
10 #include <sdbusplus/bus.hpp>
11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h>
13 
14 #include <filesystem>
15 #include <fstream>
16 #include <string>
17 #include <sys/types.h>
18 
19 namespace phosphor
20 {
21 namespace ldap
22 {
23 namespace fs = std::filesystem;
24 namespace ldap_base = sdbusplus::xyz::openbmc_project::User::Ldap::server;
25 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
26 using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
27 
28 using Config = phosphor::ldap::Config;
29 static constexpr const char* dbusPersistFile = "Config";
30 using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common::
31     Error::PrivilegeMappingExists;
32 
33 class TestLDAPConfig : public testing::Test
34 {
35   public:
36     TestLDAPConfig() : bus(sdbusplus::bus::new_default())
37     {
38     }
39     void SetUp() override
40     {
41         using namespace phosphor::ldap;
42         char tmpldap[] = "/tmp/ldap_test.XXXXXX";
43         dir = fs::path(mkdtemp(tmpldap));
44         fs::path tlsCacertFilePath{TLS_CACERT_FILE};
45         tlsCacertFile = tlsCacertFilePath.filename().c_str();
46         fs::path tlsCertFilePath{TLS_CERT_FILE};
47         tlsCertFile = tlsCertFilePath.filename().c_str();
48 
49         fs::path confFilePath{LDAP_CONFIG_FILE};
50         ldapconfFile = confFilePath.filename().c_str();
51         std::fstream fs;
52         fs.open(dir / defaultNslcdFile, std::fstream::out);
53         fs.close();
54         fs.open(dir / nsSwitchFile, std::fstream::out);
55         fs.close();
56         fs.open(dir / tlsCacertFile, std::fstream::out);
57         fs.close();
58         fs.open(dir / tlsCertFile, std::fstream::out);
59         fs.close();
60     }
61 
62     void TearDown() override
63     {
64         fs::remove_all(dir);
65     }
66 
67   protected:
68     fs::path dir;
69     std::string tlsCacertFile;
70     std::string tlsCertFile;
71     std::string ldapconfFile;
72     sdbusplus::bus::bus bus;
73 };
74 
75 class MockConfigMgr : public phosphor::ldap::ConfigMgr
76 {
77   public:
78     MockConfigMgr(sdbusplus::bus::bus& bus, const char* path,
79                   const char* filePath, const char* dbusPersistentFile,
80                   const char* caCertFile, const char* certFile) :
81         phosphor::ldap::ConfigMgr(bus, path, filePath, dbusPersistentFile,
82                                   caCertFile, certFile)
83     {
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, testRestores)
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     MockConfigMgr* managerPtr =
220         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
221                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
222                           tlsCertfile.c_str());
223     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
224     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
225     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
226     managerPtr->createConfig(
227         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
228         "MyLdap12", ldap_base::Create::SearchScope::sub,
229         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
230     managerPtr->getADConfigPtr()->enabled(false);
231     EXPECT_FALSE(fs::exists(configFilePath));
232     EXPECT_FALSE(managerPtr->getADConfigPtr()->enabled());
233     managerPtr->getADConfigPtr()->enabled(true);
234 
235     EXPECT_TRUE(fs::exists(configFilePath));
236     // Restore from configFilePath
237     managerPtr->restore();
238     // validate restored properties
239     EXPECT_TRUE(managerPtr->getADConfigPtr()->enabled());
240     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPServerURI(),
241               "ldap://9.194.251.138/");
242     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBindDN(), "cn=Users,dc=com");
243     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp");
244     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPSearchScope(),
245               ldap_base::Config::SearchScope::sub);
246     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPType(),
247               ldap_base::Config::Type::ActiveDirectory);
248     EXPECT_EQ(managerPtr->getADConfigPtr()->userNameAttribute(), "uid");
249     EXPECT_EQ(managerPtr->getADConfigPtr()->groupNameAttribute(), "gid");
250     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBindDNPassword(), "");
251     EXPECT_EQ(managerPtr->configBindPassword(), "MyLdap12");
252     delete managerPtr;
253 }
254 
255 TEST_F(TestLDAPConfig, testLDAPServerURI)
256 {
257     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
258     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
259     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
260     auto dbusPersistentFilePath = std::string(dir.c_str());
261 
262     if (fs::exists(configFilePath))
263     {
264         fs::remove(configFilePath);
265     }
266     EXPECT_FALSE(fs::exists(configFilePath));
267     MockConfigMgr* managerPtr =
268         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
269                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
270                           tlsCertfile.c_str());
271 
272     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
273     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
274     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
275 
276     managerPtr->createConfig(
277         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
278         "MyLdap12", ldap_base::Create::SearchScope::sub,
279         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
280     managerPtr->getADConfigPtr()->enabled(true);
281 
282     // Change LDAP Server URI
283     managerPtr->getADConfigPtr()->lDAPServerURI("ldap://9.194.251.139/");
284     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPServerURI(),
285               "ldap://9.194.251.139/");
286 
287     fs::remove(tlsCacertfile.c_str());
288     // Change LDAP Server URI to make it secure
289     EXPECT_THROW(
290         managerPtr->getADConfigPtr()->lDAPServerURI("ldaps://9.194.251.139/"),
291         NoCACertificate);
292 
293     // check once again
294     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPServerURI(),
295               "ldap://9.194.251.139/");
296 
297     managerPtr->restore();
298     // Check LDAP Server URI
299     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPServerURI(),
300               "ldap://9.194.251.139/");
301     delete managerPtr;
302 }
303 
304 TEST_F(TestLDAPConfig, testLDAPBindDN)
305 {
306     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
307     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
308     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
309     auto dbusPersistentFilePath = std::string(dir.c_str());
310 
311     if (fs::exists(configFilePath))
312     {
313         fs::remove(configFilePath);
314     }
315     EXPECT_FALSE(fs::exists(configFilePath));
316     MockConfigMgr* managerPtr =
317         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
318                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
319                           tlsCertfile.c_str());
320 
321     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
322     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
323     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
324 
325     managerPtr->createConfig(
326         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
327         "MyLdap12", ldap_base::Create::SearchScope::sub,
328         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
329     managerPtr->getADConfigPtr()->enabled(true);
330 
331     // Change LDAP BindDN
332     managerPtr->getADConfigPtr()->lDAPBindDN(
333         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
334     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBindDN(),
335               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
336     // Change LDAP BindDN
337     EXPECT_THROW(
338         {
339             try
340             {
341                 managerPtr->getADConfigPtr()->lDAPBindDN("");
342             }
343             catch (const InvalidArgument& e)
344             {
345                 throw;
346             }
347         },
348         InvalidArgument);
349 
350     managerPtr->restore();
351     // Check LDAP BindDN after restoring
352     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBindDN(),
353               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
354     delete managerPtr;
355 }
356 
357 TEST_F(TestLDAPConfig, testLDAPBaseDN)
358 {
359     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
360     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
361     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
362     auto dbusPersistentFilePath = std::string(dir.c_str());
363 
364     if (fs::exists(configFilePath))
365     {
366         fs::remove(configFilePath);
367     }
368     EXPECT_FALSE(fs::exists(configFilePath));
369     MockConfigMgr* managerPtr =
370         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
371                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
372                           tlsCertfile.c_str());
373     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
374     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
375     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
376     managerPtr->createConfig(
377         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
378         "MyLdap12", ldap_base::Create::SearchScope::sub,
379         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
380     managerPtr->getADConfigPtr()->enabled(true);
381     // Change LDAP BaseDN
382     managerPtr->getADConfigPtr()->lDAPBaseDN(
383         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
384     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBaseDN(),
385               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
386     // Change LDAP BaseDN
387     EXPECT_THROW(
388         {
389             try
390             {
391                 managerPtr->getADConfigPtr()->lDAPBaseDN("");
392             }
393             catch (const InvalidArgument& e)
394             {
395                 throw;
396             }
397         },
398         InvalidArgument);
399 
400     managerPtr->restore();
401     // Check LDAP BaseDN after restoring
402     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPBaseDN(),
403               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
404     delete managerPtr;
405 }
406 
407 TEST_F(TestLDAPConfig, testSearchScope)
408 {
409     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
410     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
411     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
412     auto dbusPersistentFilePath = std::string(dir.c_str());
413 
414     if (fs::exists(configFilePath))
415     {
416         fs::remove(configFilePath);
417     }
418     EXPECT_FALSE(fs::exists(configFilePath));
419     MockConfigMgr* managerPtr =
420         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
421                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
422                           tlsCertfile.c_str());
423     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
424     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
425     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
426     managerPtr->createConfig(
427         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
428         "MyLdap12", ldap_base::Create::SearchScope::sub,
429         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
430     managerPtr->getADConfigPtr()->enabled(true);
431 
432     // Change LDAP SearchScope
433     managerPtr->getADConfigPtr()->lDAPSearchScope(
434         ldap_base::Config::SearchScope::one);
435     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPSearchScope(),
436               ldap_base::Config::SearchScope::one);
437 
438     managerPtr->restore();
439     // Check LDAP SearchScope after restoring
440     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPSearchScope(),
441               ldap_base::Config::SearchScope::one);
442     delete managerPtr;
443 }
444 
445 TEST_F(TestLDAPConfig, testLDAPType)
446 {
447     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
448     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
449     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
450     auto dbusPersistentFilePath = std::string(dir.c_str());
451 
452     if (fs::exists(configFilePath))
453     {
454         fs::remove(configFilePath);
455     }
456     EXPECT_FALSE(fs::exists(configFilePath));
457     MockConfigMgr* managerPtr =
458         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
459                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
460                           tlsCertfile.c_str());
461     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
462     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
463     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
464     managerPtr->createConfig(
465         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
466         "MyLdap12", ldap_base::Create::SearchScope::sub,
467         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
468     managerPtr->getADConfigPtr()->enabled(true);
469 
470     // Change LDAP type
471     // will not be changed
472     EXPECT_THROW(managerPtr->getADConfigPtr()->lDAPType(
473                      ldap_base::Config::Type::OpenLdap),
474                  NotAllowed);
475     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPType(),
476               ldap_base::Config::Type::ActiveDirectory);
477 
478     managerPtr->restore();
479     // Check LDAP type after restoring
480     EXPECT_EQ(managerPtr->getADConfigPtr()->lDAPType(),
481               ldap_base::Config::Type::ActiveDirectory);
482     delete managerPtr;
483 }
484 
485 TEST_F(TestLDAPConfig, testsecureLDAPRestore)
486 {
487     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
488     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
489     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
490     auto dbusPersistentFilePath = std::string(dir.c_str());
491 
492     if (fs::exists(configFilePath))
493     {
494         fs::remove(configFilePath);
495     }
496     EXPECT_FALSE(fs::exists(configFilePath));
497     MockConfigMgr* managerPtr =
498         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
499                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
500                           tlsCertfile.c_str());
501     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
502     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
503     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
504     managerPtr->createConfig(
505         "ldaps://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
506         "MyLdap12", ldap_base::Create::SearchScope::sub,
507         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
508     managerPtr->getADConfigPtr()->enabled(true);
509     EXPECT_TRUE(managerPtr->secureLDAP());
510     managerPtr->restore();
511     // Check secureLDAP variable value after restoring
512     EXPECT_TRUE(managerPtr->secureLDAP());
513 
514     delete managerPtr;
515 }
516 
517 TEST_F(TestLDAPConfig, filePermission)
518 {
519     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
520     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
521     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
522     auto dbusPersistentFilePath = std::string(dir.c_str());
523 
524     if (fs::exists(configFilePath))
525     {
526         fs::remove(configFilePath);
527     }
528     EXPECT_FALSE(fs::exists(configFilePath));
529     MockConfigMgr* managerPtr =
530         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
531                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
532                           tlsCertfile.c_str());
533     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(1);
534     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
535     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(1);
536     managerPtr->createConfig(
537         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
538         "MyLdap12", ldap_base::Create::SearchScope::sub,
539         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
540     managerPtr->getADConfigPtr()->enabled(true);
541 
542     // Permission of the persistent file should be 640
543     // Others should not be allowed to read.
544     auto permission =
545         fs::perms::owner_read | fs::perms::owner_write | fs::perms::group_read;
546     auto persistFilepath = std::string(dir.c_str());
547     persistFilepath += ADDbusObjectPath;
548     persistFilepath += "/config";
549 
550     EXPECT_EQ(fs::status(persistFilepath).permissions(), permission);
551     delete managerPtr;
552 }
553 
554 TEST_F(TestLDAPConfig, ConditionalEnableConfig)
555 {
556     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
557     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
558     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
559     auto dbusPersistentFilePath = std::string(dir.c_str());
560 
561     if (fs::exists(configFilePath))
562     {
563         fs::remove(configFilePath);
564     }
565     EXPECT_FALSE(fs::exists(configFilePath));
566     MockConfigMgr* managerPtr =
567         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
568                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
569                           tlsCertfile.c_str());
570     EXPECT_CALL(*managerPtr, stopService("nslcd.service")).Times(3);
571     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
572     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
573     managerPtr->createConfig(
574         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
575         "MyLdap12", ldap_base::Create::SearchScope::sub,
576         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
577 
578     managerPtr->createConfig(
579         "ldap://9.194.251.139/", "cn=Users,dc=com, dc=ldap", "cn=Users,dc=corp",
580         "MyLdap123", ldap_base::Create::SearchScope::sub,
581         ldap_base::Create::Type::OpenLdap, "attr1", "attr2");
582 
583     // Enable the AD configuration
584     managerPtr->getADConfigPtr()->enabled(true);
585 
586     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), true);
587     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
588 
589     // AS AD is already enabled so openldap can't be enabled.
590     EXPECT_THROW(
591         {
592             try
593             {
594                 managerPtr->getOpenLdapConfigPtr()->enabled(true);
595             }
596             catch (const NotAllowed& e)
597             {
598                 throw;
599             }
600         },
601         NotAllowed);
602     // Check the values
603     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), true);
604     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
605     // Let's disable the AD.
606     managerPtr->getADConfigPtr()->enabled(false);
607     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), false);
608     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), false);
609     // Now enable the openldap
610     managerPtr->getOpenLdapConfigPtr()->enabled(true);
611     EXPECT_EQ(managerPtr->getOpenLdapConfigPtr()->enabled(), true);
612     EXPECT_EQ(managerPtr->getADConfigPtr()->enabled(), false);
613 
614     delete managerPtr;
615 }
616 
617 TEST_F(TestLDAPConfig, createPrivMapping)
618 {
619     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
620     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
621     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
622     auto dbusPersistentFilePath = std::string(dir.c_str());
623 
624     if (fs::exists(configFilePath))
625     {
626         fs::remove(configFilePath);
627     }
628     EXPECT_FALSE(fs::exists(configFilePath));
629     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
630                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
631                           tlsCertfile.c_str());
632     manager.createDefaultObjects();
633     // Create the priv-mapping under the config.
634     manager.getADConfigPtr()->create("admin", "priv-admin");
635     // Check whether the entry has been created.
636     EXPECT_THROW(
637         {
638             try
639             {
640                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
641             }
642             catch (const PrivilegeMappingExists& e)
643             {
644                 throw;
645             }
646         },
647         PrivilegeMappingExists);
648 }
649 
650 TEST_F(TestLDAPConfig, deletePrivMapping)
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     manager.getADConfigPtr()->create("user", "priv-user");
669     // Check whether the entry has been created.
670     EXPECT_THROW(
671         {
672             try
673             {
674                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
675                 manager.getADConfigPtr()->checkPrivilegeMapper("user");
676             }
677             catch (const PrivilegeMappingExists& e)
678             {
679                 throw;
680             }
681         },
682         PrivilegeMappingExists);
683 
684     // This would delete the admin privilege
685     manager.getADConfigPtr()->deletePrivilegeMapper(1);
686     EXPECT_NO_THROW(manager.getADConfigPtr()->checkPrivilegeMapper("admin"));
687     manager.getADConfigPtr()->deletePrivilegeMapper(2);
688     EXPECT_NO_THROW(manager.getADConfigPtr()->checkPrivilegeMapper("user"));
689 }
690 
691 TEST_F(TestLDAPConfig, restorePrivMapping)
692 {
693     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
694     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
695     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
696     auto dbusPersistentFilePath = std::string(dir.c_str());
697 
698     if (fs::exists(configFilePath))
699     {
700         fs::remove(configFilePath);
701     }
702     EXPECT_FALSE(fs::exists(configFilePath));
703     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
704                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
705                           tlsCertfile.c_str());
706     manager.createDefaultObjects();
707     // Create the priv-mapping under the config.
708     manager.getADConfigPtr()->create("admin", "priv-admin");
709     manager.getOpenLdapConfigPtr()->create("user", "priv-user");
710     manager.restore();
711     EXPECT_THROW(
712         {
713             try
714             {
715                 manager.getADConfigPtr()->checkPrivilegeMapper("admin");
716             }
717             catch (const PrivilegeMappingExists& e)
718             {
719                 throw;
720             }
721         },
722         PrivilegeMappingExists);
723 
724     EXPECT_THROW(
725         {
726             try
727             {
728                 manager.getOpenLdapConfigPtr()->checkPrivilegeMapper("user");
729             }
730             catch (const PrivilegeMappingExists& e)
731             {
732                 throw;
733             }
734         },
735         PrivilegeMappingExists);
736 }
737 
738 TEST_F(TestLDAPConfig, testPrivileges)
739 {
740     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
741     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tlsCacertFile;
742     auto tlsCertfile = std::string(dir.c_str()) + "/" + tlsCertFile;
743     auto dbusPersistentFilePath = std::string(dir.c_str());
744 
745     if (fs::exists(configFilePath))
746     {
747         fs::remove(configFilePath);
748     }
749     EXPECT_FALSE(fs::exists(configFilePath));
750     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
751                           dbusPersistentFilePath.c_str(), tlsCacertfile.c_str(),
752                           tlsCertfile.c_str());
753     manager.createDefaultObjects();
754 
755     std::string groupName = "admin";
756     std::string privilege = "priv-admin";
757     size_t entryId = 1;
758     auto dbusPath = std::string(LDAP_CONFIG_ROOT) +
759                     "/active_directory/role_map/" + std::to_string(entryId);
760     dbusPersistentFilePath += dbusPath;
761 
762     auto entry = std::make_unique<LDAPMapperEntry>(
763         bus, dbusPath.c_str(), dbusPersistentFilePath.c_str(), groupName,
764         privilege, *(manager.getADConfigPtr()));
765 
766     EXPECT_NO_THROW(entry->privilege("priv-operator"));
767     EXPECT_NO_THROW(entry->privilege("priv-user"));
768     EXPECT_NO_THROW(entry->privilege("priv-callback"));
769 }
770 
771 } // namespace ldap
772 } // namespace phosphor
773