diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2012-02-28 21:37:27 +0100 |
---|---|---|
committer | Yehuda Sadeh <yehuda@hq.newdream.net> | 2012-02-28 21:37:27 +0100 |
commit | cc935180247753f6d66b9f8adec3b7b63a261143 (patch) | |
tree | f18ce297640e7e837cb8f0815d2b1dcfd340950a /src/rgw | |
parent | rgw: swift read acls allow bucket listing (diff) | |
download | ceph-cc935180247753f6d66b9f8adec3b7b63a261143.tar.xz ceph-cc935180247753f6d66b9f8adec3b7b63a261143.zip |
rgw: implement swift public group
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Diffstat (limited to 'src/rgw')
-rw-r--r-- | src/rgw/rgw_acl.cc | 17 | ||||
-rw-r--r-- | src/rgw/rgw_acl.h | 20 | ||||
-rw-r--r-- | src/rgw/rgw_acl_s3.cc | 59 | ||||
-rw-r--r-- | src/rgw/rgw_acl_s3.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_acl_swift.cc | 37 |
5 files changed, 101 insertions, 33 deletions
diff --git a/src/rgw/rgw_acl.cc b/src/rgw/rgw_acl.cc index 0b2b55a834c..5f37727b7b2 100644 --- a/src/rgw/rgw_acl.cc +++ b/src/rgw/rgw_acl.cc @@ -24,16 +24,21 @@ void RGWAccessControlList::_add_grant(ACLGrant *grant) acl_group_map[grant->get_group()] |= perm.get_permissions(); break; default: - acl_user_map[grant->get_id()] |= perm.get_permissions(); + { + string id; + if (!grant->get_id(id)) { + dout(0) << "ERROR: grant->get_id() failed" << dendl; + } + acl_user_map[id] |= perm.get_permissions(); + } } } void RGWAccessControlList::add_grant(ACLGrant *grant) { - string id = grant->get_id(); - if (id.size() > 0) { - grant_map.insert(pair<string, ACLGrant>(id, *grant)); - } + string id; + grant->get_id(id); // not that this will return false for groups, but that's ok, we won't search groups + grant_map.insert(pair<string, ACLGrant>(id, *grant)); _add_grant(grant); } @@ -116,7 +121,7 @@ bool RGWAccessControlPolicy::verify_permission(string& uid, int user_perm_mask, } -ACLGroupTypeEnum ACLGrant::uri_to_group() +ACLGroupTypeEnum ACLGrant::uri_to_group(string& uri) { // this is required for backward compatibility return ACLGrant_S3::uri_to_group(uri); diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h index e8907e8e714..abbd94ef667 100644 --- a/src/rgw/rgw_acl.h +++ b/src/rgw/rgw_acl.h @@ -96,7 +96,6 @@ class ACLGrant protected: ACLGranteeType type; string id; - string uri; string email; ACLPermission permission; string name; @@ -108,14 +107,16 @@ public: /* there's an assumption here that email/uri/id encodings are different and there can't be any overlap */ - string& get_id() { + bool get_id(string& _id) { switch(type.get_type()) { case ACL_TYPE_EMAIL_USER: - return email; + _id = email; + return true; case ACL_TYPE_GROUP: - return uri; + return false; default: - return id; + _id = id; + return true; } } ACLGranteeType& get_type() { return type; } @@ -127,6 +128,7 @@ public: ::encode(struct_v, bl); ::encode(type, bl); ::encode(id, bl); + string uri; ::encode(uri, bl); ::encode(email, bl); ::encode(permission, bl); @@ -139,6 +141,7 @@ public: ::decode(struct_v, bl); ::decode(type, bl); ::decode(id, bl); + string uri; ::decode(uri, bl); ::decode(email, bl); ::decode(permission, bl); @@ -148,11 +151,11 @@ public: ::decode(g, bl); group = (ACLGroupTypeEnum)g; } else { - group = uri_to_group(); + group = uri_to_group(uri); } } - ACLGroupTypeEnum uri_to_group(); + ACLGroupTypeEnum uri_to_group(string& uri); void set_canon(string& _id, string& _name, int perm) { type.set(ACL_TYPE_CANON_USER); @@ -160,9 +163,8 @@ public: name = _name; permission.set_permissions(perm); } - void set_group(string& _uri, ACLGroupTypeEnum _group, int perm) { + void set_group(ACLGroupTypeEnum _group, int perm) { type.set(ACL_TYPE_GROUP); - uri = _uri; group = _group; permission.set_permissions(perm); } diff --git a/src/rgw/rgw_acl_s3.cc b/src/rgw/rgw_acl_s3.cc index dff96304eef..d81cc21c398 100644 --- a/src/rgw/rgw_acl_s3.cc +++ b/src/rgw/rgw_acl_s3.cc @@ -144,6 +144,7 @@ bool ACLGrant_S3::xml_end(const char *el) { ACLEmail_S3 *acl_email; ACLPermission_S3 *acl_permission; ACLDisplayName_S3 *acl_name; + string uri; acl_grantee = (ACLGrantee_S3 *)find_first("Grantee"); if (!acl_grantee) @@ -161,7 +162,6 @@ bool ACLGrant_S3::xml_end(const char *el) { id.clear(); name.clear(); - uri.clear(); email.clear(); switch (type.get_type()) { @@ -201,6 +201,8 @@ void ACLGrant_S3::to_xml(ostream& out) { if (!(perm.get_permissions() & RGW_PERM_ALL_S3)) return; + string uri; + out << "<Grant>" << "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"" << ACLGranteeType_S3::to_string(type) << "\">"; switch (type.get_type()) { @@ -214,7 +216,11 @@ void ACLGrant_S3::to_xml(ostream& out) { out << "<EmailAddress>" << email << "</EmailAddress>"; break; case ACL_TYPE_GROUP: - out << "<URI>" << uri << "</URI>"; + if (!group_to_uri(group, uri)) { + dout(0) << "ERROR: group_to_uri failed with group=" << (int)group << dendl; + break; + } + out << "<URI>" << uri << "</URI>"; break; default: break; @@ -224,6 +230,20 @@ void ACLGrant_S3::to_xml(ostream& out) { out << "</Grant>"; } +bool ACLGrant_S3::group_to_uri(ACLGroupTypeEnum group, string& uri) +{ + switch (group) { + case ACL_GROUP_ALL_USERS: + uri = rgw_uri_all_users; + return true; + case ACL_GROUP_AUTHENTICATED_USERS: + uri = rgw_uri_auth_users; + return true; + default: + return false; + } +} + ACLGroupTypeEnum ACLGrant_S3::uri_to_group(string& uri) { if (uri.compare(rgw_uri_all_users) == 0) @@ -260,15 +280,15 @@ bool RGWAccessControlList_S3::create_canned(string id, string name, string canne ACLGrant group_grant; if (canned_acl.compare("public-read") == 0) { - group_grant.set_group(rgw_uri_all_users, ACL_GROUP_ALL_USERS, RGW_PERM_READ); + group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_READ); add_grant(&group_grant); } else if (canned_acl.compare("public-read-write") == 0) { - group_grant.set_group(rgw_uri_all_users, ACL_GROUP_ALL_USERS, RGW_PERM_READ); + group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_READ); add_grant(&group_grant); - group_grant.set_group(rgw_uri_all_users, ACL_GROUP_ALL_USERS, RGW_PERM_WRITE); + group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_WRITE); add_grant(&group_grant); } else if (canned_acl.compare("authenticated-read") == 0) { - group_grant.set_group(rgw_uri_auth_users, ACL_GROUP_AUTHENTICATED_USERS, RGW_PERM_READ); + group_grant.set_group(ACL_GROUP_AUTHENTICATED_USERS, RGW_PERM_READ); add_grant(&group_grant); } else { return false; @@ -328,7 +348,11 @@ int RGWAccessControlPolicy_S3::rebuild(ACLOwner *owner, RGWAccessControlPolicy& switch (type.get_type()) { case ACL_TYPE_EMAIL_USER: { - string email = src_grant.get_id(); + string email; + if (!src_grant.get_id(email)) { + dout(0) << "ERROR: src_grant.get_id() failed" << dendl; + return -EINVAL; + } dout(10) << "grant user email=" << email << dendl; if (rgw_get_user_info_by_email(email, grant_user) < 0) { dout(10) << "grant user email not found or other error" << dendl; @@ -338,8 +362,12 @@ int RGWAccessControlPolicy_S3::rebuild(ACLOwner *owner, RGWAccessControlPolicy& } case ACL_TYPE_CANON_USER: { - if (type.get_type() == ACL_TYPE_CANON_USER) - uid = src_grant.get_id(); + if (type.get_type() == ACL_TYPE_CANON_USER) { + if (!src_grant.get_id(uid)) { + dout(0) << "ERROR: src_grant.get_id() failed" << dendl; + return -EINVAL; + } + } if (grant_user.user_id.empty() && rgw_get_user_info_by_uid(uid, grant_user) < 0) { dout(10) << "grant user does not exist:" << uid << dendl; @@ -348,20 +376,21 @@ int RGWAccessControlPolicy_S3::rebuild(ACLOwner *owner, RGWAccessControlPolicy& ACLPermission& perm = src_grant.get_permission(); new_grant.set_canon(uid, grant_user.display_name, perm.get_permissions()); grant_ok = true; - dout(10) << "new grant: " << new_grant.get_id() << ":" << grant_user.display_name << dendl; + string new_id; + new_grant.get_id(new_id); + dout(10) << "new grant: " << new_id << ":" << grant_user.display_name << dendl; } } break; case ACL_TYPE_GROUP: { - string group = src_grant.get_id(); - if (group.compare(RGW_URI_ALL_USERS) == 0 || - group.compare(RGW_URI_AUTH_USERS) == 0) { + string uri; + if (ACLGrant_S3::group_to_uri(src_grant.get_group(), uri)) { new_grant = src_grant; grant_ok = true; - dout(10) << "new grant: " << new_grant.get_id() << dendl; + dout(10) << "new grant: " << uri << dendl; } else { - dout(10) << "grant group does not exist:" << group << dendl; + dout(10) << "bad grant group:" << (int)src_grant.get_group() << dendl; return -EINVAL; } } diff --git a/src/rgw/rgw_acl_s3.h b/src/rgw/rgw_acl_s3.h index 98b78c84eaa..79ee3547da2 100644 --- a/src/rgw/rgw_acl_s3.h +++ b/src/rgw/rgw_acl_s3.h @@ -44,6 +44,7 @@ public: bool xml_start(const char *el, const char **attr); static ACLGroupTypeEnum uri_to_group(string& uri); + static bool group_to_uri(ACLGroupTypeEnum group, string& uri); }; class RGWAccessControlList_S3 : public RGWAccessControlList, public XMLObj diff --git a/src/rgw/rgw_acl_swift.cc b/src/rgw/rgw_acl_swift.cc index a0038ff9c33..644f29d48e5 100644 --- a/src/rgw/rgw_acl_swift.cc +++ b/src/rgw/rgw_acl_swift.cc @@ -12,6 +12,8 @@ using namespace std; #define SWIFT_PERM_READ RGW_PERM_READ_OBJS #define SWIFT_PERM_WRITE RGW_PERM_WRITE_OBJS +#define SWIFT_GROUP_ALL_USERS ".r:*" + static int parse_list(string& uid_list, vector<string>& uids) { char *s = strdup(uid_list.c_str()); @@ -30,6 +32,26 @@ static int parse_list(string& uid_list, vector<string>& uids) return 0; } +static bool uid_is_public(string& uid) +{ + if (uid[0] != '.' || uid[1] != 'r') + return false; + + int pos = uid.find(':'); + if (pos < 0 || pos == (int)uid.size()) + return false; + + string sub = uid.substr(0, pos); + string after = uid.substr(pos + 1); + + if (after.compare("*") != 0) + return false; + + return sub.compare(".r") == 0 || + sub.compare(".referer") == 0 || + sub.compare(".referrer") == 0; +} + void RGWAccessControlPolicy_SWIFT::add_grants(vector<string>& uids, int perm) { vector<string>::iterator iter; @@ -37,7 +59,10 @@ void RGWAccessControlPolicy_SWIFT::add_grants(vector<string>& uids, int perm) ACLGrant grant; RGWUserInfo grant_user; string& uid = *iter; - if (rgw_get_user_info_by_uid(uid, grant_user) < 0) { + if (uid_is_public(uid)) { + grant.set_group(ACL_GROUP_ALL_USERS, perm); + acl.add_grant(&grant); + } else if (rgw_get_user_info_by_uid(uid, grant_user) < 0) { dout(10) << "grant user does not exist:" << uid << dendl; /* skipping silently */ } else { @@ -84,14 +109,20 @@ void RGWAccessControlPolicy_SWIFT::to_str(string& read, string& write) for (iter = m.begin(); iter != m.end(); ++iter) { ACLGrant& grant = iter->second; int perm = grant.get_permission().get_permissions(); + string id; + if (!grant.get_id(id)) { + if (grant.get_group() != ACL_GROUP_ALL_USERS) + continue; + id = SWIFT_GROUP_ALL_USERS; + } if (perm & SWIFT_PERM_READ) { if (!read.empty()) read.append(", "); - read.append(grant.get_id()); + read.append(id); } else if (perm & SWIFT_PERM_WRITE) { if (!write.empty()) write.append(", "); - write.append(grant.get_id()); + write.append(id); } } } |