diff options
author | caleb miles <caselim@gmail.com> | 2013-02-05 14:10:03 -0500 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-02-07 14:54:39 -0800 |
commit | e345dfe04a64fcd0d37c9e0717b6714038c302ae (patch) | |
tree | cca893fa5ce8ac8b8bf2d806086eae3a9d8680ed | |
parent | 5896b971a386b62387db78411bac1b36173f3dd9 (diff) | |
download | ceph-e345dfe04a64fcd0d37c9e0717b6714038c302ae.tar.gz |
Feature 3667: Support extra canned acls.
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>
-rw-r--r-- | src/rgw/rgw_acl_s3.cc | 21 | ||||
-rw-r--r-- | src/rgw/rgw_acl_s3.h | 10 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 4 | ||||
-rw-r--r-- | src/rgw/rgw_log.cc | 5 | ||||
-rw-r--r-- | src/rgw/rgw_op.cc | 21 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 29 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.h | 1 |
7 files changed, 70 insertions, 21 deletions
diff --git a/src/rgw/rgw_acl_s3.cc b/src/rgw/rgw_acl_s3.cc index e1c81e73ac8..8ae57307d7c 100644 --- a/src/rgw/rgw_acl_s3.cc +++ b/src/rgw/rgw_acl_s3.cc @@ -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; } diff --git a/src/rgw/rgw_acl_s3.h b/src/rgw/rgw_acl_s3.h index 1e2ffe43242..453f68161f0 100644 --- a/src/rgw/rgw_acl_s3.h +++ b/src/rgw/rgw_acl_s3.h @@ -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; } }; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 4b808fcbe74..cd1ebaa71f6 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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; diff --git a/src/rgw/rgw_log.cc b/src/rgw/rgw_log.cc index e999f623a01..474d83e421e 100644 --- a/src/rgw/rgw_log.cc +++ b/src/rgw/rgw_log.cc @@ -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(); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index cfb7d177926..ad62c661ca1 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index bdba0e9c8f4..ed192310bb7 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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; diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index daa8037f065..aa460869222 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -161,6 +161,7 @@ public: ~RGWPutACLs_ObjStore_S3() {} int get_canned_policy(ACLOwner& owner, stringstream& ss); + void send_response(); }; |