diff options
author | James Feist <james.feist@linux.intel.com> | 2019-12-10 19:52:14 +0300 |
---|---|---|
committer | James Feist <james.feist@linux.intel.com> | 2019-12-10 20:22:47 +0300 |
commit | 7166bf0fd7453f2b5d6bfb3afbdad5eb00f74990 (patch) | |
tree | a75ffbf37684d15df4dd01b8a1cc3a28f1495a55 /include/sessions.hpp | |
parent | 4dcc3f92c8725e2424c7792908c44311e484a429 (diff) | |
download | bmcweb-7166bf0fd7453f2b5d6bfb3afbdad5eb00f74990.tar.xz |
Revert "Fix authorization for LDAP users"
This reverts commit 5e931ae994307babe6c3520cbaca6a7139acc81d.
Reason for revert: Causing build failures
/bmcweb/redfish-core/include/node.hpp: In member function ‘bool redfish::Node::isAllowedWithoutConfigureSelf(const crow::Request&)’:
/bmcweb/redfish-core/include/node.hpp:182:36: error: ‘crow::persistent_data::UserRoleMap’ has not been declared
crow::persistent_data::UserRoleMap::getInstance().getUserRole(
When 900f949773795141266271107219ea019f2839cd was merged first
this patch was not successfully rebased.
Change-Id: I947d96362c7dadea5572888468a11fac5ee361d4
Signed-off-by: James Feist <james.feist@linux.intel.com>
Diffstat (limited to 'include/sessions.hpp')
-rw-r--r-- | include/sessions.hpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/include/sessions.hpp b/include/sessions.hpp index 7c2575d5d1..6e74f25919 100644 --- a/include/sessions.hpp +++ b/include/sessions.hpp @@ -30,6 +30,250 @@ enum class PersistenceType SINGLE_REQUEST // User times out once this request is completed. }; +constexpr char const* userService = "xyz.openbmc_project.User.Manager"; +constexpr char const* userObjPath = "/xyz/openbmc_project/user"; +constexpr char const* userAttrIface = "xyz.openbmc_project.User.Attributes"; +constexpr char const* dbusPropertiesIface = "org.freedesktop.DBus.Properties"; + +struct UserRoleMap +{ + using GetManagedPropertyType = + boost::container::flat_map<std::string, + std::variant<std::string, bool>>; + + using InterfacesPropertiesType = + boost::container::flat_map<std::string, GetManagedPropertyType>; + + using GetManagedObjectsType = std::vector< + std::pair<sdbusplus::message::object_path, InterfacesPropertiesType>>; + + static UserRoleMap& getInstance() + { + static UserRoleMap userRoleMap; + return userRoleMap; + } + + UserRoleMap(const UserRoleMap&) = delete; + UserRoleMap& operator=(const UserRoleMap&) = delete; + + std::string getUserRole(std::string_view name) + { + auto it = roleMap.find(std::string(name)); + if (it == roleMap.end()) + { + BMCWEB_LOG_ERROR << "User name " << name + << " is not found in the UserRoleMap."; + return ""; + } + return it->second; + } + + std::string + extractUserRole(const InterfacesPropertiesType& interfacesProperties) + { + auto iface = interfacesProperties.find(userAttrIface); + if (iface == interfacesProperties.end()) + { + return {}; + } + + auto& properties = iface->second; + auto property = properties.find("UserPrivilege"); + if (property == properties.end()) + { + return {}; + } + + const std::string* role = std::get_if<std::string>(&property->second); + if (role == nullptr) + { + BMCWEB_LOG_ERROR << "UserPrivilege property value is null"; + return {}; + } + + return *role; + } + + private: + void userAdded(sdbusplus::message::message& m) + { + sdbusplus::message::object_path objPath; + InterfacesPropertiesType interfacesProperties; + + try + { + m.read(objPath, interfacesProperties); + } + catch (const sdbusplus::exception::SdBusError& e) + { + BMCWEB_LOG_ERROR << "Failed to parse user add signal." + << "ERROR=" << e.what() + << "REPLY_SIG=" << m.get_signature(); + return; + } + BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; + + std::size_t lastPos = objPath.str.rfind("/"); + if (lastPos == std::string::npos) + { + return; + }; + + std::string name = objPath.str.substr(lastPos + 1); + std::string role = this->extractUserRole(interfacesProperties); + + // Insert the newly added user name and the role + auto res = roleMap.emplace(name, role); + if (res.second == false) + { + BMCWEB_LOG_ERROR << "Insertion of the user=\"" << name + << "\" in the roleMap failed."; + return; + } + } + + void userRemoved(sdbusplus::message::message& m) + { + sdbusplus::message::object_path objPath; + + try + { + m.read(objPath); + } + catch (const sdbusplus::exception::SdBusError& e) + { + BMCWEB_LOG_ERROR << "Failed to parse user delete signal."; + BMCWEB_LOG_ERROR << "ERROR=" << e.what() + << "REPLY_SIG=" << m.get_signature(); + return; + } + + BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; + + std::size_t lastPos = objPath.str.rfind("/"); + if (lastPos == std::string::npos) + { + return; + }; + + // User name must be atleast 1 char in length. + if ((lastPos + 1) >= objPath.str.length()) + { + return; + } + + std::string name = objPath.str.substr(lastPos + 1); + + roleMap.erase(name); + } + + void userPropertiesChanged(sdbusplus::message::message& m) + { + std::string interface; + GetManagedPropertyType changedProperties; + m.read(interface, changedProperties); + const std::string path = m.get_path(); + + BMCWEB_LOG_DEBUG << "Object Path = \"" << path << "\""; + + std::size_t lastPos = path.rfind("/"); + if (lastPos == std::string::npos) + { + return; + }; + + // User name must be at least 1 char in length. + if ((lastPos + 1) == path.length()) + { + return; + } + + std::string user = path.substr(lastPos + 1); + + BMCWEB_LOG_DEBUG << "User Name = \"" << user << "\""; + + auto index = changedProperties.find("UserPrivilege"); + if (index == changedProperties.end()) + { + return; + } + + const std::string* role = std::get_if<std::string>(&index->second); + if (role == nullptr) + { + return; + } + BMCWEB_LOG_DEBUG << "Role = \"" << *role << "\""; + + auto it = roleMap.find(user); + if (it == roleMap.end()) + { + BMCWEB_LOG_ERROR << "User Name = \"" << user + << "\" is not found. But, received " + "propertiesChanged signal"; + return; + } + it->second = *role; + } + + UserRoleMap() : + userAddedSignal( + *crow::connections::systemBus, + sdbusplus::bus::match::rules::interfacesAdded(userObjPath), + [this](sdbusplus::message::message& m) { + BMCWEB_LOG_DEBUG << "User Added"; + this->userAdded(m); + }), + userRemovedSignal( + *crow::connections::systemBus, + sdbusplus::bus::match::rules::interfacesRemoved(userObjPath), + [this](sdbusplus::message::message& m) { + BMCWEB_LOG_DEBUG << "User Removed"; + this->userRemoved(m); + }), + userPropertiesChangedSignal( + *crow::connections::systemBus, + sdbusplus::bus::match::rules::path_namespace(userObjPath) + + sdbusplus::bus::match::rules::type::signal() + + sdbusplus::bus::match::rules::member("PropertiesChanged") + + sdbusplus::bus::match::rules::interface(dbusPropertiesIface) + + sdbusplus::bus::match::rules::argN(0, userAttrIface), + [this](sdbusplus::message::message& m) { + BMCWEB_LOG_DEBUG << "Properties Changed"; + this->userPropertiesChanged(m); + }) + { + crow::connections::systemBus->async_method_call( + [this](boost::system::error_code ec, + GetManagedObjectsType& managedObjects) { + if (ec) + { + BMCWEB_LOG_DEBUG << "User manager call failed, ignoring"; + return; + } + + for (auto& managedObj : managedObjects) + { + std::size_t lastPos = managedObj.first.str.rfind("/"); + if (lastPos == std::string::npos) + { + continue; + }; + std::string name = managedObj.first.str.substr(lastPos + 1); + std::string role = extractUserRole(managedObj.second); + roleMap.emplace(name, role); + } + }, + userService, userObjPath, "org.freedesktop.DBus.ObjectManager", + "GetManagedObjects"); + } + + boost::container::flat_map<std::string, std::string> roleMap; + sdbusplus::bus::match_t userAddedSignal; + sdbusplus::bus::match_t userRemovedSignal; + sdbusplus::bus::match_t userPropertiesChangedSignal; +}; + struct UserSession { std::string uniqueId; |