From 5b5f03d2665687ab717f123da1266bcd3a83da0f Mon Sep 17 00:00:00 2001 From: Poornima G Date: Fri, 26 Feb 2016 06:42:14 -0500 Subject: fuse: Add a new mount option capability Originally all security.* xattrs were forbidden if selinux is disabled, which was causing Samba's acl_xattr module to not work, as it would store the NTACL in security.NTACL. To fix this http://review.gluster.org/#/c/12826/ was sent, which forbid only security.selinux. This opened up a getxattr call on security.capability before every write fop and others. Capabilities can be used without selinux, hence if selinux is disabled, security.capability cannot be forbidden. Hence adding a new mount option called capability. Only when "--capability" or "--selinux" mount option is used, security.capability is sent to the brick, else it is forbidden. Change-Id: I77f60e0fb541deaa416159e45c78dd2ae653105e BUG: 1309462 Signed-off-by: Poornima G Reviewed-on: http://review.gluster.org/13540 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra G --- glusterfsd/src/glusterfsd.c | 15 +++++++++ glusterfsd/src/glusterfsd.h | 1 + libglusterfs/src/glusterfs.h | 1 + tests/bugs/fuse/bug-1309462.t | 49 +++++++++++++++++++++++++++++ xlators/mount/fuse/src/fuse-bridge.c | 21 +++++++++++++ xlators/mount/fuse/src/fuse-bridge.h | 3 ++ xlators/mount/fuse/utils/mount_glusterfs.in | 7 +++++ 7 files changed, 97 insertions(+) create mode 100644 tests/bugs/fuse/bug-1309462.t diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 4edb5894c60..5df33c2476e 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -151,6 +151,8 @@ static struct argp_option gf_options[] = { "Mount the filesystem with POSIX ACL support"}, {"selinux", ARGP_SELINUX_KEY, 0, 0, "Enable SELinux label (extened attributes) support on inodes"}, + {"capability", ARGP_CAPABILITY_KEY, 0, 0, + "Enable Capability (extened attributes) support on inodes"}, {"print-netgroups", ARGP_PRINT_NETGROUPS, "NETGROUP-FILE", 0, "Validate the netgroups file and print it out"}, @@ -366,6 +368,15 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options) } } + if (cmd_args->capability) { + ret = dict_set_static_ptr (options, "capability", "on"); + if (ret < 0) { + gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4, + "capability"); + goto err; + } + } + if (cmd_args->aux_gfid_mount) { ret = dict_set_static_ptr (options, "virtual-gfid-access", "on"); @@ -794,6 +805,10 @@ parse_opts (int key, char *arg, struct argp_state *state) gf_remember_xlator_option ("*-md-cache.cache-selinux=true"); break; + case ARGP_CAPABILITY_KEY: + cmd_args->capability = 1; + break; + case ARGP_AUX_GFID_MOUNT_KEY: cmd_args->aux_gfid_mount = 1; break; diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h index 8247469e6e1..2a95683b33a 100644 --- a/glusterfsd/src/glusterfsd.h +++ b/glusterfsd/src/glusterfsd.h @@ -92,6 +92,7 @@ enum argp_option_keys { ARGP_SECURE_MGMT_KEY = 172, ARGP_GLOBAL_TIMER_WHEEL = 173, ARGP_RESOLVE_GIDS_KEY = 174, + ARGP_CAPABILITY_KEY = 175, }; struct _gfd_vol_top_priv_t { diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 2eba9d19232..9dcaadfa645 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -455,6 +455,7 @@ struct _cmd_args { int read_only; int acl; int selinux; + int capability; int enable_ino32; int worm; int mac_compat; diff --git a/tests/bugs/fuse/bug-1309462.t b/tests/bugs/fuse/bug-1309462.t new file mode 100644 index 00000000000..f3b74bd2935 --- /dev/null +++ b/tests/bugs/fuse/bug-1309462.t @@ -0,0 +1,49 @@ +#!/bin/bash +# +# https://bugzilla.redhat.com/show_bug.cgi?id=1309462 +# Test the new fuse mount option --capability. +# Set/get xattr on security.capability should be sent +# down from fuse, only if --selinux or --capability option +# is used for mounting. + +. $(dirname $0)/../../include.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 + +TESTFILE="$M0/testfile" +TEST touch ${TESTFILE} + +TEST ! setfattr -n security.capability -v value ${TESTFILE} +TEST ! getfattr -n security.capability ${TESTFILE} + +TEST umount $M0 + +# Mount FUSE with selinux: +TEST glusterfs -s $H0 --volfile-id $V0 --selinux $M0 + +TEST setfattr -n security.capability -v value ${TESTFILE} +TEST getfattr -n security.capability ${TESTFILE} +TEST setfattr -x security.capability ${TESTFILE} + +TEST umount $M0 + +# Mount FUSE with capability: +TEST glusterfs -s $H0 --volfile-id $V0 --capability $M0 + +TEST setfattr -n security.capability -v value ${TESTFILE} +TEST getfattr -n security.capability ${TESTFILE} +TEST setfattr -x security.capability ${TESTFILE} + +TEST umount $M0 + diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index ff42ec11273..d34e85fb2fd 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -3244,6 +3244,14 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } } + if ((!priv->capability) && (!priv->selinux)) { + if (strcmp (name, "security.capability") == 0) { + send_fuse_err (this, finh, EOPNOTSUPP); + GF_FREE (finh); + return; + } + } + /* Check if the command is for changing the log level of process or specific xlator */ ret = is_gf_log_command (this, name, value); @@ -3573,6 +3581,13 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } } + if ((!priv->capability) && (!priv->selinux)) { + if (strcmp (name, "security.capability") == 0) { + op_errno = ENODATA; + goto err; + } + } + fuse_resolve_inode_init (state, &state->resolve, finh->nodeid); rv = fuse_flip_xattr_ns (priv, name, &newkey); @@ -5558,6 +5573,8 @@ init (xlator_t *this_xl) GF_OPTION_INIT ("selinux", priv->selinux, bool, cleanup_exit); + GF_OPTION_INIT ("capability", priv->capability, bool, cleanup_exit); + GF_OPTION_INIT ("read-only", priv->read_only, bool, cleanup_exit); GF_OPTION_INIT ("enable-ino32", priv->enable_ino32, bool, cleanup_exit); @@ -5892,5 +5909,9 @@ struct volume_options options[] = { "does not have any affect and the volume option for root-squash is " "honoured.", }, + { .key = {"capability"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "false" + }, { .key = {NULL} }, }; diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 1da04c57f8f..4f031d03581 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -131,6 +131,9 @@ struct fuse_private { /* resolve gid with getgrouplist() instead of /proc/%d/status */ gf_boolean_t resolve_gids; + + /* Enable or disable capability support */ + gf_boolean_t capability; }; typedef struct fuse_private fuse_private_t; diff --git a/xlators/mount/fuse/utils/mount_glusterfs.in b/xlators/mount/fuse/utils/mount_glusterfs.in index ea34dabf0b6..eca84557e87 100755 --- a/xlators/mount/fuse/utils/mount_glusterfs.in +++ b/xlators/mount/fuse/utils/mount_glusterfs.in @@ -173,6 +173,10 @@ start_glusterfs () cmd_line=$(echo "$cmd_line --no-root-squash"); fi + if [ -n "$capability" ]; then + cmd_line=$(echo "$cmd_line --capability"); + fi + #options with values start here if [ -n "$log_level" ]; then cmd_line=$(echo "$cmd_line --log-level=$log_level"); @@ -440,6 +444,9 @@ without_options() ;; "_netdev") ;; + "capability") + capability=1 + ;; *) warn "Invalid option $option"; exit 1 -- cgit