1 #include "config.h"
2 #include "phosphor-ldap-config/ldap_config.hpp"
3 #include "phosphor-ldap-config/ldap_config_mgr.hpp"
4 #include "phosphor-ldap-config/ldap_config_serialize.hpp"
5 
6 #include <phosphor-logging/log.hpp>
7 #include <phosphor-logging/elog-errors.hpp>
8 #include <sdbusplus/bus.hpp>
9 #include <xyz/openbmc_project/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 Config = phosphor::ldap::Config;
26 static constexpr const char* dbusPersistFile = "Config";
27 
28 class TestLDAPConfig : public testing::Test
29 {
30   public:
31     TestLDAPConfig() : bus(sdbusplus::bus::new_default())
32     {
33     }
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 tslCacertFilePath{TLS_CACERT_FILE};
40         tslCacertFile = tslCacertFilePath.filename().c_str();
41         fs::path confFilePath{LDAP_CONFIG_FILE};
42         ldapconfFile = confFilePath.filename().c_str();
43         std::fstream fs;
44         fs.open(dir / defaultNslcdFile, std::fstream::out);
45         fs.close();
46         fs.open(dir / nsSwitchFile, std::fstream::out);
47         fs.close();
48     }
49 
50     void TearDown() override
51     {
52         fs::remove_all(dir);
53     }
54 
55   protected:
56     fs::path dir;
57     std::string tslCacertFile;
58     std::string ldapconfFile;
59     sdbusplus::bus::bus bus;
60 };
61 
62 class MockConfigMgr : public phosphor::ldap::ConfigMgr
63 {
64   public:
65     MockConfigMgr(sdbusplus::bus::bus& bus, const char* path,
66                   const char* filePath, const char* dbusPersistentFile,
67                   const char* caCertFile) :
68         phosphor::ldap::ConfigMgr(bus, path, filePath, dbusPersistentFile,
69                                   caCertFile)
70     {
71     }
72     MOCK_METHOD1(restartService, void(const std::string& service));
73     MOCK_METHOD1(stopService, void(const std::string& service));
74     std::unique_ptr<Config>& getOpenLdapConfigPtr()
75     {
76         return openLDAPConfigPtr;
77     }
78 
79     std::string configBindPassword()
80     {
81         return getADConfigPtr()->lDAPBindPassword;
82     }
83 
84     std::unique_ptr<Config>& getADConfigPtr()
85     {
86         return ADConfigPtr;
87     }
88     void restore()
89     {
90         // TODO enable it in later commit.
91         // phosphor::ldap::ConfigMgr::restore();
92         return;
93     }
94 
95     void createDefaultObjects()
96     {
97         phosphor::ldap::ConfigMgr::createDefaultObjects();
98     }
99 
100     friend class TestLDAPConfig;
101 };
102 
103 TEST_F(TestLDAPConfig, testCreate)
104 {
105     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
106     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
107     auto dbusPersistentFilePath =
108         std::string(dir.c_str()) + "/" + dbusPersistFile;
109 
110     if (fs::exists(configFilePath))
111     {
112         fs::remove(configFilePath);
113     }
114     EXPECT_FALSE(fs::exists(configFilePath));
115     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
116                           dbusPersistentFilePath.c_str(),
117                           tlsCacertfile.c_str());
118 
119     EXPECT_CALL(manager, stopService("nslcd.service")).Times(1);
120     EXPECT_CALL(manager, restartService("nslcd.service")).Times(2);
121     EXPECT_CALL(manager, restartService("nscd.service")).Times(1);
122     manager.createConfig(
123         "ldap://9.194.251.136/", "cn=Users,dc=com", "cn=Users,dc=corp",
124         "MyLdap12", ldap_base::Create::SearchScope::sub,
125         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
126     manager.getADConfigPtr()->enabled(true);
127 
128     EXPECT_TRUE(fs::exists(configFilePath));
129     EXPECT_EQ(manager.getADConfigPtr()->lDAPServerURI(),
130               "ldap://9.194.251.136/");
131     EXPECT_EQ(manager.getADConfigPtr()->lDAPBindDN(), "cn=Users,dc=com");
132     EXPECT_EQ(manager.getADConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp");
133     EXPECT_EQ(manager.getADConfigPtr()->lDAPSearchScope(),
134               ldap_base::Config::SearchScope::sub);
135     EXPECT_EQ(manager.getADConfigPtr()->lDAPType(),
136               ldap_base::Config::Type::ActiveDirectory);
137 
138     EXPECT_EQ(manager.getADConfigPtr()->userNameAttribute(), "uid");
139     EXPECT_EQ(manager.getADConfigPtr()->groupNameAttribute(), "gid");
140     EXPECT_EQ(manager.getADConfigPtr()->lDAPBindDNPassword(), "");
141     EXPECT_EQ(manager.configBindPassword(), "MyLdap12");
142     // change the password
143     manager.getADConfigPtr()->lDAPBindDNPassword("MyLdap14");
144     EXPECT_EQ(manager.getADConfigPtr()->lDAPBindDNPassword(), "");
145     EXPECT_EQ(manager.configBindPassword(), "MyLdap14");
146 }
147 
148 TEST_F(TestLDAPConfig, testDefaultObject)
149 {
150     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
151     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
152     auto dbusPersistentFilePath =
153         std::string(dir.c_str()) + "/" + dbusPersistFile;
154 
155     if (fs::exists(configFilePath))
156     {
157         fs::remove(configFilePath);
158     }
159     EXPECT_FALSE(fs::exists(configFilePath));
160 
161     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
162                           dbusPersistentFilePath.c_str(),
163                           tlsCacertfile.c_str());
164 
165     EXPECT_CALL(manager, stopService("nslcd.service")).Times(2);
166 
167     manager.createDefaultObjects();
168 
169     EXPECT_NE(nullptr, manager.getADConfigPtr());
170     EXPECT_NE(nullptr, manager.getOpenLdapConfigPtr());
171     EXPECT_EQ(manager.getADConfigPtr()->lDAPType(),
172               ldap_base::Config::Type::ActiveDirectory);
173     EXPECT_EQ(manager.getOpenLdapConfigPtr()->lDAPType(),
174               ldap_base::Config::Type::OpenLdap);
175 }
176 /*
177 TEST_F(TestLDAPConfig, testRestores)
178 {
179     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
180     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
181     auto dbusPersistentFilePath =
182         std::string(dir.c_str()) + "/" + dbusPersistFile;
183 
184     if (fs::exists(configFilePath))
185     {
186         fs::remove(configFilePath);
187     }
188     EXPECT_FALSE(fs::exists(configFilePath));
189     MockConfigMgr* managerPtr = new MockConfigMgr(
190         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
191         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
192     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
193     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
194     managerPtr->createConfig(
195         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
196         "MyLdap12", ldap_base::Create::SearchScope::sub,
197         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
198     managerPtr->getConfigPtr()->enabled(false);
199 
200     EXPECT_TRUE(fs::exists(configFilePath));
201     EXPECT_FALSE(managerPtr->getConfigPtr()->enabled());
202     managerPtr->getConfigPtr()->enabled(true);
203     // Delete LDAP configuration
204     managerPtr->deleteObject();
205     EXPECT_TRUE(fs::exists(configFilePath));
206     // Restore from configFilePath
207     managerPtr->restore(configFilePath.c_str());
208     // validate restored properties
209     EXPECT_TRUE(managerPtr->getConfigPtr()->enabled());
210     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
211               "ldap://9.194.251.138/");
212     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com");
213     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp");
214     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
215               ldap_base::Config::SearchScope::sub);
216     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
217               ldap_base::Config::Type::ActiveDirectory);
218     EXPECT_EQ(managerPtr->getConfigPtr()->userNameAttribute(), "uid");
219     EXPECT_EQ(managerPtr->getConfigPtr()->groupNameAttribute(), "gid");
220     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDNPassword(), "");
221     EXPECT_EQ(managerPtr->configBindPassword(), "MyLdap12");
222     delete managerPtr;
223 }
224 
225 TEST_F(TestLDAPConfig, testLDAPServerURI)
226 {
227     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
228     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
229     auto dbusPersistentFilePath =
230         std::string(dir.c_str()) + "/" + dbusPersistFile;
231 
232     if (fs::exists(configFilePath))
233     {
234         fs::remove(configFilePath);
235     }
236     EXPECT_FALSE(fs::exists(configFilePath));
237     MockConfigMgr* managerPtr = new MockConfigMgr(
238         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
239         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
240     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
241     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
242 
243     managerPtr->createConfig(
244         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
245         "MyLdap12", ldap_base::Create::SearchScope::sub,
246         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
247     managerPtr->getConfigPtr()->enabled(true);
248 
249     // Change LDAP Server URI
250     managerPtr->getConfigPtr()->lDAPServerURI("ldap://9.194.251.139/");
251     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
252               "ldap://9.194.251.139/");
253     // Change LDAP Server URI
254     EXPECT_THROW(
255         managerPtr->getConfigPtr()->lDAPServerURI("ldaps://9.194.251.139/"),
256         NoCACertificate);
257     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
258               "ldap://9.194.251.139/");
259     // Delete LDAP configuration
260     managerPtr->deleteObject();
261 
262     managerPtr->restore(configFilePath.c_str());
263     // Check LDAP Server URI
264     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
265               "ldap://9.194.251.139/");
266     delete managerPtr;
267 }
268 
269 TEST_F(TestLDAPConfig, testLDAPBindDN)
270 {
271     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
272     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
273     auto dbusPersistentFilePath =
274         std::string(dir.c_str()) + "/" + dbusPersistFile;
275 
276     if (fs::exists(configFilePath))
277     {
278         fs::remove(configFilePath);
279     }
280     EXPECT_FALSE(fs::exists(configFilePath));
281     MockConfigMgr* managerPtr = new MockConfigMgr(
282         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
283         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
284     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
285     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
286 
287     managerPtr->createConfig(
288         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
289         "MyLdap12", ldap_base::Create::SearchScope::sub,
290         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
291     managerPtr->getConfigPtr()->enabled(true);
292 
293     // Change LDAP BindDN
294     managerPtr->getConfigPtr()->lDAPBindDN(
295         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
296     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
297               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
298     // Change LDAP BindDN
299     EXPECT_THROW(
300         {
301             try
302             {
303                 managerPtr->getConfigPtr()->lDAPBindDN("");
304             }
305             catch (const InvalidArgument& e)
306             {
307                 throw;
308             }
309         },
310         InvalidArgument);
311     // Delete LDAP configuration
312     managerPtr->deleteObject();
313 
314     managerPtr->restore(configFilePath.c_str());
315     // Check LDAP BindDN after restoring
316     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
317               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
318     delete managerPtr;
319 }
320 
321 TEST_F(TestLDAPConfig, testLDAPBaseDN)
322 {
323     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
324     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
325     auto dbusPersistentFilePath =
326         std::string(dir.c_str()) + "/" + dbusPersistFile;
327 
328     if (fs::exists(configFilePath))
329     {
330         fs::remove(configFilePath);
331     }
332     EXPECT_FALSE(fs::exists(configFilePath));
333     MockConfigMgr* managerPtr = new MockConfigMgr(
334         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
335         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
336     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
337     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
338     managerPtr->createConfig(
339         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
340         "MyLdap12", ldap_base::Create::SearchScope::sub,
341         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
342     managerPtr->getConfigPtr()->enabled(true);
343     // Change LDAP BaseDN
344     managerPtr->getConfigPtr()->lDAPBaseDN(
345         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
346     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
347               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
348     // Change LDAP BaseDN
349     EXPECT_THROW(
350         {
351             try
352             {
353                 managerPtr->getConfigPtr()->lDAPBaseDN("");
354             }
355             catch (const InvalidArgument& e)
356             {
357                 throw;
358             }
359         },
360         InvalidArgument);
361     // Delete LDAP configuration
362     managerPtr->deleteObject();
363 
364     managerPtr->restore(configFilePath.c_str());
365     // Check LDAP BaseDN after restoring
366     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
367               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
368     delete managerPtr;
369 }
370 
371 TEST_F(TestLDAPConfig, testSearchScope)
372 {
373     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
374     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
375     auto dbusPersistentFilePath =
376         std::string(dir.c_str()) + "/" + dbusPersistFile;
377 
378     if (fs::exists(configFilePath))
379     {
380         fs::remove(configFilePath);
381     }
382     EXPECT_FALSE(fs::exists(configFilePath));
383     MockConfigMgr* managerPtr = new MockConfigMgr(
384         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
385         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
386     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
387     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
388     managerPtr->createConfig(
389         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
390         "MyLdap12", ldap_base::Create::SearchScope::sub,
391         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
392     managerPtr->getConfigPtr()->enabled(true);
393 
394     // Change LDAP SearchScope
395     managerPtr->getConfigPtr()->lDAPSearchScope(
396         ldap_base::Config::SearchScope::one);
397     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
398               ldap_base::Config::SearchScope::one);
399     // Delete LDAP configuration
400     managerPtr->deleteObject();
401 
402     managerPtr->restore(configFilePath.c_str());
403     // Check LDAP SearchScope after restoring
404     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
405               ldap_base::Config::SearchScope::one);
406     delete managerPtr;
407 }
408 
409 TEST_F(TestLDAPConfig, testLDAPType)
410 {
411     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
412     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
413     auto dbusPersistentFilePath =
414         std::string(dir.c_str()) + "/" + dbusPersistFile;
415 
416     if (fs::exists(configFilePath))
417     {
418         fs::remove(configFilePath);
419     }
420     EXPECT_FALSE(fs::exists(configFilePath));
421     MockConfigMgr* managerPtr = new MockConfigMgr(
422         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(),
423         dbusPersistentFilePath.c_str(), tlsCacertfile.c_str());
424     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3);
425     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
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->getConfigPtr()->enabled(true);
431 
432     // Change LDAP type
433     managerPtr->getConfigPtr()->lDAPType(ldap_base::Config::Type::OpenLdap);
434     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
435               ldap_base::Config::Type::OpenLdap);
436     // Delete LDAP configuration
437     managerPtr->deleteObject();
438 
439     managerPtr->restore(configFilePath.c_str());
440     // Check LDAP type after restoring
441     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
442               ldap_base::Config::Type::OpenLdap);
443     delete managerPtr;
444 }
445 */
446 } // namespace ldap
447 } // namespace phosphor
448