From: Casey Bodley Date: Thu, 7 Dec 2023 20:21:52 +0000 (-0500) Subject: rgw/auth: generalize Identity::get_role_tenant() as get_tenant() X-Git-Tag: v19.1.0~99^2~166 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f0fb48d19409c012ae8422304b63ca013c1055db;p=ceph.git rgw/auth: generalize Identity::get_role_tenant() as get_tenant() all identities can return a tenant. rgw ops should consult the auth identity for this instead of a rgw_user or rgw::sal::User Signed-off-by: Casey Bodley (cherry picked from commit d82ff164505cd7a7abe6937879052ad03f1da939) --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 5d98933063c..e01f58a7f2c 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -98,6 +98,9 @@ transform_old_authinfo(CephContext* const cct, string get_subuser() const override { return {}; } + const std::string& get_tenant() const override { + return id.tenant; + } void to_str(std::ostream& out) const override { out << "RGWDummyIdentityApplier(auth_id=" << id diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index e2de0afb726..3745a539f94 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -83,7 +83,8 @@ public: /* Subuser of Account */ virtual std::string get_subuser() const = 0; - virtual std::string get_role_tenant() const { return ""; } + /* Identity's tenant namespace */ + virtual const std::string& get_tenant() const = 0; /* write any auth-specific fields that are safe to expose in the ops log */ virtual void write_ops_log_entry(rgw_log_entry& entry) const {}; @@ -479,6 +480,9 @@ public: std::string get_subuser() const override { return {}; } + const std::string& get_tenant() const override { + return role_tenant; + } struct Factory { virtual ~Factory() {} @@ -626,6 +630,9 @@ public: uint32_t get_identity_type() const override { return info.acct_type; } std::string get_acct_name() const override { return info.acct_name; } std::string get_subuser() const override { return {}; } + const std::string& get_tenant() const override { + return info.acct_user.tenant; + } struct Factory { virtual ~Factory() {} @@ -688,6 +695,10 @@ public: uint32_t get_identity_type() const override { return TYPE_RGW; } std::string get_acct_name() const override { return {}; } std::string get_subuser() const override { return subuser; } + const std::string& get_tenant() const override { + return user_info.user_id.tenant; + } + void write_ops_log_entry(rgw_log_entry& entry) const override; struct Factory { @@ -747,8 +758,9 @@ public: uint32_t get_identity_type() const override { return TYPE_ROLE; } std::string get_acct_name() const override { return {}; } std::string get_subuser() const override { return {}; } + const std::string& get_tenant() const override { return role.tenant; } + void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override; - std::string get_role_tenant() const override { return role.tenant; } struct Factory { virtual ~Factory() {} diff --git a/src/rgw/rgw_auth_filters.h b/src/rgw/rgw_auth_filters.h index 9e3818bef07..75b1c7aa1bd 100644 --- a/src/rgw/rgw_auth_filters.h +++ b/src/rgw/rgw_auth_filters.h @@ -106,8 +106,8 @@ public: get_decoratee().to_str(out); } - std::string get_role_tenant() const override { /* in/out */ - return get_decoratee().get_role_tenant(); + const std::string& get_tenant() const override { + return get_decoratee().get_tenant(); } void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override { /* out */ diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 92b01e08c0b..a2f4f4e459e 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1955,6 +1955,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix, optional_yield y) return -EINVAL; } + const std::string& auth_tenant = s->auth.identity->get_tenant(); const std::string bucket_name = url_decode(prefix_view.substr(0, pos)); const std::string obj_prefix = url_decode(prefix_view.substr(pos + 1)); @@ -1969,7 +1970,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix, optional_yield y) if (bucket_name.compare(s->bucket->get_name()) != 0) { map bucket_attrs; - r = driver->load_bucket(this, rgw_bucket(s->user->get_tenant(), bucket_name), + r = driver->load_bucket(this, rgw_bucket(auth_tenant, bucket_name), &ubucket, y); if (r < 0) { ldpp_dout(this, 0) << "could not get bucket info for bucket=" @@ -1982,7 +1983,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix, optional_yield y) ldpp_dout(this, 0) << "failed to read bucket policy" << dendl; return r; } - _bucket_policy = get_iam_policy_from_attr(s->cct, bucket_attrs, s->user->get_tenant()); + _bucket_policy = get_iam_policy_from_attr(s->cct, bucket_attrs, auth_tenant); bucket_policy = &_bucket_policy; pbucket = ubucket.get(); } else { @@ -2054,6 +2055,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl, optional_yield y) vector allocated_acls; map>> policies; map> buckets; + const std::string& auth_tenant = s->auth.identity->get_tenant(); map slo_parts; @@ -2099,8 +2101,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl, optional_yield y) RGWAccessControlPolicy& _bucket_acl = allocated_acls.emplace_back(); std::unique_ptr tmp_bucket; - int r = driver->load_bucket(this, rgw_bucket(s->user->get_tenant(), - bucket_name), + int r = driver->load_bucket(this, rgw_bucket(auth_tenant, bucket_name), &tmp_bucket, y); if (r < 0) { ldpp_dout(this, 0) << "could not get bucket info for bucket=" @@ -2117,7 +2118,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl, optional_yield y) return r; } auto _bucket_policy = get_iam_policy_from_attr( - s->cct, tmp_bucket->get_attrs(), tmp_bucket->get_tenant()); + s->cct, tmp_bucket->get_attrs(), auth_tenant); bucket_policy = _bucket_policy.get_ptr(); buckets[bucket_name].swap(tmp_bucket); policies[bucket_name] = make_pair(bucket_acl, _bucket_policy); @@ -2509,13 +2510,7 @@ int RGWListBuckets::verify_permission(optional_yield y) rgw::Partition partition = rgw::Partition::aws; rgw::Service service = rgw::Service::s3; - string tenant; - if (s->auth.identity->get_identity_type() == TYPE_ROLE) { - tenant = s->auth.identity->get_role_tenant(); - } else { - tenant = s->user->get_tenant(); - } - + const std::string& tenant = s->auth.identity->get_tenant(); if (!verify_user_permission(this, s, ARN(partition, service, "", tenant, "*"), rgw::IAM::s3ListAllMyBuckets, false)) { return -EACCES; } @@ -3177,7 +3172,7 @@ int RGWCreateBucket::verify_permission(optional_yield y) return -EACCES; } - if (s->user->get_tenant() != s->bucket_tenant) { + if (s->auth.identity->get_tenant() != s->bucket_tenant) { //AssumeRole is meant for cross account access if (s->auth.identity->get_identity_type() != TYPE_ROLE) { ldpp_dout(this, 10) << "user cannot create a bucket in a different tenant" @@ -3773,7 +3768,7 @@ int RGWPutObj::init_processing(optional_yield y) { pos = copy_source_bucket_name.find(":"); if (pos == std::string::npos) { // if tenant is not specified in x-amz-copy-source, use tenant of the requester - copy_source_tenant_name = s->user->get_tenant(); + copy_source_tenant_name = s->auth.identity->get_tenant(); } else { copy_source_tenant_name = copy_source_bucket_name.substr(0, pos); copy_source_bucket_name = copy_source_bucket_name.substr(pos + 1, copy_source_bucket_name.size()); @@ -7434,7 +7429,7 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path, optional_yie ACLOwner bowner; RGWObjVersionTracker ot; - int ret = driver->load_bucket(dpp, rgw_bucket(s->user->get_tenant(), + int ret = driver->load_bucket(dpp, rgw_bucket(s->auth.identity->get_tenant(), path.bucket_name), &bucket, y); if (ret < 0) { @@ -7576,9 +7571,9 @@ int RGWBulkUploadOp::verify_permission(optional_yield y) return -EACCES; } - if (s->user->get_tenant() != s->bucket_tenant) { + if (s->auth.identity->get_tenant() != s->bucket_tenant) { ldpp_dout(this, 10) << "user cannot create a bucket in a different tenant" - << " (user_id.tenant=" << s->user->get_tenant() + << " (authorized user tenant=" << s->auth.identity->get_tenant() << " requested=" << s->bucket_tenant << ")" << dendl; return -EACCES; } @@ -7828,7 +7823,7 @@ int RGWBulkUploadOp::handle_file(const std::string_view path, std::unique_ptr bucket; ACLOwner bowner; - op_ret = driver->load_bucket(this, rgw_bucket(s->user->get_tenant(), + op_ret = driver->load_bucket(this, rgw_bucket(s->auth.identity->get_tenant(), bucket_name), &bucket, y); if (op_ret < 0) { diff --git a/src/rgw/rgw_pubsub.cc b/src/rgw/rgw_pubsub.cc index cf207db632c..3ce0f720a38 100644 --- a/src/rgw/rgw_pubsub.cc +++ b/src/rgw/rgw_pubsub.cc @@ -522,10 +522,6 @@ void rgw_pubsub_dest::decode_json(JSONObj* f) { : std::stoul(sleep_dur); } -RGWPubSub::RGWPubSub(rgw::sal::Driver* _driver, const std::string& _tenant) - : driver(_driver), tenant(_tenant) -{} - RGWPubSub::RGWPubSub(rgw::sal::Driver* _driver, const std::string& _tenant, const rgw::SiteConfig& site) diff --git a/src/rgw/rgw_pubsub.h b/src/rgw/rgw_pubsub.h index f03d7542b73..89b6e5d7251 100644 --- a/src/rgw/rgw_pubsub.h +++ b/src/rgw/rgw_pubsub.h @@ -568,11 +568,9 @@ class RGWPubSub RGWObjVersionTracker* objv_tracker, optional_yield y) const; public: - RGWPubSub(rgw::sal::Driver* _driver, const std::string& tenant); - - RGWPubSub(rgw::sal::Driver* _driver, - const std::string& _tenant, - const rgw::SiteConfig& site); + RGWPubSub(rgw::sal::Driver* _driver, + const std::string& _tenant, + const rgw::SiteConfig& site); class Bucket { friend class RGWPubSub; diff --git a/src/rgw/rgw_rest_pubsub.cc b/src/rgw/rgw_rest_pubsub.cc index 431a8321338..27fad86a58b 100644 --- a/src/rgw/rgw_rest_pubsub.cc +++ b/src/rgw/rgw_rest_pubsub.cc @@ -92,7 +92,7 @@ std::optional get_policy_from_text(req_state* const s, const auto bl = bufferlist::static_from_string(policy_text); try { return rgw::IAM::Policy( - s->cct, s->owner.id.tenant, bl, + s->cct, s->auth.identity->get_tenant(), bl, s->cct->_conf.get_val("rgw_policy_reject_invalid_principals")); } catch (rgw::IAM::PolicyParseException& e) { ldout(s->cct, 1) << "failed to parse policy: '" << policy_text @@ -218,7 +218,7 @@ class RGWPSCreateTopicOp : public RGWOp { return ret; } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); rgw_pubsub_topic result; ret = ps.get_topic(this, topic_name, result, y, nullptr); if (ret == -ENOENT) { @@ -297,7 +297,7 @@ void RGWPSCreateTopicOp::execute(optional_yield y) { return; } } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); op_ret = ps.create_topic(this, topic_name, dest, topic_arn, opaque_data, s->owner.id, policy_text, y); if (op_ret < 0) { @@ -358,7 +358,7 @@ public: void RGWPSListTopicsOp::execute(optional_yield y) { const std::string start_token = s->info.args.get("NextToken"); - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); constexpr int max_items = 100; op_ret = ps.get_topics(this, start_token, max_items, result, next_token, y); // if there are no topics it is not considered an error @@ -446,7 +446,7 @@ void RGWPSGetTopicOp::execute(optional_yield y) { if (op_ret < 0) { return; } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); op_ret = ps.get_topic(this, topic_name, result, y, nullptr); if (op_ret < 0) { ldpp_dout(this, 1) << "failed to get topic '" << topic_name << "', ret=" << op_ret << dendl; @@ -530,7 +530,7 @@ void RGWPSGetTopicAttributesOp::execute(optional_yield y) { if (op_ret < 0) { return; } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); op_ret = ps.get_topic(this, topic_name, result, y, nullptr); if (op_ret < 0) { ldpp_dout(this, 1) << "failed to get topic '" << topic_name << "', ret=" << op_ret << dendl; @@ -662,7 +662,7 @@ class RGWPSSetTopicAttributesOp : public RGWOp { return ret; } rgw_pubsub_topic result; - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); ret = ps.get_topic(this, topic_name, result, y, nullptr); if (ret < 0) { ldpp_dout(this, 1) << "failed to get topic '" << topic_name @@ -739,7 +739,7 @@ void RGWPSSetTopicAttributesOp::execute(optional_yield y) { return; } } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); op_ret = ps.create_topic(this, topic_name, dest, topic_arn, opaque_data, topic_owner, policy_text, y); if (op_ret < 0) { @@ -823,7 +823,7 @@ void RGWPSDeleteTopicOp::execute(optional_yield y) { return; } } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); rgw_pubsub_topic result; op_ret = ps.get_topic(this, topic_name, result, y, nullptr); @@ -1047,7 +1047,7 @@ void RGWPSCreateNotifOp::execute(optional_yield y) { return; } - const RGWPubSub ps(driver, s->owner.id.tenant); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); const RGWPubSub::Bucket b(ps, bucket.get()); if(configurations.list.empty()) { @@ -1202,7 +1202,7 @@ void RGWPSCreateNotifOp::execute_v2(optional_yield y) { << "' , ret = " << op_ret << dendl; return; } - const RGWPubSub ps(driver, s->owner.id.tenant, *s->penv.site); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); std::unordered_map topics; for (const auto& c : configurations.list) { const auto& notif_name = c.id; @@ -1352,7 +1352,7 @@ void RGWPSDeleteNotifOp::execute(optional_yield y) { return; } - const RGWPubSub ps(driver, s->owner.id.tenant); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); const RGWPubSub::Bucket b(ps, bucket.get()); // get all topics on a bucket @@ -1494,7 +1494,7 @@ void RGWPSListNotifsOp::execute(optional_yield y) { driver->stat_topics_v1(s->bucket_tenant, y, this) == -ENOENT) { op_ret = get_bucket_notifications(this, bucket.get(), bucket_topics); } else { - const RGWPubSub ps(driver, s->owner.id.tenant); + const RGWPubSub ps(driver, s->auth.identity->get_tenant(), *s->penv.site); const RGWPubSub::Bucket b(ps, bucket.get()); op_ret = b.get_topics(this, bucket_topics, y); } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 67eb70ebf36..a51dbe23aea 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4907,14 +4907,13 @@ int RGWHandler_REST_S3::postauth_init(optional_yield y) { struct req_init_state *t = &s->init_state; - int ret = rgw_parse_url_bucket(t->url_bucket, s->user->get_tenant(), + const std::string& auth_tenant = s->auth.identity->get_tenant(); + + int ret = rgw_parse_url_bucket(t->url_bucket, auth_tenant, s->bucket_tenant, s->bucket_name); if (ret) { return ret; } - if (s->auth.identity->get_identity_type() == TYPE_ROLE) { - s->bucket_tenant = s->auth.identity->get_role_tenant(); - } ldpp_dout(s, 10) << "s->object=" << s->object << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl; @@ -4929,12 +4928,6 @@ int RGWHandler_REST_S3::postauth_init(optional_yield y) } if (!t->src_bucket.empty()) { - string auth_tenant; - if (s->auth.identity->get_identity_type() == TYPE_ROLE) { - auth_tenant = s->auth.identity->get_role_tenant(); - } else { - auth_tenant = s->user->get_tenant(); - } ret = rgw_parse_url_bucket(t->src_bucket, auth_tenant, s->src_tenant_name, s->src_bucket_name); if (ret) { diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index dd8d5a47321..fb4e771ddda 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2931,7 +2931,7 @@ int RGWHandler_REST_SWIFT::postauth_init(optional_yield y) && s->user->get_id().id == RGW_USER_ANON_ID) { s->bucket_tenant = s->account_name; } else { - s->bucket_tenant = s->user->get_tenant(); + s->bucket_tenant = s->auth.identity->get_tenant(); } s->bucket_name = t->url_bucket; diff --git a/src/test/rgw/test_rgw_iam_policy.cc b/src/test/rgw/test_rgw_iam_policy.cc index f36dfe5ab44..30bd6043070 100644 --- a/src/test/rgw/test_rgw_iam_policy.cc +++ b/src/test/rgw/test_rgw_iam_policy.cc @@ -132,6 +132,12 @@ public: return 0; } + const std::string& get_tenant() const override { + ceph_abort(); + static std::string empty; + return empty; + } + void to_str(std::ostream& out) const override { out << id; } diff --git a/src/test/rgw/test_rgw_lua.cc b/src/test/rgw/test_rgw_lua.cc index e6014513ba3..2adba8016e5 100644 --- a/src/test/rgw/test_rgw_lua.cc +++ b/src/test/rgw/test_rgw_lua.cc @@ -61,6 +61,11 @@ public: return ""; } + const std::string& get_tenant() const override { + static std::string empty; + return empty; + } + void to_str(std::ostream& out) const override { return; }