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