1 #include "ldap_config_mgr.hpp" 2 #include "ldap_config.hpp" 3 #include "utils.hpp" 4 5 #include <cereal/types/string.hpp> 6 #include <cereal/types/vector.hpp> 7 #include <cereal/archives/binary.hpp> 8 #include "ldap_mapper_serialize.hpp" 9 10 #include <xyz/openbmc_project/Common/error.hpp> 11 #include <xyz/openbmc_project/User/Common/error.hpp> 12 #include <filesystem> 13 #include <fstream> 14 #include <sstream> 15 16 // Register class version 17 // From cereal documentation; 18 // "This macro should be placed at global scope" 19 CEREAL_CLASS_VERSION(phosphor::ldap::Config, CLASS_VERSION); 20 21 namespace phosphor 22 { 23 namespace ldap 24 { 25 26 constexpr auto nslcdService = "nslcd.service"; 27 constexpr auto nscdService = "nscd.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::bus& 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, true), 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::bus& bus, const char* path, const char* filePath, 109 const char* caCertFile, const char* certFile, 110 ConfigIface::Type lDAPType, ConfigMgr& parent) : 111 Ifaces(bus, path, true), 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::message& 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::message& msg) 161 { 162 std::string objectName; 163 std::map<std::string, sdbusplus::message::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/bash\"\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 } 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 } 297 try 298 { 299 std::fstream stream(configFilePath.c_str(), std::fstream::out); 300 // remove the read permission from others if password is being written. 301 // nslcd forces this behaviour. 302 auto permission = fs::perms::owner_read | fs::perms::owner_write | 303 fs::perms::group_read; 304 if (isPwdTobeWritten) 305 { 306 fs::permissions(configFilePath, permission); 307 } 308 else 309 { 310 fs::permissions(configFilePath, 311 permission | fs::perms::others_read); 312 } 313 314 stream << confData.str(); 315 stream.flush(); 316 stream.close(); 317 } 318 catch (const std::exception& e) 319 { 320 log<level::ERR>(e.what()); 321 elog<InternalFailure>(); 322 } 323 return; 324 } 325 326 std::string Config::lDAPBindDNPassword(std::string value) 327 { 328 // Don't update the D-bus object, this is just to 329 // facilitate if user wants to change the bind dn password 330 // once d-bus object gets created. 331 lDAPBindPassword = value; 332 try 333 { 334 if (enabled()) 335 { 336 writeConfig(); 337 parent.startOrStopService(nslcdService, enabled()); 338 } 339 serialize(); 340 } 341 catch (const InternalFailure& e) 342 { 343 throw; 344 } 345 catch (const std::exception& e) 346 { 347 log<level::ERR>(e.what()); 348 elog<InternalFailure>(); 349 } 350 return value; 351 } 352 353 std::string Config::lDAPServerURI(std::string value) 354 { 355 std::string val; 356 try 357 { 358 if (value == lDAPServerURI()) 359 { 360 return value; 361 } 362 if (isValidLDAPURI(value, LDAPSscheme)) 363 { 364 secureLDAP = true; 365 } 366 else if (isValidLDAPURI(value, LDAPscheme)) 367 { 368 secureLDAP = false; 369 } 370 else 371 { 372 log<level::ERR>("bad LDAP Server URI", 373 entry("LDAPSERVERURI=%s", value.c_str())); 374 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"), 375 Argument::ARGUMENT_VALUE(value.c_str())); 376 } 377 378 if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) 379 { 380 log<level::ERR>("LDAP server's CA certificate not provided", 381 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str())); 382 elog<NoCACertificate>(); 383 } 384 val = ConfigIface::lDAPServerURI(value); 385 if (enabled()) 386 { 387 writeConfig(); 388 parent.startOrStopService(nslcdService, enabled()); 389 } 390 // save the object. 391 serialize(); 392 } 393 catch (const InternalFailure& e) 394 { 395 throw; 396 } 397 catch (const InvalidArgument& e) 398 { 399 throw; 400 } 401 catch (const NoCACertificate& e) 402 { 403 throw; 404 } 405 catch (const std::exception& e) 406 { 407 log<level::ERR>(e.what()); 408 elog<InternalFailure>(); 409 } 410 return val; 411 } 412 413 std::string Config::lDAPBindDN(std::string value) 414 { 415 std::string val; 416 try 417 { 418 if (value == lDAPBindDN()) 419 { 420 return value; 421 } 422 423 if (value.empty()) 424 { 425 log<level::ERR>("Not a valid LDAP BINDDN", 426 entry("LDAPBINDDN=%s", value.c_str())); 427 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBindDN"), 428 Argument::ARGUMENT_VALUE(value.c_str())); 429 } 430 431 val = ConfigIface::lDAPBindDN(value); 432 if (enabled()) 433 { 434 writeConfig(); 435 parent.startOrStopService(nslcdService, enabled()); 436 } 437 // save the object. 438 serialize(); 439 } 440 catch (const InternalFailure& e) 441 { 442 throw; 443 } 444 catch (const InvalidArgument& e) 445 { 446 throw; 447 } 448 catch (const std::exception& e) 449 { 450 log<level::ERR>(e.what()); 451 elog<InternalFailure>(); 452 } 453 return val; 454 } 455 456 std::string Config::lDAPBaseDN(std::string value) 457 { 458 std::string val; 459 try 460 { 461 if (value == lDAPBaseDN()) 462 { 463 return value; 464 } 465 466 if (value.empty()) 467 { 468 log<level::ERR>("Not a valid LDAP BASEDN", 469 entry("BASEDN=%s", value.c_str())); 470 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBaseDN"), 471 Argument::ARGUMENT_VALUE(value.c_str())); 472 } 473 474 val = ConfigIface::lDAPBaseDN(value); 475 if (enabled()) 476 { 477 writeConfig(); 478 parent.startOrStopService(nslcdService, enabled()); 479 } 480 // save the object. 481 serialize(); 482 } 483 catch (const InternalFailure& e) 484 { 485 throw; 486 } 487 catch (const InvalidArgument& e) 488 { 489 throw; 490 } 491 catch (const std::exception& e) 492 { 493 log<level::ERR>(e.what()); 494 elog<InternalFailure>(); 495 } 496 return val; 497 } 498 499 ConfigIface::SearchScope Config::lDAPSearchScope(ConfigIface::SearchScope value) 500 { 501 ConfigIface::SearchScope val; 502 try 503 { 504 if (value == lDAPSearchScope()) 505 { 506 return value; 507 } 508 509 val = ConfigIface::lDAPSearchScope(value); 510 if (enabled()) 511 { 512 writeConfig(); 513 514 parent.startOrStopService(nslcdService, enabled()); 515 } 516 // save the object. 517 serialize(); 518 } 519 catch (const InternalFailure& e) 520 { 521 throw; 522 } 523 catch (const std::exception& e) 524 { 525 log<level::ERR>(e.what()); 526 elog<InternalFailure>(); 527 } 528 return val; 529 } 530 531 ConfigIface::Type Config::lDAPType(ConfigIface::Type value) 532 { 533 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); 534 return lDAPType(); 535 } 536 537 bool Config::enabled(bool value) 538 { 539 if (value == enabled()) 540 { 541 return value; 542 } 543 // Let parent decide that can we enable this config. 544 // It may happen that other config is already enabled, 545 // Current implementation support only one config can 546 // be active at a time. 547 return parent.enableService(*this, value); 548 } 549 550 bool Config::enableService(bool value) 551 { 552 bool isEnable = false; 553 try 554 { 555 isEnable = EnableIface::enabled(value); 556 if (isEnable) 557 { 558 writeConfig(); 559 } 560 parent.startOrStopService(nslcdService, value); 561 serialize(); 562 } 563 catch (const InternalFailure& e) 564 { 565 throw; 566 } 567 catch (const std::exception& e) 568 { 569 log<level::ERR>(e.what()); 570 elog<InternalFailure>(); 571 } 572 return isEnable; 573 } 574 575 std::string Config::userNameAttribute(std::string value) 576 { 577 std::string val; 578 try 579 { 580 if (value == userNameAttribute()) 581 { 582 return value; 583 } 584 585 val = ConfigIface::userNameAttribute(value); 586 if (enabled()) 587 { 588 writeConfig(); 589 590 parent.startOrStopService(nslcdService, enabled()); 591 } 592 // save the object. 593 serialize(); 594 } 595 catch (const InternalFailure& e) 596 { 597 throw; 598 } 599 catch (const std::exception& e) 600 { 601 log<level::ERR>(e.what()); 602 elog<InternalFailure>(); 603 } 604 return val; 605 } 606 607 std::string Config::groupNameAttribute(std::string value) 608 { 609 std::string val; 610 try 611 { 612 if (value == groupNameAttribute()) 613 { 614 return value; 615 } 616 617 val = ConfigIface::groupNameAttribute(value); 618 if (enabled()) 619 { 620 writeConfig(); 621 622 parent.startOrStopService(nslcdService, enabled()); 623 } 624 // save the object. 625 serialize(); 626 } 627 catch (const InternalFailure& e) 628 { 629 throw; 630 } 631 catch (const std::exception& e) 632 { 633 log<level::ERR>(e.what()); 634 elog<InternalFailure>(); 635 } 636 return val; 637 } 638 639 template <class Archive> 640 void Config::save(Archive& archive, const std::uint32_t version) const 641 { 642 archive(this->enabled()); 643 archive(lDAPServerURI()); 644 archive(lDAPBindDN()); 645 archive(lDAPBaseDN()); 646 archive(lDAPSearchScope()); 647 archive(lDAPBindPassword); 648 archive(userNameAttribute()); 649 archive(groupNameAttribute()); 650 } 651 652 template <class Archive> 653 void Config::load(Archive& archive, const std::uint32_t version) 654 { 655 bool bVal; 656 archive(bVal); 657 EnableIface::enabled(bVal); 658 659 std::string str; 660 archive(str); 661 ConfigIface::lDAPServerURI(str); 662 663 archive(str); 664 ConfigIface::lDAPBindDN(str); 665 666 archive(str); 667 ConfigIface::lDAPBaseDN(str); 668 669 ConfigIface::SearchScope scope; 670 archive(scope); 671 ConfigIface::lDAPSearchScope(scope); 672 673 archive(str); 674 lDAPBindPassword = str; 675 676 archive(str); 677 ConfigIface::userNameAttribute(str); 678 679 archive(str); 680 ConfigIface::groupNameAttribute(str); 681 } 682 683 void Config::serialize() 684 { 685 686 if (!fs::exists(configPersistPath.c_str())) 687 { 688 std::ofstream os(configPersistPath.string(), 689 std::ios::binary | std::ios::out); 690 auto permission = fs::perms::owner_read | fs::perms::owner_write | 691 fs::perms::group_read; 692 fs::permissions(configPersistPath, permission); 693 cereal::BinaryOutputArchive oarchive(os); 694 oarchive(*this); 695 } 696 else 697 { 698 std::ofstream os(configPersistPath.string(), 699 std::ios::binary | std::ios::out); 700 cereal::BinaryOutputArchive oarchive(os); 701 oarchive(*this); 702 } 703 return; 704 } 705 706 bool Config::deserialize() 707 { 708 try 709 { 710 if (fs::exists(configPersistPath)) 711 { 712 std::ifstream is(configPersistPath.c_str(), 713 std::ios::in | std::ios::binary); 714 cereal::BinaryInputArchive iarchive(is); 715 iarchive(*this); 716 717 if (isValidLDAPURI(lDAPServerURI(), LDAPscheme)) 718 { 719 secureLDAP = false; 720 } 721 else if (isValidLDAPURI(lDAPServerURI(), LDAPSscheme)) 722 { 723 secureLDAP = true; 724 } 725 return true; 726 } 727 return false; 728 } 729 catch (cereal::Exception& e) 730 { 731 log<level::ERR>(e.what()); 732 std::error_code ec; 733 fs::remove(configPersistPath, ec); 734 return false; 735 } 736 catch (const fs::filesystem_error& e) 737 { 738 return false; 739 } 740 } 741 742 ObjectPath Config::create(std::string groupName, std::string privilege) 743 { 744 checkPrivilegeMapper(groupName); 745 checkPrivilegeLevel(privilege); 746 747 entryId++; 748 749 // Object path for the LDAP group privilege mapper entry 750 fs::path mapperObjectPath = objectPath; 751 mapperObjectPath /= "role_map"; 752 mapperObjectPath /= std::to_string(entryId); 753 754 fs::path persistPath = parent.dbusPersistentPath; 755 persistPath += mapperObjectPath; 756 757 // Create mapping for LDAP privilege mapper entry 758 auto entry = std::make_unique<LDAPMapperEntry>( 759 bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(), 760 groupName, privilege, *this); 761 762 phosphor::ldap::serialize(*entry, std::move(persistPath)); 763 764 PrivilegeMapperList.emplace(entryId, std::move(entry)); 765 return mapperObjectPath.string(); 766 } 767 768 void Config::deletePrivilegeMapper(Id id) 769 { 770 fs::path mapperObjectPath = objectPath; 771 mapperObjectPath /= "role_map"; 772 mapperObjectPath /= std::to_string(id); 773 774 fs::path persistPath = parent.dbusPersistentPath; 775 persistPath += std::move(mapperObjectPath); 776 777 // Delete the persistent representation of the privilege mapper. 778 fs::remove(std::move(persistPath)); 779 780 PrivilegeMapperList.erase(id); 781 } 782 void Config::checkPrivilegeMapper(const std::string& groupName) 783 { 784 if (groupName.empty()) 785 { 786 log<level::ERR>("Group name is empty"); 787 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"), 788 Argument::ARGUMENT_VALUE("Null")); 789 } 790 791 for (const auto& val : PrivilegeMapperList) 792 { 793 if (val.second.get()->groupName() == groupName) 794 { 795 log<level::ERR>("Group name already exists"); 796 elog<PrivilegeMappingExists>(); 797 } 798 } 799 } 800 801 void Config::checkPrivilegeLevel(const std::string& privilege) 802 { 803 if (privilege.empty()) 804 { 805 log<level::ERR>("Privilege level is empty"); 806 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 807 Argument::ARGUMENT_VALUE("Null")); 808 } 809 810 if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end()) 811 { 812 log<level::ERR>("Invalid privilege"); 813 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), 814 Argument::ARGUMENT_VALUE(privilege.c_str())); 815 } 816 } 817 818 void Config::restoreRoleMapping() 819 { 820 namespace fs = std::filesystem; 821 fs::path dir = parent.dbusPersistentPath; 822 dir += objectPath; 823 dir /= "role_map"; 824 825 if (!fs::exists(dir) || fs::is_empty(dir)) 826 { 827 return; 828 } 829 830 for (auto& file : fs::directory_iterator(dir)) 831 { 832 std::string id = file.path().filename().c_str(); 833 size_t idNum = std::stol(id); 834 835 auto entryPath = objectPath + '/' + "role_map" + '/' + id; 836 auto persistPath = parent.dbusPersistentPath + entryPath; 837 auto entry = std::make_unique<LDAPMapperEntry>( 838 bus, entryPath.c_str(), persistPath.c_str(), *this); 839 if (phosphor::ldap::deserialize(file.path(), *entry)) 840 { 841 entry->Interfaces::emit_object_added(); 842 PrivilegeMapperList.emplace(idNum, std::move(entry)); 843 if (idNum > entryId) 844 { 845 entryId = idNum; 846 } 847 } 848 } 849 } 850 851 } // namespace ldap 852 } // namespace phosphor 853