summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSubha sree Mohankumar <smohanku@redhat.com>2017-11-02 15:09:37 +0530
committerAmar Tumballi <amarts@redhat.com>2017-12-02 12:03:28 +0000
commit09cb795587772b60ba102f4369ab3f4501cdc01a (patch)
tree09c3c7bbd4ca9772f890780d13320d41d5e68bdd
parent59d1cc720f52357f7a6f20bb630febc6a622c99c (diff)
storage/posix : options to override umask
Options "create-mask" and "create-directory-mask" are added to remove the mode bits set on a file or directory when its created. Default value of these options is 0777. Options "force-create-mode" and "force-create-directory" sets the default permission for a file or directory irrespective of the clients umask. Default value of these options is 0000. Command to set option: volume set <volume name> storage.<option-name> <value> The valid value range from 0000 to 0777. Updates #301 Change-Id: Ia33d13f2117202ca55a056c747ccc3674eb8bae1 Signed-off-by: Subha sree Mohankumar <smohanku@redhat.com>
-rw-r--r--tests/bugs/glusterfs/bug-1482528.t100
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c22
-rw-r--r--xlators/storage/posix/src/posix.c142
-rw-r--r--xlators/storage/posix/src/posix.h7
4 files changed, 258 insertions, 13 deletions
diff --git a/tests/bugs/glusterfs/bug-1482528.t b/tests/bugs/glusterfs/bug-1482528.t
new file mode 100644
index 00000000000..3adf260bdcd
--- /dev/null
+++ b/tests/bugs/glusterfs/bug-1482528.t
@@ -0,0 +1,100 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+
+cleanup
+#Basic checks
+TEST glusterd
+TEST pidof glusterd
+
+#Create a distributed volume
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1..2}
+TEST $CLI volume start $V0
+
+# Mount FUSE without selinux:
+TEST glusterfs -s $H0 --volfile-id $V0 $@ $M0
+
+TEST touch $M0/default.txt
+EXPECT "644" stat -c %a $M0/default.txt
+
+TEST chmod 0444 $M0/default.txt
+EXPECT "444" stat -c %a $M0/default.txt
+
+TEST mkdir $M0/default
+EXPECT "755" stat -c %a $M0/default
+
+TEST chmod 0444 $M0/default
+EXPECT "444" stat -c %a $M0/default
+
+TEST mkfifo $M0/mkfifo
+EXPECT "644" stat -c %a $M0/mkfifo
+
+TEST mknod $M0/dmknod b 4 5
+EXPECT "644" stat -c %a $M0/dmknod
+
+#Set the create-directory-mask and create-mask options
+TEST $CLI volume set $V0 storage.create-directory-mask 0444
+TEST $CLI volume set $V0 storage.create-mask 0444
+
+TEST mkdir $M0/create-directory
+EXPECT "444" stat -c %a $M0/create-directory
+
+TEST touch $M0/create-mask.txt
+EXPECT "444" stat -c %a $M0/create-mask.txt
+
+TEST chmod 0777 $M0/create-mask.txt
+EXPECT "444" stat -c %a $M0/create-mask.txt
+
+TEST chmod 0400 $M0/create-mask.txt
+EXPECT "400" stat -c %a $M0/create-mask.txt
+
+TEST chmod 0777 $M0/create-directory
+EXPECT "444" stat -c %a $M0/create-directory
+
+TEST chmod 0400 $M0/create-directory
+EXPECT "400" stat -c %a $M0/create-directory
+
+TEST mkfifo $M0/cfifo
+EXPECT "444" stat -c %a $M0/cfifo
+
+TEST chmod 0777 $M0/cfifo
+EXPECT "444" stat -c %a $M0/cfifo
+
+TEST mknod $M0/cmknod b 4 5
+EXPECT "444" stat -c %a $M0/cmknod
+
+#set force-create-mode and force-directory-mode options
+TEST $CLI volume set $V0 storage.force-create-mode 0777
+TEST $CLI volume set $V0 storage.force-directory-mode 0333
+
+TEST touch $M0/force-create-mode.txt
+EXPECT "777" stat -c %a $M0/force-create-mode.txt
+
+TEST mkdir $M0/force-directory
+EXPECT "777" stat -c %a $M0/force-directory
+
+TEST chmod 0222 $M0/force-create-mode.txt
+EXPECT "777" stat -c %a $M0/force-create-mode.txt
+
+TEST chmod 0222 $M0/force-directory
+EXPECT "333" stat -c %a $M0/force-directory
+
+TEST mkdir $M0/link
+TEST ln -s $M0/force-create-mode.txt $M0/link
+EXPECT "777" stat -c %a $M0/link/force-create-mode.txt
+
+TEST ln $M0/force-create-mode.txt $M0/link/fc.txt
+EXPECT "777" stat -c %a $M0/link/fc.txt
+
+TEST setfacl -m o:r $M0/force-create-mode.txt
+EXPECT "777" stat -c %a $M0/force-create-mode.txt
+
+TEST ln -s $M0/force-directory $M0/link
+EXPECT "777" stat -c %a $M0/link/force-directory
+
+TEST mkfifo $M0/ffifo
+EXPECT "777" stat -c %a $M0/ffifo
+
+TEST mknod $M0/mknod b 4 5
+EXPECT "777" stat -c %a $M0/mknod
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 8ec8a3125ee..7750914705e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1,4 +1,4 @@
-/*
+ /*
Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
@@ -2823,6 +2823,26 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_4_0_0,
},
+ { .option = "force-create-mode",
+ .key = "storage.force-create-mode",
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
+ { .option = "force-directory-mode",
+ .key = "storage.force-directory-mode",
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
+ { .option = "create-mask",
+ .key = "storage.create-mask",
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
+ { .option = "create-directory-mask",
+ .key = "storage.create-directory-mask",
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
{ .key = "storage.bd-aio",
.voltype = "storage/bd",
.op_version = 3
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 0435d7a677f..3b03779f305 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -394,14 +394,27 @@ out:
return 0;
}
+static inline mode_t override_umask (mode_t mode, mode_t mode_bit)
+{
+ gf_msg_debug ("posix", 0, "The value of mode is %u", mode);
+ mode = mode >> 9; /* 3x3 (bits for each octal digit)*/
+ mode = (mode << 9) | mode_bit;
+ gf_msg_debug ("posix", 0, "The value of mode is %u", mode);
+ return mode;
+}
+
static int
posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf)
{
int32_t ret = -1;
mode_t mode = 0;
+ mode_t mode_bit = 0;
+ struct posix_private *priv = NULL;
struct stat stat;
int is_symlink = 0;
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
ret = sys_lstat (path, &stat);
if (ret != 0) {
gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_LSTAT_FAILED,
@@ -412,7 +425,17 @@ posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf)
if (S_ISLNK (stat.st_mode))
is_symlink = 1;
- mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type);
+ if (S_ISDIR (stat.st_mode)) {
+ mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type);
+ mode_bit = (mode & priv->create_directory_mask)
+ | priv->force_directory_mode;
+ mode = override_umask(mode, mode_bit);
+ } else {
+ mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type);
+ mode_bit = (mode & priv->create_mask)
+ | priv->force_create_mode;
+ mode = override_umask(mode, mode_bit);
+ }
ret = lchmod (path, mode);
if ((ret == -1) && (errno == ENOSYS)) {
/* in Linux symlinks are always in mode 0777 and no
@@ -633,10 +656,20 @@ int32_t
posix_do_fchmod (xlator_t *this,
int fd, struct iatt *stbuf)
{
- mode_t mode = 0;
+ int32_t ret = -1;
+ mode_t mode = 0;
+ mode_t mode_bit = 0;
+ struct posix_private *priv = NULL;
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type);
- return sys_fchmod (fd, mode);
+ mode_bit = (mode & priv->create_mask)
+ | priv->force_create_mode;
+ mode = override_umask (mode, mode_bit);
+ ret = sys_fchmod (fd, mode);
+out:
+ return ret;
}
static int
@@ -1392,6 +1425,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
gf_boolean_t linked = _gf_false;
gf_loglevel_t level = GF_LOG_NONE;
+ mode_t mode_bit = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -1405,11 +1439,13 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
out);
MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
+ mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
+ mode = override_umask (mode, mode_bit);
+
gid = frame->root->gid;
SET_FS_ID (frame->root->uid, gid);
DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
-
if (!real_path || !par_path) {
op_ret = -1;
op_errno = ESTALE;
@@ -1452,9 +1488,9 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
real_op:
#ifdef __NetBSD__
- if (S_ISFIFO(mode))
- op_ret = mkfifo (real_path, mode);
- else
+ if (S_ISFIFO(mode))
+ op_ret = mkfifo (real_path, mode);
+ else
#endif /* __NetBSD__ */
op_ret = sys_mknod (real_path, mode, dev);
@@ -1600,6 +1636,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
char pgfid[GF_UUID_BUF_SIZE] = {0};
char value_buf[4096] = {0,};
gf_boolean_t have_val = _gf_false;
+ mode_t mode_bit = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -1643,6 +1680,10 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
SET_FS_ID (frame->root->uid, gid);
+ mode_bit = (priv->create_directory_mask & mode)
+ | priv->force_directory_mode;
+ mode = override_umask (mode, mode_bit);
+
if (xdata) {
op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
if (!op_ret && !gf_uuid_compare (stbuf.ia_gfid, uuid_req)) {
@@ -3089,6 +3130,7 @@ posix_create (call_frame_t *frame, xlator_t *this,
int nlink_samepgfid = 0;
char * pgfid_xattr_key = NULL;
gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
+ mode_t mode_bit = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -3143,6 +3185,9 @@ posix_create (call_frame_t *frame, xlator_t *this,
if (priv->o_direct)
_flags |= O_DIRECT;
+
+ mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
+ mode = override_umask (mode, mode_bit);
_fd = sys_open (real_path, _flags, mode);
if (_fd == -1) {
@@ -3312,7 +3357,7 @@ posix_open (call_frame_t *frame, xlator_t *this,
if (priv->o_direct)
flags |= O_DIRECT;
- _fd = sys_open (real_path, flags, 0);
+ _fd = sys_open (real_path, flags, priv->force_create_mode);
if (_fd == -1) {
op_ret = -1;
op_errno = errno;
@@ -7176,10 +7221,13 @@ reconfigure (xlator_t *this, dict_t *options)
int32_t uid = -1;
int32_t gid = -1;
char *batch_fsync_mode_str = NULL;
- char *gfid2path_sep = NULL;
-
- priv = this->private;
+ char *gfid2path_sep = NULL;
+ int32_t force_create_mode = -1;
+ int32_t force_directory_mode = -1;
+ int32_t create_mask = -1;
+ int32_t create_directory_mask = -1;
+ priv = this->private;
GF_OPTION_RECONF ("brick-uid", uid, options, int32, out);
GF_OPTION_RECONF ("brick-gid", gid, options, int32, out);
if (uid != -1 || gid != -1)
@@ -7258,8 +7306,23 @@ reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count,
options, int32, out);
+ GF_OPTION_RECONF ("force-create-mode", force_create_mode,
+ options, int32, out);
+ priv->force_create_mode = force_create_mode;
+
+ GF_OPTION_RECONF ("force-directory-mode", force_directory_mode,
+ options, int32, out);
+ priv->force_directory_mode = force_directory_mode;
+
+ GF_OPTION_RECONF ("create-mask", create_mask,
+ options, int32, out);
+ priv->create_mask = create_mask;
- ret = 0;
+ GF_OPTION_RECONF ("create-directory-mask", create_directory_mask,
+ options, int32, out);
+ priv->create_directory_mask = create_directory_mask;
+
+ ret = 0;
out:
return ret;
}
@@ -7401,6 +7464,10 @@ init (xlator_t *this)
int32_t gid = -1;
char *batch_fsync_mode_str;
char *gfid2path_sep = NULL;
+ int force_create = -1;
+ int force_directory = -1;
+ int create_mask = -1;
+ int create_directory_mask = -1;
dir_data = dict_get (this->options, "directory");
@@ -7919,6 +7986,19 @@ init (xlator_t *this)
GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec,
uint32, out);
+ GF_OPTION_INIT ("force-create-mode", force_create, int32, out);
+ _private->force_create_mode = force_create;
+
+ GF_OPTION_INIT ("force-directory-mode", force_directory, int32, out);
+ _private->force_directory_mode = force_directory;
+
+ GF_OPTION_INIT ("create-mask",
+ create_mask, int32, out);
+ _private->create_mask = create_mask;
+
+ GF_OPTION_INIT ("create-directory-mask",
+ create_directory_mask, int32, out);
+ _private->create_directory_mask = create_directory_mask;
out:
if (ret) {
if (_private) {
@@ -8190,5 +8270,43 @@ struct volume_options options[] = {
" Useful for displaying the proper usable size through statvfs() "
"call (df command)",
},
+ { .key = {"force-create-mode"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0000,
+ .max = 0777,
+ .default_value = "0000",
+ .validate = GF_OPT_VALIDATE_MIN,
+ .validate = GF_OPT_VALIDATE_MAX,
+ .description = "Mode bit permission that will always be set on a file."
+ },
+ { .key = {"force-directory-mode"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0000,
+ .max = 0777,
+ .default_value = "0000",
+ .validate = GF_OPT_VALIDATE_MIN,
+ .validate = GF_OPT_VALIDATE_MAX,
+ .description = "Mode bit permission that will be always set on directory"
+ },
+ { .key = {"create-mask"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0000,
+ .max = 0777,
+ .default_value = "0777",
+ .validate = GF_OPT_VALIDATE_MIN,
+ .validate = GF_OPT_VALIDATE_MAX,
+ .description = "Any bit not set here will be removed from the"
+ "modes set on a file when it is created"
+ },
+ { .key = {"create-directory-mask"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0000,
+ .max = 0777,
+ .default_value = "0777",
+ .validate = GF_OPT_VALIDATE_MIN,
+ .validate = GF_OPT_VALIDATE_MAX,
+ .description = "Any bit not set here will be removed from the"
+ "modes set on a directory when it is created"
+ },
{ .key = {NULL} }
};
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 8db87f1de9f..e2f1dfa2dd1 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -232,6 +232,13 @@ struct posix_private {
/* Option to handle the cases of multiple bricks exported from
same backend. Very much usable in brick-splitting feature. */
int32_t shared_brick_count;
+
+ /*Option to set mode bit permission that will always be set on
+ file/directory. */
+ mode_t force_create_mode;
+ mode_t force_directory_mode;
+ mode_t create_mask;
+ mode_t create_directory_mask;
};
typedef struct {