summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXie Changlong <xiechanglong@cmss.chinamobile.com>2018-12-03 19:02:32 +0800
committerAmar Tumballi <amarts@redhat.com>2018-12-05 21:45:49 +0000
commitad446dabb88439ba83e2092021b09894351e8e71 (patch)
treee6c9185465db7ea058d1f3fbc46fd16624edd81f
parent7f7716f8194e06754d0417f27bcc40638c9f9f83 (diff)
protocol/server: support server.all-squash
We still use gnfs on our side, so do a little work to support server.all-squash. Just like server.root-squash, it's also a volume wide option. Also see bz#1285126 $ gluster volume set <VOLNAME> server.all-squash on Note: If you enable server.root-squash and server.all-squash at the same time, only server.all-squash works. Please refer to following table +---------------+-----------------+---------------------------+ | |all_squash | no_all_squash | +-------------------------------------------------------------+ | | |anonuid/anongid for root | |root_squash |anonuid/anongid |useruid/usergid for no-root| +-------------------------------------------------------------+ |no_root_squash |anonuid/anongid |useruid/usergid | +-------------------------------------------------------------+ Updates bz#1285126 Signed-off-by: Xie Changlong <xiechanglong@cmss.chinamobile.com> Signed-off-by: Xue Chuanyu <xuechuanyu@cmss.chinamobile.com> Change-Id: Iea043318fe6e9a75fa92b396737985062a26b47e
-rw-r--r--rpc/rpc-lib/src/rpcsvc-auth.c43
-rw-r--r--rpc/rpc-lib/src/rpcsvc-common.h1
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h16
-rw-r--r--tests/basic/all_squash.t72
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c4
-rw-r--r--xlators/protocol/server/src/server-helpers.c41
-rw-r--r--xlators/protocol/server/src/server.c13
7 files changed, 171 insertions, 19 deletions
diff --git a/rpc/rpc-lib/src/rpcsvc-auth.c b/rpc/rpc-lib/src/rpcsvc-auth.c
index da260ade0c0..7c45c9b2a97 100644
--- a/rpc/rpc-lib/src/rpcsvc-auth.c
+++ b/rpc/rpc-lib/src/rpcsvc-auth.c
@@ -274,6 +274,44 @@ rpcsvc_set_root_squash(rpcsvc_t *svc, dict_t *options)
}
int
+rpcsvc_set_all_squash(rpcsvc_t *svc, dict_t *options)
+{
+ int ret = -1;
+
+ uid_t anonuid = -1;
+ gid_t anongid = -1;
+
+ GF_ASSERT(svc);
+ GF_ASSERT(options);
+
+ ret = dict_get_str_boolean(options, "all-squash", 0);
+ if (ret != -1)
+ svc->all_squash = ret;
+ else
+ svc->all_squash = _gf_false;
+
+ ret = dict_get_uint32(options, "anonuid", &anonuid);
+ if (!ret)
+ svc->anonuid = anonuid;
+ else
+ svc->anonuid = RPC_NOBODY_UID;
+
+ ret = dict_get_uint32(options, "anongid", &anongid);
+ if (!ret)
+ svc->anongid = anongid;
+ else
+ svc->anongid = RPC_NOBODY_GID;
+
+ if (svc->all_squash)
+ gf_log(GF_RPCSVC, GF_LOG_DEBUG,
+ "all squashing enabled "
+ "(uid=%d, gid=%d)",
+ svc->anonuid, svc->anongid);
+
+ return 0;
+}
+
+int
rpcsvc_auth_init(rpcsvc_t *svc, dict_t *options)
{
int ret = -1;
@@ -283,6 +321,7 @@ rpcsvc_auth_init(rpcsvc_t *svc, dict_t *options)
(void)rpcsvc_set_allow_insecure(svc, options);
(void)rpcsvc_set_root_squash(svc, options);
+ (void)rpcsvc_set_all_squash(svc, options);
(void)rpcsvc_set_addr_namelookup(svc, options);
ret = rpcsvc_auth_add_initers(svc);
if (ret == -1) {
@@ -316,6 +355,10 @@ rpcsvc_auth_reconf(rpcsvc_t *svc, dict_t *options)
if (ret)
return (-1);
+ ret = rpcsvc_set_all_squash(svc, options);
+ if (ret)
+ return (-1);
+
return rpcsvc_set_addr_namelookup(svc, options);
}
diff --git a/rpc/rpc-lib/src/rpcsvc-common.h b/rpc/rpc-lib/src/rpcsvc-common.h
index 56200b38faa..361f31c27f2 100644
--- a/rpc/rpc-lib/src/rpcsvc-common.h
+++ b/rpc/rpc-lib/src/rpcsvc-common.h
@@ -79,6 +79,7 @@ typedef struct rpcsvc_state {
gf_boolean_t allow_insecure;
gf_boolean_t register_portmap;
gf_boolean_t root_squash;
+ gf_boolean_t all_squash;
} rpcsvc_t;
/* DRC START */
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
index b296f9a4bde..3e25ef3a8e9 100644
--- a/rpc/rpc-lib/src/rpcsvc.h
+++ b/rpc/rpc-lib/src/rpcsvc.h
@@ -316,6 +316,20 @@ struct rpcsvc_request {
} \
} while (0);
+#define RPC_AUTH_ALL_SQUASH(req) \
+ do { \
+ int gidcount = 0; \
+ if (req->svc->all_squash) { \
+ req->uid = req->svc->anonuid; \
+ req->gid = req->svc->anongid; \
+ \
+ for (gidcount = 0; gidcount < req->auxgidcount; ++gidcount) { \
+ if (!req->auxgids[gidcount]) \
+ req->auxgids[gidcount] = req->svc->anongid; \
+ } \
+ } \
+ } while (0);
+
#define RPCSVC_ACTOR_SUCCESS 0
#define RPCSVC_ACTOR_ERROR (-1)
#define RPCSVC_ACTOR_IGNORE (-2)
@@ -659,6 +673,8 @@ rpcsvc_set_addr_namelookup(rpcsvc_t *svc, dict_t *options);
int
rpcsvc_set_root_squash(rpcsvc_t *svc, dict_t *options);
int
+rpcsvc_set_all_squash(rpcsvc_t *svc, dict_t *options);
+int
rpcsvc_set_outstanding_rpc_limit(rpcsvc_t *svc, dict_t *options, int defvalue);
int
diff --git a/tests/basic/all_squash.t b/tests/basic/all_squash.t
new file mode 100644
index 00000000000..44631988165
--- /dev/null
+++ b/tests/basic/all_squash.t
@@ -0,0 +1,72 @@
+#!/bin/bash
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+. $(dirname $0)/../nfs.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1}
+TEST $CLI volume set $V0 nfs.disable false
+TEST $CLI volume start $V0;
+
+TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0;
+EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available;
+TEST mount_nfs $H0:/$V0 $N0 nolock;
+
+# random uid/gid
+uid=22162
+gid=5845
+
+TEST $CLI volume set $V0 server.anonuid $uid;
+TEST $CLI volume set $V0 server.anongid $gid;
+
+# Ensure server.all-squash is disabled
+TEST $CLI volume set $V0 server.all-squash disable;
+
+# Tests for the fuse mount
+mkdir $M0/other;
+chown $uid:$gid $M0/other;
+
+TEST $CLI volume set $V0 server.all-squash enable;
+
+touch $M0/file 2>/dev/null;
+TEST [ $? -ne 0 ]
+mkdir $M0/dir 2>/dev/null;
+TEST [ $? -ne 0 ]
+
+TEST touch $M0/other/file 2>/dev/null;
+TEST [ "$(stat -c %u:%g $M0/other/file)" = "$uid:$gid" ];
+TEST mkdir $M0/other/dir 2>/dev/null;
+TEST [ "$(stat -c %u:%g $M0/other/dir)" = "$uid:$gid" ];
+
+TEST $CLI volume set $V0 server.all-squash disable;
+TEST rm -rf $M0/other;
+
+sleep 1;
+
+# tests for nfs mount
+mkdir $N0/other;
+chown $uid:$gid $N0/other;
+
+TEST $CLI volume set $V0 server.all-squash enable;
+
+touch $N0/file 2>/dev/null;
+TEST [ $? -ne 0 ]
+mkdir $N0/dir 2>/dev/null;
+TEST [ $? -ne 0 ]
+
+TEST touch $N0/other/file 2>/dev/null;
+TEST [ "$(stat -c %u:%g $N0/other/file)" = "$uid:$gid" ];
+TEST mkdir $N0/other/dir 2>/dev/null;
+TEST [ "$(stat -c %u:%g $N0/other/dir)" = "$uid:$gid" ];
+
+TEST $CLI volume set $V0 server.all-squash disable;
+TEST rm -rf $N0/other;
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0
+
+TEST $CLI volume stop $V0;
+TEST $CLI volume delete $V0;
+
+cleanup;
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 53b7d98a386..70ee244d51b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1502,6 +1502,10 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "protocol/server",
.option = "root-squash",
.op_version = 2},
+ {.key = "server.all-squash",
+ .voltype = "protocol/server",
+ .option = "all-squash",
+ .op_version = GD_OP_VERSION_6_0},
{.key = "server.anonuid",
.voltype = "protocol/server",
.option = "anonuid",
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 18dc7cb169d..b1c80b62d53 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -501,44 +501,51 @@ get_frame_from_request(rpcsvc_request_t *req)
would not have been set. So for non trusted clients
(i.e clients not from the same machine as the brick,
and clients from outside the storage pool)
- do the root-squashing.
+ do the root-squashing and all-squashing.
TODO: If any client within the storage pool (i.e
mounting within a machine from the pool but using
other machine's ip/hostname from the same pool)
is present treat it as a trusted client
*/
- if (!client->auth.username && req->pid != NFS_PID)
+ if (!client->auth.username && req->pid != NFS_PID) {
RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
/* Problem: If we just check whether the client is
- trusted client and do not do root squashing for
- them, then for smb clients and UFO clients root
- squashing will never happen as they use the fuse
- mounts done within the trusted pool (i.e they are
- trusted clients).
- Solution: To fix it, do root squashing for trusted
- clients also. If one wants to have a client within
- the storage pool for which root-squashing does not
- happen, then the client has to be mounted with
+ trusted client and do not do root squashing and
+ all squashing for them, then for smb clients and
+ UFO clients root squashing and all squashing will
+ never happen as they use the fuse mounts done within
+ the trusted pool (i.e they are trusted clients).
+ Solution: To fix it, do root squashing and all squashing
+ for trusted clients also. If one wants to have a client
+ within the storage pool for which root-squashing does
+ not happen, then the client has to be mounted with
--no-root-squash option. But for defrag client and
- gsyncd client do not do root-squashing.
+ gsyncd client do not do root-squashing and all-squashing.
*/
if (client->auth.username &&
req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH &&
req->pid != GF_CLIENT_PID_GSYNCD &&
req->pid != GF_CLIENT_PID_DEFRAG &&
req->pid != GF_CLIENT_PID_SELF_HEALD &&
- req->pid != GF_CLIENT_PID_QUOTA_MOUNT)
+ req->pid != GF_CLIENT_PID_QUOTA_MOUNT) {
RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
/* For nfs clients the server processes will be running
within the trusted storage pool machines. So if we
- do not do root-squashing for nfs servers, thinking
- that its a trusted client, then root-squashing won't
- work for nfs clients.
+ do not do root-squashing and all-squashing for nfs
+ servers, thinking that its a trusted client, then
+ root-squashing and all-squashing won't work for nfs
+ clients.
*/
- if (req->pid == NFS_PID)
+ if (req->pid == NFS_PID) {
RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
}
}
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index 737e8e0907c..a8908166c76 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -1748,13 +1748,22 @@ struct volume_options server_options[] = {
"as user bin or group staff.",
.op_version = {2},
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"all-squash"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Map requests from any uid/gid to the anonymous "
+ "uid/gid. Note that this does not apply to any other "
+ "uids or gids that might be equally sensitive, such "
+ "as user bin or group staff.",
+ .op_version = {GD_OP_VERSION_6_0},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
{.key = {"anonuid"},
.type = GF_OPTION_TYPE_INT,
.default_value = "65534", /* RPC_NOBODY_UID */
.min = 0,
.max = (uint32_t)-1,
.description = "value of the uid used for the anonymous "
- "user/nfsnobody when root-squash is enabled.",
+ "user/nfsnobody when root-squash/all-squash is enabled.",
.op_version = {3},
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
{.key = {"anongid"},
@@ -1763,7 +1772,7 @@ struct volume_options server_options[] = {
.min = 0,
.max = (uint32_t)-1,
.description = "value of the gid used for the anonymous "
- "user/nfsnobody when root-squash is enabled.",
+ "user/nfsnobody when root-squash/all-squash is enabled.",
.op_version = {3},
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
{.key = {"statedump-path"},