@@ -8481,6 +8481,14 @@ void RGWPutBucketPolicy::send_response()
84818481
84828482int 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
85558568int 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
86048625int 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