]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement swift public group
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 28 Feb 2012 20:37:27 +0000 (12:37 -0800)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 28 Feb 2012 20:37:27 +0000 (12:37 -0800)
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
src/rgw/rgw_acl.cc
src/rgw/rgw_acl.h
src/rgw/rgw_acl_s3.cc
src/rgw/rgw_acl_s3.h
src/rgw/rgw_acl_swift.cc

index 0b2b55a834c32ee4979794ea0d37fe2629f44685..5f37727b7b22ac8cb7304d530fb30e2c78524b6b 100644 (file)
@@ -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);
index e8907e8e71491e049f804dbb67f51a44a5df2815..abbd94ef6672f18ae9c365f33e8b4e177a74dd80 100644 (file)
@@ -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);
   }
index dff96304eefc426bf0c9b3564417a5023d42749a..d81cc21c398eddc1b3142ff80df69dffaa18a3bf 100644 (file)
@@ -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;
         }
       }
index 98b78c84eaae5d80fecf154fb2c7932c04605cc7..79ee3547da27208f2b44fd678535eb9898c51d6d 100644 (file)
@@ -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
index a0038ff9c338230e5eb2d9da5a881670bbf5a22d..644f29d48e5c98cd1c5a3e35c10d223933a90f44 100644 (file)
@@ -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);
     }
   }
 }