From 757926a19ff5517ff1bd157227b5c2bb80ef22ce Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 23 Jun 2011 17:04:47 -0700 Subject: [PATCH] rgw: restructure permissions verification apparently 100-continue was broken --- src/rgw/rgw_main.cc | 11 ++- src/rgw/rgw_op.cc | 204 ++++++++++++++++++++++++++++-------------- src/rgw/rgw_op.h | 18 ++++ src/rgw/rgw_os_auth.h | 1 + src/rgw/rgw_user.cc | 5 ++ src/rgw/rgw_user.h | 5 ++ 6 files changed, 177 insertions(+), 67 deletions(-) diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index b29999fa2a9d2..eded7648884b2 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -112,11 +112,18 @@ int main(int argc, const char **argv) abort_early(&s, ret); goto done; } - if (s.expect_cont) - dump_continue(&s); op = handler->get_op(); if (op) { + ret = op->verify_permission(); + if (ret < 0) { + abort_early(&s, ret); + goto done; + } + + if (s.expect_cont) + dump_continue(&s); + op->execute(); } else { abort_early(&s, -ERR_METHOD_NOT_ALLOWED); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f79099a13e065..f0ca94a9fd901 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -204,16 +204,19 @@ int read_acls(struct req_state *s, bool only_bucket) return ret; } +int RGWGetObj::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_READ)) + return -EACCES; + + return 0; +} + void RGWGetObj::execute() { void *handle = NULL; rgw_obj obj; - if (!verify_permission(s, RGW_PERM_READ)) { - ret = -EACCES; - goto done; - } - ret = get_params(); if (ret < 0) goto done; @@ -274,6 +277,11 @@ int RGWGetObj::init_common() return 0; } +int RGWListBuckets::verify_permission() +{ + return 0; +} + void RGWListBuckets::execute() { ret = rgw_read_user_buckets(s->user.user_id, buckets, !!(s->prot_flags & RGW_REST_OPENSTACK)); @@ -295,6 +303,14 @@ void RGWListBuckets::execute() send_response(); } +int RGWStatBucket::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_READ)) + return -EACCES; + + return 0; +} + void RGWStatBucket::execute() { RGWUserBuckets buckets; @@ -317,15 +333,18 @@ void RGWStatBucket::execute() send_response(); } +int RGWListBucket::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_READ)) + return -EACCES; + + return 0; +} + void RGWListBucket::execute() { string no_ns; - if (!verify_permission(s, RGW_PERM_READ)) { - ret = -EACCES; - goto done; - } - url_decode(s->args.get("prefix"), prefix); marker = s->args.get("marker"); max_keys = s->args.get(limit_opt_name); @@ -355,6 +374,14 @@ done: send_response(); } +int RGWCreateBucket::verify_permission() +{ + if (!rgw_user_is_authenticated(s->user)) + return -EACCES; + + return 0; +} + void RGWCreateBucket::execute() { RGWAccessControlPolicy policy, old_policy; @@ -412,15 +439,18 @@ done: send_response(); } +int RGWDeleteBucket::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_WRITE)) + return -EACCES; + + return 0; +} + void RGWDeleteBucket::execute() { ret = -EINVAL; - if (!verify_permission(s, RGW_PERM_WRITE)) { - abort_early(s, -EACCES); - return; - } - if (s->bucket) { ret = rgwstore->delete_bucket(s->user.user_id, s->bucket_str); @@ -473,6 +503,13 @@ static int drain_pending(std::list& pending) return ret; } +int RGWPutObj::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_WRITE)) + return -EACCES; + + return 0; +} void RGWPutObj::execute() { @@ -492,11 +529,6 @@ void RGWPutObj::execute() RGWAccessControlPolicy policy; - if (!verify_permission(s, RGW_PERM_WRITE)) { - ret = -EACCES; - goto done; - } - ret = policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl); if (!ret) { ret = -EINVAL; @@ -639,6 +671,14 @@ done: send_response(); } +int RGWDeleteObj::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_WRITE)) + return -EACCES; + + return 0; +} + void RGWDeleteObj::execute() { ret = -EINVAL; @@ -677,46 +717,44 @@ static bool parse_copy_source(const char *src, string& bucket, string& object) return true; } -int RGWCopyObj::init_common() +int RGWCopyObj::verify_permission() { - RGWAccessControlPolicy dest_policy; - bufferlist aclbl; - bufferlist bl; - RGWAccessControlPolicy src_policy; string empty_str; - time_t mod_time; - time_t unmod_time; - time_t *mod_ptr = NULL; - time_t *unmod_ptr = NULL; + RGWAccessControlPolicy src_policy; + RGWAccessControlPolicy dest_policy; - if (!verify_permission(s, RGW_PERM_WRITE)) { - ret = -EACCES; - return ret; - } + if (!::verify_permission(s, RGW_PERM_WRITE)) + return -EACCES; ret = dest_policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl); - if (!ret) { - ret = -EINVAL; - return ret; - } + if (!ret) + return -EINVAL; ret = parse_copy_source(s->copy_source, src_bucket, src_object); - if (!ret) { - ret = -EINVAL; - return ret; - } + if (!ret) + return -EINVAL; + /* just checking the bucket's permission */ ret = read_acls(s, &src_policy, src_bucket, empty_str); if (ret < 0) return ret; - if (!verify_permission(&src_policy, s->user.user_id, s->perm_mask, RGW_PERM_READ)) { - ret = -EACCES; - return ret; - } + if (!::verify_permission(&src_policy, s->user.user_id, s->perm_mask, RGW_PERM_READ)) + return -EACCES; dest_policy.encode(aclbl); + return 0; +} + + +int RGWCopyObj::init_common() +{ + time_t mod_time; + time_t unmod_time; + time_t *mod_ptr = NULL; + time_t *unmod_ptr = NULL; + if (if_mod) { if (parse_time(if_mod, &mod_time) < 0) { ret = -EINVAL; @@ -766,13 +804,16 @@ done: send_response(); } -void RGWGetACLs::execute() +int RGWGetACLs::verify_permission() { - if (!verify_permission(s, RGW_PERM_READ_ACP)) { - abort_early(s, -EACCES); - return; - } + if (!::verify_permission(s, RGW_PERM_READ_ACP)) + return -EACCES; + return 0; +} + +void RGWGetACLs::execute() +{ ret = read_acls(s); if (ret < 0) { @@ -868,6 +909,14 @@ static int rebuild_policy(ACLOwner *owner, RGWAccessControlPolicy& src, RGWAcces return 0; } +int RGWPutACLs::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_WRITE_ACP)) + return -EACCES; + + return 0; +} + void RGWPutACLs::execute() { bufferlist bl; @@ -881,11 +930,6 @@ void RGWPutACLs::execute() ACLOwner owner; rgw_obj obj; - if (!verify_permission(s, RGW_PERM_WRITE_ACP)) { - ret = -EACCES; - goto done; - } - ret = 0; if (!parser.init()) { @@ -965,6 +1009,14 @@ done: send_response(); } +int RGWInitMultipart::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_WRITE)) + return -EACCES; + + return 0; +} + void RGWInitMultipart::execute() { bufferlist bl; @@ -979,11 +1031,6 @@ void RGWInitMultipart::execute() if (!s->object) goto done; - if (!verify_permission(s, RGW_PERM_WRITE)) { - ret = -EACCES; - goto done; - } - ret = policy.create_canned(s->user.user_id, s->user.display_name, s->canned_acl); if (!ret) { ret = -EINVAL; @@ -1056,6 +1103,14 @@ static int get_multiparts_info(struct req_state *s, string& meta_oid, map xattrs; @@ -1229,6 +1300,14 @@ done: send_response(); } +int RGWListBucketMultiparts::verify_permission() +{ + if (!::verify_permission(s, RGW_PERM_READ)) + return -EACCES; + + return 0; +} + void RGWListBucketMultiparts::execute() { vector objs; @@ -1238,11 +1317,6 @@ void RGWListBucketMultiparts::execute() if (ret < 0) goto done; - if (!verify_permission(s, RGW_PERM_READ)) { - ret = -EACCES; - goto done; - } - if (s->prot_flags & RGW_REST_OPENSTACK) { string path_args = s->args.get("path"); if (!path_args.empty()) { diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 88be7db45f94a..8f91cc604d83f 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -43,6 +43,7 @@ public: virtual void init(struct req_state *s) { this->s = s; } + virtual int verify_permission() = 0; virtual void execute() = 0; }; @@ -96,6 +97,7 @@ public: void set_get_data(bool get_data) { this->get_data = get_data; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -114,6 +116,7 @@ public: } RGWListBuckets() {} + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -147,6 +150,7 @@ public: objs.clear(); common_prefixes.clear(); } + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -166,6 +170,7 @@ public: RGWStatBucket() {} ~RGWStatBucket() {} + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -178,6 +183,7 @@ protected: public: RGWCreateBucket() {} + int verify_permission(); void execute(); virtual void init(struct req_state *s) { RGWOp::init(s); @@ -197,6 +203,7 @@ public: RGWOp::init(s); ret = 0; } + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -223,6 +230,7 @@ public: supplied_md5_b64 = NULL; etag = ""; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -241,12 +249,14 @@ public: RGWOp::init(s); ret = 0; } + int verify_permission(); void execute(); virtual void send_response() = 0; }; class RGWCopyObj : public RGWOp { + bufferlist aclbl; protected: const char *if_mod; const char *if_unmod; @@ -284,6 +294,7 @@ public: src_object.clear(); mtime = 0; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -303,6 +314,7 @@ public: ret = 0; acls.clear(); } + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -323,6 +335,7 @@ public: len = 0; data = NULL; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -342,6 +355,7 @@ public: ret = 0; upload_id = ""; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -367,6 +381,7 @@ public: data = NULL; len = 0; } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -384,6 +399,7 @@ public: RGWOp::init(s); ret = 0; } + int verify_permission(); void execute(); virtual void send_response() = 0; @@ -410,6 +426,7 @@ public: marker = 0; policy = RGWAccessControlPolicy(); } + int verify_permission(); void execute(); virtual int get_params() = 0; @@ -521,6 +538,7 @@ public: is_truncated = false; common_prefixes.clear(); } + int verify_permission(); void execute(); virtual int get_params() = 0; diff --git a/src/rgw/rgw_os_auth.h b/src/rgw/rgw_os_auth.h index 1dc311ce35bea..68329b86b975f 100644 --- a/src/rgw/rgw_os_auth.h +++ b/src/rgw/rgw_os_auth.h @@ -12,6 +12,7 @@ public: RGW_OS_Auth_Get() {} ~RGW_OS_Auth_Get() {} + int verify_permission() { return 0; } void execute(); }; diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index da2acb678eb1e..632b04520e671 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -33,6 +33,11 @@ void rgw_get_anon_user(RGWUserInfo& info) info.access_keys.clear(); } +bool rgw_user_is_authenticated(RGWUserInfo& info) +{ + return (info.user_id != RGW_USER_ANON_ID); +} + static int put_obj(string& uid, string& bucket, string& oid, const char *data, size_t size) { map attrs; diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index e9eb5d4ab1be5..41d7784d01e1d 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -36,6 +36,11 @@ WRITE_CLASS_ENCODER(RGWUID) * Get the anonymous (ie, unauthenticated) user info. */ extern void rgw_get_anon_user(RGWUserInfo& info); + +/** + * verify that user is an actual user, and not the anonymous user + */ +extern bool rgw_user_is_authenticated(RGWUserInfo& info); /** * Save the given user information to storage. * Returns: 0 on success, -ERR# on failure. -- 2.39.5