From: Abhishek Lekshmanan Date: Wed, 19 Jul 2017 15:06:24 +0000 (+0200) Subject: rgw_user: validate tenant names when creating user X-Git-Tag: v12.1.3~24^2~23^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d50ef542372f541ac9411f655cddd5fcab4dceac;p=ceph.git rgw_user: validate tenant names when creating user Also moved `validate_tenant_name` function from RGWHandler_REST to rgw_user, a new function called `rgw_validate_tenant_name` validates tenant names. There is special handling in rgw_admin to reraise -ERR_INVALID_TENANT to -EINVAL Signed-off-by: Abhishek Lekshmanan --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 1be1d1594ed..3c4c8bfeb8d 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -4375,6 +4375,9 @@ int main(int argc, const char **argv) ret = user.add(user_op, &err_msg); if (ret < 0) { cerr << "could not create user: " << err_msg << std::endl; + if (ret == -ERR_INVALID_TENANT_NAME) + ret = -EINVAL; + return -ret; } if (!subuser.empty()) { diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 505596242aa..f67a076c622 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -1834,18 +1834,6 @@ int RGWHandler_REST::allocate_formatter(struct req_state *s, return 0; } -int RGWHandler_REST::validate_tenant_name(string const& t) -{ - struct tench { - static bool is_good(char ch) { - return isalnum(ch) || ch == '_'; - } - }; - std::string::const_iterator it = - std::find_if_not(t.begin(), t.end(), tench::is_good); - return (it == t.end())? 0: -ERR_INVALID_TENANT_NAME; -} - // This function enforces Amazon's spec for bucket names. // (The requirements, not the recommendations.) int RGWHandler_REST::validate_bucket_name(const string& bucket) diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 615ececc595..f780ab4abac 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -501,7 +501,6 @@ public: RGWHandler_REST() {} ~RGWHandler_REST() override {} - static int validate_tenant_name(const string& bucket); static int validate_bucket_name(const string& bucket); static int validate_object_name(const string& object); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 51044e9a8f3..8141edfd0ee 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -3185,7 +3185,7 @@ int RGWHandler_REST_S3::postauth_init() << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl; int ret; - ret = validate_tenant_name(s->bucket_tenant); + ret = rgw_validate_tenant_name(s->bucket_tenant); if (ret) return ret; if (!s->bucket_name.empty()) { @@ -3200,7 +3200,7 @@ int RGWHandler_REST_S3::postauth_init() if (!t->src_bucket.empty()) { rgw_parse_url_bucket(t->src_bucket, s->user->user_id.tenant, s->src_tenant_name, s->src_bucket_name); - ret = validate_tenant_name(s->src_tenant_name); + ret = rgw_validate_tenant_name(s->src_tenant_name); if (ret) return ret; ret = valid_s3_bucket_name(s->src_bucket_name, relaxed_names); @@ -3216,8 +3216,8 @@ int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s, int ret; s->dialect = "s3"; - - ret = validate_tenant_name(s->bucket_tenant); + + ret = rgw_validate_tenant_name(s->bucket_tenant); if (ret) return ret; bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names; diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 90a829da5b9..220c349cbc1 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2557,7 +2557,7 @@ int RGWHandler_REST_SWIFT::postauth_init() << dendl; int ret; - ret = validate_tenant_name(s->bucket_tenant); + ret = rgw_validate_tenant_name(s->bucket_tenant); if (ret) return ret; ret = validate_bucket_name(s->bucket_name); diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 57f2dc227c4..e2ab8bf4321 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -542,6 +542,18 @@ uint32_t rgw_str_to_perm(const char *str) return RGW_PERM_INVALID; } +int rgw_validate_tenant_name(const string& t) +{ + struct tench { + static bool is_good(char ch) { + return isalnum(ch) || ch == '_'; + } + }; + std::string::const_iterator it = + std::find_if_not(t.begin(), t.end(), tench::is_good); + return (it == t.end())? 0: -ERR_INVALID_TENANT_NAME; +} + static bool validate_access_key(string& key) { const char *p = key.c_str(); @@ -1850,6 +1862,13 @@ int RGWUser::check_op(RGWUserAdminOpState& op_state, std::string *err_msg) return -EINVAL; } + int ret = rgw_validate_tenant_name(op_id.tenant); + if (ret) { + set_err_msg(err_msg, + "invalid tenant only alphanumeric and _ characters are allowed"); + return ret; + } + //set key type when it not set or set by context if ((op_state.get_key_type() < 0) || op_state.key_type_setbycontext) { op_state.set_key_type(KEY_TYPE_S3); diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index 7a27d0e7007..c6f15d0a46d 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -113,9 +113,6 @@ extern int rgw_get_user_attrs_by_uid(RGWRados *store, * Given an RGWUserInfo, deletes the user and its bucket ACLs. */ extern int rgw_delete_user(RGWRados *store, RGWUserInfo& user, RGWObjVersionTracker& objv_tracker); -/** - * Store a list of the user's buckets, with associated functinos. - */ /* * remove the different indexes @@ -125,14 +122,11 @@ extern int rgw_remove_uid_index(RGWRados *store, rgw_user& uid); extern int rgw_remove_email_index(RGWRados *store, string& email); extern int rgw_remove_swift_name_index(RGWRados *store, string& swift_name); -/* - * An RGWUser class along with supporting classes created - * to support the creation of an RESTful administrative API - */ - extern void rgw_perm_to_str(uint32_t mask, char *buf, int len); extern uint32_t rgw_str_to_perm(const char *str); +extern int rgw_validate_tenant_name(const string& t); + enum ObjectKeyType { KEY_TYPE_SWIFT, KEY_TYPE_S3, @@ -151,6 +145,10 @@ enum RGWUserId { RGW_ACCESS_KEY, }; +/* + * An RGWUser class along with supporting classes created + * to support the creation of an RESTful administrative API + */ struct RGWUserAdminOpState { // user attributes RGWUserInfo info;