| #include "ldap_config.hpp" |
| |
| #include "ldap_config_mgr.hpp" |
| #include "ldap_mapper_serialize.hpp" |
| #include "utils.hpp" |
| |
| #include <cereal/archives/binary.hpp> |
| #include <cereal/types/string.hpp> |
| #include <cereal/types/vector.hpp> |
| #include <phosphor-logging/elog-errors.hpp> |
| #include <phosphor-logging/elog.hpp> |
| #include <phosphor-logging/lg2.hpp> |
| #include <xyz/openbmc_project/Common/error.hpp> |
| #include <xyz/openbmc_project/User/Common/error.hpp> |
| |
| #include <filesystem> |
| #include <fstream> |
| #include <sstream> |
| |
| // Register class version |
| // From cereal documentation; |
| // "This macro should be placed at global scope" |
| CEREAL_CLASS_VERSION(phosphor::ldap::Config, CLASS_VERSION); |
| |
| namespace phosphor |
| { |
| namespace ldap |
| { |
| |
| constexpr auto nslcdService = "nslcd.service"; |
| constexpr auto ldapScheme = "ldap"; |
| constexpr auto ldapsScheme = "ldaps"; |
| constexpr auto certObjPath = "/xyz/openbmc_project/certs/client/ldap/1"; |
| constexpr auto certRootPath = "/xyz/openbmc_project/certs/client/ldap"; |
| constexpr auto authObjPath = "/xyz/openbmc_project/certs/authority/truststore"; |
| constexpr auto certIface = "xyz.openbmc_project.Certs.Certificate"; |
| constexpr auto certProperty = "CertificateString"; |
| |
| using namespace phosphor::logging; |
| using namespace sdbusplus::xyz::openbmc_project::Common::Error; |
| namespace fs = std::filesystem; |
| |
| using Argument = xyz::openbmc_project::Common::InvalidArgument; |
| using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed; |
| using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common:: |
| Error::PrivilegeMappingExists; |
| |
| using Line = std::string; |
| using Key = std::string; |
| using Val = std::string; |
| using ConfigInfo = std::map<Key, Val>; |
| |
| Config::Config( |
| sdbusplus::bus_t& bus, const char* path, const char* filePath, |
| const char* caCertFile, const char* certFile, bool secureLDAP, |
| std::string ldapServerURI, std::string ldapBindDN, std::string ldapBaseDN, |
| std::string&& ldapBindDNPassword, ConfigIface::SearchScope ldapSearchScope, |
| ConfigIface::Type ldapType, bool ldapServiceEnabled, |
| std::string userNameAttr, std::string groupNameAttr, ConfigMgr& parent) : |
| Ifaces(bus, path, Ifaces::action::defer_emit), secureLDAP(secureLDAP), |
| ldapBindPassword(std::move(ldapBindDNPassword)), tlsCacertFile(caCertFile), |
| tlsCertFile(certFile), configFilePath(filePath), objectPath(path), bus(bus), |
| parent(parent), |
| certificateInstalledSignal( |
| bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), |
| std::bind(std::mem_fn(&Config::certificateInstalled), this, |
| std::placeholders::_1)), |
| |
| cacertificateInstalledSignal( |
| bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), |
| std::bind(std::mem_fn(&Config::certificateInstalled), this, |
| std::placeholders::_1)), |
| |
| certificateChangedSignal( |
| bus, |
| sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), |
| std::bind(std::mem_fn(&Config::certificateChanged), this, |
| std::placeholders::_1)) |
| { |
| ConfigIface::ldapServerURI(ldapServerURI); |
| ConfigIface::ldapBindDN(ldapBindDN); |
| ConfigIface::ldapBaseDN(ldapBaseDN); |
| ConfigIface::ldapSearchScope(ldapSearchScope); |
| ConfigIface::ldapType(ldapType); |
| EnableIface::enabled(ldapServiceEnabled); |
| ConfigIface::userNameAttribute(userNameAttr); |
| ConfigIface::groupNameAttribute(groupNameAttr); |
| // NOTE: Don't update the bindDN password under ConfigIface |
| if (enabled()) |
| { |
| writeConfig(); |
| } |
| // save the config. |
| configPersistPath = parent.dbusPersistentPath; |
| configPersistPath += objectPath; |
| |
| // create the persistent directory |
| fs::create_directories(configPersistPath); |
| |
| configPersistPath += "/config"; |
| |
| serialize(); |
| |
| // Emit deferred signal. |
| this->emit_object_added(); |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| |
| Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath, |
| const char* caCertFile, const char* certFile, |
| ConfigIface::Type ldapType, ConfigMgr& parent) : |
| Ifaces(bus, path, Ifaces::action::defer_emit), secureLDAP(false), |
| tlsCacertFile(caCertFile), tlsCertFile(certFile), configFilePath(filePath), |
| objectPath(path), bus(bus), parent(parent), |
| certificateInstalledSignal( |
| bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath), |
| std::bind(std::mem_fn(&Config::certificateInstalled), this, |
| std::placeholders::_1)), |
| cacertificateInstalledSignal( |
| bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath), |
| std::bind(std::mem_fn(&Config::certificateInstalled), this, |
| std::placeholders::_1)), |
| certificateChangedSignal( |
| bus, |
| sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface), |
| std::bind(std::mem_fn(&Config::certificateChanged), this, |
| std::placeholders::_1)) |
| { |
| ConfigIface::ldapType(ldapType); |
| |
| configPersistPath = parent.dbusPersistentPath; |
| configPersistPath += objectPath; |
| |
| // create the persistent directory |
| fs::create_directories(configPersistPath); |
| |
| configPersistPath += "/config"; |
| } |
| |
| void Config::certificateInstalled(sdbusplus::message_t& /*msg*/) |
| { |
| try |
| { |
| if (enabled()) |
| { |
| writeConfig(); |
| } |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| } |
| |
| void Config::certificateChanged(sdbusplus::message_t& msg) |
| { |
| std::string objectName; |
| std::map<std::string, std::variant<std::string>> msgData; |
| msg.read(objectName, msgData); |
| auto valPropMap = msgData.find(certProperty); |
| { |
| if (valPropMap != msgData.end()) |
| { |
| try |
| { |
| if (enabled()) |
| { |
| writeConfig(); |
| } |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| } |
| } |
| } |
| |
| void Config::writeConfig() |
| { |
| std::stringstream confData; |
| auto isPwdTobeWritten = false; |
| std::string userNameAttr; |
| |
| confData << "uid root\n"; |
| confData << "gid root\n\n"; |
| confData << "ldap_version 3\n\n"; |
| confData << "timelimit 30\n"; |
| confData << "bind_timelimit 30\n"; |
| confData << "pagesize 1000\n"; |
| confData << "referrals off\n\n"; |
| confData << "uri " << ldapServerURI() << "\n\n"; |
| confData << "base " << ldapBaseDN() << "\n\n"; |
| confData << "binddn " << ldapBindDN() << "\n"; |
| if (!ldapBindPassword.empty()) |
| { |
| confData << "bindpw " << ldapBindPassword << "\n"; |
| isPwdTobeWritten = true; |
| } |
| confData << "\n"; |
| switch (ldapSearchScope()) |
| { |
| case ConfigIface::SearchScope::sub: |
| confData << "scope sub\n\n"; |
| break; |
| case ConfigIface::SearchScope::one: |
| confData << "scope one\n\n"; |
| break; |
| case ConfigIface::SearchScope::base: |
| confData << "scope base\n\n"; |
| break; |
| } |
| confData << "base passwd " << ldapBaseDN() << "\n"; |
| confData << "base shadow " << ldapBaseDN() << "\n\n"; |
| if (secureLDAP == true) |
| { |
| confData << "ssl on\n"; |
| confData << "tls_reqcert hard\n"; |
| if (fs::is_directory(tlsCacertFile.c_str())) |
| { |
| confData << "tls_cacertdir " << tlsCacertFile.c_str() << "\n"; |
| } |
| else |
| { |
| confData << "tls_cacertfile " << tlsCacertFile.c_str() << "\n"; |
| } |
| if (fs::exists(tlsCertFile.c_str())) |
| { |
| confData << "tls_cert " << tlsCertFile.c_str() << "\n"; |
| confData << "tls_key " << tlsCertFile.c_str() << "\n"; |
| } |
| } |
| else |
| { |
| confData << "ssl off\n"; |
| } |
| confData << "\n"; |
| if (ldapType() == ConfigIface::Type::ActiveDirectory) |
| { |
| if (ConfigIface::userNameAttribute().empty()) |
| { |
| ConfigIface::userNameAttribute("sAMAccountName"); |
| } |
| if (ConfigIface::groupNameAttribute().empty()) |
| { |
| ConfigIface::groupNameAttribute("primaryGroupID"); |
| } |
| confData << "filter passwd (&(objectClass=user)(objectClass=person)" |
| "(!(objectClass=computer)))\n"; |
| confData |
| << "filter group (|(objectclass=group)(objectclass=groupofnames) " |
| "(objectclass=groupofuniquenames))\n"; |
| confData << "map passwd uid " |
| << ConfigIface::userNameAttribute() << "\n"; |
| confData << "map passwd uidNumber " |
| "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; |
| confData << "map passwd gidNumber " |
| << ConfigIface::groupNameAttribute() << "\n"; |
| confData << "map passwd homeDirectory \"/home/$sAMAccountName\"\n"; |
| confData << "map passwd gecos displayName\n"; |
| confData << "map passwd loginShell \"/bin/sh\"\n"; |
| confData << "map group gidNumber " |
| "objectSid:S-1-5-21-3623811015-3361044348-30300820\n"; |
| confData << "map group cn " |
| << ConfigIface::userNameAttribute() << "\n"; |
| confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; |
| } |
| else if (ldapType() == ConfigIface::Type::OpenLdap) |
| { |
| if (ConfigIface::userNameAttribute().empty()) |
| { |
| ConfigIface::userNameAttribute("cn"); |
| } |
| if (ConfigIface::groupNameAttribute().empty()) |
| { |
| ConfigIface::groupNameAttribute("gidNumber"); |
| } |
| confData << "filter passwd (objectclass=*)\n"; |
| confData << "map passwd gecos displayName\n"; |
| confData << "filter group (objectclass=posixGroup)\n"; |
| confData << "map passwd uid " |
| << ConfigIface::userNameAttribute() << "\n"; |
| confData << "map passwd gidNumber " |
| << ConfigIface::groupNameAttribute() << "\n"; |
| confData << "map passwd loginShell \"/bin/sh\"\n"; |
| confData << "nss_initgroups_ignoreusers ALLLOCAL\n"; |
| } |
| try |
| { |
| std::fstream stream(configFilePath.c_str(), std::fstream::out); |
| // remove the read permission from others if password is being written. |
| // nslcd forces this behaviour. |
| auto permission = fs::perms::owner_read | fs::perms::owner_write | |
| fs::perms::group_read; |
| if (isPwdTobeWritten) |
| { |
| fs::permissions(configFilePath, permission); |
| } |
| else |
| { |
| fs::permissions(configFilePath, |
| permission | fs::perms::others_read); |
| } |
| |
| stream << confData.str(); |
| stream.flush(); |
| stream.close(); |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return; |
| } |
| |
| std::string Config::ldapBindDNPassword(std::string value) |
| { |
| // Don't update the D-bus object, this is just to |
| // facilitate if user wants to change the bind dn password |
| // once d-bus object gets created. |
| ldapBindPassword = value; |
| try |
| { |
| if (enabled()) |
| { |
| writeConfig(); |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return value; |
| } |
| |
| std::string Config::ldapServerURI(std::string value) |
| { |
| std::string val; |
| try |
| { |
| if (value == ldapServerURI()) |
| { |
| return value; |
| } |
| if (isValidLDAPURI(value, ldapsScheme)) |
| { |
| secureLDAP = true; |
| } |
| else if (isValidLDAPURI(value, ldapScheme)) |
| { |
| secureLDAP = false; |
| } |
| else |
| { |
| lg2::error("Bad LDAP Server URI {URI}", "URI", value); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"), |
| Argument::ARGUMENT_VALUE(value.c_str())); |
| } |
| |
| if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) |
| { |
| lg2::error("LDAP server CA certificate not found at {PATH}", "PATH", |
| tlsCacertFile); |
| elog<NoCACertificate>(); |
| } |
| val = ConfigIface::ldapServerURI(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const InvalidArgument& e) |
| { |
| throw; |
| } |
| catch (const NoCACertificate& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| std::string Config::ldapBindDN(std::string value) |
| { |
| std::string val; |
| try |
| { |
| if (value == ldapBindDN()) |
| { |
| return value; |
| } |
| |
| if (value.empty()) |
| { |
| lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN", |
| value); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBindDN"), |
| Argument::ARGUMENT_VALUE(value.c_str())); |
| } |
| |
| val = ConfigIface::ldapBindDN(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const InvalidArgument& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| std::string Config::ldapBaseDN(std::string value) |
| { |
| std::string val; |
| try |
| { |
| if (value == ldapBaseDN()) |
| { |
| return value; |
| } |
| |
| if (value.empty()) |
| { |
| lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN", |
| value); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBaseDN"), |
| Argument::ARGUMENT_VALUE(value.c_str())); |
| } |
| |
| val = ConfigIface::ldapBaseDN(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const InvalidArgument& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| ConfigIface::SearchScope Config::ldapSearchScope(ConfigIface::SearchScope value) |
| { |
| ConfigIface::SearchScope val; |
| try |
| { |
| if (value == ldapSearchScope()) |
| { |
| return value; |
| } |
| |
| val = ConfigIface::ldapSearchScope(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| ConfigIface::Type Config::ldapType(ConfigIface::Type /*value*/) |
| { |
| elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); |
| return ldapType(); |
| } |
| |
| bool Config::enabled(bool value) |
| { |
| if (value == enabled()) |
| { |
| return value; |
| } |
| // Let parent decide that can we enable this config. |
| // It may happen that other config is already enabled, |
| // Current implementation support only one config can |
| // be active at a time. |
| return parent.enableService(*this, value); |
| } |
| |
| bool Config::enableService(bool value) |
| { |
| bool isEnable = false; |
| try |
| { |
| isEnable = EnableIface::enabled(value); |
| if (isEnable) |
| { |
| writeConfig(); |
| } |
| parent.startOrStopService(nslcdService, value); |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return isEnable; |
| } |
| |
| std::string Config::userNameAttribute(std::string value) |
| { |
| std::string val; |
| try |
| { |
| if (value == userNameAttribute()) |
| { |
| return value; |
| } |
| |
| val = ConfigIface::userNameAttribute(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| std::string Config::groupNameAttribute(std::string value) |
| { |
| std::string val; |
| try |
| { |
| if (value == groupNameAttribute()) |
| { |
| return value; |
| } |
| |
| val = ConfigIface::groupNameAttribute(value); |
| if (enabled()) |
| { |
| writeConfig(); |
| |
| parent.startOrStopService(nslcdService, enabled()); |
| } |
| // save the object. |
| serialize(); |
| } |
| catch (const InternalFailure& e) |
| { |
| throw; |
| } |
| catch (const std::exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| elog<InternalFailure>(); |
| } |
| return val; |
| } |
| |
| template <class Archive> |
| void Config::save(Archive& archive, const std::uint32_t /*version*/) const |
| { |
| archive(this->enabled()); |
| archive(ldapServerURI()); |
| archive(ldapBindDN()); |
| archive(ldapBaseDN()); |
| archive(ldapSearchScope()); |
| archive(ldapBindPassword); |
| archive(userNameAttribute()); |
| archive(groupNameAttribute()); |
| } |
| |
| template <class Archive> |
| void Config::load(Archive& archive, const std::uint32_t /*version*/) |
| { |
| bool bVal; |
| archive(bVal); |
| EnableIface::enabled(bVal); |
| |
| std::string str; |
| archive(str); |
| ConfigIface::ldapServerURI(str); |
| |
| archive(str); |
| ConfigIface::ldapBindDN(str); |
| |
| archive(str); |
| ConfigIface::ldapBaseDN(str); |
| |
| ConfigIface::SearchScope scope; |
| archive(scope); |
| ConfigIface::ldapSearchScope(scope); |
| |
| archive(str); |
| ldapBindPassword = str; |
| |
| archive(str); |
| ConfigIface::userNameAttribute(str); |
| |
| archive(str); |
| ConfigIface::groupNameAttribute(str); |
| } |
| |
| void Config::serialize() |
| { |
| if (!fs::exists(configPersistPath.c_str())) |
| { |
| std::ofstream os(configPersistPath.string(), |
| std::ios::binary | std::ios::out); |
| auto permission = fs::perms::owner_read | fs::perms::owner_write | |
| fs::perms::group_read; |
| fs::permissions(configPersistPath, permission); |
| cereal::BinaryOutputArchive oarchive(os); |
| oarchive(*this); |
| } |
| else |
| { |
| std::ofstream os(configPersistPath.string(), |
| std::ios::binary | std::ios::out); |
| cereal::BinaryOutputArchive oarchive(os); |
| oarchive(*this); |
| } |
| return; |
| } |
| |
| bool Config::deserialize() |
| { |
| try |
| { |
| if (fs::exists(configPersistPath)) |
| { |
| std::ifstream is(configPersistPath.c_str(), |
| std::ios::in | std::ios::binary); |
| cereal::BinaryInputArchive iarchive(is); |
| iarchive(*this); |
| |
| if (isValidLDAPURI(ldapServerURI(), ldapScheme)) |
| { |
| secureLDAP = false; |
| } |
| else if (isValidLDAPURI(ldapServerURI(), ldapsScheme)) |
| { |
| secureLDAP = true; |
| } |
| return true; |
| } |
| return false; |
| } |
| catch (const cereal::Exception& e) |
| { |
| lg2::error("Exception: {ERR}", "ERR", e); |
| std::error_code ec; |
| fs::remove(configPersistPath, ec); |
| return false; |
| } |
| catch (const fs::filesystem_error& e) |
| { |
| return false; |
| } |
| } |
| |
| ObjectPath Config::create(std::string groupName, std::string privilege) |
| { |
| checkPrivilegeMapper(groupName); |
| checkPrivilegeLevel(privilege); |
| |
| entryId++; |
| |
| // Object path for the LDAP group privilege mapper entry |
| fs::path mapperObjectPath = objectPath; |
| mapperObjectPath /= "role_map"; |
| mapperObjectPath /= std::to_string(entryId); |
| |
| fs::path persistPath = parent.dbusPersistentPath; |
| persistPath += mapperObjectPath; |
| |
| // Create mapping for LDAP privilege mapper entry |
| auto entry = std::make_unique<LDAPMapperEntry>( |
| bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(), |
| groupName, privilege, *this); |
| |
| phosphor::ldap::serialize(*entry, std::move(persistPath)); |
| |
| PrivilegeMapperList.emplace(entryId, std::move(entry)); |
| return mapperObjectPath.string(); |
| } |
| |
| void Config::deletePrivilegeMapper(Id id) |
| { |
| fs::path mapperObjectPath = objectPath; |
| mapperObjectPath /= "role_map"; |
| mapperObjectPath /= std::to_string(id); |
| |
| fs::path persistPath = parent.dbusPersistentPath; |
| persistPath += std::move(mapperObjectPath); |
| |
| // Delete the persistent representation of the privilege mapper. |
| fs::remove(std::move(persistPath)); |
| |
| PrivilegeMapperList.erase(id); |
| } |
| void Config::checkPrivilegeMapper(const std::string& groupName) |
| { |
| if (groupName.empty()) |
| { |
| lg2::error("Group name is empty"); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"), |
| Argument::ARGUMENT_VALUE("Null")); |
| } |
| |
| for (const auto& val : PrivilegeMapperList) |
| { |
| if (val.second.get()->groupName() == groupName) |
| { |
| lg2::error("Group name '{GROUPNAME}' already exists", "GROUPNAME", |
| groupName); |
| elog<PrivilegeMappingExists>(); |
| } |
| } |
| } |
| |
| void Config::checkPrivilegeLevel(const std::string& privilege) |
| { |
| if (privilege.empty()) |
| { |
| lg2::error("Privilege level is empty"); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"), |
| Argument::ARGUMENT_VALUE("Null")); |
| } |
| |
| if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end()) |
| { |
| lg2::error("Invalid privilege '{PRIVILEGE}'", "PRIVILEGE", privilege); |
| elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege"), |
| Argument::ARGUMENT_VALUE(privilege.c_str())); |
| } |
| } |
| |
| void Config::restoreRoleMapping() |
| { |
| namespace fs = std::filesystem; |
| fs::path dir = parent.dbusPersistentPath; |
| dir += objectPath; |
| dir /= "role_map"; |
| |
| if (!fs::exists(dir) || fs::is_empty(dir)) |
| { |
| return; |
| } |
| |
| for (auto& file : fs::directory_iterator(dir)) |
| { |
| std::string id = file.path().filename().c_str(); |
| size_t idNum = std::stol(id); |
| |
| auto entryPath = objectPath + '/' + "role_map" + '/' + id; |
| auto persistPath = parent.dbusPersistentPath + entryPath; |
| auto entry = std::make_unique<LDAPMapperEntry>( |
| bus, entryPath.c_str(), persistPath.c_str(), *this); |
| if (phosphor::ldap::deserialize(file.path(), *entry)) |
| { |
| entry->Interfaces::emit_object_added(); |
| PrivilegeMapperList.emplace(idNum, std::move(entry)); |
| if (idNum > entryId) |
| { |
| entryId = idNum; |
| } |
| } |
| } |
| } |
| |
| } // namespace ldap |
| } // namespace phosphor |