]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/sts: by-passing authentication using temp creds
authorPritha Srivastava <prsrivas@redhat.com>
Thu, 28 Mar 2024 11:16:20 +0000 (16:46 +0530)
committerCasey Bodley <cbodley@redhat.com>
Tue, 29 Apr 2025 14:21:24 +0000 (10:21 -0400)
in case the request is forwarded from secondary in
a multi-site setup. authenticating with the system
user creds of which are used to sign the request.
Permissions are still derived from the role.

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
(cherry picked from commit 63bc73802ddb0ef74d66d468293e489e4d5fa58f)

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

index f04ef6c38d9a27c175dfd27b33d7347dcb345662..c255e1ac3652b50eef42b0a87d09018cf1782f53 100644 (file)
@@ -1297,6 +1297,9 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp,
   for (auto& it : token_attrs.token_claims) {
     s->token_claims.emplace_back(it);
   }
+  if (is_system_request) {
+    s->system_request = true;
+  }
 }
 
 rgw::auth::Engine::result_t
index 6632a38e6a61bd15c9754b480f3f25816d4dab5f..eeb00615a2b16f159cb5ecba1b0c3f81d2996b6d 100644 (file)
@@ -793,17 +793,20 @@ protected:
   rgw::sal::Driver* driver;
   Role role;
   TokenAttrs token_attrs;
+  bool is_system_request;
 
 public:
 
   RoleApplier(CephContext* const cct,
                rgw::sal::Driver* driver,
                const Role& role,
-               const TokenAttrs& token_attrs)
+               const TokenAttrs& token_attrs,
+               bool is_system_request)
     : cct(cct),
       driver(driver),
       role(role),
-      token_attrs(token_attrs) {}
+      token_attrs(token_attrs),
+      is_system_request(is_system_request) {}
 
   ACLOwner get_aclowner() const override;
   uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
@@ -835,11 +838,12 @@ public:
 
   struct Factory {
     virtual ~Factory() {}
-    virtual aplptr_t create_apl_role(CephContext* cct,
-                                     const req_state* s,
-                                     Role role,
-                                     TokenAttrs token_attrs) const = 0;
-  };
+    virtual aplptr_t create_apl_role( CephContext* cct,
+                                      const req_state* s,
+                                      Role role,
+                                      TokenAttrs token_attrs,
+                                      bool is_system_request) const = 0;
+    };
 };
 
 class ServiceIdentity : public Identity {
index f9cb204fd2875621e32db030f8254427ff5adc89..b6fc6ef1e083771c911a02e188c267abeb5eed4c 100644 (file)
@@ -70,9 +70,10 @@ class STSAuthStrategy : public rgw::auth::Strategy,
   aplptr_t create_apl_role(CephContext* const cct,
                             const req_state* const s,
                             RoleApplier::Role role,
-                            RoleApplier::TokenAttrs token_attrs) const override {
+                            RoleApplier::TokenAttrs token_attrs,
+                            bool is_system_request) const override {
     auto apl = rgw::auth::add_sysreq(cct, driver, s,
-      rgw::auth::RoleApplier(cct, driver, std::move(role), std::move(token_attrs)));
+      rgw::auth::RoleApplier(cct, driver, std::move(role), std::move(token_attrs), is_system_request));
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
 
index 1b49b8e995c4e5a6d8a9bdefeb66eae7c2196d8f..9f12e7903373263a5fd0fa9a7aadd297adaeaf77 100644 (file)
@@ -6960,6 +6960,7 @@ rgw::auth::s3::STSEngine::authenticate(
   const req_state* const s,
   optional_yield y) const
 {
+  bool is_system_request{false};
   if (! s->info.args.exists("x-amz-security-token") &&
       ! s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN") &&
       s->auth.s3_postobj_creds.x_amz_security_token.empty()) {
@@ -6971,10 +6972,36 @@ rgw::auth::s3::STSEngine::authenticate(
     return result_t::reject(ret);
   }
   //Authentication
+  std::string secret_access_key;
   //Check if access key is not the same passed in by client
   if (token.access_key_id != _access_key_id) {
-    ldpp_dout(dpp, 0) << "Invalid access key" << dendl;
-    return result_t::reject(-EPERM);
+    /* In case the request is forwarded from secondary in case of multi-site,
+      we by-pass authentication using the session token credentials,
+      instead we use the system user's credentials that was used to sign
+      this request */
+    std::unique_ptr<rgw::sal::User> user;
+    const std::string access_key_id(_access_key_id);
+    if (driver->get_user_by_access_key(dpp, access_key_id, y, &user) < 0) {
+        ldpp_dout(dpp, 5) << "error reading user info, uid=" << access_key_id
+                << " can't authenticate" << dendl;
+        return result_t::reject(-ERR_INVALID_ACCESS_KEY);
+    }
+    // only allow system users as this could be a forwarded request from secondary
+    if (user->get_info().system && driver->is_meta_master()) {
+      const auto iter = user->get_info().access_keys.find(access_key_id);
+      if (iter == std::end(user->get_info().access_keys)) {
+        ldpp_dout(dpp, 0) << "ERROR: access key not encoded in user info" << dendl;
+        return result_t::reject(-EPERM);
+      }
+      const RGWAccessKey& k = iter->second;
+      secret_access_key = k.key;
+      is_system_request = true;
+    } else {
+      ldpp_dout(dpp, 0) << "Invalid access key" << dendl;
+      return result_t::reject(-EPERM);
+    }
+  } else {
+    secret_access_key = token.secret_access_key;
   }
   //Check if the token has expired
   if (! token.expiration.empty()) {
@@ -6995,7 +7022,7 @@ rgw::auth::s3::STSEngine::authenticate(
   }
   //Check for signature mismatch
   const VersionAbstractor::server_signature_t server_signature = \
-    signature_factory(cct, token.secret_access_key, string_to_sign);
+    signature_factory(cct, secret_access_key, string_to_sign);
   auto compare = signature.compare(server_signature);
 
   ldpp_dout(dpp, 15) << "string_to_sign="
@@ -7059,7 +7086,7 @@ rgw::auth::s3::STSEngine::authenticate(
     t_attrs.token_issued_at = std::move(token.issued_at);
     t_attrs.principal_tags = std::move(token.principal_tags);
     auto apl = role_apl_factory->create_apl_role(cct, s, std::move(r),
-                                                 std::move(t_attrs));
+                                                 std::move(t_attrs), is_system_request);
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   } else { // This is for all local users of type TYPE_RGW|ROOT|NONE
     if (token.user.empty()) {