]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
RGW:support x-amz-expected-bucket-owner to verify bucket ownership with bucket owner... 61215/head
authorRaja Sharma <raja@ibm.com>
Thu, 2 Jan 2025 20:22:10 +0000 (01:52 +0530)
committerRaja Sharma <raja@ibm.com>
Mon, 20 Jan 2025 06:20:57 +0000 (11:50 +0530)
Bucket owner condition enables to verify that the target bucket is owned by the expected user id, providing an additional layer of assurance that your S3 operations are having the effects you intend.

Fixes: https://tracker.ceph.com/issues/64526
AWS: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html

Signed-off-by: Raja Sharma <raja@ibm.com>
src/rgw/rgw_common.cc

index 6610538542cf55673644d988cad8c63fd5468dc1..5140ed4e9cf8028ad66593ec8ab57a1f8aca66f6 100644 (file)
@@ -225,6 +225,16 @@ static string get_abs_path(const string& request_uri) {
   return request_uri.substr(beg_pos, len - beg_pos);
 }
 
+static std::string to_expected_bucket_owner(const rgw_owner &o)
+{
+  struct visitor
+  {
+    std::string operator()(const rgw_account_id &a) { return a; }
+    std::string operator()(const rgw_user &u) { return u.id; }
+  };
+  return std::visit(visitor{}, o);
+}
+
 req_info::req_info(CephContext *cct, const class RGWEnv *env) : env(env) {
   method = env->get("REQUEST_METHOD", "");
   script_uri = env->get("SCRIPT_URI", cct->_conf->rgw_script_uri.c_str());
@@ -1378,6 +1388,12 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp,
                               const uint64_t op)
 {
   perm_state_from_req_state ps(s);
+  auto expected = s->info.env->get("HTTP_X_AMZ_EXPECTED_BUCKET_OWNER");
+
+  if (expected && expected != to_expected_bucket_owner(s->bucket->get_owner())) {
+    ldpp_dout(dpp, 4) << "ERROR: The expected-source-bucket-owner does not match bucket owner." << dendl;
+    return false;
+  }
 
   if (ps.identity->get_account()) {
     const bool account_root = (ps.identity->get_identity_type() == TYPE_ROOT);
@@ -1522,6 +1538,12 @@ bool verify_object_permission(const DoutPrefixProvider* dpp, req_state * const s
                               const uint64_t op)
 {
   perm_state_from_req_state ps(s);
+  auto expected = s->info.env->get("HTTP_X_AMZ_EXPECTED_BUCKET_OWNER");
+
+  if (expected && expected != to_expected_bucket_owner(s->bucket->get_owner())) {
+    ldpp_dout(dpp, 4) << "ERROR: The expected-source-bucket-owner does not match bucket owner." << dendl;
+    return false;
+  }
 
   if (ps.identity->get_account()) {
     const bool account_root = (ps.identity->get_identity_type() == TYPE_ROOT);