]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/sts: GetCallerIndentity API
authorRaja Sharma <raja@ibm.com>
Thu, 22 May 2025 11:08:00 +0000 (16:38 +0530)
committerThomas Serlin <tserlin@redhat.com>
Mon, 22 Sep 2025 19:18:18 +0000 (15:18 -0400)
Tracker: https://tracker.ceph.com/issues/72157
Resolves: rhbz#2381577

Signed-off-by: Raja Sharma <raja@ibm.com>
(cherry picked from commit 694bffd999442016f39eba9616ade83ce2dedefa)

src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_op_type.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_sts.h

index 2bb4d8a89fa40464d37e6090f54caec0646dcad0..2f6bc5d2763aa678f17bdac878d0af7691373b00 100644 (file)
@@ -1030,11 +1030,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::ARN> 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;
@@ -1142,6 +1151,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());
index a795da50f8921f1d83d359c08c9164441bb722dd..1951040a323d38626a4bd829da23ec6b03fb9540 100644 (file)
@@ -683,9 +683,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<rgw::ARN> get_caller_identity() const override {
-    return std::nullopt;
-  }
+  std::optional<rgw::ARN> get_caller_identity() const override;
 
   std::string get_acct_name() const override { return info.acct_name; }
   std::string get_subuser() const override { return {}; }
@@ -854,7 +852,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);
   }
index 314775f2e92a5133804af82b3e1cf024da7c1609..9d7f6ec1f485a76e08d32c9b324298f51fd1b231 100644 (file)
@@ -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:
index 321095ad0f05f3cbc492f6f3566835f2fd4888cd..9721da13abbf1adeee2162f2e92e971b988664f4 100644 (file)
@@ -133,6 +133,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,
index 7e413ed5b58a0330f315bee7d05452887c629a2a..18cdfad4c88ef7a86fd9d94d6fdf7e85d05c1bc7 100644 (file)
@@ -6462,6 +6462,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:
index 862c4b81a2a11351b12ba2776b2e9df15ab3c8ae..99c633c5a7e8bf1d2ee3de1dd66eeef7c3cda154 100644 (file)
@@ -1064,6 +1064,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,
@@ -1076,7 +1115,8 @@ using op_generator = RGWOp*(*)();
 static const std::unordered_map<std::string_view, op_generator> 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)
index f00e66493c5b715eb74864806ef34a52edac327b..0558ecb573d0589823ca8d5bdc291ddb2a60faf9 100644 (file)
@@ -205,6 +205,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,