summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLubomir Rintel <lubo.rintel@gooddata.com>2011-12-19 23:40:11 +0100
committerAnand Avati <avati@gluster.com>2012-01-12 09:12:38 -0800
commit919e3424849db2276e003dcd919a470838bf084f (patch)
treee06f45b4e855828e7180ce0cde932f2abcecbe17
parent8a78d969ee8b7c284751364d72496eec84c7290b (diff)
posix-acl: properly process umask in case client sent it
FUSE used to interpret the umask itself. That was a bad idea, since there are cases where umask is not applied, such as when extended POSIX ACLs are present and default ACLs are set on parent directory. The FUSE bridge was changed to send original mode with umask (alongside masked mode, for compatibility). If that is the case, we decide whether to apply the umask or not in the posix-acl translator depending on whether a default umask is set, or not. The original, broken, behavior is preserved in following cases: * Unpatched client (not sending umask with original mode) * Unpatched server (not understanding umask with original mode) * Old FUSE on client side (FUSE < 7.12 or linux < 2.6.31) (can not find out the umask and original mode) Change-Id: I2e3bfc4c7c9611bc51119ca5c8e28f6582677516 Signed-off-by: Lubomir Rintel <lubo.rintel@gooddata.com> Tested-by: Lubomir Rintel <lubo.rintel@gooddata.com> BUG: 765508 Reviewed-on: http://review.gluster.com/668 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c
index 7acd1b5f09a..9a425ff13dd 100644
--- a/xlators/system/posix-acl/src/posix-acl.c
+++ b/xlators/system/posix-acl/src/posix-acl.c
@@ -552,8 +552,21 @@ posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode,
int size_default = 0;
int size_access = 0;
mode_t retmode = 0;
+ int16_t tmp_mode = 0;
+ mode_t client_umask = 0;
retmode = mode;
+ ret = dict_get_int16 (params, "umask", &tmp_mode);
+ if (ret == 0) {
+ client_umask = (mode_t)tmp_mode;
+ ret = dict_get_int16 (params, "mode", &tmp_mode);
+ if (ret == 0) {
+ retmode = (mode_t)tmp_mode;
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "client sent umask, but not the original mode");
+ }
+ }
ret = posix_acl_get (loc->parent, this, NULL, &par_default);
@@ -566,7 +579,8 @@ posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode,
if (!acl_access)
goto out;
- retmode = posix_acl_inherit_mode (acl_access, mode);
+ client_umask = 0; // No umask if we inherit an ACL
+ retmode = posix_acl_inherit_mode (acl_access, retmode);
ctx->perm = retmode;
size_access = posix_acl_to_xattr (this, acl_access, NULL, 0);
@@ -615,6 +629,8 @@ set:
goto out;
out:
+ retmode &= ~client_umask;
+
if (par_default)
posix_acl_unref (this, par_default);
if (acl_access)
return -1; } if ((tmp & -tmp) != tmp) { answer = cli_cmd_get_confirmation(state, question3); if (answer == GF_ANSWER_NO) return -1; } return 0; } static int32_t cli_validate_disperse_volume (char *word, gf1_cluster_type type, const char **words, int32_t wordcount, int32_t index, int32_t *disperse_count, int32_t *redundancy_count, int32_t *data_count) { int ret = -1; switch (type) { case GF_CLUSTER_TYPE_NONE: case GF_CLUSTER_TYPE_DISPERSE: if (strcmp (word, "disperse") == 0) { if (*disperse_count >= 0) { cli_err ("disperse option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index + 1], disperse_count); if (ret == -1 && errno == EINVAL) { *disperse_count = 0; ret = 1; } else if (ret == -1) { goto out; } else { if (*disperse_count < 3) { cli_err ("disperse count must " "be greater than 2"); goto out; } ret = 2; } } else if (strcmp (word, "disperse-data") == 0) { if (*data_count >= 0) { cli_err ("disperse-data option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index+1], data_count); if (ret == -1 || *data_count < 2) { cli_err ("disperse-data must be greater than 1"); goto out; } ret = 2; } else if (strcmp (word, "redundancy") == 0) { if (*redundancy_count >= 0) { cli_err ("redundancy option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index+1], redundancy_count); if (ret == -1 || *redundancy_count < 1) { cli_err ("redundancy must be greater than 0"); goto out; } ret = 2; } break; case GF_CLUSTER_TYPE_STRIPE_REPLICATE: cli_err ("striped-replicated-dispersed volume " "is not supported"); goto out; case GF_CLUSTER_TYPE_TIER: cli_err ("tier-dispersed volume is not " "supported"); goto out; case GF_CLUSTER_TYPE_STRIPE: cli_err ("striped-dispersed volume is not " "supported"); goto out; case GF_CLUSTER_TYPE_REPLICATE: cli_err ("replicated-dispersed volume is not " "supported"); goto out; default: cli_err ("Invalid type given"); break; } out: return ret; } int32_t cli_validate_volname (const char *volname) { int32_t ret = -1; int32_t i = -1; static const char * const invalid_volnames[] = { "volume", "type", "subvolumes", "option", "end-volume", "all", "volume_not_in_ring", "description", "force", "snap-max-hard-limit", "snap-max-soft-limit", "auto-delete", "activate-on-create", NULL}; if (volname[0] == '-') goto out; for (i = 0; invalid_volnames[i]; i++) { if (!strcmp (volname, invalid_volnames[i])) { cli_err ("\"%s\" cannot be the name of a volume.", volname);