From cc2eed84a58a5fc29b211c7b1388c634881bf1d7 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Fri, 9 Aug 2019 13:51:01 -0700 Subject: [PATCH] Promote default ACL to enum This sanity checks ACLs during initialization and also omits sending the header when set to PRIVATE which is the default. --- doc/man/s3fs.1 | 1 - src/curl.cpp | 70 +++++++++++++++++++++++++++++++++++++++-------- src/curl.h | 20 ++++++++++++-- src/s3fs.cpp | 15 +++++----- src/s3fs_util.cpp | 3 +- 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/doc/man/s3fs.1 b/doc/man/s3fs.1 index b2c6978..6061a05 100644 --- a/doc/man/s3fs.1 +++ b/doc/man/s3fs.1 @@ -65,7 +65,6 @@ if it is not specified bucket name (and path) in command line, must specify this .TP \fB\-o\fR default_acl (default="private") the default canned acl to apply to all written s3 objects, e.g., "private", "public-read". -empty string means do not send header. see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl for the full list of canned acls. .TP \fB\-o\fR retries (default="5") diff --git a/src/curl.cpp b/src/curl.cpp index faf55c6..b0b6a3f 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -357,7 +357,7 @@ long S3fsCurl::connect_timeout = 300; // default time_t S3fsCurl::readwrite_timeout = 120; // default int S3fsCurl::retries = 5; // default bool S3fsCurl::is_public_bucket = false; -string S3fsCurl::default_acl = "private"; +acl_t S3fsCurl::default_acl = PRIVATE; storage_class_t S3fsCurl::storage_class = STANDARD; sseckeylist_t S3fsCurl::sseckeys; std::string S3fsCurl::ssekmsid; @@ -955,14 +955,14 @@ bool S3fsCurl::SetPublicBucket(bool flag) return old; } -string S3fsCurl::SetDefaultAcl(const char* acl) +acl_t S3fsCurl::SetDefaultAcl(acl_t acl) { - string old = S3fsCurl::default_acl; - S3fsCurl::default_acl = acl ? acl : ""; + acl_t old = S3fsCurl::default_acl; + S3fsCurl::default_acl = acl; return old; } -string S3fsCurl::GetDefaultAcl() +acl_t S3fsCurl::GetDefaultAcl() { return S3fsCurl::default_acl; } @@ -2959,8 +2959,8 @@ int S3fsCurl::PutHeadRequest(const char* tpath, headers_t& meta, bool is_copy) } // "x-amz-acl", storage class, sse - if(!S3fsCurl::default_acl.empty()){ - requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", S3fsCurl::default_acl.c_str()); + if(S3fsCurl::default_acl != PRIVATE){ + requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", acl_to_string(S3fsCurl::default_acl)); } if(REDUCED_REDUNDANCY == GetStorageClass()){ requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class", "REDUCED_REDUNDANCY"); @@ -3089,8 +3089,8 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd) } } // "x-amz-acl", storage class, sse - if(!S3fsCurl::default_acl.empty()){ - requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", S3fsCurl::default_acl.c_str()); + if(S3fsCurl::default_acl != PRIVATE){ + requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", acl_to_string(S3fsCurl::default_acl)); } if(REDUCED_REDUNDANCY == GetStorageClass()){ requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class", "REDUCED_REDUNDANCY"); @@ -3354,8 +3354,8 @@ int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string } } // "x-amz-acl", storage class, sse - if(!S3fsCurl::default_acl.empty()){ - requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", S3fsCurl::default_acl.c_str()); + if(S3fsCurl::default_acl != PRIVATE){ + requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-acl", acl_to_string(S3fsCurl::default_acl)); } if(REDUCED_REDUNDANCY == GetStorageClass()){ requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-storage-class", "REDUCED_REDUNDANCY"); @@ -4549,6 +4549,54 @@ string prepare_url(const char* url) return url_str; } +const char *acl_to_string(acl_t acl) +{ + switch(acl){ + case PRIVATE: + return "private"; + case PUBLIC_READ: + return "public-read"; + case PUBLIC_READ_WRITE: + return "public-read-write"; + case AWS_EXEC_READ: + return "aws-exec-read"; + case AUTHENTICATED_READ: + return "authenticated-read"; + case BUCKET_OWNER_READ: + return "bucket-owner-read"; + case BUCKET_OWNER_FULL_CONTROL: + return "bucket-owner-full-control"; + case LOG_DELIVERY_WRITE: + return "log-delivery-write"; + case INVALID_ACL: + return NULL; + } + abort(); +} + +acl_t string_to_acl(const char *acl) +{ + if(0 == strcmp(acl, "private")){ + return PRIVATE; + }else if(0 == strcmp(acl, "public-read")){ + return PUBLIC_READ; + }else if(0 == strcmp(acl, "public-read-write")){ + return PUBLIC_READ_WRITE; + }else if(0 == strcmp(acl, "aws-exec-read")){ + return AWS_EXEC_READ; + }else if(0 == strcmp(acl, "authenticated-read")){ + return AUTHENTICATED_READ; + }else if(0 == strcmp(acl, "bucket-owner-read")){ + return BUCKET_OWNER_READ; + }else if(0 == strcmp(acl, "bucket-owner-full-control")){ + return BUCKET_OWNER_FULL_CONTROL; + }else if(0 == strcmp(acl, "log-delivery-write")){ + return LOG_DELIVERY_WRITE; + }else{ + return INVALID_ACL; + } +} + /* * Local variables: * tab-width: 4 diff --git a/src/curl.h b/src/curl.h index 707f008..b3e3496 100644 --- a/src/curl.h +++ b/src/curl.h @@ -203,6 +203,18 @@ enum storage_class_t { REDUCED_REDUNDANCY }; +enum acl_t { + PRIVATE, + PUBLIC_READ, + PUBLIC_READ_WRITE, + AWS_EXEC_READ, + AUTHENTICATED_READ, + BUCKET_OWNER_READ, + BUCKET_OWNER_FULL_CONTROL, + LOG_DELIVERY_WRITE, + INVALID_ACL +}; + // sse type enum sse_type_t { SSE_DISABLE = 0, // not use server side encrypting @@ -258,7 +270,7 @@ class S3fsCurl static time_t readwrite_timeout; static int retries; static bool is_public_bucket; - static std::string default_acl; // TODO: to enum + static acl_t default_acl; static storage_class_t storage_class; static sseckeylist_t sseckeys; static std::string ssekmsid; @@ -407,8 +419,8 @@ class S3fsCurl static int SetRetries(int count); static bool SetPublicBucket(bool flag); static bool IsPublicBucket(void) { return S3fsCurl::is_public_bucket; } - static std::string SetDefaultAcl(const char* acl); - static std::string GetDefaultAcl(); + static acl_t SetDefaultAcl(acl_t acl); + static acl_t GetDefaultAcl(); static storage_class_t SetStorageClass(storage_class_t storage_class); static storage_class_t GetStorageClass() { return S3fsCurl::storage_class; } static bool LoadEnvSse(void) { return (S3fsCurl::LoadEnvSseCKeys() && S3fsCurl::LoadEnvSseKmsid()); } @@ -569,6 +581,8 @@ std::string get_header_value(const struct curl_slist* list, const std::string &k bool MakeUrlResource(const char* realpath, std::string& resourcepath, std::string& url); std::string prepare_url(const char* url); bool get_object_sse_type(const char* path, sse_type_t& ssetype, std::string& ssevalue); // implement in s3fs.cpp +const char *acl_to_string(acl_t acl); +acl_t string_to_acl(const char *acl); #endif // S3FS_CURL_H_ diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 37dff70..3743b79 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -4535,7 +4535,12 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar return 0; } if(0 == STR2NCMP(arg, "default_acl=")){ - const char* acl = strchr(arg, '=') + sizeof(char); + const char* acl_string = strchr(arg, '=') + sizeof(char); + acl_t acl = string_to_acl(acl_string); + if(acl == INVALID_ACL){ + S3FS_PRN_EXIT("unknown value for default_acl: %s", acl_string); + return -1; + } S3fsCurl::SetDefaultAcl(acl); return 0; } @@ -5292,12 +5297,8 @@ int main(int argc, char* argv[]) if(is_ibm_iam_auth){ // check that default ACL is either public-read or private - string defaultACL = S3fsCurl::GetDefaultAcl(); - if(defaultACL == "private"){ - // IBM's COS default ACL is private - // set acl as empty string to avoid sending x-amz-acl header - S3fsCurl::SetDefaultAcl(""); - }else if(defaultACL != "public-read"){ + acl_t defaultACL = S3fsCurl::GetDefaultAcl(); + if(defaultACL != PRIVATE && defaultACL != PUBLIC_READ){ S3FS_PRN_EXIT("can only use 'public-read' or 'private' ACL while using ibm_iam_auth"); S3fsCurl::DestroyS3fsCurl(); s3fs_destroy_global_ssl(); diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index a14c9b2..c99e208 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -1077,8 +1077,7 @@ void show_help () "\n" " default_acl (default=\"private\")\n" " - the default canned acl to apply to all written s3 objects,\n" - " e.g., private, public-read. empty string means do not send\n" - " header. see\n" + " e.g., private, public-read. see\n" " https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl\n" " for the full list of canned acls\n" "\n"