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 <phosphor-logging/elog-errors.hpp> 11 #include <phosphor-logging/elog.hpp> 12 #include <phosphor-logging/lg2.hpp> 13 #include <xyz/openbmc_project/Common/error.hpp> 14 #include <xyz/openbmc_project/User/Common/error.hpp> 15 16 #include <filesystem> 17 #include <fstream> 18 #include <sstream> 19 20 // Register class version 21 // From cereal documentation; 22 // "This macro should be placed at global scope" 23 CEREAL_CLASS_VERSION(phosphor::ldap::Config, CLASS_VERSION); 24 25 namespace phosphor 26 { 27 namespace ldap 28 { 29 30 constexpr auto nslcdService = "nslcd.service"; 31 constexpr auto ldapScheme = "ldap"; 32 constexpr auto ldapsScheme = "ldaps"; 33 constexpr auto certObjPath = "/xyz/openbmc_project/certs/client/ldap/1"; 34 constexpr auto certRootPath = "/xyz/openbmc_project/certs/client/ldap"; 35 constexpr auto authObjPath = "/xyz/openbmc_project/certs/authority/truststore"; 36 constexpr auto certIface = "xyz.openbmc_project.Certs.Certificate"; 37 constexpr auto certProperty = "CertificateString"; 38 39 using namespace phosphor::logging; 40 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 41 namespace fs = std::filesystem; 42 43 using Argument = xyz::openbmc_project::Common::InvalidArgument; 44 using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed; 45 using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common:: 46 Error::PrivilegeMappingExists; 47 48 using Line = std::string; 49 using Key = std::string; 50 using Val = std::string; 51 using ConfigInfo = std::map<Key, Val>; 52 53 Config::Config( 54 sdbusplus::bus_t& bus, const char* path, const char* filePath, 55 const char* caCertFile, const char* certFile, bool secureLDAP, 56 std::string ldapServerURI, std::string ldapBindDN, std::string ldapBaseDN, 57 std::string&& ldapBindDNPassword, ConfigIface::SearchScope ldapSearchScope, 58 ConfigIface::Type ldapType, bool ldapServiceEnabled, 59 std::string userNameAttr, std::string groupNameAttr, ConfigMgr& parent) : 60 Ifaces(bus, path, Ifaces::action::defer_emit), secureLDAP(secureLDAP), 61 ldapBindPassword(std::move(ldapBindDNPassword)), tlsCacertFile(caCertFile), 62 tlsCertFile(certFile), configFilePath(filePath), objectPath(path), bus(bus), 63 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), secureLDAP(false), 113 tlsCacertFile(caCertFile), tlsCertFile(certFile), configFilePath(filePath), 114 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 lg2::error("Exception: {ERR}", "ERR", e); 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 writeConfig(); 175 } 176 parent.startOrStopService(nslcdService, enabled()); 177 } 178 catch (const InternalFailure& e) 179 { 180 throw; 181 } 182 catch (const std::exception& e) 183 { 184 lg2::error("Exception: {ERR}", "ERR", e); 185 elog<InternalFailure>(); 186 } 187 } 188 } 189 } 190 191 void Config::writeConfig() 192 { 193 std::stringstream confData; 194 auto isPwdTobeWritten = false; 195 std::string userNameAttr; 196 197 confData << "uid root\n"; 198 confData << "gid root\n\n"; 199 confData << "ldap_version 3\n\n"; 200 confData << "timelimit 30\n"; 201 confData << "bind_timelimit 30\n"; 202 confData << "pagesize 1000\n"; 203 confData << "referrals off\n\n"; 204 confData << "uri " << ldapServerURI() << "\n\n"; 205 confData << "base " << ldapBaseDN() << "\n\n"; 206 confData << "binddn " << ldapBindDN() << "\n"; 207 if (!ldapBindPassword.empty()) 208 { 209 confData << "bindpw " << ldapBindPassword << "\n"; 210 isPwdTobeWritten = true; 211 } 212 confData << "\n"; 213 switch (ldapSearchScope()) 214 { 215 case ConfigIface::SearchScope::sub: 216 confData << "scope sub\n\n"; 217 break; 218 case ConfigIface::SearchScope::one: 219 confData << "scope one\n\n"; 220 break; 221 case ConfigIface::SearchScope::base: 222 confData << "scope base\n\n"; 223 break; 224 } 225 confData << "base passwd " << ldapBaseDN() << "\n"; 226 confData << "base shadow " << ldapBaseDN() << "\n\n"; 227 if (secureLDAP == true) 228 { 229 confData << "ssl on\n"; 230 confData << "tls_reqcert hard\n"; 231 if (fs::is_directory(tlsCacertFile.c_str())) 232 { 233 confData << "tls_cacertdir " << tlsCacertFile.c_str() << "\n"; 234 } 235 else 236 { 237 confData << "tls_cacertfile " << tlsCacertFile.c_str() << "\n"; 238 } 239 if (fs::exists(tlsCertFile.c_str())) 240 { 241 confData << "tls_cert " << tlsCertFile.c_str() << "\n"; 242 confData << "tls_key " << tlsCertFile.c_str() << "\n"; 243 } 244 } 245 else 246 { 247 confData << "ssl off\n"; 248 } 249 confData << "\n"; 250 if (ldapType() == ConfigIface::Type::ActiveDirectory) 251 { 252 if (ConfigIface::userNameAttribute().empty()) 253 { 254 ConfigIface::userNameAttribute("sAMAccountName"); 255 } 256 if (ConfigIface::groupNameAttribute().empty()) 257 { 258 ConfigIface::groupNameAttribute("primaryGroupID"); 259 } 260 confData << "filter passwd (&(objectClass=user)(objectClass=person)" 261 "(!(objectClass=computer)))\n"; 262 confData 263 << "filter group (|(objectclass=group)(objectclass=groupofnames) " 264 "(objectclass=groupofuniquenames))\n"; 265 confData << "map passwd uid " 266 << ConfigIface::userNameAttribute() << "\n"; 267 confData << "map passwd uidNumber " 268 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; 269 confData << "map passwd gidNumber " 270 << ConfigIface::groupNameAttribute() << "\n"; 271 confData << "map passwd homeDirectory \"/home/$sAMAccountName\"\n"; 272 confData << "map passwd gecos displayName\n"; 273 confData << "map passwd loginShell \"/bin/sh\"\n"; 274 confData << "map group gidNumber " 275 "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; 276 confData << "map group cn " 277 << ConfigIface::userNameAttribute() << "\n"; 278 confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; 279 } 280 else if (ldapType() == ConfigIface::Type::OpenLdap) 281 { 282 if (ConfigIface::userNameAttribute().empty()) 283 { 284 ConfigIface::userNameAttribute("cn"); 285 } 286 if (ConfigIface::groupNameAttribute().empty()) 287 { 288 ConfigIface::groupNameAttribute("gidNumber"); 289 } 290 confData << "filter passwd (objectclass=*)\n"; 291 confData << "map passwd gecos displayName\n"; 292 confData << "filter group (objectclass=posixGroup)\n"; 293 confData << "map passwd uid " 294 << ConfigIface::userNameAttribute() << "\n"; 295 confData << "map passwd gidNumber " 296 << ConfigIface::groupNameAttribute() << "\n"; 297 confData << "map passwd loginShell \"/bin/sh\"\n"; 298 confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; 299 } 300 try 301 { 302 std::fstream stream(configFilePath.c_str(), std::fstream::out); 303 // remove the read permission from others if password is being written. 304 // nslcd forces this behaviour. 305 auto permission = fs::perms::owner_read | fs::perms::owner_write | 306 fs::perms::group_read; 307 if (isPwdTobeWritten) 308 { 309 fs::permissions(configFilePath, permission); 310 } 311 else 312 { 313 fs::permissions(configFilePath, 314 permission | fs::perms::others_read); 315 } 316 317 stream << confData.str(); 318 stream.flush(); 319 stream.close(); 320 } 321 catch (const std::exception& e) 322 { 323 lg2::error("Exception: {ERR}", "ERR", e); 324 elog<InternalFailure>(); 325 } 326 return; 327 } 328 329 std::string Config::ldapBindDNPassword(std::string value) 330 { 331 // Don't update the D-bus object, this is just to 332 // facilitate if user wants to change the bind dn password 333 // once d-bus object gets created. 334 ldapBindPassword = value; 335 try 336 { 337 if (enabled()) 338 { 339 writeConfig(); 340 parent.startOrStopService(nslcdService, enabled()); 341 } 342 serialize(); 343 } 344 catch (const InternalFailure& e) 345 { 346 throw; 347 } 348 catch (const std::exception& e) 349 { 350 lg2::error("Exception: {ERR}", "ERR", e); 351 elog<InternalFailure>(); 352 } 353 return value; 354 } 355 356 std::string Config::ldapServerURI(std::string value) 357 { 358 std::string val; 359 try 360 { 361 if (value == ldapServerURI()) 362 { 363 return value; 364 } 365 if (isValidLDAPURI(value, ldapsScheme)) 366 { 367 secureLDAP = true; 368 } 369 else if (isValidLDAPURI(value, ldapScheme)) 370 { 371 secureLDAP = false; 372 } 373 else 374 { 375 lg2::error("Bad LDAP Server URI {URI}", "URI", value); 376 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"), 377 Argument::ARGUMENT_VALUE(value.c_str())); 378 } 379 380 if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) 381 { 382 lg2::error("LDAP server CA certificate not found at {PATH}", "PATH", 383 tlsCacertFile); 384 elog<NoCACertificate>(); 385 } 386 val = ConfigIface::ldapServerURI(value); 387 if (enabled()) 388 { 389 writeConfig(); 390 parent.startOrStopService(nslcdService, enabled()); 391 } 392 // save the object. 393 serialize(); 394 } 395 catch (const InternalFailure& e) 396 { 397 throw; 398 } 399 catch (const InvalidArgument& e) 400 { 401 throw; 402 } 403 catch (const NoCACertificate& e) 404 { 405 throw; 406 } 407 catch (const std::exception& e) 408 { 409 lg2::error("Exception: {ERR}", "ERR", e); 410 elog<InternalFailure>(); 411 } 412 return val; 413 } 414 415 std::string Config::ldapBindDN(std::string value) 416 { 417 std::string val; 418 try 419 { 420 if (value == ldapBindDN()) 421 { 422 return value; 423 } 424 425 if (value.empty()) 426 { 427 lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN", 428 value); 429 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBindDN"), 430 Argument::ARGUMENT_VALUE(value.c_str())); 431 } 432 433 val = ConfigIface::ldapBindDN(value); 434 if (enabled()) 435 { 436 writeConfig(); 437 parent.startOrStopService(nslcdService, enabled()); 438 } 439 // save the object. 440 serialize(); 441 } 442 catch (const InternalFailure& e) 443 { 444 throw; 445 } 446 catch (const InvalidArgument& e) 447 { 448 throw; 449 } 450 catch (const std::exception& e) 451 { 452 lg2::error("Exception: {ERR}", "ERR", e); 453 elog<InternalFailure>(); 454 } 455 return val; 456 } 457 458 std::string Config::ldapBaseDN(std::string value) 459 { 460 std::string val; 461 try 462 { 463 if (value == ldapBaseDN()) 464 { 465 return value; 466 } 467 468 if (value.empty()) 469 { 470 lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN", 471 value); 472 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBaseDN"), 473 Argument::ARGUMENT_VALUE(value.c_str())); 474 } 475 476 val = ConfigIface::ldapBaseDN(value); 477 if (enabled()) 478 { 479 writeConfig(); 480 parent.startOrStopService(nslcdService, enabled()); 481 } 482 // save the object. 483 serialize(); 484 } 485 catch (const InternalFailure& e) 486 { 487 throw; 488 } 489 catch (const InvalidArgument& e) 490 { 491 throw; 492 } 493 catch (const std::exception& e) 494 { 495 lg2::error("Exception: {ERR}", "ERR", e); 496 elog<InternalFailure>(); 497 } 498 return val; 499 } 500 501 ConfigIface::SearchScope Config::ldapSearchScope(ConfigIface::SearchScope value) 502 { 503 ConfigIface::SearchScope val; 504 try 505 { 506 if (value == ldapSearchScope()) 507 { 508 return value; 509 } 510 511 val = ConfigIface::ldapSearchScope(value); 512 if (enabled()) 513 { 514 writeConfig(); 515 516 parent.startOrStopService(nslcdService, enabled()); 517 } 518 // save the object. 519 serialize(); 520 } 521 catch (const InternalFailure& e) 522 { 523 throw; 524 } 525 catch (const std::exception& e) 526 { 527 lg2::error("Exception: {ERR}", "ERR", e); 528 elog<InternalFailure>(); 529 } 530 return val; 531 } 532 533 ConfigIface::Type Config::ldapType(ConfigIface::Type /*value*/) 534 { 535 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); 536 return ldapType(); 537 } 538 539 bool Config::enabled(bool value) 540 { 541 if (value == enabled()) 542 { 543 return value; 544 } 545 // Let parent decide that can we enable this config. 546 // It may happen that other config is already enabled, 547 // Current implementation support only one config can 548 // be active at a time. 549 return parent.enableService(*this, value); 550 } 551 552 bool Config::enableService(bool value) 553 { 554 bool isEnable = false; 555 try 556 { 557 isEnable = EnableIface::enabled(value); 558 if (isEnable) 559 { 560 writeConfig(); 561 } 562 parent.startOrStopService(nslcdService, value); 563 serialize(); 564 } 565 catch (const InternalFailure& e) 566 { 567 throw; 568 } 569 catch (const std::exception& e) 570 { 571 lg2::error("Exception: {ERR}", "ERR", e); 572 elog<InternalFailure>(); 573 } 574 return isEnable; 575 } 576 577 std::string Config::userNameAttribute(std::string value) 578 { 579 std::string val; 580 try 581 { 582 if (value == userNameAttribute()) 583 { 584 return value; 585 } 586 587 val = ConfigIface::userNameAttribute(value); 588 if (enabled()) 589 { 590 writeConfig(); 591 592 parent.startOrStopService(nslcdService, enabled()); 593 } 594 // save the object. 595 serialize(); 596 } 597 catch (const InternalFailure& e) 598 { 599 throw; 600 } 601 catch (const std::exception& e) 602 { 603 lg2::error("Exception: {ERR}", "ERR", e); 604 elog<InternalFailure>(); 605 } 606 return val; 607 } 608 609 std::string Config::groupNameAttribute(std::string value) 610 { 611 std::string val; 612 try 613 { 614 if (value == groupNameAttribute()) 615 { 616 return value; 617 } 618 619 val = ConfigIface::groupNameAttribute(value); 620 if (enabled()) 621 { 622 writeConfig(); 623 624 parent.startOrStopService(nslcdService, enabled()); 625 } 626 // save the object. 627 serialize(); 628 } 629 catch (const InternalFailure& e) 630 { 631 throw; 632 } 633 catch (const std::exception& e) 634 { 635 lg2::error("Exception: {ERR}", "ERR", e); 636 elog<InternalFailure>(); 637 } 638 return val; 639 } 640 641 template <class Archive> 642 void Config::save(Archive& archive, const std::uint32_t /*version*/) const 643 { 644 archive(this->enabled()); 645 archive(ldapServerURI()); 646 archive(ldapBindDN()); 647 archive(ldapBaseDN()); 648 archive(ldapSearchScope()); 649 archive(ldapBindPassword); 650 archive(userNameAttribute()); 651 archive(groupNameAttribute()); 652 } 653 654 template <class Archive> 655 void Config::load(Archive& archive, const std::uint32_t /*version*/) 656 { 657 bool bVal; 658 archive(bVal); 659 EnableIface::enabled(bVal); 660 661 std::string str; 662 archive(str); 663 ConfigIface::ldapServerURI(str); 664 665 archive(str); 666 ConfigIface::ldapBindDN(str); 667 668 archive(str); 669 ConfigIface::ldapBaseDN(str); 670 671 ConfigIface::SearchScope scope; 672 archive(scope); 673 ConfigIface::ldapSearchScope(scope); 674 675 archive(str); 676 ldapBindPassword = str; 677 678 archive(str); 679 ConfigIface::userNameAttribute(str); 680 681 archive(str); 682 ConfigIface::groupNameAttribute(str); 683 } 684 685 void Config::serialize() 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