bmcweb: Handle ConfigureSelf privilege
Enhances BMCWeb to correctly handle the Redfish ConfigureSelf privilege.
Redfish document DSP2046 defines the ConfigureSelf privilege as
"Can change the password for the current user account and log out of
their own sessions." This notion is formalized in the Redfish DSP8011
PrivilegeRegistry where ConfigureSelf appears in three operations:
- ManagerAccount (/redfish/v1/AccountService/Accounts/{account}) GET operation.
- ManagerAccount (/redfish/v1/AccountService/Accounts/{account}) PATCH
Password property override.
- Session (/redfish/v1/SessionService/Sessions/{sessionid}) DELETE operation.
Tested: Yes, tested the above operations using users with various Roles to
determine which operations are allowed.
ReadOnly users (privileges: Login, ConfigureSelf):
- Can GET their own account.
- Can change their password.
- Can log out.
- Cannot change any other properties of their own account.
- Cannot change anyone else's password.
- Cannot GET someone else's account.
- Cannot log out anyone else.
Operator users (privileges: Login, ConfigureComponents, ConfigureSelf):
- Same access as a ReadOnly user.
Administrator users (all privileges):
- Can do everything Operator can do.
- Can change one or more properties of their account
- Can GET and change properties of someone else's account.
- Can logoff any session.
Signed-off-by: Joseph Reynolds <joseph-reynolds@charter.net>
Change-Id: If8efd71cb9743a59b7c5fe1565804d21e788ea29
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 637be86..9f066e3 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1499,7 +1499,8 @@
{boost::beast::http::verb::get,
{{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}}},
{boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
+ {boost::beast::http::verb::patch,
+ {{"ConfigureUsers"}, {"ConfigureSelf"}}},
{boost::beast::http::verb::put, {{"ConfigureUsers"}}},
{boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
{boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
@@ -1509,7 +1510,6 @@
void doGet(crow::Response& res, const crow::Request& req,
const std::vector<std::string>& params) override
{
-
auto asyncResp = std::make_shared<AsyncResp>(res);
if (params.size() != 1)
@@ -1518,6 +1518,21 @@
return;
}
+ // Perform a proper ConfigureSelf authority check. If the
+ // user is operating on an account not their own, then their
+ // ConfigureSelf privilege does not apply. In this case,
+ // perform the authority check again without the user's
+ // ConfigureSelf privilege.
+ if (req.session->username != params[0])
+ {
+ if (!isAllowedWithoutConfigureSelf(req))
+ {
+ BMCWEB_LOG_DEBUG << "GET Account denied access";
+ messages::insufficientPrivilege(asyncResp->res);
+ return;
+ }
+ }
+
crow::connections::systemBus->async_method_call(
[asyncResp, accountName{std::string(params[0])}](
const boost::system::error_code ec,
@@ -1655,6 +1670,25 @@
const std::string& username = params[0];
+ // Perform a proper ConfigureSelf authority check. If the
+ // session is being used to PATCH a property other than
+ // Password, then the ConfigureSelf privilege does not apply.
+ // If the user is operating on an account not their own, then
+ // their ConfigureSelf privilege does not apply. In either
+ // case, perform the authority check again without the user's
+ // ConfigureSelf privilege.
+ if ((username != req.session->username) ||
+ (newUserName || enabled || roleId || locked))
+ {
+ if (!isAllowedWithoutConfigureSelf(req))
+ {
+ BMCWEB_LOG_WARNING << "PATCH Password denied access";
+ asyncResp->res.clear();
+ messages::insufficientPrivilege(asyncResp->res);
+ return;
+ }
+ }
+
// if user name is not provided in the patch method or if it
// matches the user name in the URI, then we are treating it as updating
// user properties other then username. If username provided doesn't
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index d4085af..88f250b 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -35,7 +35,8 @@
{boost::beast::http::verb::head, {{"Login"}}},
{boost::beast::http::verb::patch, {{"ConfigureManager"}}},
{boost::beast::http::verb::put, {{"ConfigureManager"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_,
+ {{"ConfigureManager"}, {"ConfigureSelf"}}},
{boost::beast::http::verb::post, {{"ConfigureManager"}}}};
}
@@ -43,6 +44,7 @@
void doGet(crow::Response& res, const crow::Request& req,
const std::vector<std::string>& params) override
{
+ // Note that control also reaches here via doPost and doDelete.
auto session =
crow::persistent_data::SessionStore::getInstance().getSessionByUid(
params[0]);
@@ -93,6 +95,22 @@
return;
}
+ // Perform a proper ConfigureSelf authority check. If a
+ // session is being used to DELETE some other user's session,
+ // then the ConfigureSelf privilege does not apply. In that
+ // case, perform the authority check again without the user's
+ // ConfigureSelf privilege.
+ if (session->username != req.session->username)
+ {
+ if (!isAllowedWithoutConfigureSelf(req))
+ {
+ BMCWEB_LOG_WARNING << "DELETE Session denied access";
+ messages::insufficientPrivilege(res);
+ res.end();
+ return;
+ }
+ }
+
// DELETE should return representation of object that will be removed
doGet(res, req, params);