]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/auth: generalize Identity::get_role_tenant() as get_tenant()
authorCasey Bodley <cbodley@redhat.com>
Thu, 7 Dec 2023 20:21:52 +0000 (15:21 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 16:53:04 +0000 (12:53 -0400)
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 <cbodley@redhat.com>
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_filters.h
src/rgw/rgw_op.cc
src/rgw/rgw_pubsub.cc
src/rgw/rgw_pubsub.h
src/rgw/rgw_rest_pubsub.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc
src/test/rgw/test_rgw_iam_policy.cc
src/test/rgw/test_rgw_lua.cc

index 5d98933063c84043270b8716f1901f570be55810..e01f58a7f2c7225aa453558875a07ea089a1f8c7 100644 (file)
@@ -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
index e2de0afb72655ad7be1368abab7e5960ae4f326f..3745a539f94bf21cd3ea395ecd53af596a438b4c 100644 (file)
@@ -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() {}
index 9e3818bef071d5b3761e0211bb26eadd0199316b..75b1c7aa1bdfca3a335db41c18f87b64363d8eaf 100644 (file)
@@ -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 */
index 92b01e08c0bb26c82b9492eb40696818953facf6..a2f4f4e459e1fc7eb868f73e260f8c5dc807b840 100644 (file)
@@ -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<string, bufferlist> 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<RGWAccessControlPolicy> allocated_acls;
   map<string, pair<RGWAccessControlPolicy *, boost::optional<Policy>>> policies;
   map<string, std::unique_ptr<rgw::sal::Bucket>> buckets;
+  const std::string& auth_tenant = s->auth.identity->get_tenant();
 
   map<uint64_t, rgw_slo_part> 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<rgw::sal::Bucket> 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<rgw::sal::Bucket> 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) {
index 4a420f004c588e81970232594bad7aa6c687823e..46fb56874b39b95c2a74504e6b073fe190e363b0 100644 (file)
@@ -530,10 +530,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)
index f03d7542b7388ad3c3769214c6c56dcb6d97034b..89b6e5d72519630bc319c01ea71946bcc198ab1e 100644 (file)
@@ -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;
index 431a83213389dcb46484396deb225c7fa3404e10..27fad86a58b0180814a3c2bbb67edd9038977e49 100644 (file)
@@ -92,7 +92,7 @@ std::optional<rgw::IAM::Policy> 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<bool>("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<std::string, rgw_pubsub_topic> 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);
   }
index 3389f59d42df36211d4862747ae9a01b77ffcb91..13383b78c33ff1b24fdce995acb66714e2c877c4 100644 (file)
@@ -4918,14 +4918,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;
@@ -4940,12 +4939,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) {
index dd8d5a47321aec47f9d6e2d6ebccec441a5a1f75..fb4e771ddda1deb92a9c20fff66e7a2ac1146eec 100644 (file)
@@ -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;
 
index 67c79508a49a6c4d0a026d501cdaaa9033f3d78c..32fd0d23a4564b713d83d8c5d9b631a3fe0a059e 100644 (file)
@@ -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;
   }
index e6014513ba3a7cebda01a530f2560ca2a9b8e807..2adba8016e50e788647485cb52b884c6f6ffaad3 100644 (file)
@@ -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;
   }