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 log<level::ERR>(e.what()); 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 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 log<level::ERR>("bad LDAP Server URI", 376 entry("LDAPSERVERURI=%s", value.c_str())); 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 log<level::ERR>("LDAP server's CA certificate not provided", 384 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str())); 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 log<level::ERR>(e.what()); 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 log<level::ERR>("Not a valid LDAP BINDDN", 429 entry("LDAPBINDDN=%s", value.c_str())); 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 log<level::ERR>(e.what()); 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 log<level::ERR>("Not a valid LDAP BASEDN", 472 entry("BASEDN=%s", value.c_str())); 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 log<level::ERR>(e.what()); 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 689 if (!fs::exists(configPersistPath.c_str())) 690 { 691 std::ofstream os(configPersistPath.string(), 692 std::ios::binary | std::ios::out); 693 auto permission = fs::perms::owner_read | fs::perms::owner_write | 694 fs::perms::group_read; 695 fs::permissions(configPersistPath, permission); 696 cereal::BinaryOutputArchive oarchive(os); 697 oarchive(*this); 698 } 699 else 700 { 701 std::ofstream os(configPersistPath.string(), 702 std::ios::binary | std::ios::out); 703 cereal::BinaryOutputArchive oarchive(os); 704 oarchive(*this); 705 } 706 return; 707 } 708 709 bool Config::deserialize() 710 { 711 try 712 { 713 if (fs::exists(configPersistPath)) 714 { 715 std::ifstream is(configPersistPath.c_str(), 716 std::ios::in | std::ios::binary); 717 cereal::BinaryInputArchive iarchive(is); 718 iarchive(*this); 719 720 if (isValidLDAPURI(ldapServerURI(), LDAPscheme)) 721 { 722 secureLDAP = false; 723 } 724 else if (isValidLDAPURI(ldapServerURI(), LDAPSscheme)) 725 { 726 secureLDAP = true; 727 } 728 return true; 729 } 730 return false; 731 } 732 catch (const cereal::Exception& e) 733 { 734 log<level::ERR>(e.what()); 735 std::error_code ec; 736 fs::remove(configPersistPath, ec); 737 return false; 738 } 739 catch (const fs::filesystem_error& e) 740 { 741 return false; 742 } 743 } 744 745 ObjectPath Config::create(std::string groupName, std::string privilege) 746 { 747 checkPrivilegeMapper(groupName); 748 checkPrivilegeLevel(privilege); 749 750 entryId++; 751 752 // Object path for the LDAP group privilege mapper entry 753 fs::path mapperObjectPath = objectPath; 754 mapperObjectPath /= "role_map"; 755 mapperObjectPath /= std::to_string(entryId); 756 757 fs::path persistPath = parent.dbusPersistentPath; 758 persistPath += mapperObjectPath; 759 760 // Create mapping for LDAP privilege mapper entry 761 auto entry = std::make_unique<LDAPMapperEntry>( 762 bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(), 763 groupName, privilege, *this); 764 765 phosphor::ldap::serialize(*entry, std::move(persistPath)); 766 767 PrivilegeMapperList.emplace(entryId, std::move(entry)); 768 return mapperObjectPath.string(); 769 } 770 771 void Config::deletePrivilegeMapper(Id id) 772 { 773 fs::path mapperObjectPath = objectPath; 774 mapperObjectPath /= "role_map"; 775 mapperObjectPath /= std::to_string(id); 776 777 fs::path persistPath = parent.dbusPersistentPath; 778 persistPath += std::move(mapperObjectPath); 779 780 // Delete the persistent representation of the privilege mapper. 781 fs::remove(std::move(persistPath)); 782 783 PrivilegeMapperList.erase(id); 784 } 785 void Config::checkPrivilegeMapper(const std::string& groupName) 786 { 787 if (groupName.empty()) 788 { 789 log<level::ERR>("Group name is empty"); 790 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"), 791 Argument::ARGUMENT_VALUE("Null")); 792 } 793 794 for (const auto& val : PrivilegeMapperList) 795 { 796 if (val.second.get()->groupName() == groupName) 797 { 798 log<level::ERR>("Group name already exists"); 799 elog<PrivilegeMappingExists>(); 800 } 801 } 802 } 803 804 void Config::checkPrivilegeLevel(const std::string& privilege) 805 { 806 if (privilege.empty()) 807 { 808 log<level::ERR>("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 log<level::ERR>("Invalid privilege"); 816 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 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