1 #include "config.h" 2 #include "phosphor-ldap-config/ldap_configuration.hpp" 3 #include "phosphor-ldap-config/ldap_serialize.hpp" 4 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 13 #include <filesystem> 14 #include <fstream> 15 #include <string> 16 #include <sys/types.h> 17 18 namespace phosphor 19 { 20 namespace ldap 21 { 22 namespace fs = std::filesystem; 23 namespace ldap_base = sdbusplus::xyz::openbmc_project::User::Ldap::server; 24 using Config = phosphor::ldap::Config; 25 static constexpr const char* dbusPersistFile = "Config"; 26 27 class TestLDAPConfig : public testing::Test 28 { 29 public: 30 TestLDAPConfig() : bus(sdbusplus::bus::new_default()) 31 { 32 } 33 void SetUp() override 34 { 35 using namespace phosphor::ldap; 36 char tmpldap[] = "/tmp/ldap_test.XXXXXX"; 37 dir = fs::path(mkdtemp(tmpldap)); 38 fs::path tslCacertFilePath{TLS_CACERT_FILE}; 39 tslCacertFile = tslCacertFilePath.filename().c_str(); 40 fs::path confFilePath{LDAP_CONFIG_FILE}; 41 ldapconfFile = confFilePath.filename().c_str(); 42 std::fstream fs; 43 fs.open(dir / defaultNslcdFile, std::fstream::out); 44 fs.close(); 45 fs.open(dir / nsSwitchFile, std::fstream::out); 46 fs.close(); 47 } 48 49 void TearDown() override 50 { 51 fs::remove_all(dir); 52 } 53 54 protected: 55 fs::path dir; 56 std::string tslCacertFile; 57 std::string ldapconfFile; 58 sdbusplus::bus::bus bus; 59 }; 60 61 class MockConfigMgr : public phosphor::ldap::ConfigMgr 62 { 63 public: 64 MockConfigMgr(sdbusplus::bus::bus& bus, const char* path, 65 const char* filePath, const char* dbusPersistentFile, 66 const char* caCertFile) : 67 phosphor::ldap::ConfigMgr(bus, path, filePath, dbusPersistentFile, 68 caCertFile) 69 { 70 } 71 MOCK_METHOD1(restartService, void(const std::string& service)); 72 MOCK_METHOD1(stopService, void(const std::string& service)); 73 std::unique_ptr<Config>& getConfigPtr() 74 { 75 return configPtr; 76 } 77 78 std::string configBindPassword() 79 { 80 return getConfigPtr()->lDAPBindPassword; 81 } 82 83 void restore(const char* filePath) 84 { 85 phosphor::ldap::ConfigMgr::restore(filePath); 86 return; 87 } 88 89 friend class TestLDAPConfig; 90 }; 91 92 TEST_F(TestLDAPConfig, testCreate) 93 { 94 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 95 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 96 auto dbusPersistentFilePath = 97 std::string(dir.c_str()) + "/" + dbusPersistFile; 98 99 if (fs::exists(configFilePath)) 100 { 101 fs::remove(configFilePath); 102 } 103 EXPECT_FALSE(fs::exists(configFilePath)); 104 MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 105 dbusPersistentFilePath.c_str(), 106 tlsCacertfile.c_str()); 107 EXPECT_CALL(manager, restartService("nslcd.service")).Times(2); 108 EXPECT_CALL(manager, restartService("nscd.service")).Times(1); 109 manager.createConfig( 110 "ldap://9.194.251.136/", "cn=Users,dc=com", "cn=Users,dc=corp", 111 "MyLdap12", ldap_base::Create::SearchScope::sub, 112 ldap_base::Create::Type::ActiveDirectory, "uid", "gid"); 113 manager.getConfigPtr()->enabled(true); 114 115 EXPECT_TRUE(fs::exists(configFilePath)); 116 EXPECT_EQ(manager.getConfigPtr()->lDAPServerURI(), "ldap://9.194.251.136/"); 117 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com"); 118 EXPECT_EQ(manager.getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp"); 119 EXPECT_EQ(manager.getConfigPtr()->lDAPSearchScope(), 120 ldap_base::Config::SearchScope::sub); 121 EXPECT_EQ(manager.getConfigPtr()->lDAPType(), 122 ldap_base::Config::Type::ActiveDirectory); 123 EXPECT_EQ(manager.getConfigPtr()->userNameAttribute(), "uid"); 124 EXPECT_EQ(manager.getConfigPtr()->groupNameAttribute(), "gid"); 125 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDNPassword(), ""); 126 EXPECT_EQ(manager.configBindPassword(), "MyLdap12"); 127 // change the password 128 manager.getConfigPtr()->lDAPBindDNPassword("MyLdap14"); 129 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDNPassword(), ""); 130 EXPECT_EQ(manager.configBindPassword(), "MyLdap14"); 131 } 132 133 TEST_F(TestLDAPConfig, testRestores) 134 { 135 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 136 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 137 auto dbusPersistentFilePath = 138 std::string(dir.c_str()) + "/" + dbusPersistFile; 139 140 if (fs::exists(configFilePath)) 141 { 142 fs::remove(configFilePath); 143 } 144 EXPECT_FALSE(fs::exists(configFilePath)); 145 MockConfigMgr* managerPtr = new MockConfigMgr( 146 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 147 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 148 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2); 149 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 150 managerPtr->createConfig( 151 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 152 "MyLdap12", ldap_base::Create::SearchScope::sub, 153 ldap_base::Create::Type::ActiveDirectory, "uid", "gid"); 154 managerPtr->getConfigPtr()->enabled(false); 155 156 EXPECT_TRUE(fs::exists(configFilePath)); 157 EXPECT_FALSE(managerPtr->getConfigPtr()->enabled()); 158 managerPtr->getConfigPtr()->enabled(true); 159 // Delete LDAP configuration 160 managerPtr->deleteObject(); 161 EXPECT_TRUE(fs::exists(configFilePath)); 162 // Restore from configFilePath 163 managerPtr->restore(configFilePath.c_str()); 164 // validate restored properties 165 EXPECT_TRUE(managerPtr->getConfigPtr()->enabled()); 166 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 167 "ldap://9.194.251.138/"); 168 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com"); 169 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp"); 170 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 171 ldap_base::Config::SearchScope::sub); 172 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 173 ldap_base::Config::Type::ActiveDirectory); 174 EXPECT_EQ(managerPtr->getConfigPtr()->userNameAttribute(), "uid"); 175 EXPECT_EQ(managerPtr->getConfigPtr()->groupNameAttribute(), "gid"); 176 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDNPassword(), ""); 177 EXPECT_EQ(managerPtr->configBindPassword(), "MyLdap12"); 178 delete managerPtr; 179 } 180 181 TEST_F(TestLDAPConfig, testLDAPServerURI) 182 { 183 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 184 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 185 auto dbusPersistentFilePath = 186 std::string(dir.c_str()) + "/" + dbusPersistFile; 187 188 if (fs::exists(configFilePath)) 189 { 190 fs::remove(configFilePath); 191 } 192 EXPECT_FALSE(fs::exists(configFilePath)); 193 MockConfigMgr* managerPtr = new MockConfigMgr( 194 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 195 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 196 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 197 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 198 199 managerPtr->createConfig( 200 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 201 "MyLdap12", ldap_base::Create::SearchScope::sub, 202 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 203 managerPtr->getConfigPtr()->enabled(true); 204 205 // Change LDAP Server URI 206 managerPtr->getConfigPtr()->lDAPServerURI("ldap://9.194.251.139/"); 207 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 208 "ldap://9.194.251.139/"); 209 // Change LDAP Server URI 210 EXPECT_THROW( 211 managerPtr->getConfigPtr()->lDAPServerURI("ldaps://9.194.251.139/"), 212 NoCACertificate); 213 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 214 "ldap://9.194.251.139/"); 215 // Delete LDAP configuration 216 managerPtr->deleteObject(); 217 218 managerPtr->restore(configFilePath.c_str()); 219 // Check LDAP Server URI 220 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 221 "ldap://9.194.251.139/"); 222 delete managerPtr; 223 } 224 225 TEST_F(TestLDAPConfig, testLDAPBindDN) 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 BindDN 250 managerPtr->getConfigPtr()->lDAPBindDN( 251 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 252 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), 253 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 254 // Change LDAP BindDN 255 EXPECT_THROW( 256 { 257 try 258 { 259 managerPtr->getConfigPtr()->lDAPBindDN(""); 260 } 261 catch (const InvalidArgument& e) 262 { 263 throw; 264 } 265 }, 266 InvalidArgument); 267 // Delete LDAP configuration 268 managerPtr->deleteObject(); 269 270 managerPtr->restore(configFilePath.c_str()); 271 // Check LDAP BindDN after restoring 272 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), 273 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 274 delete managerPtr; 275 } 276 277 TEST_F(TestLDAPConfig, testLDAPBaseDN) 278 { 279 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 280 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 281 auto dbusPersistentFilePath = 282 std::string(dir.c_str()) + "/" + dbusPersistFile; 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(), 291 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 292 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 293 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 294 managerPtr->createConfig( 295 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 296 "MyLdap12", ldap_base::Create::SearchScope::sub, 297 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 298 managerPtr->getConfigPtr()->enabled(true); 299 // Change LDAP BaseDN 300 managerPtr->getConfigPtr()->lDAPBaseDN( 301 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 302 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), 303 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 304 // Change LDAP BaseDN 305 EXPECT_THROW( 306 { 307 try 308 { 309 managerPtr->getConfigPtr()->lDAPBaseDN(""); 310 } 311 catch (const InvalidArgument& e) 312 { 313 throw; 314 } 315 }, 316 InvalidArgument); 317 // Delete LDAP configuration 318 managerPtr->deleteObject(); 319 320 managerPtr->restore(configFilePath.c_str()); 321 // Check LDAP BaseDN after restoring 322 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), 323 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 324 delete managerPtr; 325 } 326 327 TEST_F(TestLDAPConfig, testSearchScope) 328 { 329 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 330 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 331 auto dbusPersistentFilePath = 332 std::string(dir.c_str()) + "/" + dbusPersistFile; 333 334 if (fs::exists(configFilePath)) 335 { 336 fs::remove(configFilePath); 337 } 338 EXPECT_FALSE(fs::exists(configFilePath)); 339 MockConfigMgr* managerPtr = new MockConfigMgr( 340 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 341 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 342 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 343 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 344 managerPtr->createConfig( 345 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 346 "MyLdap12", ldap_base::Create::SearchScope::sub, 347 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 348 managerPtr->getConfigPtr()->enabled(true); 349 350 // Change LDAP SearchScope 351 managerPtr->getConfigPtr()->lDAPSearchScope( 352 ldap_base::Config::SearchScope::one); 353 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 354 ldap_base::Config::SearchScope::one); 355 // Delete LDAP configuration 356 managerPtr->deleteObject(); 357 358 managerPtr->restore(configFilePath.c_str()); 359 // Check LDAP SearchScope after restoring 360 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 361 ldap_base::Config::SearchScope::one); 362 delete managerPtr; 363 } 364 365 TEST_F(TestLDAPConfig, testLDAPType) 366 { 367 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 368 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 369 auto dbusPersistentFilePath = 370 std::string(dir.c_str()) + "/" + dbusPersistFile; 371 372 if (fs::exists(configFilePath)) 373 { 374 fs::remove(configFilePath); 375 } 376 EXPECT_FALSE(fs::exists(configFilePath)); 377 MockConfigMgr* managerPtr = new MockConfigMgr( 378 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 379 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 380 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 381 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 382 managerPtr->createConfig( 383 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 384 "MyLdap12", ldap_base::Create::SearchScope::sub, 385 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 386 managerPtr->getConfigPtr()->enabled(true); 387 388 // Change LDAP type 389 managerPtr->getConfigPtr()->lDAPType(ldap_base::Config::Type::OpenLdap); 390 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 391 ldap_base::Config::Type::OpenLdap); 392 // Delete LDAP configuration 393 managerPtr->deleteObject(); 394 395 managerPtr->restore(configFilePath.c_str()); 396 // Check LDAP type after restoring 397 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 398 ldap_base::Config::Type::OpenLdap); 399 delete managerPtr; 400 } 401 } // namespace ldap 402 } // namespace phosphor 403