Project

General

Profile

Bug #36530

Radosgw bucket policy does not work when applying to LDAP user

Added by Son Hai Ha over 2 years ago. Updated 28 days ago.

Status:
In Progress
Priority:
Normal
Assignee:
Target version:
-
% Done:

0%

Source:
Community (user)
Tags:
rgw, ldap, bucket policy
Backport:
Regression:
No
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
rgw
Pull request ID:
Crash signature:

Description

Hello,

I create a bucket by a normal rgw user (named ceph-dashboard) and then use the bucket policy to share that bucket to an LDAP user.

The detail on the bucket policy is as below:

[sonhaiha@DEFRXXXX500 ~]$ s3cmd -c .s3cfg-cephdb info s3://shared-bucket
s3://shared-bucket/ (bucket):
   Location:  us-east-1
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    {
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": ["arn:aws:iam:::user/sonhaiha"]},
    "Action": "s3:*",
    "Resource": [
      "arn:aws:s3:::shared-bucket",
      "arn:aws:s3:::shared-bucket/*" 
    ]
  }]
}

   CORS:      none
   ACL:       Ceph Dashboard: FULL_CONTROL

I found that, the rgw server does not found the permission for ldap user:

2018-10-15 10:43:36.521 7f3c65146700 15 decode_policy Read AccessControlPolicy<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>ceph-dashboard</ID><DisplayName>Ceph Dashboard</DisplayName></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>ceph-dashboard</ID><DisplayName>Ceph Dashboard</DisplayName></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>
2018-10-15 10:43:36.522 7f3c65146700  2 req 4:0.026275:s3:GET /shared-bucket/:list_bucket:recalculating target
2018-10-15 10:43:36.522 7f3c65146700  2 req 4:0.026288:s3:GET /shared-bucket/:list_bucket:reading permissions
2018-10-15 10:43:36.522 7f3c65146700  2 req 4:0.026291:s3:GET /shared-bucket/:list_bucket:init op
2018-10-15 10:43:36.522 7f3c65146700  2 req 4:0.026292:s3:GET /shared-bucket/:list_bucket:verifying op mask
2018-10-15 10:43:36.522 7f3c65146700 20 required_mask= 1 user.op_mask=7
2018-10-15 10:43:36.522 7f3c65146700  2 req 4:0.026295:s3:GET /shared-bucket/:list_bucket:verifying op permissions
2018-10-15 10:43:36.522 7f3c65146700 20 -- Getting permissions begin with perm_mask=49
2018-10-15 10:43:36.522 7f3c65146700  5 Searching permissions for identity=rgw::auth::SysReqApplier -> rgw::auth::RemoteApplier(acct_user=sonhaiha, acct_name=sonhaiha, perm_mask=15, is_admin=0) mask=49
2018-10-15 10:43:36.522 7f3c65146700  5 Searching permissions for uid=sonhaiha
2018-10-15 10:43:36.522 7f3c65146700  5 Permissions for user not found
2018-10-15 10:43:36.522 7f3c65146700  5 Searching permissions for uid=sonhaiha$sonhaiha
2018-10-15 10:43:36.522 7f3c65146700  5 Permissions for user not found
2018-10-15 10:43:36.522 7f3c65146700 20 from ACL got perm=0
2018-10-15 10:43:36.522 7f3c65146700  5 Searching permissions for group=1 mask=49
2018-10-15 10:43:36.522 7f3c65146700  5 Permissions for group not found
2018-10-15 10:43:36.522 7f3c65146700  5 Searching permissions for group=2 mask=49
2018-10-15 10:43:36.522 7f3c65146700  5 Permissions for group not found
2018-10-15 10:43:36.522 7f3c65146700  5 -- Getting permissions done for identity=rgw::auth::SysReqApplier -> rgw::auth::RemoteApplier(acct_user=sonhaiha, acct_name=sonhaiha, perm_mask=15, is_admin=0), owner=ceph-dashboard, perm=0

At first, I thought that it was because of the "type" of the users are different (rgw and ldap type) so the "principal" in the bucket policy has different format. But by exchanging email with some experienced users from the mailing list, they said that the format for principal should be the same. So I don't know where the problem could be. Below is the setting for our LDAP server.

rgw_ldap_binddn = CN=DE-SVCAAPdexLDAPBIND,OU=User,OU=ServiceAccounts,DC=example,DC=com
rgw_ldap_dnattr = name
rgw_ldap_searchdn = ou=Professional,ou=User,DC=example,DC=com
rgw_ldap_searchfilter = memberOf=CN=DE-SG ITS AAP Test Users,OU=Groups,DC=example,DC=com
rgw_ldap_secret = /etc/ceph/bindpass
rgw_ldap_uri = ldaps://DEFR2XXXX.example.com:636
rgw_s3_auth_use_ldap = True

If I use the ldap user to create the bucket and share it to the normal rgw user, it will work fine.

I think this could be a bug.

ldap_user_shares_bucket_to_rgw_user.log View (23.6 KB) Son Hai Ha, 10/19/2018 09:24 AM

rgw_user_shares_bucket_to_ldap_user.log View (20.2 KB) Son Hai Ha, 10/19/2018 09:24 AM

user_metadata.txt View (1.64 KB) Son Hai Ha, 10/19/2018 09:28 AM

History

#1 Updated by John Spray over 2 years ago

  • Project changed from Ceph to rgw

#2 Updated by Son Hai Ha over 2 years ago

We found a way to walk around. Because rgw looking for permission in both the 'emptyName' tenant and 'username$username', so we change the principal from:

"Principal": {"AWS": ["arn:aws:iam:::user/ldapuser"]}

to:
"Principal": {"AWS": ["arn:aws:iam::ldapuser:user/ldapuser"]}

Then it works well for LDAP user. I think this could be a bug, because with a normal rgw user created without tenant tag, we only need to specify:

"Principal": {"AWS": ["arn:aws:iam:::user/rgwuser"]}

for bucket policy to work.

Son Hai Ha wrote:

Hello,

I create a bucket by a normal rgw user (named ceph-dashboard) and then use the bucket policy to share that bucket to an LDAP user.

The detail on the bucket policy is as below:

[...]

I found that, the rgw server does not found the permission for ldap user:

[...]

At first, I thought that it was because of the "type" of the users are different (rgw and ldap type) so the "principal" in the bucket policy has different format. But by exchanging email with some experienced users from the mailing list, they said that the format for principal should be the same. So I don't know where the problem could be. Below is the setting for our LDAP server.

[...]

If I use the ldap user to create the bucket and share it to the normal rgw user, it will work fine.

I think this could be a bug.

#3 Updated by Matt Benjamin over 2 years ago

Thanks for narrowing this down. Adam?

Matt

#4 Updated by Adam Emerson over 2 years ago

  • Assignee set to Adam Emerson

#5 Updated by Thomas Kriechbaumer over 1 year ago

Yes - thank you! I was debugging this for over two weeks now until I found this ticket.

I would consider this a bug - as it not obvious that I have to specify the username twice!

#6 Updated by Dan Williams 5 months ago

Echoing Thomas's comments above it was quite frustrating to work this one out.
I guess it only applies if running in a multitenant setup.

Perhaps this could be as simple as updating the docs to show the namespace is required if using multitenancy?

#7 Updated by Ian Marsh about 1 month ago

This also appears to affect the assume role policy attached to a role in order to allow LDAP-authenticated users to use STS via the AssumeRole call. The same workaround - adding the username at the 5th part of the ARN (e.g. arn:aws:iam::myuser:user/myuser) - works. Tracking this down cost me several days; hopefully this comment will save someone else the trouble. Using local credentials instead of LDAP works as usual and does not work with only the workaround version of the ARN present.

#8 Updated by Matt Benjamin about 1 month ago

  • Status changed from New to In Progress

#9 Updated by Matt Benjamin about 1 month ago

Is there consensus that this issue would be resolved by (and demonstrates the need for) improvements in the documentation regarding user ARNs?

#10 Updated by Ian Marsh about 1 month ago

This doesn't appear to be correct behaviour to me, so no. You shouldn't have to specify the user name twice in the ARN when using LDAP, and once when using local authentication. There seems to be a bug in the policy evaluation when processing LDAP users?

#11 Updated by Matt Benjamin about 1 month ago

Thanks, Ian, I didn't pick up on that.

Matt

#12 Updated by Ian Marsh 28 days ago

I've tracked this peculiarity down to this bit of code:

https://github.com/ceph/ceph/blob/ae167bd496d7dc0a72a24d7c393c32c5420c6bc2/src/rgw/rgw_auth.cc#L507

bool rgw::auth::RemoteApplier::is_identity(const idset_t& ids) const {
  for (auto& id : ids) {
    if (id.is_wildcard()) {
      return true;

      // We also need to cover cases where rgw_keystone_implicit_tenants
      // was enabled. */
    } else if (id.is_tenant() &&
           (info.acct_user.tenant.empty() ?
        info.acct_user.id :
        info.acct_user.tenant) == id.get_tenant()) {
      return true;
    } else if (id.is_user() &&
           info.acct_user.id == id.get_id() &&
           (info.acct_user.tenant.empty() ?
        info.acct_user.id :
        info.acct_user.tenant) == id.get_tenant()) {
      return true;
    }
  }
  return false;
}

I don't know why an empty tenant field triggers a comparison between the user ID of the user we're checking and the tenant of the ARN we're matching against from the policy.

The "rgw_keystone_implicit_tenants" comment is interesting... my Ceph instance (which behaves incorrectly) has this set to false, I'm using LDAP and not Keystone, and besides there's no test in this code to check it is enabled, yet the behaviour of the code feels like it's implementing something along those lines.

For comparison, rgw::auth::LocalApplier simply does this:

https://github.com/ceph/ceph/blob/ae167bd496d7dc0a72a24d7c393c32c5420c6bc2/src/rgw/rgw_auth.cc#L683

    } else if (id.is_user() &&
           (id.get_tenant() == user_info.user_id.tenant)) {
      if (id.get_id() == user_info.user_id.id) {
        return true;
      }

Also available in: Atom PDF