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/ldap"; 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(sdbusplus::bus_t& bus, const char* path, const char* filePath, 54 const char* caCertFile, const char* certFile, bool secureLDAP, 55 std::string ldapServerURI, std::string ldapBindDN, 56 std::string ldapBaseDN, std::string&& ldapBindDNPassword, 57 ConfigIface::SearchScope ldapSearchScope, 58 ConfigIface::Type ldapType, bool ldapServiceEnabled, 59 std::string userNameAttr, std::string groupNameAttr, 60 ConfigMgr& parent) : 61 Ifaces(bus, path, Ifaces::action::defer_emit), 62 secureLDAP(secureLDAP), ldapBindPassword(std::move(ldapBindDNPassword)), 63 tlsCacertFile(caCertFile), tlsCertFile(certFile), configFilePath(filePath), 64 objectPath(path), bus(bus), parent(parent), 65 certificateInstalledSignal( 66 bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), 67 std::bind(std::mem_fn(&Config::certificateInstalled), this, 68 std::placeholders::_1)), 69 70 cacertificateInstalledSignal( 71 bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), 72 std::bind(std::mem_fn(&Config::certificateInstalled), this, 73 std::placeholders::_1)), 74 75 certificateChangedSignal( 76 bus, 77 sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), 78 std::bind(std::mem_fn(&Config::certificateChanged), this, 79 std::placeholders::_1)) 80 { 81 ConfigIface::ldapServerURI(ldapServerURI); 82 ConfigIface::ldapBindDN(ldapBindDN); 83 ConfigIface::ldapBaseDN(ldapBaseDN); 84 ConfigIface::ldapSearchScope(ldapSearchScope); 85 ConfigIface::ldapType(ldapType); 86 EnableIface::enabled(ldapServiceEnabled); 87 ConfigIface::userNameAttribute(userNameAttr); 88 ConfigIface::groupNameAttribute(groupNameAttr); 89 // NOTE: Don't update the bindDN password under ConfigIface 90 if (enabled()) 91 { 92 writeConfig(); 93 } 94 // save the config. 95 configPersistPath = parent.dbusPersistentPath; 96 configPersistPath += objectPath; 97 98 // create the persistent directory 99 fs::create_directories(configPersistPath); 100 101 configPersistPath += "/config"; 102 103 serialize(); 104 105 // Emit deferred signal. 106 this->emit_object_added(); 107 parent.startOrStopService(nslcdService, enabled()); 108 } 109 110 Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath, 111 const char* caCertFile, const char* certFile, 112 ConfigIface::Type ldapType, ConfigMgr& parent) : 113 Ifaces(bus, path, Ifaces::action::defer_emit), 114 secureLDAP(false), tlsCacertFile(caCertFile), tlsCertFile(certFile), 115 configFilePath(filePath), objectPath(path), bus(bus), parent(parent), 116 certificateInstalledSignal( 117 bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), 118 std::bind(std::mem_fn(&Config::certificateInstalled), this, 119 std::placeholders::_1)), 120 cacertificateInstalledSignal( 121 bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), 122 std::bind(std::mem_fn(&Config::certificateInstalled), this, 123 std::placeholders::_1)), 124 certificateChangedSignal( 125 bus, 126 sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), 127 std::bind(std::mem_fn(&Config::certificateChanged), this, 128 std::placeholders::_1)) 129 { 130 ConfigIface::ldapType(ldapType); 131 132 configPersistPath = parent.dbusPersistentPath; 133 configPersistPath += objectPath; 134 135 // create the persistent directory 136 fs::create_directories(configPersistPath); 137 138 configPersistPath += "/config"; 139 } 140 141 void Config::certificateInstalled(sdbusplus::message_t& /*msg*/) 142 { 143 try 144 { 145 if (enabled()) 146 { 147 writeConfig(); 148 } 149 parent.startOrStopService(nslcdService, enabled()); 150 } 151 catch (const InternalFailure& e) 152 { 153 throw; 154 } 155 catch (const std::exception& e) 156 { 157 lg2::error("Exception: {ERR}", "ERR", e); 158 elog<InternalFailure>(); 159 } 160 } 161 162 void Config::certificateChanged(sdbusplus::message_t& msg) 163 { 164 std::string objectName; 165 std::map<std::string, std::variant<std::string>> msgData; 166 msg.read(objectName, msgData); 167 auto valPropMap = msgData.find(certProperty); 168 { 169 if (valPropMap != msgData.end()) 170 { 171 try 172 { 173 if (enabled()) 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 lg2::error("Exception: {ERR}", "ERR", e); 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 lg2::error("Exception: {ERR}", "ERR", e); 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 lg2::error("Exception: {ERR}", "ERR", e); 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 lg2::error("Bad LDAP Server URI {URI}", "URI", value); 377 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"), 378 Argument::ARGUMENT_VALUE(value.c_str())); 379 } 380 381 if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) 382 { 383 lg2::error("LDAP server CA certificate not found at {PATH}", "PATH", 384 tlsCacertFile); 385 elog<NoCACertificate>(); 386 } 387 val = ConfigIface::ldapServerURI(value); 388 if (enabled()) 389 { 390 writeConfig(); 391 parent.startOrStopService(nslcdService, enabled()); 392 } 393 // save the object. 394 serialize(); 395 } 396 catch (const InternalFailure& e) 397 { 398 throw; 399 } 400 catch (const InvalidArgument& e) 401 { 402 throw; 403 } 404 catch (const NoCACertificate& e) 405 { 406 throw; 407 } 408 catch (const std::exception& e) 409 { 410 lg2::error("Exception: {ERR}", "ERR", e); 411 elog<InternalFailure>(); 412 } 413 return val; 414 } 415 416 std::string Config::ldapBindDN(std::string value) 417 { 418 std::string val; 419 try 420 { 421 if (value == ldapBindDN()) 422 { 423 return value; 424 } 425 426 if (value.empty()) 427 { 428 lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN", 429 value); 430 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBindDN"), 431 Argument::ARGUMENT_VALUE(value.c_str())); 432 } 433 434 val = ConfigIface::ldapBindDN(value); 435 if (enabled()) 436 { 437 writeConfig(); 438 parent.startOrStopService(nslcdService, enabled()); 439 } 440 // save the object. 441 serialize(); 442 } 443 catch (const InternalFailure& e) 444 { 445 throw; 446 } 447 catch (const InvalidArgument& e) 448 { 449 throw; 450 } 451 catch (const std::exception& e) 452 { 453 lg2::error("Exception: {ERR}", "ERR", e); 454 elog<InternalFailure>(); 455 } 456 return val; 457 } 458 459 std::string Config::ldapBaseDN(std::string value) 460 { 461 std::string val; 462 try 463 { 464 if (value == ldapBaseDN()) 465 { 466 return value; 467 } 468 469 if (value.empty()) 470 { 471 lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN", 472 value); 473 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBaseDN"), 474 Argument::ARGUMENT_VALUE(value.c_str())); 475 } 476 477 val = ConfigIface::ldapBaseDN(value); 478 if (enabled()) 479 { 480 writeConfig(); 481 parent.startOrStopService(nslcdService, enabled()); 482 } 483 // save the object. 484 serialize(); 485 } 486 catch (const InternalFailure& e) 487 { 488 throw; 489 } 490 catch (const InvalidArgument& e) 491 { 492 throw; 493 } 494 catch (const std::exception& e) 495 { 496 lg2::error("Exception: {ERR}", "ERR", e); 497 elog<InternalFailure>(); 498 } 499 return val; 500 } 501 502 ConfigIface::SearchScope Config::ldapSearchScope(ConfigIface::SearchScope value) 503 { 504 ConfigIface::SearchScope val; 505 try 506 { 507 if (value == ldapSearchScope()) 508 { 509 return value; 510 } 511 512 val = ConfigIface::ldapSearchScope(value); 513 if (enabled()) 514 { 515 writeConfig(); 516 517 parent.startOrStopService(nslcdService, enabled()); 518 } 519 // save the object. 520 serialize(); 521 } 522 catch (const InternalFailure& e) 523 { 524 throw; 525 } 526 catch (const std::exception& e) 527 { 528 lg2::error("Exception: {ERR}", "ERR", e); 529 elog<InternalFailure>(); 530 } 531 return val; 532 } 533 534 ConfigIface::Type Config::ldapType(ConfigIface::Type /*value*/) 535 { 536 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); 537 return ldapType(); 538 } 539 540 bool Config::enabled(bool value) 541 { 542 if (value == enabled()) 543 { 544 return value; 545 } 546 // Let parent decide that can we enable this config. 547 // It may happen that other config is already enabled, 548 // Current implementation support only one config can 549 // be active at a time. 550 return parent.enableService(*this, value); 551 } 552 553 bool Config::enableService(bool value) 554 { 555 bool isEnable = false; 556 try 557 { 558 isEnable = EnableIface::enabled(value); 559 if (isEnable) 560 { 561 writeConfig(); 562 } 563 parent.startOrStopService(nslcdService, value); 564 serialize(); 565 } 566 catch (const InternalFailure& e) 567 { 568 throw; 569 } 570 catch (const std::exception& e) 571 { 572 lg2::error("Exception: {ERR}", "ERR", e); 573 elog<InternalFailure>(); 574 } 575 return isEnable; 576 } 577 578 std::string Config::userNameAttribute(std::string value) 579 { 580 std::string val; 581 try 582 { 583 if (value == userNameAttribute()) 584 { 585 return value; 586 } 587 588 val = ConfigIface::userNameAttribute(value); 589 if (enabled()) 590 { 591 writeConfig(); 592 593 parent.startOrStopService(nslcdService, enabled()); 594 } 595 // save the object. 596 serialize(); 597 } 598 catch (const InternalFailure& e) 599 { 600 throw; 601 } 602 catch (const std::exception& e) 603 { 604 lg2::error("Exception: {ERR}", "ERR", e); 605 elog<InternalFailure>(); 606 } 607 return val; 608 } 609 610 std::string Config::groupNameAttribute(std::string value) 611 { 612 std::string val; 613 try 614 { 615 if (value == groupNameAttribute()) 616 { 617 return value; 618 } 619 620 val = ConfigIface::groupNameAttribute(value); 621 if (enabled()) 622 { 623 writeConfig(); 624 625 parent.startOrStopService(nslcdService, enabled()); 626 } 627 // save the object. 628 serialize(); 629 } 630 catch (const InternalFailure& e) 631 { 632 throw; 633 } 634 catch (const std::exception& e) 635 { 636 lg2::error("Exception: {ERR}", "ERR", e); 637 elog<InternalFailure>(); 638 } 639 return val; 640 } 641 642 template <class Archive> 643 void Config::save(Archive& archive, const std::uint32_t /*version*/) const 644 { 645 archive(this->enabled()); 646 archive(ldapServerURI()); 647 archive(ldapBindDN()); 648 archive(ldapBaseDN()); 649 archive(ldapSearchScope()); 650 archive(ldapBindPassword); 651 archive(userNameAttribute()); 652 archive(groupNameAttribute()); 653 } 654 655 template <class Archive> 656 void Config::load(Archive& archive, const std::uint32_t /*version*/) 657 { 658 bool bVal; 659 archive(bVal); 660 EnableIface::enabled(bVal); 661 662 std::string str; 663 archive(str); 664 ConfigIface::ldapServerURI(str); 665 666 archive(str); 667 ConfigIface::ldapBindDN(str); 668 669 archive(str); 670 ConfigIface::ldapBaseDN(str); 671 672 ConfigIface::SearchScope scope; 673 archive(scope); 674 ConfigIface::ldapSearchScope(scope); 675 676 archive(str); 677 ldapBindPassword = str; 678 679 archive(str); 680 ConfigIface::userNameAttribute(str); 681 682 archive(str); 683 ConfigIface::groupNameAttribute(str); 684 } 685 686 void Config::serialize() 687 { 688 if (!fs::exists(configPersistPath.c_str())) 689 { 690 std::ofstream os(configPersistPath.string(), 691 std::ios::binary | std::ios::out); 692 auto permission = fs::perms::owner_read | fs::perms::owner_write | 693 fs::perms::group_read; 694 fs::permissions(configPersistPath, permission); 695 cereal::BinaryOutputArchive oarchive(os); 696 oarchive(*this); 697 } 698 else 699 { 700 std::ofstream os(configPersistPath.string(), 701 std::ios::binary | std::ios::out); 702 cereal::BinaryOutputArchive oarchive(os); 703 oarchive(*this); 704 } 705 return; 706 } 707 708 bool Config::deserialize() 709 { 710 try 711 { 712 if (fs::exists(configPersistPath)) 713 { 714 std::ifstream is(configPersistPath.c_str(), 715 std::ios::in | std::ios::binary); 716 cereal::BinaryInputArchive iarchive(is); 717 iarchive(*this); 718 719 if (isValidLDAPURI(ldapServerURI(), ldapScheme)) 720 { 721 secureLDAP = false; 722 } 723 else if (isValidLDAPURI(ldapServerURI(), ldapsScheme)) 724 { 725 secureLDAP = true; 726 } 727 return true; 728 } 729 return false; 730 } 731 catch (const cereal::Exception& e) 732 { 733 lg2::error("Exception: {ERR}", "ERR", e); 734 std::error_code ec; 735 fs::remove(configPersistPath, ec); 736 return false; 737 } 738 catch (const fs::filesystem_error& e) 739 { 740 return false; 741 } 742 } 743 744 ObjectPath Config::create(std::string groupName, std::string privilege) 745 { 746 checkPrivilegeMapper(groupName); 747 checkPrivilegeLevel(privilege); 748 749 entryId++; 750 751 // Object path for the LDAP group privilege mapper entry 752 fs::path mapperObjectPath = objectPath; 753 mapperObjectPath /= "role_map"; 754 mapperObjectPath /= std::to_string(entryId); 755 756 fs::path persistPath = parent.dbusPersistentPath; 757 persistPath += mapperObjectPath; 758 759 // Create mapping for LDAP privilege mapper entry 760 auto entry = std::make_unique<LDAPMapperEntry>( 761 bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(), 762 groupName, privilege, *this); 763 764 phosphor::ldap::serialize(*entry, std::move(persistPath)); 765 766 PrivilegeMapperList.emplace(entryId, std::move(entry)); 767 return mapperObjectPath.string(); 768 } 769 770 void Config::deletePrivilegeMapper(Id id) 771 { 772 fs::path mapperObjectPath = objectPath; 773 mapperObjectPath /= "role_map"; 774 mapperObjectPath /= std::to_string(id); 775 776 fs::path persistPath = parent.dbusPersistentPath; 777 persistPath += std::move(mapperObjectPath); 778 779 // Delete the persistent representation of the privilege mapper. 780 fs::remove(std::move(persistPath)); 781 782 PrivilegeMapperList.erase(id); 783 } 784 void Config::checkPrivilegeMapper(const std::string& groupName) 785 { 786 if (groupName.empty()) 787 { 788 lg2::error("Group name is empty"); 789 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"), 790 Argument::ARGUMENT_VALUE("Null")); 791 } 792 793 for (const auto& val : PrivilegeMapperList) 794 { 795 if (val.second.get()->groupName() == groupName) 796 { 797 lg2::error("Group name '{GROUPNAME}' already exists", "GROUPNAME", 798 groupName); 799 elog<PrivilegeMappingExists>(); 800 } 801 } 802 } 803 804 void Config::checkPrivilegeLevel(const std::string& privilege) 805 { 806 if (privilege.empty()) 807 { 808 lg2::error("Privilege level is empty"); 809 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 810 Argument::ARGUMENT_VALUE("Null")); 811 } 812 813 if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end()) 814 { 815 lg2::error("Invalid privilege '{PRIVILEGE}'", "PRIVILEGE", privilege); 816 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege"), 817 Argument::ARGUMENT_VALUE(privilege.c_str())); 818 } 819 } 820 821 void Config::restoreRoleMapping() 822 { 823 namespace fs = std::filesystem; 824 fs::path dir = parent.dbusPersistentPath; 825 dir += objectPath; 826 dir /= "role_map"; 827 828 if (!fs::exists(dir) || fs::is_empty(dir)) 829 { 830 return; 831 } 832 833 for (auto& file : fs::directory_iterator(dir)) 834 { 835 std::string id = file.path().filename().c_str(); 836 size_t idNum = std::stol(id); 837 838 auto entryPath = objectPath + '/' + "role_map" + '/' + id; 839 auto persistPath = parent.dbusPersistentPath + entryPath; 840 auto entry = std::make_unique<LDAPMapperEntry>( 841 bus, entryPath.c_str(), persistPath.c_str(), *this); 842 if (phosphor::ldap::deserialize(file.path(), *entry)) 843 { 844 entry->Interfaces::emit_object_added(); 845 PrivilegeMapperList.emplace(idNum, std::move(entry)); 846 if (idNum > entryId) 847 { 848 entryId = idNum; 849 } 850 } 851 } 852 } 853 854 } // namespace ldap 855 } // namespace phosphor 856