From: Raja Sharma Date: Thu, 2 Jan 2025 20:22:10 +0000 (+0530) Subject: RGW:support x-amz-expected-bucket-owner to verify bucket ownership with bucket owner... X-Git-Tag: testing/wip-pdonnell-testing-20250129.020559-debug~3^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5d590f5b2038ccc7fc6fd96c208eef3c6e08d01a;p=ceph-ci.git RGW:support x-amz-expected-bucket-owner to verify bucket ownership with bucket owner condition 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 --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 6610538542c..5140ed4e9cf 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -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);