Skip to content

Commit 753fcff

Browse files
committed
rgw: implement ConfirmRemoveSelfBucketAccess header for bucket policy
According to https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html root user should always have access to do Put/Get/DeleteBucketPolicy. By implementing the `x-amz-confirm-remove-self-bucket-access` header this privilege can also be dropped from the root user. Fixes: https://tracker.ceph.com/issues/66177 Signed-off-by: Seena Fallah <[email protected]>
1 parent 01caaa3 commit 753fcff

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

PendingReleaseNotes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
redistribution. In contrast, a stretch rule with a single-take configuration
8383
will not cause any data movement during the upgrade process.
8484

85+
* RGW: The `x-amz-confirm-remove-self-bucket-access` header is now supported by
86+
`PutBucketPolicy`. Additionally, the root user will always have access to modify
87+
the bucket policy, even if the current policy explicitly denies access.
88+
8589
>=19.2.1
8690

8791
* CephFS: Command `fs subvolume create` now allows tagging subvolumes through option

src/rgw/rgw_common.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,11 @@ using ceph::crypto::MD5;
163163
#define RGW_ATTR_OBJ_REPLICATION_TIMESTAMP RGW_ATTR_PREFIX "replicated-at"
164164

165165
/* IAM Policy */
166-
#define RGW_ATTR_IAM_POLICY RGW_ATTR_PREFIX "iam-policy"
167-
#define RGW_ATTR_USER_POLICY RGW_ATTR_PREFIX "user-policy"
168-
#define RGW_ATTR_MANAGED_POLICY RGW_ATTR_PREFIX "managed-policy"
169-
#define RGW_ATTR_PUBLIC_ACCESS RGW_ATTR_PREFIX "public-access"
166+
#define RGW_ATTR_IAM_POLICY RGW_ATTR_PREFIX "iam-policy"
167+
#define RGW_ATTR_USER_POLICY RGW_ATTR_PREFIX "user-policy"
168+
#define RGW_ATTR_MANAGED_POLICY RGW_ATTR_PREFIX "managed-policy"
169+
#define RGW_ATTR_PUBLIC_ACCESS RGW_ATTR_PREFIX "public-access"
170+
#define RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS RGW_ATTR_PREFIX "iam-policy-remove-self-access"
170171

171172
/* RGW File Attributes */
172173
#define RGW_ATTR_UNIX_KEY1 RGW_ATTR_PREFIX "unix-key1"

src/rgw/rgw_op.cc

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8481,6 +8481,14 @@ void RGWPutBucketPolicy::send_response()
84818481

84828482
int RGWPutBucketPolicy::verify_permission(optional_yield y)
84838483
{
8484+
// If the user is the root account of the bucket owner,
8485+
// and x-amz-confirm-remove-self-bucket-access was not set,
8486+
// then the user can put bucket policy.
8487+
if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
8488+
s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
8489+
return 0;
8490+
}
8491+
84848492
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
84858493
if (has_s3_resource_tag)
84868494
rgw_iam_add_buckettags(this, s);
@@ -8530,10 +8538,15 @@ void RGWPutBucketPolicy::execute(optional_yield y)
85308538
}
85318539

85328540
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [&p, this, &attrs] {
8533-
attrs[RGW_ATTR_IAM_POLICY].clear();
8534-
attrs[RGW_ATTR_IAM_POLICY].append(p.text);
8535-
op_ret = s->bucket->merge_and_store_attrs(this, attrs, s->yield);
8536-
return op_ret;
8541+
attrs[RGW_ATTR_IAM_POLICY].clear();
8542+
attrs[RGW_ATTR_IAM_POLICY].append(p.text);
8543+
if (s->info.env->exists("HTTP_X_AMZ_CONFIRM_REMOVE_SELF_BUCKET_ACCESS")) {
8544+
attrs[RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS].clear();
8545+
} else {
8546+
attrs.erase(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS);
8547+
}
8548+
op_ret = s->bucket->merge_and_store_attrs(this, attrs, s->yield);
8549+
return op_ret;
85378550
}, y);
85388551
} catch (rgw::IAM::PolicyParseException& e) {
85398552
ldpp_dout(this, 5) << "failed to parse policy: " << e.what() << dendl;
@@ -8554,6 +8567,14 @@ void RGWGetBucketPolicy::send_response()
85548567

85558568
int RGWGetBucketPolicy::verify_permission(optional_yield y)
85568569
{
8570+
// If the user is the root account of the bucket owner,
8571+
// and x-amz-confirm-remove-self-bucket-access was not set,
8572+
// then the user can put bucket policy.
8573+
if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
8574+
s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
8575+
return 0;
8576+
}
8577+
85578578
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
85588579
if (has_s3_resource_tag)
85598580
rgw_iam_add_buckettags(this, s);
@@ -8603,6 +8624,14 @@ void RGWDeleteBucketPolicy::send_response()
86038624

86048625
int RGWDeleteBucketPolicy::verify_permission(optional_yield y)
86058626
{
8627+
// If the user is the root account of the bucket owner,
8628+
// and x-amz-confirm-remove-self-bucket-access was not set,
8629+
// then the user can put bucket policy.
8630+
if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
8631+
s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
8632+
return 0;
8633+
}
8634+
86068635
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
86078636
if (has_s3_resource_tag)
86088637
rgw_iam_add_buckettags(this, s);
@@ -8626,6 +8655,7 @@ void RGWDeleteBucketPolicy::execute(optional_yield y)
86268655
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this] {
86278656
rgw::sal::Attrs& attrs = s->bucket->get_attrs();
86288657
attrs.erase(RGW_ATTR_IAM_POLICY);
8658+
attrs.erase(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS);
86298659
op_ret = s->bucket->put_info(this, false, real_time(), s->yield);
86308660
return op_ret;
86318661
}, y);

0 commit comments

Comments
 (0)