From 5b9f1281a3bfe3e75bd4ecd2d3983543396d119d Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Fri, 27 Oct 2017 22:48:18 -0400 Subject: [PATCH] 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) --- src/rgw/rgw_common.cc | 65 ++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 25 deletions(-) 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); -- 2.47.3