#define RGW_ATTR_OBJ_REPLICATION_TIMESTAMP RGW_ATTR_PREFIX "replicated-at"
/* IAM Policy */
-#define RGW_ATTR_IAM_POLICY RGW_ATTR_PREFIX "iam-policy"
-#define RGW_ATTR_USER_POLICY RGW_ATTR_PREFIX "user-policy"
-#define RGW_ATTR_MANAGED_POLICY RGW_ATTR_PREFIX "managed-policy"
-#define RGW_ATTR_PUBLIC_ACCESS RGW_ATTR_PREFIX "public-access"
+#define RGW_ATTR_IAM_POLICY RGW_ATTR_PREFIX "iam-policy"
+#define RGW_ATTR_USER_POLICY RGW_ATTR_PREFIX "user-policy"
+#define RGW_ATTR_MANAGED_POLICY RGW_ATTR_PREFIX "managed-policy"
+#define RGW_ATTR_PUBLIC_ACCESS RGW_ATTR_PREFIX "public-access"
+#define RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS RGW_ATTR_PREFIX "iam-policy-remove-self-access"
/* RGW File Attributes */
#define RGW_ATTR_UNIX_KEY1 RGW_ATTR_PREFIX "unix-key1"
int RGWPutBucketPolicy::verify_permission(optional_yield y)
{
+ // If the user is the root account of the bucket owner,
+ // and x-amz-confirm-remove-self-bucket-access was not set,
+ // then the user can put bucket policy.
+ if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
+ s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
+ return 0;
+ }
+
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
if (has_s3_resource_tag)
rgw_iam_add_buckettags(this, s);
}
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [&p, this, &attrs] {
- attrs[RGW_ATTR_IAM_POLICY].clear();
- attrs[RGW_ATTR_IAM_POLICY].append(p.text);
- op_ret = s->bucket->merge_and_store_attrs(this, attrs, s->yield);
- return op_ret;
+ attrs[RGW_ATTR_IAM_POLICY].clear();
+ attrs[RGW_ATTR_IAM_POLICY].append(p.text);
+ if (s->info.env->exists("HTTP_X_AMZ_CONFIRM_REMOVE_SELF_BUCKET_ACCESS")) {
+ attrs[RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS].clear();
+ } else {
+ attrs.erase(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS);
+ }
+ op_ret = s->bucket->merge_and_store_attrs(this, attrs, s->yield);
+ return op_ret;
}, y);
} catch (rgw::IAM::PolicyParseException& e) {
ldpp_dout(this, 5) << "failed to parse policy: " << e.what() << dendl;
int RGWGetBucketPolicy::verify_permission(optional_yield y)
{
+ // If the user is the root account of the bucket owner,
+ // and x-amz-confirm-remove-self-bucket-access was not set,
+ // then the user can put bucket policy.
+ if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
+ s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
+ return 0;
+ }
+
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
if (has_s3_resource_tag)
rgw_iam_add_buckettags(this, s);
int RGWDeleteBucketPolicy::verify_permission(optional_yield y)
{
+ // If the user is the root account of the bucket owner,
+ // and x-amz-confirm-remove-self-bucket-access was not set,
+ // then the user can put bucket policy.
+ if (s->auth.identity->is_root_of(s->bucket_owner.id) &&
+ s->bucket_attrs.find(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS) == s->bucket_attrs.end()) {
+ return 0;
+ }
+
auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
if (has_s3_resource_tag)
rgw_iam_add_buckettags(this, s);
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this] {
rgw::sal::Attrs& attrs = s->bucket->get_attrs();
attrs.erase(RGW_ATTR_IAM_POLICY);
+ attrs.erase(RGW_ATTR_IAM_POLICY_REMOVE_SELF_ACCESS);
op_ret = s->bucket->put_info(this, false, real_time(), s->yield);
return op_ret;
}, y);