From: Adam C. Emerson Date: Sat, 28 Oct 2017 02:48:18 +0000 (-0400) Subject: rgw: Fix evaluation of bucket management permissions X-Git-Tag: v12.2.3~202^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F19810%2Fhead;p=ceph.git rgw: Fix evaluation of bucket management permissions I spent some more time looking through the documentation of how work is evaluated, and the examples on Have convinced me that the behavior that was requested is more correct than what we were doing before. Fixes: http://tracker.ceph.com/issues/21901 Signed-off-by: Adam C. Emerson (cherry picked from commit 343a25aa2134b6fdddeca6c9dfbaefde2dc9c66a) --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index a59152858687..1a6cbbdf7da7 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -1123,6 +1123,19 @@ bool verify_requester_payer_permission(struct req_state *s) return false; } +namespace { +Effect eval_or_pass(const optional& policy, + const rgw::IAM::Environment& env, + const rgw::auth::Identity& id, + const uint64_t op, + const ARN& arn) { + if (!policy) + return Effect::Pass; + else + return policy->eval(env, id, op, arn); +} +} + bool verify_bucket_permission(struct req_state * const s, const rgw_bucket& bucket, RGWAccessControlPolicy * const user_acl, @@ -1133,15 +1146,14 @@ bool verify_bucket_permission(struct req_state * const s, if (!verify_requester_payer_permission(s)) return false; - if (bucket_policy) { - auto r = bucket_policy->eval(s->env, *s->auth.identity, op, ARN(bucket)); - if (r == Effect::Allow) - // It looks like S3 ACLs only GRANT permissions rather than - // denying them, so this should be safe. - return true; - else if (r == Effect::Deny) - return false; - } + auto r = eval_or_pass(bucket_policy, s->env, *s->auth.identity, + op, ARN(bucket)); + if (r == Effect::Allow) + // It looks like S3 ACLs only GRANT permissions rather than + // denying them, so this should be safe. + return true; + else if (r == Effect::Deny) + return false; const auto perm = op_to_perm(op); @@ -1190,18 +1202,22 @@ bool verify_bucket_permission(struct req_state * const s, const uint64_t op) op); } +// Authorize anyone permitted by the policy and the bucket owner +// unless explicitly denied by the policy. + int verify_bucket_owner_or_policy(struct req_state* const s, const uint64_t op) { - if (s->iam_policy) { - if (s->iam_policy->eval(s->env, *s->auth.identity, op, - ARN(s->bucket)) == Effect::Allow) { - return 0; - } - } else if (s->auth.identity->is_owner_of(s->bucket_owner.get_id())) { + auto e = eval_or_pass(s->iam_policy, + s->env, *s->auth.identity, + op, ARN(s->bucket)); + if (e == Effect::Allow || + (e == Effect::Pass && + s->auth.identity->is_owner_of(s->bucket_owner.get_id()))) { return 0; + } else { + return -EACCES; } - return -EACCES; } @@ -1238,15 +1254,14 @@ bool verify_object_permission(struct req_state * const s, if (!verify_requester_payer_permission(s)) return false; - if (bucket_policy) { - auto r = bucket_policy->eval(s->env, *s->auth.identity, op, ARN(obj)); - if (r == Effect::Allow) - // It looks like S3 ACLs only GRANT permissions rather than - // denying them, so this should be safe. - return true; - else if (r == Effect::Deny) - return false; - } + + auto r = eval_or_pass(bucket_policy, s->env, *s->auth.identity, op, ARN(obj)); + if (r == Effect::Allow) + // It looks like S3 ACLs only GRANT permissions rather than + // denying them, so this should be safe. + return true; + else if (r == Effect::Deny) + return false; const auto perm = op_to_perm(op);