Bug 1490921

Summary: 'Condition' block doesn't work as expected in bucket policy
Product: [Red Hat Storage] Red Hat Ceph Storage Reporter: shilpa <smanjara>
Component: RGWAssignee: Adam C. Emerson <aemerson>
Status: CLOSED NOTABUG QA Contact: Vidushi Mishra <vimishra>
Severity: medium Docs Contact:
Priority: high    
Version: 3.0CC: aemerson, anharris, cbodley, ceph-eng-bugs, hnallurv, kbader, mbenjamin, owasserm, smanjara, sweil
Target Milestone: rc   
Target Release: 3.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-10-02 17:27:22 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description shilpa 2017-09-12 13:32:48 UTC
Description of problem:
Write a bucket policy, for example s3:GetObjectVersion to allow access to object versions and specify a condition to allow access to only a particular versionID. The 'Condition' block does not have any effect on the policy.

Version-Release number of selected component (if applicable):
ceph-radosgw-12.2.0-2.el7cp.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Write a bucket policy to allow another user to access a versioned object in a bucket
2. Specify a condition that only a particular versionID can be accessed in either 'Allow' or 'Deny' mode.
3. Apply the policy on the bucket and test object access with the user that is given permission to.

Actual results:
The policy gives access to all versions of the object instead of denying them.

Expected results:
The policy should give access only to the version id specified in the 'Condition' block

Additional info:

Bucket policy with 'Allow' Effect:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "statement1",
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:ListBucket","s3:GetObjectVersion"],
    "Resource": [
      "arn:aws:s3::*:my-version-bucket",
      "arn:aws:s3::*:my-version-bucket/hello"
    ]
  },
  {
    "Sid": "statement2",
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:GetObjectVersion"],
    "Resource": ["arn:aws:s3::*:my-version-bucket/hello"],
    "Condition": {
                "StringEquals": {
                    "s3:VersionId": "nZQ7BSTYen8ynko13xOZPlpc39QIDy8"
                }
            }
      }
 ]
}

With bucket owner credentials set in s3cmd, set the policy on the bucket

# s3cmd -c s3test.cfg setpolicy getversioncondition  s3://my-version-bucket

Boto script used to test:

#vi getversion.py

conn = boto.connect_s3(
        aws_access_key_id = '8JYYLOKNFCO25OB7EF56',
        aws_secret_access_key = 'VCOSOCuH7uGqv40AMH8ZHpRWPP3OhBKnq4QR2Mlp',
        host = 'magna089',
        port = 8080,
        is_secure=False,
        calling_format = boto.s3.connection.OrdinaryCallingFormat(),
        )

b = conn.get_bucket("testx:my-version-bucket")
key = b.get_key('hello', version_id='eA9oO6SlnXJ8TO6mu-Dm8foT7dZPcMr') 
key.get_contents_to_filename('hello_download')


# python getversion.py
<Bucket: testx:my-version-bucket>
Key downloaded

In the script, when I gave a different versionID from the one mentioned in the policy, the policy allowed the download. 

Similarly, a 'Deny' Effect seems to show the same behaviour. 

Bucket policy with 'Deny' Effect:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "statement1",
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:ListBucket","s3:GetObjectVersion"],
    "Resource": [
      "arn:aws:s3::*:my-version-bucket",
      "arn:aws:s3::*:my-version-bucket/hello"
    ]
  },
  {
    "Sid": "statement2",
    "Effect": "Deny",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:GetObjectVersion"],
    "Resource": ["arn:aws:s3::*:my-version-bucket/hello"],
    "Condition": {
                "StringNotEquals": {
                    "s3:VersionId": "nZQ7BSTYen8ynko13xOZPlpc39QIDy8"
                }
            }
      }
 ]
}

Comment 2 shilpa 2017-09-14 11:45:55 UTC
Tried "s3:DeleteObjectVersion" with a condition block in 'Allow' statement. Deleting the object verisonID specified fails with '403 Forbidden' error. However "s3:DeleteObjectVersion" works when there is no object versionID specified in the policy

 
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:ListBucket"],
    "Resource": [
      "arn:aws:s3::*:test"]
    },
{
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam::testy:user/u2"]},
    "Action": ["s3:DeleteObjectVersion"],
    "Resource": [
      "arn:aws:s3::*:test/hello"
    ],
    "Condition": {
                "StringEquals": { 
                    "s3:VersionId": "wwj31ZSgGxl9VPB6f782b8qyZl.Mip5"
                }
            }
  }]
}


b = conn.get_bucket("testx:test")
b.delete_key('hello', version_id="wwj31ZSgGxl9VPB6f782b8qyZl.Mip5")

Traceback (most recent call last):
  File "deleteversion.py", line 26, in <module>
    b.delete_key('hello', version_id='wwj31ZSgGxl9VPB6f782b8qyZl.Mip5')
  File "/usr/lib/python2.7/site-packages/boto/s3/bucket.py", line 762, in delete_key
    query_args_l=None)
  File "/usr/lib/python2.7/site-packages/boto/s3/bucket.py", line 781, in _delete_key_internal
    response.reason, body)
boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><BucketName>test</BucketName><RequestId>tx0000000000000000000c1-0059ba67fa-5e4d-us-east</RequestId><HostId>5e4d-us-east-us</HostId></Error>



Logs:

2017-09-14 11:26:40.692458 7f2128151700 20 rgw::auth::s3::LocalEngine granted access
2017-09-14 11:26:40.692460 7f2128151700 20 rgw::auth::s3::AWSAuthStrategy granted access
2017-09-14 11:26:40.692462 7f2128151700  2 req 184:0.000116:s3:DELETE /testx:test/hello:delete_obj:normalizing buckets and tenants
2017-09-14 11:26:40.692464 7f2128151700 10 s->object=hello[wwj31ZSgGxl9VPB6f782b8qyZl.Mip5] s->bucket=testx/test
2017-09-14 11:26:40.692628 7f2128151700  5 Permissions for group not found
2017-09-14 11:26:40.692629 7f2128151700  5 -- Getting permissions done for identity=rgw::auth::SysReqApplier -> rgw::auth::LocalApplier(acct_user=testy$u2, acct_name=Test User, subuser=, perm_mask=15, is_admin=0), owner=testx$tester, perm=0
2017-09-14 11:26:40.692632 7f2128151700 10  identity=rgw::auth::SysReqApplier -> rgw::auth::LocalApplier(acct_user=testy$u2, acct_name=Test User, subuser=, perm_mask=15, is_admin=0) requested perm (type)=2, policy perm=0, user_perm_mask=2, acl perm=0
2017-09-14 11:26:40.692634 7f2128151700 20 op->ERRORHANDLER: err_no=-13 new_err_no=-13
2017-09-14 11:26:40.692771 7f2128151700  2 req 184:0.000425:s3:DELETE /testx:test/hello:delete_obj:op status=0
2017-09-14 11:26:40.692777 7f2128151700  2 req 184:0.000431:s3:DELETE /testx:test/hello:delete_obj:http status=403
2017-09-14 11:26:40.692780 7f2128151700  1 ====== req done req=0x7f212814b190 op status=0 http_status=403 ======
2017-09-14 11:26:40.692791 7f2128151700 20 process_request() returned -13

Comment 3 Adam C. Emerson 2017-09-14 16:42:54 UTC
There's a list of all supported condition keys in doc/radosgw/bucketpolicy.rgw

If it's not there, we don't expect it to work.

(We can always support more, but that's the list of things we claim to support.)

Comment 5 Adam C. Emerson 2017-09-28 18:31:05 UTC
What's the behavior when you use one of the keys listed as supported in bucketpolicy.rst?

For an unsupported key, the expected behavior is that it should deny the operation whatever the value is set to.

Comment 7 Adam C. Emerson 2017-10-02 17:27:22 UTC
Closing, since the described behavior is correct for an unsupported condition key.