From 3841906eeb2e64a07c74b746ffe79649627b8d55 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 11 Jan 2024 18:45:55 -0500 Subject: [PATCH] rgw/rest: enable iam UserPolicy apis against account users when the authenticated user belongs to an account: * operate only on that account's users * match UserName to user's display_name instead of user_id Signed-off-by: Casey Bodley --- src/rgw/rgw_rest_user_policy.cc | 41 +++++++++++++++++++++++++-------- src/rgw/rgw_rest_user_policy.h | 2 ++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/rgw/rgw_rest_user_policy.cc b/src/rgw/rgw_rest_user_policy.cc index 6ef3ab04a17..e452369ccb7 100644 --- a/src/rgw/rgw_rest_user_policy.cc +++ b/src/rgw/rgw_rest_user_policy.cc @@ -52,16 +52,36 @@ int RGWRestUserPolicy::init_processing(optional_yield y) return r; } - // interpret UserName as a uid with optional tenant - const auto uid = rgw_user{user_name}; - // user ARN includes tenant and user id - user_arn = rgw::ARN{uid.id, "user", uid.tenant}; - - user = driver->get_user(uid); - r = user->load_user(this, y); - if (r == -ENOENT) { - s->err.message = "No such UserName in the tenant"; - return -ERR_NO_SUCH_ENTITY; + if (const auto* id = std::get_if(&s->owner.id); id) { + account_id = *id; + + // look up account user by UserName + const std::string& tenant = s->auth.identity->get_tenant(); + r = driver->load_account_user_by_name(this, y, account_id, + tenant, user_name, &user); + + if (r == -ENOENT) { + s->err.message = "No such UserName in the account"; + return -ERR_NO_SUCH_ENTITY; + } + if (r >= 0) { + // user ARN includes account id, path, and display name + const RGWUserInfo& info = user->get_info(); + const std::string resource = string_cat_reserve(info.path, info.display_name); + user_arn = rgw::ARN{resource, "user", account_id, true}; + } + } else { + // interpret UserName as a uid with optional tenant + const auto uid = rgw_user{user_name}; + // user ARN includes tenant and user id + user_arn = rgw::ARN{uid.id, "user", uid.tenant}; + + user = driver->get_user(uid); + r = user->load_user(this, y); + if (r == -ENOENT) { + s->err.message = "No such UserName in the tenant"; + return -ERR_NO_SUCH_ENTITY; + } } return r; @@ -78,6 +98,7 @@ int RGWRestUserPolicy::verify_permission(optional_yield y) return -EACCES; } + // admin caps are required for non-account users if (check_caps(s->user->get_caps()) == 0) { return 0; } diff --git a/src/rgw/rgw_rest_user_policy.h b/src/rgw/rgw_rest_user_policy.h index d14d2f51573..681dfd80065 100644 --- a/src/rgw/rgw_rest_user_policy.h +++ b/src/rgw/rgw_rest_user_policy.h @@ -5,6 +5,7 @@ #include "rgw_arn.h" #include "rgw_rest.h" +#include "rgw_user_types.h" #include "rgw_sal_fwd.h" class RGWRestUserPolicy : public RGWRESTOp { @@ -13,6 +14,7 @@ protected: uint64_t action; uint32_t perm; + rgw_account_id account_id; std::unique_ptr user; rgw::ARN user_arn; std::string policy_name; -- 2.39.5