diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 9e1ce6808c9..60364be2b69 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -704,46 +704,6 @@ int rgw_statfs(struct rgw_fs *rgw_fs, return 0; } -/* XXX can't call these virtual methods from non-REST handler */ -static int valid_s3_bucket_name(const string& name, bool relaxed=false) -{ - // This function enforces Amazon's spec for bucket names. - // (The requirements, not the recommendations.) - int len = name.size(); - if (len < 3) { - // Name too short - return -ERR_INVALID_BUCKET_NAME; - } else if (len > 255) { - // Name too long - return -ERR_INVALID_BUCKET_NAME; - } - - // bucket names must start with a number, letter, or underscore - if (!(isalpha(name[0]) || isdigit(name[0]))) { - if (!relaxed) - return -ERR_INVALID_BUCKET_NAME; - else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-')) - return -ERR_INVALID_BUCKET_NAME; - } - - for (const char *s = name.c_str(); *s; ++s) { - char c = *s; - if (isdigit(c) || (c == '.')) - continue; - if (isalpha(c)) - continue; - if ((c == '-') || (c == '_')) - continue; - // Invalid character - return -ERR_INVALID_BUCKET_NAME; - } - - if (looks_like_ip_address(name.c_str())) - return -ERR_INVALID_BUCKET_NAME; - - return 0; -} - /* generic create -- create an empty regular file */ diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index fe70fa71790..1cafcfb04dd 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -1219,18 +1219,6 @@ public: }; /* RGWDeleteBucketRequest */ -static inline bool valid_s3_object_name(const string& name) { - if (name.size() > 1024) { - // Name too long - return false; - } - if (check_utf8(name.c_str(), name.size())) { - // Object names must be valid UTF-8. - return false; - } - return true; -} - /* put object */ diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 7c798f36019..9cbbd860aac 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2508,7 +2508,7 @@ int RGWHandler_REST_S3::postauth_init() ret = validate_tenant_name(s->bucket_tenant); if (ret) return ret; - ret = validate_bucket_name(s->bucket_name, relaxed_names); + ret = valid_s3_bucket_name(s->bucket_name, relaxed_names); if (ret) return ret; ret = validate_object_name(s->object.name); @@ -2521,55 +2521,30 @@ int RGWHandler_REST_S3::postauth_init() ret = validate_tenant_name(s->src_tenant_name); if (ret) return ret; - ret = validate_bucket_name(s->src_bucket_name, relaxed_names); + ret = valid_s3_bucket_name(s->src_bucket_name, relaxed_names); if (ret) return ret; } return 0; } -int RGWHandler_REST_S3::validate_bucket_name(const string& bucket, - bool relaxed_names) -{ - int ret = RGWHandler_REST::validate_bucket_name(bucket); - if (ret < 0) - return ret; - - if (bucket.size() == 0) - return 0; - - // bucket names must start with a number, letter, or underscore - if (!(isalpha(bucket[0]) || isdigit(bucket[0]))) { - if (!relaxed_names) - return -ERR_INVALID_BUCKET_NAME; - else if (!(bucket[0] == '_' || bucket[0] == '.' || bucket[0] == '-')) - return -ERR_INVALID_BUCKET_NAME; - } - - for (const char *s = bucket.c_str(); *s; ++s) { - char c = *s; - if (isdigit(c) || (c == '.')) - continue; - if (isalpha(c)) - continue; - if ((c == '-') || (c == '_')) - continue; - // Invalid character - return -ERR_INVALID_BUCKET_NAME; - } - - if (looks_like_ip_address(bucket.c_str())) - return -ERR_INVALID_BUCKET_NAME; - - return 0; -} - int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s, - RGWClientIO *cio) + RGWClientIO *cio) { int ret; s->dialect = "s3"; + + ret = validate_tenant_name(s->bucket_tenant); + if (ret) + return ret; + bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names; + ret = valid_s3_bucket_name(s->bucket_name, relaxed_names); + if (ret) + return ret; + ret = validate_object_name(s->object.name); + if (ret) + return ret; const char *cacl = s->info.env->get("HTTP_X_AMZ_ACL"); if (cacl) diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index e7b23d08b17..129934a9fdb 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -416,11 +416,9 @@ public: RGWHandler_REST_S3() : RGWHandler_REST() {} virtual ~RGWHandler_REST_S3() {} - int validate_bucket_name(const string& bucket, bool relaxed_names); - int get_errordoc(const string& errordoc_key, string* error_content); + int validate_bucket_name(const string& bucket, bool relaxed_names) = delete; + int get_errordoc(const string& errordoc_key, string* error_content); - using RGWHandler_REST::validate_bucket_name; - virtual int init(RGWRados *store, struct req_state *s, RGWClientIO *cio); virtual int authorize() { return RGW_Auth_S3::authorize(store, s); @@ -530,4 +528,53 @@ static inline bool looks_like_ip_address(const char *bucket) return (num_periods == 3); } +static inline bool valid_s3_object_name(const string& name) { + if (name.size() > 1024) { + return false; + } + if (check_utf8(name.c_str(), name.size())) { + return false; + } + return true; +} + +static inline int valid_s3_bucket_name(const string& name, bool relaxed=false) +{ + // This function enforces Amazon's spec for bucket names. + // (The requirements, not the recommendations.) + int len = name.size(); + if (len < 3) { + // Name too short + return -ERR_INVALID_BUCKET_NAME; + } else if (len > 255) { + // Name too long + return -ERR_INVALID_BUCKET_NAME; + } + + // bucket names must start with a number, letter, or underscore + if (!(isalpha(name[0]) || isdigit(name[0]))) { + if (!relaxed) + return -ERR_INVALID_BUCKET_NAME; + else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-')) + return -ERR_INVALID_BUCKET_NAME; + } + + for (const char *s = name.c_str(); *s; ++s) { + char c = *s; + if (isdigit(c) || (c == '.')) + continue; + if (isalpha(c)) + continue; + if ((c == '-') || (c == '_')) + continue; + // Invalid character + return -ERR_INVALID_BUCKET_NAME; + } + + if (looks_like_ip_address(name.c_str())) + return -ERR_INVALID_BUCKET_NAME; + + return 0; +} + #endif /* CEPH_RGW_REST_S3_H */