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