summaryrefslogtreecommitdiffstats
path: root/src/rgw
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2012-02-28 21:37:27 +0100
committerYehuda Sadeh <yehuda@hq.newdream.net>2012-02-28 21:37:27 +0100
commitcc935180247753f6d66b9f8adec3b7b63a261143 (patch)
treef18ce297640e7e837cb8f0815d2b1dcfd340950a /src/rgw
parentrgw: swift read acls allow bucket listing (diff)
downloadceph-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.cc17
-rw-r--r--src/rgw/rgw_acl.h20
-rw-r--r--src/rgw/rgw_acl_s3.cc59
-rw-r--r--src/rgw/rgw_acl_s3.h1
-rw-r--r--src/rgw/rgw_acl_swift.cc37
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);
}
}
}