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