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>
diff --git a/include/dbus_privileges.hpp b/include/dbus_privileges.hpp
index 07a1216..fca4a13 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,10 +128,44 @@
return false;
}
+ req.userRole = req.session->userRole;
return true;
}
template <typename CallbackFn>
+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 (ec)
+ {
+ BMCWEB_LOG_ERROR("GetUserInfo failed...");
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
+
+ if (!populateUserInfo(req, asyncResp, userInfoMap))
+ {
+ 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_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)
@@ -67,29 +175,15 @@
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)
- {
- req.session->userGroups = std::move(*props.userGroups);
- }
-
- if (!isUserPrivileged(req, asyncResp, rule))
- {
- // User is not privileged
- BMCWEB_LOG_WARNING("Insufficient Privilege");
- asyncResp->res.result(boost::beast::http::status::forbidden);
- return;
- }
- callback(req);
+ 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