]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Feature 3667: Support extra canned acls.
authorcaleb miles <caselim@gmail.com>
Tue, 5 Feb 2013 19:10:03 +0000 (14:10 -0500)
committerYehuda Sadeh <yehuda@inktank.com>
Thu, 7 Feb 2013 22:54:39 +0000 (14:54 -0800)
Support the bucket-owner-read and bucket-owner-full
canned acls.

Signed-off-by caleb miles <caleb.miles@inktank.com>
Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_acl_s3.cc
src/rgw/rgw_acl_s3.h
src/rgw/rgw_common.h
src/rgw/rgw_log.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index e1c81e73ac8d3ba9c0330e195d7a125cf48b983c..8ae57307d7c8a961bfb5ec6f059ef4234ec1e9ae 100644 (file)
@@ -264,20 +264,25 @@ bool RGWAccessControlList_S3::xml_end(const char *el) {
   return true;
 }
 
-bool RGWAccessControlList_S3::create_canned(string id, string name, string canned_acl)
+bool RGWAccessControlList_S3::create_canned(ACLOwner& owner, ACLOwner& bucket_owner, const string& canned_acl)
 {
   acl_user_map.clear();
   grant_map.clear();
 
+  ACLGrant owner_grant;
+
+  string bid = bucket_owner.get_id();
+  string bname = bucket_owner.get_display_name();
+
   /* owner gets full control */
-  ACLGrant grant;
-  grant.set_canon(id, name, RGW_PERM_FULL_CONTROL);
-  add_grant(&grant);
+  owner_grant.set_canon(owner.get_id(), owner.get_display_name(), RGW_PERM_FULL_CONTROL);
+  add_grant(&owner_grant);
 
   if (canned_acl.size() == 0 || canned_acl.compare("private") == 0) {
     return true;
   }
 
+  ACLGrant bucket_owner_grant;
   ACLGrant group_grant;
   if (canned_acl.compare("public-read") == 0) {
     group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_READ);
@@ -290,6 +295,14 @@ bool RGWAccessControlList_S3::create_canned(string id, string name, string canne
   } else if (canned_acl.compare("authenticated-read") == 0) {
     group_grant.set_group(ACL_GROUP_AUTHENTICATED_USERS, RGW_PERM_READ);
     add_grant(&group_grant);
+  } else if (canned_acl.compare("bucket-owner-read") == 0) {
+    bucket_owner_grant.set_canon(bid, bname, RGW_PERM_READ);
+    if (bid.compare(owner.get_id()) != 0)
+      add_grant(&bucket_owner_grant);
+  } else if (canned_acl.compare("bucket-owner-full-control") == 0) {
+    bucket_owner_grant.set_canon(bid, bname, RGW_PERM_FULL_CONTROL);
+    if (bid.compare(owner.get_id()) != 0)
+      add_grant(&bucket_owner_grant);
   } else {
     return false;
   }
index 1e2ffe4324203380546db04fb7bf6dbfb378f5f4..453f68161f0e213b3fa7dc8213b24c8636a21920 100644 (file)
@@ -66,7 +66,7 @@ public:
     out << "</AccessControlList>";
   }
 
-  bool create_canned(string id, string name, string canned_acl);
+  bool create_canned(ACLOwner& owner, ACLOwner& bucket_owner, const string& canned_acl);
 };
 
 class ACLOwner_S3 : public ACLOwner, public XMLObj
@@ -104,11 +104,11 @@ public:
   }
   int rebuild(RGWRados *store, ACLOwner *owner, RGWAccessControlPolicy& dest);
   bool compare_group_name(string& id, ACLGroupTypeEnum group);
-  virtual bool create_canned(string id, string name, string canned_acl) {
+
+  virtual bool create_canned(ACLOwner& _owner, ACLOwner& bucket_owner, string canned_acl) {
     RGWAccessControlList_S3& _acl = static_cast<RGWAccessControlList_S3 &>(acl);
-    bool ret = _acl.create_canned(id, name, canned_acl);
-    owner.set_id(id);
-    owner.set_name(name);
+    bool ret = _acl.create_canned(_owner, bucket_owner, canned_acl);
+    owner = _owner;
     return ret;
   }
 };
index 4b808fcbe745f657240f785dc81537d3ed392667..cd1ebaa71f6de5704c5b0cd4cb4e91f54902153d 100644 (file)
@@ -27,6 +27,7 @@
 #include <map>
 #include "include/types.h"
 #include "include/utime.h"
+#include "rgw_acl.h"
 
 using namespace std;
 
@@ -597,7 +598,8 @@ struct req_state {
    rgw_bucket bucket;
    string bucket_name_str;
    string object_str;
-   string bucket_owner;
+   ACLOwner bucket_owner;
+   ACLOwner owner;
 
    map<string, string> x_meta_map;
    bool has_bad_meta;
index e999f623a018b7abab7c28d4be3be4a6e61a76ac..474d83e421e304672ac42f0a008d0173af2595a2 100644 (file)
@@ -172,7 +172,7 @@ static void log_usage(struct req_state *s, const string& op_name)
   string user;
 
   if (s->bucket_name)
-    user = s->bucket_owner;
+    user = s->bucket_owner.get_id();
   else
     user = s->user.user_id;
 
@@ -304,7 +304,8 @@ int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name, OpsL
   entry.user = s->user.user_id;
   if (s->object_acl)
     entry.object_owner = s->object_acl->get_owner().get_id();
-  entry.bucket_owner = s->bucket_owner;
+  entry.bucket_owner = s->bucket_acl->get_owner().get_id();
+
 
   uint64_t bytes_sent = s->cio->get_bytes_sent();
   uint64_t bytes_received = s->cio->get_bytes_received();
index cfb7d177926f513331eab2cdbc4fd4ad5c17caf5..ad62c661ca1d76a3b9bcf5262fee8f6615e74abb 100644 (file)
@@ -287,6 +287,7 @@ int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, b
 {
   int ret = 0;
   string obj_str;
+  RGWUserInfo bucket_owner_info;
 
   s->bucket_acl = new RGWAccessControlPolicy(s->cct);
 
@@ -298,7 +299,19 @@ int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, b
       return ret;
     }
     s->bucket = bucket_info.bucket;
-    s->bucket_owner = bucket_info.owner;
+
+    if (s->user.user_id.compare(bucket_info.owner) != 0) {
+      ret = rgw_get_user_info_by_uid(store, bucket_info.owner, bucket_owner_info);
+      if (ret < 0) {
+        ldout(s->cct, 0) << "NOTICE: couldn't get bucket owner info for (id=" << bucket_info.owner << ")" << dendl;
+        return ret;
+      }
+
+      s->bucket_owner.set_id(bucket_info.owner);
+      s->bucket_owner.set_name(bucket_owner_info.display_name);
+    } else {
+      s->bucket_owner = s->owner;
+    }
 
     string no_obj;
     RGWAccessControlPolicy bucket_acl(s->cct);
@@ -773,7 +786,7 @@ void RGWListBucket::execute()
 
 int RGWGetBucketLogging::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner) != 0)
+  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -811,7 +824,9 @@ void RGWCreateBucket::execute()
   if (ret < 0)
     return;
 
-  s->bucket_owner = s->user.user_id;
+  s->bucket_owner.set_id(s->user.user_id);
+  s->bucket_owner.set_name(s->user.display_name);
+
   r = get_policy_from_attr(s->cct, store, s->obj_ctx, &old_policy, obj);
   if (r >= 0)  {
     if (old_policy.get_owner().get_id().compare(s->user.user_id) != 0) {
index bdba0e9c8f425136adeaf9fcf72b111dbb94ff5b..ed192310bb778d0a43f0b23d4f8949a50d0178b9 100644 (file)
@@ -9,6 +9,7 @@
 #include "rgw_rest_s3.h"
 #include "rgw_acl.h"
 #include "rgw_policy_s3.h"
+#include "rgw_user.h"
 
 #include "common/armor.h"
 
@@ -279,7 +280,8 @@ void RGWStatBucket_ObjStore_S3::send_response()
 int RGWCreateBucket_ObjStore_S3::get_params()
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
-  int r = s3policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl);
+
+  int r = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
   if (r < 0)
     return r;
 
@@ -315,7 +317,7 @@ int RGWPutObj_ObjStore_S3::get_params()
   if (!s->length)
     return -ERR_LENGTH_REQUIRED;
 
-  int r = s3policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl);
+  int r = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
   if (!r)
      return -EINVAL;
 
@@ -898,6 +900,8 @@ int RGWPostObj_ObjStore_S3::get_policy()
     }
 
     s->user = user_info;
+    s->owner.set_id(user_info.user_id);
+    s->owner.set_name(user_info.display_name);
   } else {
     ldout(s->cct, 0) << "No attached policy found!" << dendl;
   }
@@ -907,7 +911,7 @@ int RGWPostObj_ObjStore_S3::get_policy()
 
   RGWAccessControlPolicy_S3 s3policy(s->cct);
   ldout(s->cct, 20) << "canned_acl=" << canned_acl << dendl;
-  if (!s3policy.create_canned(s->user.user_id, "", canned_acl)) {
+  if (!s3policy.create_canned(s->owner, s->bucket_owner, canned_acl)) {
     err_msg = "Bad canned ACLs";
     return -EINVAL;
   }
@@ -1114,7 +1118,7 @@ int RGWCopyObj_ObjStore_S3::init_dest_policy()
   RGWAccessControlPolicy_S3 s3policy(s->cct);
 
   /* build a policy for the target object */
-  ret = s3policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl);
+  ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
   if (!ret)
      return -EINVAL;
 
@@ -1197,7 +1201,16 @@ void RGWGetACLs_ObjStore_S3::send_response()
 int RGWPutACLs_ObjStore_S3::get_canned_policy(ACLOwner& owner, stringstream& ss)
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
-  bool r = s3policy.create_canned(owner.get_id(), owner.get_display_name(), s->canned_acl);
+
+  // bucket-* canned acls do not apply to bucket
+  if (s->object_str.empty()) {
+    if (s->canned_acl.find("bucket") != string::npos)
+      s->canned_acl.clear();
+  }
+
+  bool r;
+  r = s3policy.create_canned(owner, s->bucket_owner, s->canned_acl);
+
   if (!r)
     return -EINVAL;
 
@@ -1218,7 +1231,7 @@ void RGWPutACLs_ObjStore_S3::send_response()
 int RGWInitMultipart_ObjStore_S3::get_params()
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
-  ret = s3policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl);
+  ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
   if (!ret)
      return -EINVAL;
 
@@ -1868,6 +1881,10 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
     return -EPERM;
   }
 
+  // populate the owner info
+  s->owner.set_id(s->user.user_id);
+  s->owner.set_name(s->user.display_name);
+
   /* now verify signature */
    
   string auth_hdr;
index daa8037f065f1d7a6d9a12c8cb6a9a27862b5a38..aa4608692222a595dc857a514cd8c1b9c9572e70 100644 (file)
@@ -161,6 +161,7 @@ public:
   ~RGWPutACLs_ObjStore_S3() {}
 
   int get_canned_policy(ACLOwner& owner, stringstream& ss);
+
   void send_response();
 };