From a6e688551a0fb0089905fc687e77ba691e125771 Mon Sep 17 00:00:00 2001 From: Raja Sharma Date: Thu, 22 May 2025 16:38:00 +0530 Subject: [PATCH] rgw/sts: GetCallerIndentity API Tracker: https://tracker.ceph.com/issues/72157 Signed-off-by: Raja Sharma --- src/rgw/rgw_auth.cc | 13 +++++++++++++ src/rgw/rgw_auth.h | 6 ++---- src/rgw/rgw_auth_s3.cc | 1 + src/rgw/rgw_op_type.h | 1 + src/rgw/rgw_rest_s3.cc | 1 + src/rgw/rgw_rest_sts.cc | 42 ++++++++++++++++++++++++++++++++++++++++- src/rgw/rgw_rest_sts.h | 9 +++++++++ 7 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 0d6c749af05..a2f792ac008 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -1032,11 +1032,20 @@ auto rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp) con void rgw::auth::RemoteApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const { + string key = "aws:userid"; + string value = info.acct_user.id; + s->env.emplace(key, value); + // copy our identity policies into req_state s->iam_identity_policies.insert(s->iam_identity_policies.end(), policies.begin(), policies.end()); } +std::optional rgw::auth::RemoteApplier::get_caller_identity() const +{ + return rgw::ARN(owner_acct_user.id, "user", owner_acct_user.tenant, true); +} + /* rgw::auth::LocalApplier */ /* static declaration */ const std::string rgw::auth::LocalApplier::NO_SUBUSER; @@ -1144,6 +1153,10 @@ auto rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp) cons void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const { + string key = "aws:userid"; + string value = user_info.type == TYPE_ROOT ? user_info.account_id : user_info.user_id.id; + s->env.emplace(key, value); + // copy our identity policies into req_state s->iam_identity_policies.insert(s->iam_identity_policies.end(), policies.begin(), policies.end()); diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index f4e469fb262..0630f36d929 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -687,9 +687,7 @@ public: void write_ops_log_entry(rgw_log_entry& entry) const override; uint32_t get_identity_type() const override { return info.acct_type; } - std::optional get_caller_identity() const override { - return std::nullopt; - } + std::optional get_caller_identity() const override; std::string get_acct_name() const override { return info.acct_name; } std::string get_subuser() const override { return {}; } @@ -858,7 +856,7 @@ public: rgw::Partition partition = rgw::Partition::aws; rgw::Service service = rgw::Service::sts; std::string acct = role.account->id.empty() ? role.tenant : role.account->id; - std::string resource = "assumed-role/" + role.name + "/" + token_attrs.role_session_name; + std::string resource = "assumed-role" + role.path + role.name + "/" + token_attrs.role_session_name; return rgw::ARN(partition, service, "", acct, resource); } diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index 8e243d89ce6..36332f7f35f 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -472,6 +472,7 @@ static inline int parse_v4_auth_header(const req_info& info, /* in bool is_non_s3_op(RGWOpType op_type) { switch (op_type) { + case RGW_STS_GET_CALLER_IDENTITY: case RGW_STS_GET_SESSION_TOKEN: case RGW_STS_ASSUME_ROLE: case RGW_STS_ASSUME_ROLE_WEB_IDENTITY: diff --git a/src/rgw/rgw_op_type.h b/src/rgw/rgw_op_type.h index 01f5a432e92..ca8a71748ec 100644 --- a/src/rgw/rgw_op_type.h +++ b/src/rgw/rgw_op_type.h @@ -132,6 +132,7 @@ enum RGWOpType { RGW_OP_SYNC_MDLOG_NOTIFY, RGW_OP_PERIOD_POST, /* sts specific*/ + RGW_STS_GET_CALLER_IDENTITY, RGW_STS_ASSUME_ROLE, RGW_STS_GET_SESSION_TOKEN, RGW_STS_ASSUME_ROLE_WEB_IDENTITY, diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index ac1b1e3f54f..5d37827143b 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -6467,6 +6467,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s, case RGW_OP_PUT_BUCKET_OBJ_LOCK: case RGW_OP_PUT_OBJ_RETENTION: case RGW_OP_PUT_OBJ_LEGAL_HOLD: + case RGW_STS_GET_CALLER_IDENTITY: case RGW_STS_GET_SESSION_TOKEN: case RGW_STS_ASSUME_ROLE: case RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK: diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index 0b57f2ea858..f893e727a49 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -1055,6 +1055,45 @@ void RGWSTSAssumeRole::execute(optional_yield y) } } +int RGWSTSGetCallerIdentity::verify_permission(optional_yield y) +{ + // https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html + // Permissions are not required because the same information is returned when access is denied. + + return 0; +} + +void RGWSTSGetCallerIdentity::execute(optional_yield y) +{ + std::string account; + std::string userid; + std::string arn; + + if (const auto& acc = s->auth.identity->get_account(); acc) { + account = acc->id; + } + + if(account.empty()) { + account = s->user->get_tenant(); + } + if (auto it = s->env.find("aws:userid"); it != s->env.end()) { + userid = it->second; + } + + auto a = s->auth.identity->get_caller_identity(); + if(a) { + arn = a->to_string(); + } + + s->formatter->open_object_section_in_ns("GetCallerIdentityResponse", RGW_REST_STS_XMLNS); + s->formatter->open_object_section("GetCallerIdentityResult"); + encode_json("Arn", arn, s->formatter); + encode_json("UserId", userid, s->formatter); + encode_json("Account", account, s->formatter); + s->formatter->close_section(); + s->formatter->close_section(); +} + int RGW_Auth_STS::authorize(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, const rgw::auth::StrategyRegistry& auth_registry, @@ -1067,7 +1106,8 @@ using op_generator = RGWOp*(*)(); static const std::unordered_map op_generators = { {"AssumeRole", []() -> RGWOp* {return new RGWSTSAssumeRole;}}, {"GetSessionToken", []() -> RGWOp* {return new RGWSTSGetSessionToken;}}, - {"AssumeRoleWithWebIdentity", []() -> RGWOp* {return new RGWSTSAssumeRoleWithWebIdentity;}} + {"AssumeRoleWithWebIdentity", []() -> RGWOp* {return new RGWSTSAssumeRoleWithWebIdentity;}}, + {"GetCallerIdentity", []() -> RGWOp* {return new RGWSTSGetCallerIdentity;}} }; bool RGWHandler_REST_STS::action_exists(const req_state* s) diff --git a/src/rgw/rgw_rest_sts.h b/src/rgw/rgw_rest_sts.h index befa93169b4..8a02d561788 100644 --- a/src/rgw/rgw_rest_sts.h +++ b/src/rgw/rgw_rest_sts.h @@ -203,6 +203,15 @@ public: RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; } }; +class RGWSTSGetCallerIdentity : public RGWREST_STS { +public: + RGWSTSGetCallerIdentity() = default; + void execute(optional_yield y) override; + int verify_permission(optional_yield y) override; + const char* name() const override { return "get_caller_identity"; } + RGWOpType get_type() override { return RGW_STS_GET_CALLER_IDENTITY; } +}; + class RGW_Auth_STS { public: static int authorize(const DoutPrefixProvider *dpp, -- 2.39.5