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(
97         "ldap://9.194.251.136/", "cn=Users,dc=com", "cn=Users,dc=corp",
98         "MyLdap12", ldap_base::Create::SearchScope::sub,
99         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
100     manager.getConfigPtr()->enabled(true);
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     EXPECT_EQ(manager.getConfigPtr()->userNameAttribute(), "uid");
110     EXPECT_EQ(manager.getConfigPtr()->groupNameAttribute(), "gid");
111 }
112 
113 TEST_F(TestLDAPConfig, testRestores)
114 {
115     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
116     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
117 
118     if (fs::exists(configFilePath))
119     {
120         fs::remove(configFilePath);
121     }
122     EXPECT_FALSE(fs::exists(configFilePath));
123     MockConfigMgr* managerPtr = new MockConfigMgr(
124         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
125     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(1);
126     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
127     managerPtr->createConfig(
128         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
129         "MyLdap12", ldap_base::Create::SearchScope::sub,
130         ldap_base::Create::Type::ActiveDirectory, "uid", "gid");
131     managerPtr->getConfigPtr()->enabled(true);
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     EXPECT_EQ(managerPtr->getConfigPtr()->userNameAttribute(), "uid");
148     EXPECT_EQ(managerPtr->getConfigPtr()->groupNameAttribute(), "gid");
149     delete managerPtr;
150 }
151 
152 TEST_F(TestLDAPConfig, testLDAPServerURI)
153 {
154     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
155     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
156 
157     if (fs::exists(configFilePath))
158     {
159         fs::remove(configFilePath);
160     }
161     EXPECT_FALSE(fs::exists(configFilePath));
162     MockConfigMgr* managerPtr = new MockConfigMgr(
163         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
164     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
165     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
166 
167     managerPtr->createConfig(
168         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
169         "MyLdap12", ldap_base::Create::SearchScope::sub,
170         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
171     managerPtr->getConfigPtr()->enabled(true);
172     // Change LDAP Server URI
173     managerPtr->getConfigPtr()->lDAPServerURI("ldap://9.194.251.139/");
174     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
175               "ldap://9.194.251.139/");
176     // Change LDAP Server URI
177     EXPECT_THROW(
178         managerPtr->getConfigPtr()->lDAPServerURI("ldaps://9.194.251.139/"),
179         NoCACertificate);
180     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
181               "ldap://9.194.251.139/");
182     // Delete LDAP configuration
183     managerPtr->deleteObject();
184 
185     managerPtr->restore(configFilePath.c_str());
186     // Check LDAP Server URI
187     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(),
188               "ldap://9.194.251.139/");
189     delete managerPtr;
190 }
191 
192 TEST_F(TestLDAPConfig, testLDAPBindDN)
193 {
194     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
195     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
196 
197     if (fs::exists(configFilePath))
198     {
199         fs::remove(configFilePath);
200     }
201     EXPECT_FALSE(fs::exists(configFilePath));
202     MockConfigMgr* managerPtr = new MockConfigMgr(
203         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
204     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
205     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
206 
207     managerPtr->createConfig(
208         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
209         "MyLdap12", ldap_base::Create::SearchScope::sub,
210         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
211     managerPtr->getConfigPtr()->enabled(true);
212     // Change LDAP BindDN
213     managerPtr->getConfigPtr()->lDAPBindDN(
214         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
215     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
216               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
217     // Change LDAP BindDN
218     EXPECT_THROW(
219         {
220             try
221             {
222                 managerPtr->getConfigPtr()->lDAPBindDN("");
223             }
224             catch (const InvalidArgument& e)
225             {
226                 throw;
227             }
228         },
229         InvalidArgument);
230     // Delete LDAP configuration
231     managerPtr->deleteObject();
232 
233     managerPtr->restore(configFilePath.c_str());
234     // Check LDAP BindDN after restoring
235     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(),
236               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
237     delete managerPtr;
238 }
239 
240 TEST_F(TestLDAPConfig, testLDAPBaseDN)
241 {
242     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
243     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
244 
245     if (fs::exists(configFilePath))
246     {
247         fs::remove(configFilePath);
248     }
249     EXPECT_FALSE(fs::exists(configFilePath));
250     MockConfigMgr* managerPtr = new MockConfigMgr(
251         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
252     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
253     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
254     managerPtr->createConfig(
255         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
256         "MyLdap12", ldap_base::Create::SearchScope::sub,
257         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
258     managerPtr->getConfigPtr()->enabled(true);
259     // Change LDAP BaseDN
260     managerPtr->getConfigPtr()->lDAPBaseDN(
261         "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
262     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
263               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
264     // Change LDAP BaseDN
265     EXPECT_THROW(
266         {
267             try
268             {
269                 managerPtr->getConfigPtr()->lDAPBaseDN("");
270             }
271             catch (const InvalidArgument& e)
272             {
273                 throw;
274             }
275         },
276         InvalidArgument);
277     // Delete LDAP configuration
278     managerPtr->deleteObject();
279 
280     managerPtr->restore(configFilePath.c_str());
281     // Check LDAP BaseDN after restoring
282     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(),
283               "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com");
284     delete managerPtr;
285 }
286 
287 TEST_F(TestLDAPConfig, testSearchScope)
288 {
289     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
290     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
291 
292     if (fs::exists(configFilePath))
293     {
294         fs::remove(configFilePath);
295     }
296     EXPECT_FALSE(fs::exists(configFilePath));
297     MockConfigMgr* managerPtr = new MockConfigMgr(
298         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
299     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
300     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
301     managerPtr->createConfig(
302         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
303         "MyLdap12", ldap_base::Create::SearchScope::sub,
304         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
305     managerPtr->getConfigPtr()->enabled(true);
306     // Change LDAP SearchScope
307     managerPtr->getConfigPtr()->lDAPSearchScope(
308         ldap_base::Config::SearchScope::one);
309     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
310               ldap_base::Config::SearchScope::one);
311     // Delete LDAP configuration
312     managerPtr->deleteObject();
313 
314     managerPtr->restore(configFilePath.c_str());
315     // Check LDAP SearchScope after restoring
316     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(),
317               ldap_base::Config::SearchScope::one);
318     delete managerPtr;
319 }
320 
321 TEST_F(TestLDAPConfig, testLDAPType)
322 {
323     auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile;
324     auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile;
325 
326     if (fs::exists(configFilePath))
327     {
328         fs::remove(configFilePath);
329     }
330     EXPECT_FALSE(fs::exists(configFilePath));
331     MockConfigMgr* managerPtr = new MockConfigMgr(
332         bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), tlsCacertfile.c_str());
333     EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2);
334     EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2);
335     managerPtr->createConfig(
336         "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp",
337         "MyLdap12", ldap_base::Create::SearchScope::sub,
338         ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2");
339     managerPtr->getConfigPtr()->enabled(true);
340     // Change LDAP type
341     managerPtr->getConfigPtr()->lDAPType(ldap_base::Config::Type::OpenLdap);
342     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
343               ldap_base::Config::Type::OpenLdap);
344     // Delete LDAP configuration
345     managerPtr->deleteObject();
346 
347     managerPtr->restore(configFilePath.c_str());
348     // Check LDAP type after restoring
349     EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(),
350               ldap_base::Config::Type::OpenLdap);
351     delete managerPtr;
352 }
353 } // namespace ldap
354 } // namespace phosphor
355