summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcaleb miles <caselim@gmail.com>2013-02-05 14:10:03 -0500
committerYehuda Sadeh <yehuda@inktank.com>2013-02-07 14:54:39 -0800
commite345dfe04a64fcd0d37c9e0717b6714038c302ae (patch)
treecca893fa5ce8ac8b8bf2d806086eae3a9d8680ed
parent5896b971a386b62387db78411bac1b36173f3dd9 (diff)
downloadceph-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.cc21
-rw-r--r--src/rgw/rgw_acl_s3.h10
-rw-r--r--src/rgw/rgw_common.h4
-rw-r--r--src/rgw/rgw_log.cc5
-rw-r--r--src/rgw/rgw_op.cc21
-rw-r--r--src/rgw/rgw_rest_s3.cc29
-rw-r--r--src/rgw/rgw_rest_s3.h1
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();
};