1 #include "ldap_config.hpp" 2 3 #include "ldap_config_mgr.hpp" 4 #include "ldap_mapper_serialize.hpp" 5 #include "utils.hpp" 6 7 #include <cereal/archives/binary.hpp> 8 #include <cereal/types/string.hpp> 9 #include <cereal/types/vector.hpp> 10 #include <xyz/openbmc_project/Common/error.hpp> 11 #include <xyz/openbmc_project/User/Common/error.hpp> 12 13 #include <filesystem> 14 #include <fstream> 15 #include <sstream> 16 17 // Register class version 18 // From cereal documentation; 19 // "This macro should be placed at global scope" 20 CEREAL_CLASS_VERSION(phosphor::ldap::Config, CLASS_VERSION); 21 22 namespace phosphor 23 { 24 namespace ldap 25 { 26 27 constexpr auto nslcdService = "nslcd.service"; 28 constexpr auto nscdService = "nscd.service"; 29 constexpr auto LDAPscheme = "ldap"; 30 constexpr auto LDAPSscheme = "ldaps"; 31 constexpr auto certObjPath = "/xyz/openbmc_project/certs/client/ldap/1"; 32 constexpr auto certRootPath = "/xyz/openbmc_project/certs/client/ldap"; 33 constexpr auto authObjPath = "/xyz/openbmc_project/certs/authority/ldap"; 34 constexpr auto certIface = "xyz.openbmc_project.Certs.Certificate"; 35 constexpr auto certProperty = "CertificateString"; 36 37 using namespace phosphor::logging; 38 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 39 namespace fs = std::filesystem; 40 41 using Argument = xyz::openbmc_project::Common::InvalidArgument; 42 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 43 using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed; 44 using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common:: 45 Error::PrivilegeMappingExists; 46 47 using Line = std::string; 48 using Key = std::string; 49 using Val = std::string; 50 using ConfigInfo = std::map<Key, Val>; 51 52 Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath, 53 const char* caCertFile, const char* certFile, bool secureLDAP, 54 std::string ldapServerURI, std::string ldapBindDN, 55 std::string ldapBaseDN, std::string&& ldapBindDNPassword, 56 ConfigIface::SearchScope ldapSearchScope, 57 ConfigIface::Type ldapType, bool ldapServiceEnabled, 58 std::string userNameAttr, std::string groupNameAttr, 59 ConfigMgr& parent) : 60 Ifaces(bus, path, Ifaces::action::defer_emit), 61 secureLDAP(secureLDAP), ldapBindPassword(std::move(ldapBindDNPassword)), 62 tlsCacertFile(caCertFile), tlsCertFile(certFile), configFilePath(filePath), 63 objectPath(path), bus(bus), parent(parent), 64 certificateInstalledSignal( 65 bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), 66 std::bind(std::mem_fn(&Config::certificateInstalled), this, 67 std::placeholders::_1)), 68 69 cacertificateInstalledSignal( 70 bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), 71 std::bind(std::mem_fn(&Config::certificateInstalled), this, 72 std::placeholders::_1)), 73 74 certificateChangedSignal( 75 bus, 76 sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), 77 std::bind(std::mem_fn(&Config::certificateChanged), this, 78 std::placeholders::_1)) 79 { 80 ConfigIface::ldapServerURI(ldapServerURI); 81 ConfigIface::ldapBindDN(ldapBindDN); 82 ConfigIface::ldapBaseDN(ldapBaseDN); 83 ConfigIface::ldapSearchScope(ldapSearchScope); 84 ConfigIface::ldapType(ldapType); 85 EnableIface::enabled(ldapServiceEnabled); 86 ConfigIface::userNameAttribute(userNameAttr); 87 ConfigIface::groupNameAttribute(groupNameAttr); 88 // NOTE: Don't update the bindDN password under ConfigIface 89 if (enabled()) 90 { 91 writeConfig(); 92 } 93 // save the config. 94 configPersistPath = parent.dbusPersistentPath; 95 configPersistPath += objectPath; 96 97 // create the persistent directory 98 fs::create_directories(configPersistPath); 99 100 configPersistPath += "/config"; 101 102 serialize(); 103 104 // Emit deferred signal. 105 this->emit_object_added(); 106 parent.startOrStopService(nslcdService, enabled()); 107 } 108 109 Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath, 110 const char* caCertFile, const char* certFile, 111 ConfigIface::Type ldapType, ConfigMgr& parent) : 112 Ifaces(bus, path, Ifaces::action::defer_emit), 113 secureLDAP(false), tlsCacertFile(caCertFile), tlsCertFile(certFile), 114 configFilePath(filePath), objectPath(path), bus(bus), parent(parent), 115 certificateInstalledSignal( 116 bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), 117 std::bind(std::mem_fn(&Config::certificateInstalled), this, 118 std::placeholders::_1)), 119 cacertificateInstalledSignal( 120 bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), 121 std::bind(std::mem_fn(&Config::certificateInstalled), this, 122 std::placeholders::_1)), 123 certificateChangedSignal( 124 bus, 125 sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), 126 std::bind(std::mem_fn(&Config::certificateChanged), this, 127 std::placeholders::_1)) 128 { 129 ConfigIface::ldapType(ldapType); 130 131 configPersistPath = parent.dbusPersistentPath; 132 configPersistPath += objectPath; 133 134 // create the persistent directory 135 fs::create_directories(configPersistPath); 136 137 configPersistPath += "/config"; 138 } 139 140 void Config::certificateInstalled(sdbusplus::message_t& /*msg*/) 141 { 142 try 143 { 144 if (enabled()) 145 { 146 writeConfig(); 147 } 148 parent.startOrStopService(nslcdService, enabled()); 149 } 150 catch (const InternalFailure& e) 151 { 152 throw; 153 } 154 catch (const std::exception& e) 155 { 156 log<level::ERR>(e.what()); 157 elog<InternalFailure>(); 158 } 159 } 160 161 void Config::certificateChanged(sdbusplus::message_t& msg) 162 { 163 std::string objectName; 164 std::map<std::string, std::variant<std::string>> msgData; 165 msg.read(objectName, msgData); 166 auto valPropMap = msgData.find(certProperty); 167 { 168 if (valPropMap != msgData.end()) 169 { 170 try 171 { 172 if (enabled()) 173 { 174 175 writeConfig(); 176 } 177 parent.startOrStopService(nslcdService, enabled()); 178 } 179 catch (const InternalFailure& e) 180 { 181 throw; 182 } 183 catch (const std::exception& e) 184 { 185 log<level::ERR>(e.what()); 186 elog<InternalFailure>(); 187 } 188 } 189 } 190 } 191 192 void Config::writeConfig() 193 { 194 std::stringstream confData; 195 auto isPwdTobeWritten = false; 196 std::string userNameAttr; 197 198 confData << "uid root\n"; 199 confData << "gid root\n\n"; 200 confData << "ldap_version 3\n\n"; 201 confData << "timelimit 30\n"; 202 confData << "bind_timelimit 30\n"; 203 confData << "pagesize 1000\n"; 204 confData << "referrals off\n\n"; 205 confData << "uri " << ldapServerURI() << "\n\n"; 206 confData << "base " << ldapBaseDN() << "\n\n"; 207 confData << "binddn " << ldapBindDN() << "\n"; 208 if (!ldapBindPassword.empty()) 209 { 210 confData << "bindpw " << ldapBindPassword << "\n"; 211 isPwdTobeWritten = true; 212 } 213 confData << "\n"; 214 switch (ldapSearchScope()) 215 { 216 case ConfigIface::SearchScope::sub: 217 confData << "scope sub\n\n"; 218 break; 219 case ConfigIface::SearchScope::one: 220 confData << "scope one\n\n"; 221 break; 222 case ConfigIface::SearchScope::base: 223 confData << "scope base\n\n"; 224 break; 225 } 226 confData << "base passwd " << ldapBaseDN() << "\n"; 227 confData << "base shadow " << ldapBaseDN() << "\n\n"; 228 if (secureLDAP == true) 229 { 230 confData << "ssl on\n"; 231 confData << "tls_reqcert hard\n"; 232 if (fs::is_directory(tlsCacertFile.c_str())) 233 { 234 confData << "tls_cacertdir " << tlsCacertFile.c_str() << "\n"; 235 } 236 else 237 { 238 confData << "tls_cacertfile " << tlsCacertFile.c_str() << "\n"; 239 } 240 if (fs::exists(tlsCertFile.c_str())) 241 { 242 confData << "tls_cert " << tlsCertFile.c_str() << "\n"; 243 confData << "tls_key " << tlsCertFile.c_str() << "\n"; 244 } 245 } 246 else 247 { 248 confData << "ssl off\n"; 249 } 250 confData << "\n"; 251 if (ldapType() == ConfigIface::Type::ActiveDirectory) 252 { 253 if (ConfigIface::userNameAttribute().empty()) 254 { 255 ConfigIface::userNameAttribute("sAMAccountName"); 256 } 257 if (ConfigIface::groupNameAttribute().empty()) 258 { 259 ConfigIface::groupNameAttribute("primaryGroupID"); 260 } 261 confData << "filter passwd (&(objectClass=user)(objectClass=person)" 262 "(!(objectClass=computer)))\n"; 263 confData 264 << "filter group (|(objectclass=group)(objectclass=groupofnames) " 265 "(objectclass=groupofuniquenames))\n"; 266 confData << "map passwd uid " 267 << ConfigIface::userNameAttribute() << "\n"; 268 confData << "map passwd uidNumber " 269 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; 270 confData << "map passwd gidNumber " 271 << ConfigIface::groupNameAttribute() << "\n"; 272 confData << "map passwd homeDirectory \"/home/$sAMAccountName\"\n"; 273 confData << "map passwd gecos displayName\n"; 274 confData << "map passwd loginShell \"/bin/sh\"\n"; 275 confData << "map group gidNumber " 276 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; 277 confData << "map group cn " 278 << ConfigIface::userNameAttribute() << "\n"; 279 confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; 280 } 281 else if (ldapType() == ConfigIface::Type::OpenLdap) 282 { 283 if (ConfigIface::userNameAttribute().empty()) 284 { 285 ConfigIface::userNameAttribute("cn"); 286 } 287 if (ConfigIface::groupNameAttribute().empty()) 288 { 289 ConfigIface::groupNameAttribute("gidNumber"); 290 } 291 confData << "filter passwd (objectclass=*)\n"; 292 confData << "map passwd gecos displayName\n"; 293 confData << "filter group (objectclass=posixGroup)\n"; 294 confData << "map passwd uid " 295 << ConfigIface::userNameAttribute() << "\n"; 296 confData << "map passwd gidNumber " 297 << ConfigIface::groupNameAttribute() << "\n"; 298 confData << "map passwd loginShell \"/bin/sh\"\n"; 299 confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; 300 } 301 try 302 { 303 std::fstream stream(configFilePath.c_str(), std::fstream::out); 304 // remove the read permission from others if password is being written. 305 // nslcd forces this behaviour. 306 auto permission = fs::perms::owner_read | fs::perms::owner_write | 307 fs::perms::group_read; 308 if (isPwdTobeWritten) 309 { 310 fs::permissions(configFilePath, permission); 311 } 312 else 313 { 314 fs::permissions(configFilePath, 315 permission | fs::perms::others_read); 316 } 317 318 stream << confData.str(); 319 stream.flush(); 320 stream.close(); 321 } 322 catch (const std::exception& e) 323 { 324 log<level::ERR>(e.what()); 325 elog<InternalFailure>(); 326 } 327 return; 328 } 329 330 std::string Config::ldapBindDNPassword(std::string value) 331 { 332 // Don't update the D-bus object, this is just to 333 // facilitate if user wants to change the bind dn password 334 // once d-bus object gets created. 335 ldapBindPassword = value; 336 try 337 { 338 if (enabled()) 339 { 340 writeConfig(); 341 parent.startOrStopService(nslcdService, enabled()); 342 } 343 serialize(); 344 } 345 catch (const InternalFailure& e) 346 { 347 throw; 348 } 349 catch (const std::exception& e) 350 { 351 log<level::ERR>(e.what()); 352 elog<InternalFailure>(); 353 } 354 return value; 355 } 356 357 std::string Config::ldapServerURI(std::string value) 358 { 359 std::string val; 360 try 361 { 362 if (value == ldapServerURI()) 363 { 364 return value; 365 } 366 if (isValidLDAPURI(value, LDAPSscheme)) 367 { 368 secureLDAP = true; 369 } 370 else if (isValidLDAPURI(value, LDAPscheme)) 371 { 372 secureLDAP = false; 373 } 374 else 375 { 376 log<level::ERR>("bad LDAP Server URI", 377 entry("LDAPSERVERURI=%s", value.c_str())); 378 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"), 379 Argument::ARGUMENT_VALUE(value.c_str())); 380 } 381 382 if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) 383 { 384 log<level::ERR>("LDAP server's CA certificate not provided", 385 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str())); 386 elog<NoCACertificate>(); 387 } 388 val = ConfigIface::ldapServerURI(value); 389 if (enabled()) 390 { 391 writeConfig(); 392 parent.startOrStopService(nslcdService, enabled()); 393 } 394 // save the object. 395 serialize(); 396 } 397 catch (const InternalFailure& e) 398 { 399 throw; 400 } 401 catch (const InvalidArgument& e) 402 { 403 throw; 404 } 405 catch (const NoCACertificate& e) 406 { 407 throw; 408 } 409 catch (const std::exception& e) 410 { 411 log<level::ERR>(e.what()); 412 elog<InternalFailure>(); 413 } 414 return val; 415 } 416 417 std::string Config::ldapBindDN(std::string value) 418 { 419 std::string val; 420 try 421 { 422 if (value == ldapBindDN()) 423 { 424 return value; 425 } 426 427 if (value.empty()) 428 { 429 log<level::ERR>("Not a valid LDAP BINDDN", 430 entry("LDAPBINDDN=%s", value.c_str())); 431 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBindDN"), 432 Argument::ARGUMENT_VALUE(value.c_str())); 433 } 434 435 val = ConfigIface::ldapBindDN(value); 436 if (enabled()) 437 { 438 writeConfig(); 439 parent.startOrStopService(nslcdService, enabled()); 440 } 441 // save the object. 442 serialize(); 443 } 444 catch (const InternalFailure& e) 445 { 446 throw; 447 } 448 catch (const InvalidArgument& e) 449 { 450 throw; 451 } 452 catch (const std::exception& e) 453 { 454 log<level::ERR>(e.what()); 455 elog<InternalFailure>(); 456 } 457 return val; 458 } 459 460 std::string Config::ldapBaseDN(std::string value) 461 { 462 std::string val; 463 try 464 { 465 if (value == ldapBaseDN()) 466 { 467 return value; 468 } 469 470 if (value.empty()) 471 { 472 log<level::ERR>("Not a valid LDAP BASEDN", 473 entry("BASEDN=%s", value.c_str())); 474 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBaseDN"), 475 Argument::ARGUMENT_VALUE(value.c_str())); 476 } 477 478 val = ConfigIface::ldapBaseDN(value); 479 if (enabled()) 480 { 481 writeConfig(); 482 parent.startOrStopService(nslcdService, enabled()); 483 } 484 // save the object. 485 serialize(); 486 } 487 catch (const InternalFailure& e) 488 { 489 throw; 490 } 491 catch (const InvalidArgument& e) 492 { 493 throw; 494 } 495 catch (const std::exception& e) 496 { 497 log<level::ERR>(e.what()); 498 elog<InternalFailure>(); 499 } 500 return val; 501 } 502 503 ConfigIface::SearchScope Config::ldapSearchScope(ConfigIface::SearchScope value) 504 { 505 ConfigIface::SearchScope val; 506 try 507 { 508 if (value == ldapSearchScope()) 509 { 510 return value; 511 } 512 513 val = ConfigIface::ldapSearchScope(value); 514 if (enabled()) 515 { 516 writeConfig(); 517 518 parent.startOrStopService(nslcdService, enabled()); 519 } 520 // save the object. 521 serialize(); 522 } 523 catch (const InternalFailure& e) 524 { 525 throw; 526 } 527 catch (const std::exception& e) 528 { 529 log<level::ERR>(e.what()); 530 elog<InternalFailure>(); 531 } 532 return val; 533 } 534 535 ConfigIface::Type Config::ldapType(ConfigIface::Type /*value*/) 536 { 537 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); 538 return ldapType(); 539 } 540 541 bool Config::enabled(bool value) 542 { 543 if (value == enabled()) 544 { 545 return value; 546 } 547 // Let parent decide that can we enable this config. 548 // It may happen that other config is already enabled, 549 // Current implementation support only one config can 550 // be active at a time. 551 return parent.enableService(*this, value); 552 } 553 554 bool Config::enableService(bool value) 555 { 556 bool isEnable = false; 557 try 558 { 559 isEnable = EnableIface::enabled(value); 560 if (isEnable) 561 { 562 writeConfig(); 563 } 564 parent.startOrStopService(nslcdService, value); 565 serialize(); 566 } 567 catch (const InternalFailure& e) 568 { 569 throw; 570 } 571 catch (const std::exception& e) 572 { 573 log<level::ERR>(e.what()); 574 elog<InternalFailure>(); 575 } 576 return isEnable; 577 } 578 579 std::string Config::userNameAttribute(std::string value) 580 { 581 std::string val; 582 try 583 { 584 if (value == userNameAttribute()) 585 { 586 return value; 587 } 588 589 val = ConfigIface::userNameAttribute(value); 590 if (enabled()) 591 { 592 writeConfig(); 593 594 parent.startOrStopService(nslcdService, enabled()); 595 } 596 // save the object. 597 serialize(); 598 } 599 catch (const InternalFailure& e) 600 { 601 throw; 602 } 603 catch (const std::exception& e) 604 { 605 log<level::ERR>(e.what()); 606 elog<InternalFailure>(); 607 } 608 return val; 609 } 610 611 std::string Config::groupNameAttribute(std::string value) 612 { 613 std::string val; 614 try 615 { 616 if (value == groupNameAttribute()) 617 { 618 return value; 619 } 620 621 val = ConfigIface::groupNameAttribute(value); 622 if (enabled()) 623 { 624 writeConfig(); 625 626 parent.startOrStopService(nslcdService, enabled()); 627 } 628 // save the object. 629 serialize(); 630 } 631 catch (const InternalFailure& e) 632 { 633 throw; 634 } 635 catch (const std::exception& e) 636 { 637 log<level::ERR>(e.what()); 638 elog<InternalFailure>(); 639 } 640 return val; 641 } 642 643 template <class Archive> 644 void Config::save(Archive& archive, const std::uint32_t /*version*/) const 645 { 646 archive(this->enabled()); 647 archive(ldapServerURI()); 648 archive(ldapBindDN()); 649 archive(ldapBaseDN()); 650 archive(ldapSearchScope()); 651 archive(ldapBindPassword); 652 archive(userNameAttribute()); 653 archive(groupNameAttribute()); 654 } 655 656 template <class Archive> 657 void Config::load(Archive& archive, const std::uint32_t /*version*/) 658 { 659 bool bVal; 660 archive(bVal); 661 EnableIface::enabled(bVal); 662 663 std::string str; 664 archive(str); 665 ConfigIface::ldapServerURI(str); 666 667 archive(str); 668 ConfigIface::ldapBindDN(str); 669 670 archive(str); 671 ConfigIface::ldapBaseDN(str); 672 673 ConfigIface::SearchScope scope; 674 archive(scope); 675 ConfigIface::ldapSearchScope(scope); 676 677 archive(str); 678 ldapBindPassword = str; 679 680 archive(str); 681 ConfigIface::userNameAttribute(str); 682 683 archive(str); 684 ConfigIface::groupNameAttribute(str); 685 } 686 687 void Config::serialize() 688 { 689 690 if (!fs::exists(configPersistPath.c_str())) 691 { 692 std::ofstream os(configPersistPath.string(), 693 std::ios::binary | std::ios::out); 694 auto permission = fs::perms::owner_read | fs::perms::owner_write | 695 fs::perms::group_read; 696 fs::permissions(configPersistPath, permission); 697 cereal::BinaryOutputArchive oarchive(os); 698 oarchive(*this); 699 } 700 else 701 { 702 std::ofstream os(configPersistPath.string(), 703 std::ios::binary | std::ios::out); 704 cereal::BinaryOutputArchive oarchive(os); 705 oarchive(*this); 706 } 707 return; 708 } 709 710 bool Config::deserialize() 711 { 712 try 713 { 714 if (fs::exists(configPersistPath)) 715 { 716 std::ifstream is(configPersistPath.c_str(), 717 std::ios::in | std::ios::binary); 718 cereal::BinaryInputArchive iarchive(is); 719 iarchive(*this); 720 721 if (isValidLDAPURI(ldapServerURI(), LDAPscheme)) 722 { 723 secureLDAP = false; 724 } 725 else if (isValidLDAPURI(ldapServerURI(), LDAPSscheme)) 726 { 727 secureLDAP = true; 728 } 729 return true; 730 } 731 return false; 732 } 733 catch (const cereal::Exception& e) 734 { 735 log<level::ERR>(e.what()); 736 std::error_code ec; 737 fs::remove(configPersistPath, ec); 738 return false; 739 } 740 catch (const fs::filesystem_error& e) 741 { 742 return false; 743 } 744 } 745 746 ObjectPath Config::create(std::string groupName, std::string privilege) 747 { 748 checkPrivilegeMapper(groupName); 749 checkPrivilegeLevel(privilege); 750 751 entryId++; 752 753 // Object path for the LDAP group privilege mapper entry 754 fs::path mapperObjectPath = objectPath; 755 mapperObjectPath /= "role_map"; 756 mapperObjectPath /= std::to_string(entryId); 757 758 fs::path persistPath = parent.dbusPersistentPath; 759 persistPath += mapperObjectPath; 760 761 // Create mapping for LDAP privilege mapper entry 762 auto entry = std::make_unique<LDAPMapperEntry>( 763 bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(), 764 groupName, privilege, *this); 765 766 phosphor::ldap::serialize(*entry, std::move(persistPath)); 767 768 PrivilegeMapperList.emplace(entryId, std::move(entry)); 769 return mapperObjectPath.string(); 770 } 771 772 void Config::deletePrivilegeMapper(Id id) 773 { 774 fs::path mapperObjectPath = objectPath; 775 mapperObjectPath /= "role_map"; 776 mapperObjectPath /= std::to_string(id); 777 778 fs::path persistPath = parent.dbusPersistentPath; 779 persistPath += std::move(mapperObjectPath); 780 781 // Delete the persistent representation of the privilege mapper. 782 fs::remove(std::move(persistPath)); 783 784 PrivilegeMapperList.erase(id); 785 } 786 void Config::checkPrivilegeMapper(const std::string& groupName) 787 { 788 if (groupName.empty()) 789 { 790 log<level::ERR>("Group name is empty"); 791 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"), 792 Argument::ARGUMENT_VALUE("Null")); 793 } 794 795 for (const auto& val : PrivilegeMapperList) 796 { 797 if (val.second.get()->groupName() == groupName) 798 { 799 log<level::ERR>("Group name already exists"); 800 elog<PrivilegeMappingExists>(); 801 } 802 } 803 } 804 805 void Config::checkPrivilegeLevel(const std::string& privilege) 806 { 807 if (privilege.empty()) 808 { 809 log<level::ERR>("Privilege level is empty"); 810 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 811 Argument::ARGUMENT_VALUE("Null")); 812 } 813 814 if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end()) 815 { 816 log<level::ERR>("Invalid privilege"); 817 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 818 Argument::ARGUMENT_VALUE(privilege.c_str())); 819 } 820 } 821 822 void Config::restoreRoleMapping() 823 { 824 namespace fs = std::filesystem; 825 fs::path dir = parent.dbusPersistentPath; 826 dir += objectPath; 827 dir /= "role_map"; 828 829 if (!fs::exists(dir) || fs::is_empty(dir)) 830 { 831 return; 832 } 833 834 for (auto& file : fs::directory_iterator(dir)) 835 { 836 std::string id = file.path().filename().c_str(); 837 size_t idNum = std::stol(id); 838 839 auto entryPath = objectPath + '/' + "role_map" + '/' + id; 840 auto persistPath = parent.dbusPersistentPath + entryPath; 841 auto entry = std::make_unique<LDAPMapperEntry>( 842 bus, entryPath.c_str(), persistPath.c_str(), *this); 843 if (phosphor::ldap::deserialize(file.path(), *entry)) 844 { 845 entry->Interfaces::emit_object_added(); 846 PrivilegeMapperList.emplace(idNum, std::move(entry)); 847 if (idNum > entryId) 848 { 849 entryId = idNum; 850 } 851 } 852 } 853 } 854 855 } // namespace ldap 856 } // namespace phosphor 857