From: Casey Bodley Date: Sat, 27 Jan 2024 20:55:27 +0000 (-0500) Subject: rgw: add generic evaluate_iam_policies() X-Git-Tag: testing/wip-pdonnell-testing-20240416.232051-debug~25^2~88 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=2a5abafaeee9c3ebe8776db1e6b91031a5b8e088;p=ceph-ci.git rgw: add generic evaluate_iam_policies() Signed-off-by: Casey Bodley --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index cf94fcfdd7d..af95c448558 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -44,6 +44,7 @@ using rgw::ARN; using rgw::IAM::Effect; using rgw::IAM::op_to_perm; using rgw::IAM::Policy; +using rgw::IAM::PolicyPrincipal; const uint32_t RGWBucketInfo::NUM_SHARDS_BLIND_BUCKET(UINT32_MAX); @@ -1147,6 +1148,82 @@ Effect eval_identity_or_session_policies(const DoutPrefixProvider* dpp, return policy_res; } +// determine whether a request is allowed or denied within an account +Effect evaluate_iam_policies( + const DoutPrefixProvider* dpp, + const rgw::IAM::Environment& env, + const rgw::auth::Identity& identity, + uint64_t op, const rgw::ARN& arn, + const boost::optional& resource_policy, + const vector& identity_policies, + const vector& session_policies) +{ + auto identity_res = eval_identity_or_session_policies(dpp, identity_policies, env, op, arn); + if (identity_res == Effect::Deny) { + ldpp_dout(dpp, 10) << __func__ << ": explicit deny from identity-based policy" << dendl; + return Effect::Deny; + } + + PolicyPrincipal princ_type = PolicyPrincipal::Other; + auto resource_res = eval_or_pass(dpp, resource_policy, env, identity, + op, arn, princ_type); + if (resource_res == Effect::Deny) { + ldpp_dout(dpp, 10) << __func__ << ": explicit deny from resource-based policy" << dendl; + return Effect::Deny; + } + + //Take into account session policies, if the identity making a request is a role + if (!session_policies.empty()) { + auto session_res = eval_identity_or_session_policies(dpp, session_policies, env, op, arn); + if (session_res == Effect::Deny) { + ldpp_dout(dpp, 10) << __func__ << ": explicit deny from session policy" << dendl; + return Effect::Deny; + } + if (princ_type == PolicyPrincipal::Role) { + //Intersection of session policy and identity policy plus intersection of session policy and bucket policy + if (session_res == Effect::Allow && identity_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by session and identity-based policy" << dendl; + return Effect::Allow; + } + if (session_res == Effect::Allow && resource_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by session and resource-based policy" << dendl; + return Effect::Allow; + } + } else if (princ_type == PolicyPrincipal::Session) { + //Intersection of session policy and identity policy plus bucket policy + if (session_res == Effect::Allow && identity_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by session and identity-based policy" << dendl; + return Effect::Allow; + } + if (resource_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by resource-based policy" << dendl; + return Effect::Allow; + } + } else if (princ_type == PolicyPrincipal::Other) {// there was no match in the bucket policy + if (session_res == Effect::Allow && identity_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by session and identity-based policy" << dendl; + return Effect::Allow; + } + } + ldpp_dout(dpp, 10) << __func__ << ": implicit deny from session policy" << dendl; + return Effect::Pass; + } + + // Allow from resource policy overrides implicit deny from identity + if (resource_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by resource-based policy" << dendl; + return Effect::Allow; + } + + if (identity_res == Effect::Allow) { + ldpp_dout(dpp, 10) << __func__ << ": allowed by identity-based policy" << dendl; + return Effect::Allow; + } + + ldpp_dout(dpp, 10) << __func__ << ": implicit deny from identity-based policy" << dendl; + return Effect::Pass; +} + bool verify_user_permission(const DoutPrefixProvider* dpp, perm_state_base * const s, const RGWAccessControlPolicy& user_acl, @@ -1156,24 +1233,12 @@ bool verify_user_permission(const DoutPrefixProvider* dpp, const uint64_t op, bool mandatory_policy) { - auto identity_policy_res = eval_identity_or_session_policies(dpp, user_policies, s->env, op, res); - if (identity_policy_res == Effect::Deny) { - return false; - } - - if (! session_policies.empty()) { - auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, res); - if (session_policy_res == Effect::Deny) { - return false; - } - //Intersection of identity policies and session policies - if (identity_policy_res == Effect::Allow && session_policy_res == Effect::Allow) { - return true; - } + const auto effect = evaluate_iam_policies(dpp, s->env, *s->identity, op, res, + {}, user_policies, session_policies); + if (effect == Effect::Deny) { return false; } - - if (identity_policy_res == Effect::Allow) { + if (effect == Effect::Allow) { return true; } @@ -1263,49 +1328,21 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, if (!verify_requester_payer_permission(s)) return false; - auto identity_policy_res = eval_identity_or_session_policies(dpp, identity_policies, s->env, op, ARN(bucket)); - if (identity_policy_res == Effect::Deny) - return false; - - rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other; if (bucket_policy) { ldpp_dout(dpp, 16) << __func__ << ": policy: " << bucket_policy.get() - << "resource: " << ARN(bucket) << dendl; + << " resource: " << ARN(bucket) << dendl; } - auto r = eval_or_pass(dpp, bucket_policy, s->env, *s->identity, - op, ARN(bucket), princ_type); - if (r == Effect::Deny) - return false; - - //Take into account session policies, if the identity making a request is a role - if (!session_policies.empty()) { - auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, ARN(bucket)); - if (session_policy_res == Effect::Deny) { - return false; - } - if (princ_type == rgw::IAM::PolicyPrincipal::Role) { - //Intersection of session policy and identity policy plus intersection of session policy and bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || - (session_policy_res == Effect::Allow && r == Effect::Allow)) - return true; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Session) { - //Intersection of session policy and identity policy plus bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || r == Effect::Allow) - return true; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Other) {// there was no match in the bucket policy - if (session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) - return true; - } + const auto effect = evaluate_iam_policies( + dpp, s->env, *s->identity, op, ARN(bucket), bucket_policy, + identity_policies, session_policies); + if (effect == Effect::Deny) { return false; } - - if (r == Effect::Allow || identity_policy_res == Effect::Allow) - // It looks like S3 ACLs only GRANT permissions rather than - // denying them, so this should be safe. + if (effect == Effect::Allow) { return true; + } const auto perm = op_to_perm(op); - return verify_bucket_permission_no_policy(dpp, s, user_acl, bucket_acl, perm); } @@ -1381,88 +1418,34 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, req_state * const s // request is missing a bucket name return false; } - - perm_state_from_req_state ps(s); - - return verify_bucket_permission(dpp, - &ps, - s->bucket->get_key(), - s->user_acl, - s->bucket_acl, - s->iam_policy, - s->iam_user_policies, - s->session_policies, - op); + return verify_bucket_permission(dpp, s, s->bucket->get_key(), s->user_acl, s->bucket_acl, + s->iam_policy, s->iam_user_policies, s->session_policies, op); } // Authorize anyone permitted by the bucket policy, identity policies, session policies and the bucket owner // unless explicitly denied by the policy. -int verify_bucket_owner_or_policy(req_state* const s, - const uint64_t op) +int verify_bucket_owner_or_policy(const DoutPrefixProvider* dpp, + req_state* const s, const uint64_t op) { - auto identity_policy_res = eval_identity_or_session_policies(s, s->iam_user_policies, s->env, op, ARN(s->bucket->get_key())); - if (identity_policy_res == Effect::Deny) { + const auto arn = ARN(s->bucket->get_key()); + const auto effect = evaluate_iam_policies( + dpp, s->env, *s->auth.identity, op, arn, + s->iam_policy, s->iam_user_policies, s->session_policies); + if (effect == Effect::Deny) { return -EACCES; } - - rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other; - auto e = eval_or_pass(s, s->iam_policy, - s->env, *s->auth.identity, - op, ARN(s->bucket->get_key()), princ_type); - if (e == Effect::Deny) { - return -EACCES; - } - - if (!s->session_policies.empty()) { - auto session_policy_res = eval_identity_or_session_policies(s, s->session_policies, s->env, op, - ARN(s->bucket->get_key())); - if (session_policy_res == Effect::Deny) { - return -EACCES; - } - if (princ_type == rgw::IAM::PolicyPrincipal::Role) { - //Intersection of session policy and identity policy plus intersection of session policy and bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || - (session_policy_res == Effect::Allow && e == Effect::Allow)) - return 0; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Session) { - //Intersection of session policy and identity policy plus bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || e == Effect::Allow) - return 0; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Other) {// there was no match in the bucket policy - if (session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) - return 0; - } - return -EACCES; + if (effect == Effect::Allow) { + return 0; } - - if (e == Effect::Allow || - identity_policy_res == Effect::Allow || - (e == Effect::Pass && - identity_policy_res == Effect::Pass && - s->auth.identity->is_owner_of(s->bucket_owner.id))) { + if (s->auth.identity->is_owner_of(s->bucket_owner.id)) { + ldpp_dout(dpp, 10) << __func__ << ": granted to bucket owner" << dendl; return 0; - } else { - return -EACCES; } + return -EACCES; } -static inline bool check_deferred_bucket_perms(const DoutPrefixProvider* dpp, - struct perm_state_base * const s, - const rgw_bucket& bucket, - const RGWAccessControlPolicy& user_acl, - const RGWAccessControlPolicy& bucket_acl, - const boost::optional& bucket_policy, - const vector& identity_policies, - const vector& session_policies, - const uint8_t deferred_check, - const uint64_t op) -{ - return (s->defer_to_bucket_acls == deferred_check \ - && verify_bucket_permission(dpp, s, bucket, user_acl, bucket_acl, bucket_policy, identity_policies, session_policies,op)); -} - static inline bool check_deferred_bucket_only_acl(const DoutPrefixProvider* dpp, struct perm_state_base * const s, const RGWAccessControlPolicy& user_acl, @@ -1487,86 +1470,19 @@ bool verify_object_permission(const DoutPrefixProvider* dpp, struct perm_state_b if (!verify_requester_payer_permission(s)) return false; - auto identity_policy_res = eval_identity_or_session_policies(dpp, identity_policies, s->env, op, ARN(obj)); - if (identity_policy_res == Effect::Deny) - return false; - - rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other; - auto r = eval_or_pass(dpp, bucket_policy, s->env, *s->identity, op, ARN(obj), princ_type); - if (r == Effect::Deny) - return false; - - if (!session_policies.empty()) { - auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, ARN(obj)); - if (session_policy_res == Effect::Deny) { - return false; - } - if (princ_type == rgw::IAM::PolicyPrincipal::Role) { - //Intersection of session policy and identity policy plus intersection of session policy and bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || - (session_policy_res == Effect::Allow && r == Effect::Allow)) - return true; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Session) { - //Intersection of session policy and identity policy plus bucket policy - if ((session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) || r == Effect::Allow) - return true; - } else if (princ_type == rgw::IAM::PolicyPrincipal::Other) {// there was no match in the bucket policy - if (session_policy_res == Effect::Allow && identity_policy_res == Effect::Allow) - return true; - } + const auto effect = evaluate_iam_policies( + dpp, s->env, *s->identity, op, ARN(obj), bucket_policy, + identity_policies, session_policies); + if (effect == Effect::Deny) { return false; } - - if (r == Effect::Allow || identity_policy_res == Effect::Allow) - // It looks like S3 ACLs only GRANT permissions rather than - // denying them, so this should be safe. - return true; - - const auto perm = op_to_perm(op); - - if (check_deferred_bucket_perms(dpp, s, obj.bucket, user_acl, bucket_acl, bucket_policy, - identity_policies, session_policies, RGW_DEFER_TO_BUCKET_ACLS_RECURSE, op) || - check_deferred_bucket_perms(dpp, s, obj.bucket, user_acl, bucket_acl, bucket_policy, - identity_policies, session_policies, RGW_DEFER_TO_BUCKET_ACLS_FULL_CONTROL, rgw::IAM::s3All)) { + if (effect == Effect::Allow) { return true; } - bool ret = object_acl.verify_permission(dpp, *s->identity, s->perm_mask, perm, - nullptr, /* http_referrer */ - s->bucket_access_conf && - s->bucket_access_conf->ignore_public_acls()); - if (ret) { - ldpp_dout(dpp, 10) << __func__ << ": granted by user acl" << dendl; - return true; - } - - if (!s->cct->_conf->rgw_enforce_swift_acls) - return ret; - - if ((perm & (int)s->perm_mask) != perm) - return false; - - int swift_perm = 0; - if (perm & (RGW_PERM_READ | RGW_PERM_READ_ACP)) - swift_perm |= RGW_PERM_READ_OBJS; - if (perm & RGW_PERM_WRITE) - swift_perm |= RGW_PERM_WRITE_OBJS; - - if (!swift_perm) - return false; - - /* we already verified the user mask above, so we pass swift_perm as the mask here, - otherwise the mask might not cover the swift permissions bits */ - if (bucket_acl.verify_permission(dpp, *s->identity, swift_perm, swift_perm, - s->get_referer())) { - ldpp_dout(dpp, 10) << __func__ << ": granted by bucket acl" << dendl; - return true; - } - if (user_acl.verify_permission(dpp, *s->identity, swift_perm, swift_perm)) { - ldpp_dout(dpp, 10) << __func__ << ": granted by user acl" << dendl; - return true; - } - return false; + const auto perm = op_to_perm(op); + return verify_object_permission_no_policy(dpp, s, user_acl, bucket_acl, + object_acl, perm); } bool verify_object_permission(const DoutPrefixProvider* dpp, req_state * const s, @@ -1653,10 +1569,7 @@ bool verify_object_permission_no_policy(const DoutPrefixProvider* dpp, req_state bool verify_object_permission(const DoutPrefixProvider* dpp, req_state *s, uint64_t op) { - perm_state_from_req_state ps(s); - - return verify_object_permission(dpp, - &ps, + return verify_object_permission(dpp, s, rgw_obj(s->bucket->get_key(), s->object->get_key()), s->user_acl, s->bucket_acl, diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index b1dd29e9057..cf1345f3527 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1769,8 +1769,8 @@ bool verify_bucket_permission_no_policy( bool verify_bucket_permission_no_policy(const DoutPrefixProvider* dpp, req_state * const s, const int perm); -int verify_bucket_owner_or_policy(req_state* const s, - const uint64_t op); +int verify_bucket_owner_or_policy(const DoutPrefixProvider* dpp, + req_state* s, const uint64_t op); extern bool verify_object_permission( const DoutPrefixProvider* dpp, req_state * const s, diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f261209fee6..c188e9e6f41 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1236,7 +1236,7 @@ int RGWPutBucketTags::verify_permission(optional_yield y) { if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketTagging); } void RGWPutBucketTags::execute(optional_yield y) @@ -1272,7 +1272,7 @@ int RGWDeleteBucketTags::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketTagging); } void RGWDeleteBucketTags::execute(optional_yield y) @@ -1324,7 +1324,7 @@ int RGWPutBucketReplication::verify_permission(optional_yield y) { 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); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutReplicationConfiguration); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutReplicationConfiguration); } void RGWPutBucketReplication::execute(optional_yield y) { @@ -1370,7 +1370,7 @@ int RGWDeleteBucketReplication::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteReplicationConfiguration); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3DeleteReplicationConfiguration); } void RGWDeleteBucketReplication::execute(optional_yield y) @@ -2774,7 +2774,7 @@ int RGWGetBucketVersioning::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketVersioning); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketVersioning); } void RGWGetBucketVersioning::pre_exec() @@ -2800,7 +2800,7 @@ int RGWSetBucketVersioning::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketVersioning); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketVersioning); } void RGWSetBucketVersioning::pre_exec() @@ -2899,7 +2899,7 @@ int RGWGetBucketWebsite::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketWebsite); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketWebsite); } void RGWGetBucketWebsite::pre_exec() @@ -2920,7 +2920,7 @@ int RGWSetBucketWebsite::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketWebsite); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketWebsite); } void RGWSetBucketWebsite::pre_exec() @@ -2967,7 +2967,7 @@ int RGWDeleteBucketWebsite::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteBucketWebsite); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3DeleteBucketWebsite); } void RGWDeleteBucketWebsite::pre_exec() @@ -3148,7 +3148,7 @@ int RGWGetBucketLogging::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLogging); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketLogging); } int RGWGetBucketLocation::verify_permission(optional_yield y) @@ -3157,7 +3157,7 @@ int RGWGetBucketLocation::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLocation); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketLocation); } static int get_account_max_buckets(const DoutPrefixProvider* dpp, @@ -6287,7 +6287,7 @@ int RGWGetCORS::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketCORS); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketCORS); } void RGWGetCORS::execute(optional_yield y) @@ -6309,7 +6309,7 @@ int RGWPutCORS::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketCORS); } void RGWPutCORS::execute(optional_yield y) @@ -6341,7 +6341,7 @@ int RGWDeleteCORS::verify_permission(optional_yield y) rgw_iam_add_buckettags(this, s); // No separate delete permission - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketCORS); } void RGWDeleteCORS::execute(optional_yield y) @@ -6435,7 +6435,7 @@ int RGWGetRequestPayment::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketRequestPayment); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketRequestPayment); } void RGWGetRequestPayment::pre_exec() @@ -6454,7 +6454,7 @@ int RGWSetRequestPayment::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketRequestPayment); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketRequestPayment); } void RGWSetRequestPayment::pre_exec() @@ -8627,7 +8627,7 @@ int RGWPutBucketObjectLock::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketObjectLockConfiguration); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3PutBucketObjectLockConfiguration); } void RGWPutBucketObjectLock::execute(optional_yield y) @@ -8694,7 +8694,7 @@ int RGWGetBucketObjectLock::verify_permission(optional_yield y) if (has_s3_resource_tag) rgw_iam_add_buckettags(this, s); - return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketObjectLockConfiguration); + return verify_bucket_owner_or_policy(this, s, rgw::IAM::s3GetBucketObjectLockConfiguration); } void RGWGetBucketObjectLock::execute(optional_yield y)