From 31115617f801f0c4c1477b8f63a0d151b3a54217 Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Thu, 28 Mar 2024 16:46:20 +0530 Subject: [PATCH] rgw/sts: by-passing authentication using temp creds 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 (cherry picked from commit 63bc73802ddb0ef74d66d468293e489e4d5fa58f) --- src/rgw/rgw_auth.cc | 3 +++ src/rgw/rgw_auth.h | 18 +++++++++++------- src/rgw/rgw_auth_s3.h | 5 +++-- src/rgw/rgw_rest_s3.cc | 35 +++++++++++++++++++++++++++++++---- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index f04ef6c38d9..c255e1ac365 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -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 diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 6632a38e6a6..eeb00615a2b 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -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 { diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index f9cb204fd28..b6fc6ef1e08 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -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))); } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 1b49b8e995c..9f12e790337 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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 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()) { -- 2.39.5