1 #include "config.h"
2 #include "phosphor-ldap-config/ldap_configuration.hpp"
3 
4 #include <experimental/filesystem>
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 <sdbusplus/bus.hpp>
10 #include <gmock/gmock.h>
11 #include <gtest/gtest.h>
12 #include <fstream>
13 #include <string>
14 #include <sys/types.h>
15 
16 namespace phosphor
17 {
18 namespace ldap
19 {
20 namespace fs = std::experimental::filesystem;
21 namespace ldap_base = sdbusplus::xyz::openbmc_project::User::Ldap::server;
22 using Config = phosphor::ldap::Config;
23 
24 class TestLDAPConfig : public testing::Test
25 {
26   public:
27     TestLDAPConfig() : bus(sdbusplus::bus::new_default())
28     {
29     }
30     void SetUp() override
31     {
32         using namespace phosphor::ldap;
33         char tmpldap[] = "/tmp/ldap_test.XXXXXX";
34         dir = fs::path(mkdtemp(tmpldap));
35         fs::path tslCacertFilePath{TLS_CACERT_FILE};
36         tslCacertFile = tslCacertFilePath.filename().c_str();
37         fs::path confFilePath{LDAP_CONFIG_FILE};
38         ldapconfFile = confFilePath.filename().c_str();
39         std::fstream fs;
40         fs.open(dir / defaultNslcdFile, std::fstream::out);
41         fs.close();
42         fs.open(dir / nsSwitchFile, std::fstream::out);
43         fs.close();
44         fs.open(dir / LDAPNsSwitchFile, std::fstream::out);
45         fs.close();
46         fs.open(dir / linuxNsSwitchFile, std::fstream::out);
47         fs.close();
48         fs.open(dir / tslCacertFile, std::fstream::out);
49         fs.close();
50     }
51 
52     void TearDown() override
53     {
54         fs::remove_all(dir);
55     }
56 
57   protected:
58     fs::path dir;
59     std::string tslCacertFile;
60     std::string ldapconfFile;
61     sdbusplus::bus::bus bus;
62 };
63 
64 class MockConfigMgr : public phosphor::ldap::ConfigMgr
65 {
66   public:
67     MockConfigMgr(sdbusplus::bus::bus& bus, const char* path,
68                   const char* filePath) :
69         phosphor::ldap::ConfigMgr(bus, path, filePath)
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>& getConfigPtr()
75     {
76         return configPtr;
77     }
78 
79     void restore(const char* filePath)
80     {
81         phosphor::ldap::ConfigMgr::restore(filePath);
82         return;
83     }
84 
85     friend class TestLDAPConfig;
86 };
87 
88 TEST_F(TestLDAPConfig, testCreate)
89 {
90     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
91 
92     if (fs::exists(configFilePath))
93     {
94         fs::remove(configFilePath);
95     }
96     EXPECT_FALSE(fs::exists(configFilePath));
97     MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
98     EXPECT_CALL(manager, restartService("nslcd.service")).Times(2);
99     EXPECT_CALL(manager, restartService("nscd.service")).Times(1);
100     manager.createConfig("ldap://9.194.251.136/", "cn=Users,dc=com",
101                          "cn=Users,dc=corp", "MyLdap12",
102                          ldap_base::Create::SearchScope::sub,
103                          ldap_base::Create::Type::ActiveDirectory);
104 
105     EXPECT_TRUE(fs::exists(configFilePath));
106     EXPECT_EQ(manager.getConfigPtr()->lDAPServerURI(), "ldap://9.194.251.136/");
107     EXPECT_EQ(manager.getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com");
108     EXPECT_EQ(manager.getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp");
109     EXPECT_EQ(manager.getConfigPtr()->lDAPSearchScope(),
110               ldap_base::Config::SearchScope::sub);
111     EXPECT_EQ(manager.getConfigPtr()->lDAPType(),
112               ldap_base::Config::Type::ActiveDirectory);
113 }
114 
115 TEST_F(TestLDAPConfig, testRestores)
116 {
117     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
118 
119     if (fs::exists(configFilePath))
120     {
121         fs::remove(configFilePath);
122     }
123     EXPECT_FALSE(fs::exists(configFilePath));
124     MockConfigMgr* managerPtr =
125         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
126     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(4);
127     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
128     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
129                              "cn=Users,dc=corp", "MyLdap12",
130                              ldap_base::Create::SearchScope::sub,
131                              ldap_base::Create::Type::ActiveDirectory);
132     EXPECT_TRUE(fs::exists(configFilePath));
133     // Delete LDAP configuration
134     managerPtr->deleteObject();
135     EXPECT_TRUE(fs::exists(configFilePath));
136     // Restore from configFilePath
137     managerPtr->restore(configFilePath.c_str());
138     // validate restored properties
139     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
140               "ldap://9.194.251.138/");
141     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com");
142     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp");
143     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
144               ldap_base::Config::SearchScope::sub);
145     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
146               ldap_base::Config::Type::ActiveDirectory);
147     delete managerPtr;
148 }
149 
150 TEST_F(TestLDAPConfig, testLDAPServerURI)
151 {
152     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
153     if (fs::exists(configFilePath))
154     {
155         fs::remove(configFilePath);
156     }
157     EXPECT_FALSE(fs::exists(configFilePath));
158     MockConfigMgr* managerPtr =
159         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
160     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(6);
161     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
162 
163     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
164                              "cn=Users,dc=corp", "MyLdap12",
165                              ldap_base::Create::SearchScope::sub,
166                              ldap_base::Create::Type::ActiveDirectory);
167     // Change LDAP Server URI
168     managerPtr->getConfigPtr()->lDAPServerURI("ldap://9.194.251.139");
169     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
170               "ldap://9.194.251.139");
171     // Change LDAP Server URI
172     managerPtr->getConfigPtr()->lDAPServerURI("ldaps://9.194.251.139");
173     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
174               "ldaps://9.194.251.139");
175     // Delete LDAP configuration
176     managerPtr->deleteObject();
177 
178     managerPtr->restore(configFilePath.c_str());
179     // Check LDAP Server URI
180     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
181               "ldaps://9.194.251.139");
182     delete managerPtr;
183 }
184 
185 TEST_F(TestLDAPConfig, testLDAPBindDN)
186 {
187     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
188     if (fs::exists(configFilePath))
189     {
190         fs::remove(configFilePath);
191     }
192     EXPECT_FALSE(fs::exists(configFilePath));
193     MockConfigMgr* managerPtr =
194         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
195     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(5);
196     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
197 
198     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
199                              "cn=Users,dc=corp", "MyLdap12",
200                              ldap_base::Create::SearchScope::sub,
201                              ldap_base::Create::Type::ActiveDirectory);
202     // Change LDAP BindDN
203     managerPtr->getConfigPtr()->lDAPBindDN(
204         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
205     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
206               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
207     // Change LDAP BindDN
208     EXPECT_THROW(
209         {
210             try
211             {
212                 managerPtr->getConfigPtr()->lDAPBindDN("");
213             }
214             catch (const InvalidArgument& e)
215             {
216                 throw;
217             }
218         },
219         InvalidArgument);
220     // Delete LDAP configuration
221     managerPtr->deleteObject();
222 
223     managerPtr->restore(configFilePath.c_str());
224     // Check LDAP BindDN after restoring
225     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
226               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
227     delete managerPtr;
228 }
229 
230 TEST_F(TestLDAPConfig, testLDAPBaseDN)
231 {
232     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
233     if (fs::exists(configFilePath))
234     {
235         fs::remove(configFilePath);
236     }
237     EXPECT_FALSE(fs::exists(configFilePath));
238     MockConfigMgr* managerPtr =
239         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
240     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(5);
241     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
242     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
243                              "cn=Users,dc=corp", "MyLdap12",
244                              ldap_base::Create::SearchScope::sub,
245                              ldap_base::Create::Type::ActiveDirectory);
246     // Change LDAP BaseDN
247     managerPtr->getConfigPtr()->lDAPBaseDN(
248         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
249     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
250               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
251     // Change LDAP BaseDN
252     EXPECT_THROW(
253         {
254             try
255             {
256                 managerPtr->getConfigPtr()->lDAPBaseDN("");
257             }
258             catch (const InvalidArgument& e)
259             {
260                 throw;
261             }
262         },
263         InvalidArgument);
264     // Delete LDAP configuration
265     managerPtr->deleteObject();
266 
267     managerPtr->restore(configFilePath.c_str());
268     // Check LDAP BaseDN after restoring
269     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
270               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
271     delete managerPtr;
272 }
273 
274 TEST_F(TestLDAPConfig, testSearchScope)
275 {
276     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
277     if (fs::exists(configFilePath))
278     {
279         fs::remove(configFilePath);
280     }
281     EXPECT_FALSE(fs::exists(configFilePath));
282     MockConfigMgr* managerPtr =
283         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
284     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(5);
285     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
286     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
287                              "cn=Users,dc=corp", "MyLdap12",
288                              ldap_base::Create::SearchScope::sub,
289                              ldap_base::Create::Type::ActiveDirectory);
290     // Change LDAP SearchScope
291     managerPtr->getConfigPtr()->lDAPSearchScope(
292         ldap_base::Config::SearchScope::one);
293     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
294               ldap_base::Config::SearchScope::one);
295     // Delete LDAP configuration
296     managerPtr->deleteObject();
297 
298     managerPtr->restore(configFilePath.c_str());
299     // Check LDAP SearchScope after restoring
300     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
301               ldap_base::Config::SearchScope::one);
302     delete managerPtr;
303 }
304 
305 TEST_F(TestLDAPConfig, testLDAPType)
306 {
307     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
308     if (fs::exists(configFilePath))
309     {
310         fs::remove(configFilePath);
311     }
312     EXPECT_FALSE(fs::exists(configFilePath));
313     MockConfigMgr* managerPtr =
314         new MockConfigMgr(bus, LDAP_CONFIG_ROOT, configFilePath.c_str());
315     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(5);
316     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
317     managerPtr->createConfig("ldap://9.194.251.138/", "cn=Users,dc=com",
318                              "cn=Users,dc=corp", "MyLdap12",
319                              ldap_base::Create::SearchScope::sub,
320                              ldap_base::Create::Type::ActiveDirectory);
321     // Change LDAP type
322     managerPtr->getConfigPtr()->lDAPType(ldap_base::Config::Type::OpenLdap);
323     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
324               ldap_base::Config::Type::OpenLdap);
325     // Delete LDAP configuration
326     managerPtr->deleteObject();
327 
328     managerPtr->restore(configFilePath.c_str());
329     // Check LDAP type after restoring
330     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
331               ldap_base::Config::Type::OpenLdap);
332     delete managerPtr;
333 }
334 } // namespace ldap
335 } // namespace phosphor
336