diff options
Diffstat (limited to 'include/dbus_privileges.hpp')
-rw-r--r-- | include/dbus_privileges.hpp | 134 |
1 files changed, 114 insertions, 20 deletions
diff --git a/include/dbus_privileges.hpp b/include/dbus_privileges.hpp index 07a1216cdc..fca4a137d3 100644 --- a/include/dbus_privileges.hpp +++ b/include/dbus_privileges.hpp @@ -6,11 +6,9 @@ #include "http_response.hpp" #include "logging.hpp" #include "routing/baserule.hpp" -#include "user_role_map.hpp" #include "utils/dbus_utils.hpp" #include <boost/url/format.hpp> -#include <sdbusplus/bus/match.hpp> #include <sdbusplus/unpack_properties.hpp> #include <memory> @@ -18,6 +16,82 @@ namespace crow { +// Populate session with user information. +inline bool + populateUserInfo(Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const dbus::utility::DBusPropertiesMap& userInfoMap) +{ + const std::string* userRolePtr = nullptr; + const bool* remoteUser = nullptr; + const bool* passwordExpired = nullptr; + const std::vector<std::string>* userGroups = nullptr; + + const bool success = sdbusplus::unpackPropertiesNoThrow( + redfish::dbus_utils::UnpackErrorPrinter(), userInfoMap, "UserPrivilege", + userRolePtr, "RemoteUser", remoteUser, "UserPasswordExpired", + passwordExpired, "UserGroups", userGroups); + + if (!success) + { + BMCWEB_LOG_ERROR("Failed to unpack user properties."); + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return false; + } + + if (req.session == nullptr) + { + return false; + } + + if (userRolePtr != nullptr) + { + req.session->userRole = *userRolePtr; + BMCWEB_LOG_DEBUG("userName = {} userRole = {}", req.session->username, + *userRolePtr); + } + + if (remoteUser == nullptr) + { + BMCWEB_LOG_ERROR("RemoteUser property missing or wrong type"); + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return false; + } + bool expired = false; + if (passwordExpired == nullptr) + { + if (!*remoteUser) + { + BMCWEB_LOG_ERROR("UserPasswordExpired property is expected for" + " local user but is missing or wrong type"); + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return false; + } + } + else + { + expired = *passwordExpired; + } + + // Set isConfigureSelfOnly based on D-Bus results. This + // ignores the results from both pamAuthenticateUser and the + // value from any previous use of this session. + req.session->isConfigureSelfOnly = expired; + + if (userGroups != nullptr) + { + // Populate session with user groups. + for (const auto& userGroup : *userGroups) + { + req.session->userGroups.emplace_back(userGroup); + } + } + + return true; +} inline bool isUserPrivileged(Request& req, @@ -54,42 +128,62 @@ inline bool return false; } + req.userRole = req.session->userRole; return true; } template <typename CallbackFn> -void validatePrivilege(Request& req, - const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, - BaseRule& rule, CallbackFn&& callback) +void afterGetUserInfo(Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + BaseRule& rule, CallbackFn&& callback, + const boost::system::error_code& ec, + const dbus::utility::DBusPropertiesMap& userInfoMap) { - if (req.session == nullptr) + if (ec) { + BMCWEB_LOG_ERROR("GetUserInfo failed..."); + asyncResp->res.result( + boost::beast::http::status::internal_server_error); return; } - std::string username = req.session->username; - UserFields props = - UserRoleMap::getInstance().getUserRole(req.session->username); - if (props.userRole) - { - req.session->userRole = props.userRole.value_or(""); - } - if (props.passwordExpired) - { - req.session->isConfigureSelfOnly = *props.passwordExpired; - } - if (props.userGroups) + + if (!populateUserInfo(req, asyncResp, userInfoMap)) { - req.session->userGroups = std::move(*props.userGroups); + BMCWEB_LOG_ERROR("Failed to populate user information"); + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return; } if (!isUserPrivileged(req, asyncResp, rule)) { // User is not privileged - BMCWEB_LOG_WARNING("Insufficient Privilege"); + BMCWEB_LOG_ERROR("Insufficient Privilege"); asyncResp->res.result(boost::beast::http::status::forbidden); return; } callback(req); } +template <typename CallbackFn> +void validatePrivilege(Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + BaseRule& rule, CallbackFn&& callback) +{ + if (req.session == nullptr) + { + return; + } + std::string username = req.session->username; + crow::connections::systemBus->async_method_call( + [&req, asyncResp, &rule, callback(std::forward<CallbackFn>(callback))]( + const boost::system::error_code& ec, + const dbus::utility::DBusPropertiesMap& userInfoMap) mutable { + afterGetUserInfo(req, asyncResp, rule, + std::forward<CallbackFn>(callback), ec, userInfoMap); + }, + "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", + "xyz.openbmc_project.User.Manager", "GetUserInfo", username); +} + } // namespace crow |