summaryrefslogtreecommitdiff
path: root/include/dbus_privileges.hpp
diff options
context:
space:
mode:
authorGunnar Mills <gmills@us.ibm.com>2023-08-01 20:41:17 +0300
committerGunnar Mills <gmills@us.ibm.com>2023-08-01 22:58:54 +0300
commit59ba63885eadecea4bd722141cd41bffecf96397 (patch)
treeb6df056c77ea0b8e4664150eaa0c3a532834cf53 /include/dbus_privileges.hpp
parent46228e0e80488ecbe1058f01cdaa018eaa6bd654 (diff)
downloadbmcweb-59ba63885eadecea4bd722141cd41bffecf96397.tar.xz
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 <gmills@us.ibm.com>
Diffstat (limited to 'include/dbus_privileges.hpp')
-rw-r--r--include/dbus_privileges.hpp134
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