From 59ba63885eadecea4bd722141cd41bffecf96397 Mon Sep 17 00:00:00 2001 From: Gunnar Mills Date: Tue, 1 Aug 2023 12:41:17 -0500 Subject: Revert "Cache user role in session object" This reverts commit 8ed41c35a314580bb794fa0fff2e01b0bf7efcf7. In discord, it was posted 2 systems are hitting 403 Forbidden for all endpoints. Reverting fixed the problem, until time is given to dive into this, just revert. One of the things wrong is this is missing an After/Want xyz.openbmc_project.User.Manager.service. Change-Id: I1766a6ec2dbc9fb52da3940b07ac002a1a6d269a Signed-off-by: Gunnar Mills --- include/dbus_privileges.hpp | 134 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 20 deletions(-) (limited to 'include/dbus_privileges.hpp') 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 -#include #include #include @@ -18,6 +16,82 @@ namespace crow { +// Populate session with user information. +inline bool + populateUserInfo(Request& req, + const std::shared_ptr& asyncResp, + const dbus::utility::DBusPropertiesMap& userInfoMap) +{ + const std::string* userRolePtr = nullptr; + const bool* remoteUser = nullptr; + const bool* passwordExpired = nullptr; + const std::vector* 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 -void validatePrivilege(Request& req, - const std::shared_ptr& asyncResp, - BaseRule& rule, CallbackFn&& callback) +void afterGetUserInfo(Request& req, + const std::shared_ptr& 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 +void validatePrivilege(Request& req, + const std::shared_ptr& 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(callback))]( + const boost::system::error_code& ec, + const dbus::utility::DBusPropertiesMap& userInfoMap) mutable { + afterGetUserInfo(req, asyncResp, rule, + std::forward(callback), ec, userInfoMap); + }, + "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", + "xyz.openbmc_project.User.Manager", "GetUserInfo", username); +} + } // namespace crow -- cgit v1.2.3