summaryrefslogtreecommitdiff
path: root/include/dbus_privileges.hpp
diff options
context:
space:
mode:
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