]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: subuser permissions
authorYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 23 May 2011 22:12:48 +0000 (15:12 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 23 May 2011 22:12:48 +0000 (15:12 -0700)
src/rgw/rgw_admin.cc
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_rest_s3.cc

index d722c333f07eab31c7ec5986c8ff94ee669aad33..66237bd41e3a3c09b476044724d785e6ef7a1b1b 100644 (file)
@@ -41,6 +41,8 @@ void usage()
   cerr << "   --auth_uid=<auid>         librados uid\n";
   cerr << "   --secret=<key>            S3 key\n";
   cerr << "   --os-secret=<key>         OpenStack key\n";
+  cerr << "   --access=<access>         Set access permissions for sub-user, should be one\n";
+  cerr << "                             of read, write, readwrite, full\n";
   cerr << "   --display-name=<name>\n";
   cerr << "   --bucket=<bucket>\n";
   cerr << "   --object=<object>\n";
@@ -61,6 +63,59 @@ enum {
   OPT_LOG_SHOW,
 };
 
+static uint32_t str_to_perm(const char *str)
+{
+  if (strcasecmp(str, "read") == 0)
+    return RGW_PERM_READ;
+  else if (strcasecmp(str, "write") == 0)
+    return RGW_PERM_WRITE;
+  else if (strcasecmp(str, "readwrite") == 0)
+    return RGW_PERM_READ | RGW_PERM_WRITE;
+  else if (strcasecmp(str, "full") == 0)
+    return RGW_PERM_FULL_CONTROL;
+
+  usage();
+  return 0; // unreachable
+}
+
+struct rgw_flags_desc {
+  int mask;
+  const char *str;
+};
+
+static struct rgw_flags_desc rgw_perms[] = {
+ { RGW_PERM_FULL_CONTROL, "full-control" },
+ { RGW_PERM_READ | RGW_PERM_WRITE, "read-write" },
+ { RGW_PERM_READ, "read" },
+ { RGW_PERM_WRITE, "write" },
+ { RGW_PERM_READ_ACP, "read-acp" },
+ { RGW_PERM_WRITE_ACP, "read-acp" },
+ { 0, NULL }
+};
+
+static void perm_to_str(uint32_t mask, char *buf, int len)
+{
+  const char *sep = "";
+  int pos = 0;
+  while (mask) {
+    int orig_mask = mask;
+    for (int i = 0; rgw_perms[i].mask; i++) {
+      struct rgw_flags_desc *desc = &rgw_perms[i];
+      if ((mask & desc->mask) == desc->mask) {
+        pos += snprintf(buf + pos, len - pos, "%s%s", sep, desc->str);
+        if (pos == len)
+          return;
+        sep = ", ";
+        mask &= ~desc->mask;
+        if (!mask)
+          return;
+      }
+    }
+    if (mask == orig_mask) // no change
+      break;
+  }
+}
+
 static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
 {
   *need_more = false;
@@ -189,6 +244,8 @@ int main(int argc, char **argv)
   const char *openstack_key = 0;
   const char *date = 0;
   char *subuser = 0;
+  const char *access = 0;
+  uint32_t perm_mask = 0;
   uint64_t auid = 0;
   RGWUserInfo info;
   RGWAccess *store;
@@ -229,6 +286,9 @@ int main(int argc, char **argv)
       CEPH_ARGPARSE_SET_ARG_VAL(&openstack_key, OPT_STR);
     } else if (CEPH_ARGPARSE_EQ("date", '\0')) {
       CEPH_ARGPARSE_SET_ARG_VAL(&date, OPT_STR);
+    } else if (CEPH_ARGPARSE_EQ("access", '\0')) {
+      CEPH_ARGPARSE_SET_ARG_VAL(&access, OPT_STR);
+      perm_mask = str_to_perm(access);
     } else {
       if (!opt_cmd) {
         opt_cmd = get_cmd(CEPH_ARGPARSE_VAL, prev_cmd, &need_more);
@@ -366,6 +426,7 @@ int main(int argc, char **argv)
     if (subuser) {
       RGWSubUser u;
       u.name = subuser;
+      u.perm_mask = perm_mask;
 
       info.subusers[subuser] = u;
     }
@@ -389,6 +450,9 @@ int main(int argc, char **argv)
     for (uiter = info.subusers.begin(); uiter != info.subusers.end(); ++uiter) {
       RGWSubUser& u = uiter->second;
       cout << " Name: " << info.user_id << ":" << u.name << std::endl;
+      char buf[256];
+      perm_to_str(u.perm_mask, buf, sizeof(buf));
+      cout << " Permissions: " << buf << std::endl;
     }
     cout << "Display Name: " << info.display_name << std::endl;
     cout << "Email: " << info.user_email << std::endl;
index 2b09c72c503cb5ca995284583d9dc65094a03198..ebe9bd637196ff9007fcefc072be334743a63dba 100644 (file)
@@ -138,19 +138,19 @@ string& XMLArgs::get(const char *name)
   return get(s);
 }
 
-bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm)
+bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int user_perm_mask, int perm)
 {
    if (!policy)
      return false;
 
-   int acl_perm = policy->get_perm(uid, perm);
+   int acl_perm = policy->get_perm(uid, perm) & user_perm_mask;
 
    return (perm == acl_perm);
 }
 
 bool verify_permission(struct req_state *s, int perm)
 {
-  return verify_permission(s->acl, s->user.user_id, perm);
+  return verify_permission(s->acl, s->user.user_id, s->perm_mask, perm);
 }
 
 static char hex_to_num(char c)
index b4c4774d8aac2390141673dae40413682ab04a48..d8b049b30df55dc42eb01c53d51c3ec4413ccb08 100644 (file)
@@ -181,21 +181,21 @@ WRITE_CLASS_ENCODER(RGWAccessKey);
 
 struct RGWSubUser {
   string name;
-  uint32_t flags;
+  uint32_t perm_mask;
 
-  RGWSubUser() {}
+  RGWSubUser() : perm_mask(0) {}
   void encode(bufferlist& bl) const {
      __u32 ver = 1;
     ::encode(ver, bl);
     ::encode(name, bl);
-    ::encode(flags, bl);
+    ::encode(perm_mask, bl);
   }
 
   void decode(bufferlist::iterator& bl) {
      __u32 ver;
      ::decode(ver, bl);
      ::decode(name, bl);
-     ::decode(flags, bl);
+     ::decode(perm_mask, bl);
   }
 };
 WRITE_CLASS_ENCODER(RGWSubUser);
@@ -328,6 +328,7 @@ struct req_state {
    uint64_t bytes_received; // data received
    uint64_t obj_size;
    bool should_log;
+   uint32_t perm_mask;
 
    XMLArgs args;
 
@@ -434,7 +435,7 @@ static inline int rgw_str_to_bool(const char *s, int def_val)
 /** */
 extern int parse_time(const char *time_str, time_t *time);
 /** Check if a user has a permission on that ACL */
-extern bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm);
+extern bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int user_perm_mask, int perm);
 /** Check if the req_state's user has the necessary permissions
  * to do the requested action */
 extern bool verify_permission(struct req_state *s, int perm);
index 315273be9d36c1e99b39513cc971b52e25ac6514..bf07e7553457c7acf844f1b280e902af5c52c6ee 100644 (file)
@@ -118,7 +118,7 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, string& bucke
     if (ret < 0)
       return ret;
 
-    if (!verify_permission(&bucket_policy, s->user.user_id, RGW_PERM_READ))
+    if (!verify_permission(&bucket_policy, s->user.user_id, s->perm_mask, RGW_PERM_READ))
       ret = -EACCES;
     else
       ret = -ENOENT;
@@ -530,7 +530,7 @@ int RGWCopyObj::init_common()
   if (ret < 0)
     return ret;
 
-  if (!verify_permission(&src_policy, s->user.user_id, RGW_PERM_READ)) {
+  if (!verify_permission(&src_policy, s->user.user_id, s->perm_mask, RGW_PERM_READ)) {
     ret = -EACCES;
     return ret;
   }
@@ -813,6 +813,7 @@ void RGWHandler::init_state(struct req_state *s, struct fcgx_state *fcgx)
   s->os_groups = NULL;
   s->time = g_clock.now();
   s->user.clear();
+  s->perm_mask = 0;
 }
 
 int RGWHandler::do_read_permissions(bool only_bucket)
index fec2e4702af5fd59a71a3c6d627e6df35a81f38a..3d5f6e26bd3aa26d77a238431a15f326e6deebd7 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "rgw_rest.h"
 #include "rgw_rest_s3.h"
+#include "rgw_acl.h"
 
 #include "common/armor.h"
 
@@ -436,6 +437,17 @@ bool RGWHandler_REST_S3::authorize(struct req_state *s)
   const char *key = k.key.c_str();
   int key_len = k.key.size();
 
+  if (!k.subuser.empty()) {
+    map<string, RGWSubUser>::iterator uiter = s->user.subusers.find(k.subuser);
+    if (uiter == s->user.subusers.end()) {
+      RGW_LOG(0) << "ERROR: could not find subuser: " << k.subuser << dendl;
+      return false;
+    }
+    RGWSubUser& subuser = uiter->second;
+    s->perm_mask = subuser.perm_mask;
+  } else
+    s->perm_mask = RGW_PERM_FULL_CONTROL;
+
   char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
   calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);