Skip to content

Commit

Permalink
rgw: Fix evaluation of bucket management permissions
Browse files Browse the repository at this point in the history
I spent some more time looking through the documentation of how work
is evaluated, and the examples on

<http://docs.aws.amazon.com/AmazonS3/latest/dev/
access-control-auth-workflow-bucket-operation.html>

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 <aemerson@redhat.com>
(cherry picked from commit 343a25a)
  • Loading branch information
adamemerson committed Jan 5, 2018
1 parent febd39c commit 5b9f128
Showing 1 changed file with 40 additions and 25 deletions.
65 changes: 40 additions & 25 deletions src/rgw/rgw_common.cc
Expand Up @@ -1123,6 +1123,19 @@ bool verify_requester_payer_permission(struct req_state *s)
return false;
}

namespace {
Effect eval_or_pass(const optional<Policy>& 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,
Expand All @@ -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);

Expand Down Expand Up @@ -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;
}


Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 5b9f128

Please sign in to comment.