1 #include "config.h" 2 #include "phosphor-ldap-config/ldap_configuration.hpp" 3 #include "phosphor-ldap-config/ldap_config_mgr.hpp" 4 #include "phosphor-ldap-config/ldap_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>& getConfigPtr() 75 { 76 return configPtr; 77 } 78 79 std::string configBindPassword() 80 { 81 return getConfigPtr()->lDAPBindPassword; 82 } 83 84 void restore(const char* filePath) 85 { 86 phosphor::ldap::ConfigMgr::restore(filePath); 87 return; 88 } 89 90 friend class TestLDAPConfig; 91 }; 92 93 TEST_F(TestLDAPConfig, testCreate) 94 { 95 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 96 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 97 auto dbusPersistentFilePath = 98 std::string(dir.c_str()) + "/" + dbusPersistFile; 99 100 if (fs::exists(configFilePath)) 101 { 102 fs::remove(configFilePath); 103 } 104 EXPECT_FALSE(fs::exists(configFilePath)); 105 MockConfigMgr manager(bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 106 dbusPersistentFilePath.c_str(), 107 tlsCacertfile.c_str()); 108 EXPECT_CALL(manager, restartService("nslcd.service")).Times(2); 109 EXPECT_CALL(manager, restartService("nscd.service")).Times(1); 110 manager.createConfig( 111 "ldap://9.194.251.136/", "cn=Users,dc=com", "cn=Users,dc=corp", 112 "MyLdap12", ldap_base::Create::SearchScope::sub, 113 ldap_base::Create::Type::ActiveDirectory, "uid", "gid"); 114 manager.getConfigPtr()->enabled(true); 115 116 EXPECT_TRUE(fs::exists(configFilePath)); 117 EXPECT_EQ(manager.getConfigPtr()->lDAPServerURI(), "ldap://9.194.251.136/"); 118 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com"); 119 EXPECT_EQ(manager.getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp"); 120 EXPECT_EQ(manager.getConfigPtr()->lDAPSearchScope(), 121 ldap_base::Config::SearchScope::sub); 122 EXPECT_EQ(manager.getConfigPtr()->lDAPType(), 123 ldap_base::Config::Type::ActiveDirectory); 124 EXPECT_EQ(manager.getConfigPtr()->userNameAttribute(), "uid"); 125 EXPECT_EQ(manager.getConfigPtr()->groupNameAttribute(), "gid"); 126 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDNPassword(), ""); 127 EXPECT_EQ(manager.configBindPassword(), "MyLdap12"); 128 // change the password 129 manager.getConfigPtr()->lDAPBindDNPassword("MyLdap14"); 130 EXPECT_EQ(manager.getConfigPtr()->lDAPBindDNPassword(), ""); 131 EXPECT_EQ(manager.configBindPassword(), "MyLdap14"); 132 } 133 134 TEST_F(TestLDAPConfig, testRestores) 135 { 136 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 137 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 138 auto dbusPersistentFilePath = 139 std::string(dir.c_str()) + "/" + dbusPersistFile; 140 141 if (fs::exists(configFilePath)) 142 { 143 fs::remove(configFilePath); 144 } 145 EXPECT_FALSE(fs::exists(configFilePath)); 146 MockConfigMgr* managerPtr = new MockConfigMgr( 147 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 148 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 149 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(2); 150 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 151 managerPtr->createConfig( 152 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 153 "MyLdap12", ldap_base::Create::SearchScope::sub, 154 ldap_base::Create::Type::ActiveDirectory, "uid", "gid"); 155 managerPtr->getConfigPtr()->enabled(false); 156 157 EXPECT_TRUE(fs::exists(configFilePath)); 158 EXPECT_FALSE(managerPtr->getConfigPtr()->enabled()); 159 managerPtr->getConfigPtr()->enabled(true); 160 // Delete LDAP configuration 161 managerPtr->deleteObject(); 162 EXPECT_TRUE(fs::exists(configFilePath)); 163 // Restore from configFilePath 164 managerPtr->restore(configFilePath.c_str()); 165 // validate restored properties 166 EXPECT_TRUE(managerPtr->getConfigPtr()->enabled()); 167 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 168 "ldap://9.194.251.138/"); 169 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), "cn=Users,dc=com"); 170 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), "cn=Users,dc=corp"); 171 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 172 ldap_base::Config::SearchScope::sub); 173 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 174 ldap_base::Config::Type::ActiveDirectory); 175 EXPECT_EQ(managerPtr->getConfigPtr()->userNameAttribute(), "uid"); 176 EXPECT_EQ(managerPtr->getConfigPtr()->groupNameAttribute(), "gid"); 177 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDNPassword(), ""); 178 EXPECT_EQ(managerPtr->configBindPassword(), "MyLdap12"); 179 delete managerPtr; 180 } 181 182 TEST_F(TestLDAPConfig, testLDAPServerURI) 183 { 184 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 185 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 186 auto dbusPersistentFilePath = 187 std::string(dir.c_str()) + "/" + dbusPersistFile; 188 189 if (fs::exists(configFilePath)) 190 { 191 fs::remove(configFilePath); 192 } 193 EXPECT_FALSE(fs::exists(configFilePath)); 194 MockConfigMgr* managerPtr = new MockConfigMgr( 195 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 196 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 197 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 198 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 199 200 managerPtr->createConfig( 201 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 202 "MyLdap12", ldap_base::Create::SearchScope::sub, 203 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 204 managerPtr->getConfigPtr()->enabled(true); 205 206 // Change LDAP Server URI 207 managerPtr->getConfigPtr()->lDAPServerURI("ldap://9.194.251.139/"); 208 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 209 "ldap://9.194.251.139/"); 210 // Change LDAP Server URI 211 EXPECT_THROW( 212 managerPtr->getConfigPtr()->lDAPServerURI("ldaps://9.194.251.139/"), 213 NoCACertificate); 214 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 215 "ldap://9.194.251.139/"); 216 // Delete LDAP configuration 217 managerPtr->deleteObject(); 218 219 managerPtr->restore(configFilePath.c_str()); 220 // Check LDAP Server URI 221 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPServerURI(), 222 "ldap://9.194.251.139/"); 223 delete managerPtr; 224 } 225 226 TEST_F(TestLDAPConfig, testLDAPBindDN) 227 { 228 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 229 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 230 auto dbusPersistentFilePath = 231 std::string(dir.c_str()) + "/" + dbusPersistFile; 232 233 if (fs::exists(configFilePath)) 234 { 235 fs::remove(configFilePath); 236 } 237 EXPECT_FALSE(fs::exists(configFilePath)); 238 MockConfigMgr* managerPtr = new MockConfigMgr( 239 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 240 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 241 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 242 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 243 244 managerPtr->createConfig( 245 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 246 "MyLdap12", ldap_base::Create::SearchScope::sub, 247 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 248 managerPtr->getConfigPtr()->enabled(true); 249 250 // Change LDAP BindDN 251 managerPtr->getConfigPtr()->lDAPBindDN( 252 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 253 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), 254 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 255 // Change LDAP BindDN 256 EXPECT_THROW( 257 { 258 try 259 { 260 managerPtr->getConfigPtr()->lDAPBindDN(""); 261 } 262 catch (const InvalidArgument& e) 263 { 264 throw; 265 } 266 }, 267 InvalidArgument); 268 // Delete LDAP configuration 269 managerPtr->deleteObject(); 270 271 managerPtr->restore(configFilePath.c_str()); 272 // Check LDAP BindDN after restoring 273 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBindDN(), 274 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 275 delete managerPtr; 276 } 277 278 TEST_F(TestLDAPConfig, testLDAPBaseDN) 279 { 280 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 281 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 282 auto dbusPersistentFilePath = 283 std::string(dir.c_str()) + "/" + dbusPersistFile; 284 285 if (fs::exists(configFilePath)) 286 { 287 fs::remove(configFilePath); 288 } 289 EXPECT_FALSE(fs::exists(configFilePath)); 290 MockConfigMgr* managerPtr = new MockConfigMgr( 291 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 292 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 293 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 294 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 295 managerPtr->createConfig( 296 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 297 "MyLdap12", ldap_base::Create::SearchScope::sub, 298 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 299 managerPtr->getConfigPtr()->enabled(true); 300 // Change LDAP BaseDN 301 managerPtr->getConfigPtr()->lDAPBaseDN( 302 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 303 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), 304 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 305 // Change LDAP BaseDN 306 EXPECT_THROW( 307 { 308 try 309 { 310 managerPtr->getConfigPtr()->lDAPBaseDN(""); 311 } 312 catch (const InvalidArgument& e) 313 { 314 throw; 315 } 316 }, 317 InvalidArgument); 318 // Delete LDAP configuration 319 managerPtr->deleteObject(); 320 321 managerPtr->restore(configFilePath.c_str()); 322 // Check LDAP BaseDN after restoring 323 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPBaseDN(), 324 "cn=Administrator,cn=Users,dc=corp,dc=ibm,dc=com"); 325 delete managerPtr; 326 } 327 328 TEST_F(TestLDAPConfig, testSearchScope) 329 { 330 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 331 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 332 auto dbusPersistentFilePath = 333 std::string(dir.c_str()) + "/" + dbusPersistFile; 334 335 if (fs::exists(configFilePath)) 336 { 337 fs::remove(configFilePath); 338 } 339 EXPECT_FALSE(fs::exists(configFilePath)); 340 MockConfigMgr* managerPtr = new MockConfigMgr( 341 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 342 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 343 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 344 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 345 managerPtr->createConfig( 346 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 347 "MyLdap12", ldap_base::Create::SearchScope::sub, 348 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 349 managerPtr->getConfigPtr()->enabled(true); 350 351 // Change LDAP SearchScope 352 managerPtr->getConfigPtr()->lDAPSearchScope( 353 ldap_base::Config::SearchScope::one); 354 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 355 ldap_base::Config::SearchScope::one); 356 // Delete LDAP configuration 357 managerPtr->deleteObject(); 358 359 managerPtr->restore(configFilePath.c_str()); 360 // Check LDAP SearchScope after restoring 361 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPSearchScope(), 362 ldap_base::Config::SearchScope::one); 363 delete managerPtr; 364 } 365 366 TEST_F(TestLDAPConfig, testLDAPType) 367 { 368 auto configFilePath = std::string(dir.c_str()) + "/" + ldapconfFile; 369 auto tlsCacertfile = std::string(dir.c_str()) + "/" + tslCacertFile; 370 auto dbusPersistentFilePath = 371 std::string(dir.c_str()) + "/" + dbusPersistFile; 372 373 if (fs::exists(configFilePath)) 374 { 375 fs::remove(configFilePath); 376 } 377 EXPECT_FALSE(fs::exists(configFilePath)); 378 MockConfigMgr* managerPtr = new MockConfigMgr( 379 bus, LDAP_CONFIG_ROOT, configFilePath.c_str(), 380 dbusPersistentFilePath.c_str(), tlsCacertfile.c_str()); 381 EXPECT_CALL(*managerPtr, restartService("nslcd.service")).Times(3); 382 EXPECT_CALL(*managerPtr, restartService("nscd.service")).Times(2); 383 managerPtr->createConfig( 384 "ldap://9.194.251.138/", "cn=Users,dc=com", "cn=Users,dc=corp", 385 "MyLdap12", ldap_base::Create::SearchScope::sub, 386 ldap_base::Create::Type::ActiveDirectory, "attr1", "attr2"); 387 managerPtr->getConfigPtr()->enabled(true); 388 389 // Change LDAP type 390 managerPtr->getConfigPtr()->lDAPType(ldap_base::Config::Type::OpenLdap); 391 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 392 ldap_base::Config::Type::OpenLdap); 393 // Delete LDAP configuration 394 managerPtr->deleteObject(); 395 396 managerPtr->restore(configFilePath.c_str()); 397 // Check LDAP type after restoring 398 EXPECT_EQ(managerPtr->getConfigPtr()->lDAPType(), 399 ldap_base::Config::Type::OpenLdap); 400 delete managerPtr; 401 } 402 } // namespace ldap 403 } // namespace phosphor 404