diff options
| -rw-r--r-- | rpc/rpc-lib/src/rpcsvc-auth.c | 43 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/rpcsvc-common.h | 1 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 16 | ||||
| -rw-r--r-- | tests/basic/all_squash.t | 72 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 4 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 41 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 13 | 
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"},  | 
