From 7668bbfe0321a9718b4c114f2aa7e2f600beec1c Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Mon, 4 Mar 2024 16:10:17 -0500 Subject: [PATCH] rgw/auth: pass user policies into identities loading user policies in rgw_build_bucket_policies() doesn't work for PostObj requests because we haven't authenticated yet at that point instead, auth engines load/parse policies when they load the user info. policies are passed into the auth identities and applied to req_state via modify_request_state() similar to how RoleApplier handles role policy this also moves the load_iam_identity_policies() into rgw_auth.cc for use by transform_old_authinfo() Signed-off-by: Casey Bodley (cherry picked from commit 582970a69399d989370bb1ced6e42de724509622) --- src/rgw/driver/rados/rgw_data_sync.cc | 18 +-- src/rgw/rgw_auth.cc | 195 ++++++++++++++++++++++---- src/rgw/rgw_auth.h | 31 ++-- src/rgw/rgw_auth_s3.h | 10 +- src/rgw/rgw_lib.cc | 20 ++- src/rgw/rgw_op.cc | 94 ------------- src/rgw/rgw_op.h | 8 -- src/rgw/rgw_process.cc | 2 +- src/rgw/rgw_rest.cc | 14 -- src/rgw/rgw_rest_s3.cc | 50 +++---- src/rgw/rgw_rest_swift.cc | 16 ++- src/rgw/rgw_rest_swift.h | 3 +- src/rgw/rgw_swift_auth.cc | 50 +++---- src/rgw/rgw_swift_auth.h | 9 +- 14 files changed, 273 insertions(+), 247 deletions(-) diff --git a/src/rgw/driver/rados/rgw_data_sync.cc b/src/rgw/driver/rados/rgw_data_sync.cc index 77e676c81a0..dbea56d4de7 100644 --- a/src/rgw/driver/rados/rgw_data_sync.cc +++ b/src/rgw/driver/rados/rgw_data_sync.cc @@ -2614,7 +2614,6 @@ class RGWUserPermHandler { rgw_user uid; struct _info { - RGWUserInfo user_info; rgw::IAM::Environment env; std::unique_ptr identity; RGWAccessControlPolicy user_acl; @@ -2638,28 +2637,23 @@ class RGWUserPermHandler { uid(handler->uid), info(handler->info) {} int operate() override { - auto user_ctl = sync_env->driver->getRados()->ctl.user; - - ret = user_ctl->get_info_by_uid(sync_env->dpp, uid, &info->user_info, null_yield); + auto user = sync_env->driver->get_user(uid); + ret = user->load_user(sync_env->dpp, null_yield); if (ret < 0) { return ret; } auto result = rgw::auth::transform_old_authinfo( - sync_env->dpp, null_yield, sync_env->driver, info->user_info); + sync_env->dpp, null_yield, sync_env->driver, user.get()); if (!result) { return result.error(); } info->identity = std::move(result).value(); - map uattrs; - - ret = user_ctl->get_attrs_by_uid(sync_env->dpp, uid, &uattrs, null_yield); - if (ret == 0) { - ret = RGWUserPermHandler::policy_from_attrs(sync_env->cct, uattrs, &info->user_acl); - } + ret = RGWUserPermHandler::policy_from_attrs( + sync_env->cct, user->get_attrs(), &info->user_acl); if (ret == -ENOENT) { - info->user_acl.create_default(uid, info->user_info.display_name); + info->user_acl.create_default(uid, user->get_display_name()); } return 0; diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index b01451f047e..6fe40836036 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -82,14 +82,119 @@ static bool match_account_or_tenant(const std::optional& account || (tenant == expected); } -auto transform_old_authinfo(const RGWUserInfo& user, - std::optional account) +static void load_inline_policy(CephContext* cct, const bufferlist& bl, + const string* tenant, + std::vector& policies) +{ + map policy_map; + using ceph::decode; + decode(policy_map, bl); + for (const auto& [name, policy] : policy_map) { + policies.emplace_back(cct, tenant, policy, false); + } +} + +static void load_managed_policy(CephContext* cct, const bufferlist& bl, + std::vector& policies) +{ + rgw::IAM::ManagedPolicies policy_set; + using ceph::decode; + decode(policy_set, bl); + for (const auto& arn : policy_set.arns) { + if (auto p = rgw::IAM::get_managed_policy(cct, arn); p) { + policies.push_back(std::move(*p)); + } + } +} + +static int load_group_policies(const DoutPrefixProvider* dpp, + optional_yield y, + rgw::sal::Driver* driver, + const std::string* tenant, + std::string_view group_id, + std::vector& policies) +{ + RGWGroupInfo info; + rgw::sal::Attrs attrs; + RGWObjVersionTracker objv; + int r = driver->load_group_by_id(dpp, y, group_id, info, attrs, objv); + if (r < 0) { + return r; + } + + CephContext* cct = dpp->get_cct(); + if (auto i = attrs.find(RGW_ATTR_IAM_POLICY); i != attrs.end()) { + load_inline_policy(cct, i->second, tenant, policies); + } + if (auto i = attrs.find(RGW_ATTR_MANAGED_POLICY); i != attrs.end()) { + load_managed_policy(cct, i->second, policies); + } + return 0; +} + +int load_account_and_policies(const DoutPrefixProvider* dpp, + optional_yield y, + sal::Driver* driver, + const RGWUserInfo& info, + const sal::Attrs& attrs, + std::optional& account, + std::vector& policies) +{ + if (!info.account_id.empty()) { + account.emplace(); + rgw::sal::Attrs attrs; // ignored + RGWObjVersionTracker objv; // ignored + int r = driver->load_account_by_id(dpp, y, info.account_id, + *account, attrs, objv); + if (r < 0) { + ldpp_dout(dpp, 1) << "ERROR: failed to load account " + << info.account_id << " for user " << info.user_id + << ": " << cpp_strerror(r) << dendl; + return r; + } + } + + // non-account identity policy is restricted to the current tenant + const std::string* policy_tenant = info.account_id.empty() + ? &info.user_id.tenant : nullptr; + + // load user policies from user attrs + CephContext* cct = dpp->get_cct(); + if (auto bl = attrs.find(RGW_ATTR_USER_POLICY); bl != attrs.end()) { + load_inline_policy(cct, bl->second, policy_tenant, policies); + } + if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) { + load_managed_policy(cct, bl->second, policies); + } + + // load each group and its policies + for (const auto& id : info.group_ids) { + int r = load_group_policies(dpp, y, driver, policy_tenant, id, policies); + if (r == -ENOENT) { + // in multisite, metadata sync may race to replicate the user before its + // group. ignore ENOENT here so we don't reject all the user's requests + // in the meantime + ldpp_dout(dpp, 1) << "WARNING: skipping nonexistent group id " << id + << " for user " << info.user_id << ": " << cpp_strerror(r) << dendl; + } else if (r < 0) { + ldpp_dout(dpp, 1) << "ERROR: failed to load group id " << id + << " for user " << info.user_id << ": " << cpp_strerror(r) << dendl; + return r; + } + } + + return 0; +} + +static auto transform_old_authinfo(const RGWUserInfo& user, + std::optional account, + std::vector policies) -> std::unique_ptr { /* This class is not intended for public use. Should be removed altogether * with this function after moving all our APIs to the new authentication * infrastructure. */ - class DummyIdentityApplier : public rgw::auth::Identity { + class DummyIdentityApplier : public rgw::auth::IdentityApplier { /* For this particular case it's OK to use rgw_user structure to convey * the identity info as this was the policy for doing that before the * new auth. */ @@ -99,15 +204,18 @@ auto transform_old_authinfo(const RGWUserInfo& user, const bool is_admin; const uint32_t type; const std::optional account; + const std::vector policies; public: DummyIdentityApplier(const RGWUserInfo& user, - std::optional account) + std::optional account, + std::vector policies) : id(user.user_id), display_name(user.display_name), path(user.path), is_admin(user.admin), type(user.type), - account(std::move(account)) + account(std::move(account)), + policies(std::move(policies)) {} ACLOwner get_aclowner() const { @@ -176,33 +284,42 @@ auto transform_old_authinfo(const RGWUserInfo& user, out << "RGWDummyIdentityApplier(auth_id=" << id << ", is_admin=" << is_admin << ")"; } + + void load_acct_info(const DoutPrefixProvider* dpp, + RGWUserInfo& user_info) const override { + // noop, this user info was passed in on construction + } + + void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const { + // copy our identity policies into req_state + s->iam_identity_policies.insert(s->iam_identity_policies.end(), + policies.begin(), policies.end()); + } }; - return std::make_unique(user, std::move(account)); + return std::make_unique( + user, std::move(account), std::move(policies)); } auto transform_old_authinfo(const DoutPrefixProvider* dpp, optional_yield y, - rgw::sal::Driver* driver, - const RGWUserInfo& user) + sal::Driver* driver, + sal::User* user) -> tl::expected, int> { + const RGWUserInfo& info = user->get_info(); + const sal::Attrs& attrs = user->get_attrs(); + std::optional account; - if (!user.account_id.empty()) { - account.emplace(); - rgw::sal::Attrs attrs; // ignored - RGWObjVersionTracker objv; // ignored - int r = driver->load_account_by_id(dpp, y, user.account_id, - *account, attrs, objv); - if (r < 0) { - ldpp_dout(dpp, 1) << "ERROR: failed to load account " - << user.account_id << " for user " << user.user_id - << ": " << cpp_strerror(r) << dendl; - return tl::unexpected(r); - } + std::vector policies; + + int r = load_account_and_policies(dpp, y, driver, info, attrs, + account, policies); + if (r < 0) { + return tl::unexpected(r); } - return transform_old_authinfo(user, std::move(account)); + return transform_old_authinfo(info, std::move(account), std::move(policies)); } } /* namespace auth */ @@ -626,9 +743,13 @@ const std::string rgw::auth::RemoteApplier::AuthInfo::NO_ACCESS_KEY; ACLOwner rgw::auth::RemoteApplier::get_aclowner() const { ACLOwner owner; - // TODO: handle account ownership - owner.id = info.acct_user; - owner.display_name = info.acct_name; + if (account) { + owner.id = account->id; + owner.display_name = account->name; + } else { + owner.id = info.acct_user; + owner.display_name = info.acct_name; + } return owner; } @@ -822,7 +943,10 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW if (user->load_user(dpp, null_yield) >= 0) { /* Succeeded. */ - user_info = user->get_info(); + (void) load_account_and_policies(dpp, null_yield, driver, user->get_info(), + user->get_attrs(), account, policies); + + user_info = std::move(user->get_info()); return; } } @@ -833,7 +957,10 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW ; /* suppress lookup for id used by "other" protocol */ else if (user->load_user(dpp, null_yield) >= 0) { /* Succeeded. */ - user_info = user->get_info(); + (void) load_account_and_policies(dpp, null_yield, driver, user->get_info(), + user->get_attrs(), account, policies); + + user_info = std::move(user->get_info()); return; } @@ -843,6 +970,13 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW /* Succeeded if we are here (create_account() hasn't throwed). */ } +void rgw::auth::RemoteApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const +{ + // copy our identity policies into req_state + s->iam_identity_policies.insert(s->iam_identity_policies.end(), + policies.begin(), policies.end()); +} + /* rgw::auth::LocalApplier */ /* static declaration */ const std::string rgw::auth::LocalApplier::NO_SUBUSER; @@ -940,6 +1074,13 @@ void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWU user_info = this->user_info; } +void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const +{ + // copy our identity policies into req_state + s->iam_identity_policies.insert(s->iam_identity_policies.end(), + policies.begin(), policies.end()); +} + void rgw::auth::LocalApplier::write_ops_log_entry(rgw_log_entry& entry) const { entry.access_key_id = access_key_id; @@ -1086,7 +1227,7 @@ rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const re rgw_get_anon_user(user_info); auto apl = \ - apl_factory->create_apl_local(cct, s, user_info, std::nullopt, + apl_factory->create_apl_local(cct, s, user_info, std::nullopt, {}, rgw::auth::LocalApplier::NO_SUBUSER, std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY); return result_t::grant(std::move(apl)); diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 0e7eabe0c9f..90e60374550 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -98,18 +98,23 @@ inline std::ostream& operator<<(std::ostream& out, } -// Return an identity for the given user and account. -auto transform_old_authinfo(const RGWUserInfo& user, - std::optional account) - -> std::unique_ptr; - -// Return an identity for the given user, loading its account if necessary. +// Return an identity for the given user after loading its account and policies. auto transform_old_authinfo(const DoutPrefixProvider* dpp, optional_yield y, - rgw::sal::Driver* driver, - const RGWUserInfo& user) + sal::Driver* driver, + sal::User* user) -> tl::expected, int>; +// Load the user account and all user/group policies. May throw +// PolicyParseException on malformed policy. +int load_account_and_policies(const DoutPrefixProvider* dpp, + optional_yield y, + sal::Driver* driver, + const RGWUserInfo& info, + const sal::Attrs& attrs, + std::optional& account, + std::vector& policies); + /* Interface for classes applying changes to request state/RADOS store * imposed by a particular rgw::auth::Engine. @@ -609,6 +614,10 @@ protected: const rgw::auth::ImplicitTenants& implicit_tenant_context; const rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit; + // account and policies are loaded by load_acct_info() + mutable std::optional account; + mutable std::vector policies; + virtual void create_account(const DoutPrefixProvider* dpp, const rgw_user& acct_user, bool implicit_tenant, @@ -638,6 +647,7 @@ public: uint32_t get_perm_mask() const override { return info.perm_mask; } void to_str(std::ostream& out) const override; void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */ + void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override; void write_ops_log_entry(rgw_log_entry& entry) const override; uint32_t get_identity_type() const override { return info.acct_type; } std::string get_acct_name() const override { return info.acct_name; } @@ -669,6 +679,7 @@ class LocalApplier : public IdentityApplier { protected: const RGWUserInfo user_info; const std::optional account; + const std::vector policies; const std::string subuser; uint32_t perm_mask; const std::string access_key_id; @@ -683,11 +694,13 @@ public: LocalApplier(CephContext* const cct, const RGWUserInfo& user_info, std::optional account, + std::vector policies, std::string subuser, const std::optional& perm_mask, const std::string access_key_id) : user_info(user_info), account(std::move(account)), + policies(std::move(policies)), subuser(std::move(subuser)), perm_mask(perm_mask.value_or(RGW_PERM_INVALID)), access_key_id(access_key_id) { @@ -707,6 +720,7 @@ public: } void to_str(std::ostream& out) const override; void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */ + void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override; uint32_t get_identity_type() const override { return user_info.type; } std::string get_acct_name() const override { return {}; } std::string get_subuser() const override { return subuser; } @@ -722,6 +736,7 @@ public: const req_state* s, const RGWUserInfo& user_info, std::optional account, + std::vector policies, const std::string& subuser, const std::optional& perm_mask, const std::string& access_key_id) const = 0; diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index c7cde7c0496..e1fe5163f02 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -57,12 +57,13 @@ class STSAuthStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, std::optional account, + std::vector policies, const std::string& subuser, const std::optional& perm_mask, const std::string& access_key_id) const override { auto apl = rgw::auth::add_sysreq(cct, driver, s, - rgw::auth::LocalApplier(cct, user_info, std::move(account), - subuser, perm_mask, access_key_id)); + LocalApplier(cct, user_info, std::move(account), std::move(policies), + subuser, perm_mask, access_key_id)); return aplptr_t(new decltype(apl)(std::move(apl))); } @@ -177,12 +178,13 @@ class AWSAuthStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, std::optional account, + std::vector policies, const std::string& subuser, const std::optional& perm_mask, const std::string& access_key_id) const override { auto apl = rgw::auth::add_sysreq(cct, driver, s, - rgw::auth::LocalApplier(cct, user_info, std::move(account), - subuser, perm_mask, access_key_id)); + LocalApplier(cct, user_info, std::move(account), std::move(policies), + subuser, perm_mask, access_key_id)); /* TODO(rzarzynski): replace with static_ptr. */ return aplptr_t(new decltype(apl)(std::move(apl))); } diff --git a/src/rgw/rgw_lib.cc b/src/rgw/rgw_lib.cc index 85763e1a267..665a03b6279 100644 --- a/src/rgw/rgw_lib.cc +++ b/src/rgw/rgw_lib.cc @@ -247,8 +247,14 @@ namespace rgw { /* FIXME: remove this after switching all handlers to the new * authentication infrastructure. */ if (! s->auth.identity) { - s->auth.identity = rgw::auth::transform_old_authinfo( - io->get_user(), std::nullopt); + auto result = rgw::auth::transform_old_authinfo( + op, null_yield, env.driver, s->user.get()); + if (!result) { + ret = result.error(); + abort_req(s, op, ret); + goto done; + } + s->auth.identity = std::move(result).value(); } ldpp_dout(s, 2) << "reading op permissions" << dendl; @@ -378,8 +384,14 @@ namespace rgw { /* FIXME: remove this after switching all handlers to the new authentication * infrastructure. */ if (! s->auth.identity) { - s->auth.identity = rgw::auth::transform_old_authinfo( - io_ctx.get_user(), std::nullopt); + auto result = rgw::auth::transform_old_authinfo( + op, null_yield, env.driver, s->user.get()); + if (!result) { + ret = result.error(); + abort_req(s, op, ret); + goto done; + } + s->auth.identity = std::move(result).value(); } ldpp_dout(s, 2) << "reading op permissions" << dendl; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 15bdf13c2f8..f30077ea484 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -355,77 +355,6 @@ get_public_access_conf_from_attr(const map& attrs) return boost::none; } -static void load_inline_policy(CephContext* cct, const bufferlist& bl, - const string* tenant, - std::vector& policies) -{ - map policy_map; - decode(policy_map, bl); - for (const auto& [name, policy] : policy_map) { - policies.emplace_back(cct, tenant, policy, false); - } -} - -static void load_managed_policy(CephContext* cct, const bufferlist& bl, - std::vector& policies) -{ - rgw::IAM::ManagedPolicies policy_set; - decode(policy_set, bl); - for (const auto& arn : policy_set.arns) { - if (auto p = rgw::IAM::get_managed_policy(cct, arn); p) { - policies.push_back(std::move(*p)); - } - } -} - -static void load_iam_group_policies(const DoutPrefixProvider* dpp, - optional_yield y, - rgw::sal::Driver* driver, - const std::string* tenant, - std::string_view group_id, - std::vector& policies) -{ - RGWGroupInfo info; - rgw::sal::Attrs attrs; - RGWObjVersionTracker objv; - int r = driver->load_group_by_id(dpp, y, group_id, info, attrs, objv); - if (r >= 0) { - CephContext* cct = dpp->get_cct(); - if (auto bl = attrs.find(RGW_ATTR_IAM_POLICY); bl != attrs.end()) { - load_inline_policy(cct, bl->second, tenant, policies); - } - if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) { - load_managed_policy(cct, bl->second, policies); - } - } -} - -void load_iam_identity_policies(const DoutPrefixProvider* dpp, - optional_yield y, - rgw::sal::Driver* driver, - const RGWUserInfo& info, - const rgw::sal::Attrs& attrs, - std::vector& policies) -{ - // non-account identity policy is restricted to the current tenant - const std::string* policy_tenant = info.account_id.empty() - ? &info.user_id.tenant : nullptr; - - // load user policies from user attrs - CephContext* cct = dpp->get_cct(); - if (auto bl = attrs.find(RGW_ATTR_USER_POLICY); bl != attrs.end()) { - load_inline_policy(cct, bl->second, policy_tenant, policies); - } - if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) { - load_managed_policy(cct, bl->second, policies); - } - - // load each group and its policies - for (const auto& id : info.group_ids) { - load_iam_group_policies(dpp, y, driver, policy_tenant, id, policies); - } -} - static int read_bucket_policy(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, req_state *s, @@ -683,29 +612,6 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d return ret; } } - // We don't need user policies in case of STS token returned by AssumeRole, - // hence the check for user type - if (! s->user->get_id().empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) { - try { - ret = s->user->read_attrs(dpp, y); - if (ret == 0) { - // load all user and group policies - load_iam_identity_policies(dpp, y, driver, - s->user->get_info(), - s->user->get_attrs(), - s->iam_identity_policies); - } else { - if (ret == -ENOENT) - ret = 0; - else ret = -EACCES; - } - } catch (const std::exception& e) { - ldpp_dout(dpp, -1) << "Error reading IAM User Policy: " << e.what() << dendl; - if (!s->system_request) { - ret = -EACCES; - } - } - } try { s->iam_policy = get_iam_policy_from_attr(s->cct, s->bucket_attrs); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 016a6f38dd3..9302017fc3e 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -2071,14 +2071,6 @@ extern int rgw_build_object_policies(const DoutPrefixProvider *dpp, rgw::sal::Dr extern void rgw_build_iam_environment(rgw::sal::Driver* driver, req_state* s); -// load all user/group policies -void load_iam_identity_policies(const DoutPrefixProvider* dpp, - optional_yield y, - rgw::sal::Driver* driver, - const RGWUserInfo& info, - const rgw::sal::Attrs& attrs, - std::vector& policies); - inline int get_system_versioning_params(req_state *s, uint64_t *olh_epoch, std::string *version_id) diff --git a/src/rgw/rgw_process.cc b/src/rgw/rgw_process.cc index 7a7f70fa30d..10e544b577d 100644 --- a/src/rgw/rgw_process.cc +++ b/src/rgw/rgw_process.cc @@ -367,7 +367,7 @@ int process_request(const RGWProcessEnv& penv, * infrastructure. */ if (nullptr == s->auth.identity) { auto result = rgw::auth::transform_old_authinfo( - op, yield, driver, s->user->get_info()); + op, yield, driver, s->user.get()); if (!result) { abort_early(s, op, result.error(), handler, yield); goto done; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index b44baf35dfe..020309038eb 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -1874,20 +1874,6 @@ static http_op op_from_method(const char *method) int RGWHandler_REST::init_permissions(RGWOp* op, optional_yield y) { if (op->get_type() == RGW_OP_CREATE_BUCKET) { - // We don't need user policies in case of STS token returned by AssumeRole, hence the check for user type - if (! s->user->get_id().empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) { - try { - if (auto ret = s->user->read_attrs(s, y); ! ret) { - // load all user and group policies - load_iam_identity_policies(op, y, driver, - s->user->get_info(), - s->user->get_attrs(), - s->iam_identity_policies); - } - } catch (const std::exception& e) { - ldpp_dout(op, -1) << "Error reading IAM User Policy: " << e.what() << dendl; - } - } rgw_build_iam_environment(driver, s); return 0; } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 391953219ae..8a8ef5a7c44 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -6281,18 +6281,11 @@ rgw::auth::s3::LocalEngine::authenticate( }*/ std::optional account; - if (!user->get_info().account_id.empty()) { - account.emplace(); - rgw::sal::Attrs attrs; // ignored - RGWObjVersionTracker objv; // ignored - int r = driver->load_account_by_id(dpp, y, user->get_info().account_id, - *account, attrs, objv); - if (r < 0) { - ldpp_dout(dpp, 1) << "ERROR: failed to load account " - << user->get_info().account_id << " for user " << *user - << ": " << cpp_strerror(r) << dendl; - return result_t::deny(-EPERM); - } + std::vector policies; + int ret = load_account_and_policies(dpp, y, driver, user->get_info(), + user->get_attrs(), account, policies); + if (ret < 0) { + return result_t::deny(-EPERM); } const auto iter = user->get_info().access_keys.find(access_key_id); @@ -6304,8 +6297,9 @@ rgw::auth::s3::LocalEngine::authenticate( /* Ignore signature for HTTP OPTIONS */ if (s->op_type == RGW_OP_OPTIONS_CORS) { - auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account), - k.subuser, std::nullopt, access_key_id); + auto apl = apl_factory->create_apl_local( + cct, s, user->get_info(), std::move(account), std::move(policies), + k.subuser, std::nullopt, access_key_id); return result_t::grant(std::move(apl), completer_factory(k.key)); } @@ -6324,8 +6318,9 @@ rgw::auth::s3::LocalEngine::authenticate( return result_t::reject(-ERR_SIGNATURE_NO_MATCH); } - auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account), - k.subuser, std::nullopt, access_key_id); + auto apl = apl_factory->create_apl_local( + cct, s, user->get_info(), std::move(account), std::move(policies), + k.subuser, std::nullopt, access_key_id); return result_t::grant(std::move(apl), completer_factory(k.key)); } @@ -6524,24 +6519,17 @@ rgw::auth::s3::STSEngine::authenticate( } std::optional account; - if (!user->get_info().account_id.empty()) { - account.emplace(); - rgw::sal::Attrs attrs; // ignored - RGWObjVersionTracker objv; // ignored - int r = driver->load_account_by_id(dpp, y, user->get_info().account_id, - *account, attrs, objv); - if (r < 0) { - ldpp_dout(dpp, 1) << "ERROR: failed to load account " - << user->get_info().account_id << " for user " << *user - << ": " << cpp_strerror(r) << dendl; - return result_t::deny(-EPERM); - } + std::vector policies; + ret = load_account_and_policies(dpp, y, driver, user->get_info(), + user->get_attrs(), account, policies); + if (ret < 0) { + return result_t::deny(-EPERM); } string subuser; - auto apl = local_apl_factory->create_apl_local(cct, s, user->get_info(), - std::move(account), subuser, - token.perm_mask, std::string(_access_key_id)); + auto apl = local_apl_factory->create_apl_local( + cct, s, user->get_info(), std::move(account), std::move(policies), + subuser, token.perm_mask, std::string(_access_key_id)); return result_t::grant(std::move(apl), completer_factory(token.secret_access_key)); } } diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 129726f0584..fa92f2ec885 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2137,9 +2137,13 @@ bool RGWFormPost::is_integral() bool r = false; try { - get_owner_info(s, s->user->get_info()); - s->auth.identity = rgw::auth::transform_old_authinfo( - s->user->get_info(), std::nullopt); + s->user = get_owner_info(s); + auto result = rgw::auth::transform_old_authinfo( + this, s->yield, driver, s->user.get()); + if (!result) { + return false; + } + s->auth.identity = std::move(result).value(); } catch (...) { ldpp_dout(this, 5) << "cannot get user_info of account's owner" << dendl; return false; @@ -2180,8 +2184,8 @@ bool RGWFormPost::is_integral() return r; } -void RGWFormPost::get_owner_info(const req_state* const s, - RGWUserInfo& owner_info) const +auto RGWFormPost::get_owner_info(const req_state* const s) const + -> std::unique_ptr { /* We cannot use req_state::bucket_name because it isn't available * now. It will be initialized in RGWHandler_REST_SWIFT::postauth_init(). */ @@ -2243,7 +2247,7 @@ void RGWFormPost::get_owner_info(const req_state* const s, throw -EPERM; } - owner_info = user->get_info(); + return user; } int RGWFormPost::get_params(optional_yield y) diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index 154a069d73f..18c80aea402 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -254,8 +254,7 @@ class RGWFormPost : public RGWPostObj_ObjStore { bool is_next_file_to_upload() override; bool is_integral(); bool is_non_expired(); - void get_owner_info(const req_state* s, - RGWUserInfo& owner_info) const; + std::unique_ptr get_owner_info(const req_state* s) const; parts_collection_t ctrl_parts; boost::optional current_data_part; diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index f191d3628af..af60a0e275d 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -514,24 +514,17 @@ ExternalTokenEngine::authenticate(const DoutPrefixProvider* dpp, } std::optional account; - if (!user->get_info().account_id.empty()) { - account.emplace(); - rgw::sal::Attrs attrs; // ignored - RGWObjVersionTracker objv; // ignored - int r = driver->load_account_by_id(dpp, y, user->get_info().account_id, - *account, attrs, objv); - if (r < 0) { - ldpp_dout(dpp, 1) << "ERROR: failed to load account " - << user->get_info().account_id << " for user " << *user - << ": " << cpp_strerror(r) << dendl; - return result_t::deny(-EPERM); - } + std::vector policies; + ret = load_account_and_policies(dpp, y, driver, user->get_info(), + user->get_attrs(), account, policies); + if (ret < 0) { + return result_t::deny(-EPERM); } - auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), - std::move(account), - extract_swift_subuser(swift_user), - std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY); + auto apl = apl_factory->create_apl_local( + cct, s, user->get_info(), std::move(account), + std::move(policies), extract_swift_subuser(swift_user), + std::nullopt, LocalApplier::NO_ACCESS_KEY); return result_t::grant(std::move(apl)); } @@ -650,18 +643,11 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp, } std::optional account; - if (!user->get_info().account_id.empty()) { - account.emplace(); - rgw::sal::Attrs attrs; // ignored - RGWObjVersionTracker objv; // ignored - int r = driver->load_account_by_id(dpp, s->yield, user->get_info().account_id, - *account, attrs, objv); - if (r < 0) { - ldpp_dout(dpp, 1) << "ERROR: failed to load account " - << user->get_info().account_id << " for user " << *user - << ": " << cpp_strerror(r) << dendl; - return result_t::deny(-EPERM); - } + std::vector policies; + ret = load_account_and_policies(dpp, s->yield, driver, user->get_info(), + user->get_attrs(), account, policies); + if (ret < 0) { + return result_t::deny(-EPERM); } ldpp_dout(dpp, 10) << "swift_user=" << swift_user << dendl; @@ -698,10 +684,10 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp, return result_t::deny(-EPERM); } - auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), - std::move(account), - extract_swift_subuser(swift_user), - std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY); + auto apl = apl_factory->create_apl_local( + cct, s, user->get_info(), std::move(account), + std::move(policies), extract_swift_subuser(swift_user), + std::nullopt, LocalApplier::NO_ACCESS_KEY); return result_t::grant(std::move(apl)); } diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index c5435556fd2..9049c54f5ca 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -24,7 +24,7 @@ class TempURLApplier : public rgw::auth::LocalApplier { public: TempURLApplier(CephContext* const cct, const RGWUserInfo& user_info) - : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER, + : LocalApplier(cct, user_info, std::nullopt, {}, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) {} @@ -156,7 +156,7 @@ class SwiftAnonymousApplier : public rgw::auth::LocalApplier { public: SwiftAnonymousApplier(CephContext* const cct, const RGWUserInfo& user_info) - : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER, + : LocalApplier(cct, user_info, std::nullopt, {}, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) { } bool is_admin_of(const rgw_owner& o) const {return false;} @@ -240,14 +240,15 @@ class DefaultStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, std::optional account, + std::vector policies, const std::string& subuser, const std::optional& perm_mask, const std::string& access_key_id) const override { auto apl = \ rgw::auth::add_3rdparty(driver, rgw_user(s->account_name), rgw::auth::add_sysreq(cct, driver, s, - rgw::auth::LocalApplier(cct, user_info, std::move(account), - subuser, perm_mask, access_key_id))); + LocalApplier(cct, user_info, std::move(account), std::move(policies), + subuser, perm_mask, access_key_id))); /* TODO(rzarzynski): replace with static_ptr. */ return aplptr_t(new decltype(apl)(std::move(apl))); } -- 2.39.5