summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtests/basic/mount-nfs-auth.t40
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c13
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c4
-rw-r--r--xlators/nfs/server/src/mount3.c27
-rw-r--r--xlators/nfs/server/src/nfs.c42
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c11
-rw-r--r--xlators/nfs/server/src/nfs3.c50
-rw-r--r--xlators/nfs/server/src/nfs3.h8
8 files changed, 167 insertions, 28 deletions
diff --git a/tests/basic/mount-nfs-auth.t b/tests/basic/mount-nfs-auth.t
index 5c5e62e0d58..7f990c9aeb2 100755
--- a/tests/basic/mount-nfs-auth.t
+++ b/tests/basic/mount-nfs-auth.t
@@ -48,7 +48,7 @@ EXPORT_ALLOW_L1="/$V0L1 $H0(sec=sys,rw,anonuid=0) @ngtop(sec=sys,rw,anonuid=0)"
EXPORT_WILDCARD="/$V0 *(sec=sys,rw,anonuid=0) @ngtop(sec=sys,rw,anonuid=0)"
function build_dirs () {
- mkdir -p $B0/b{0,1,2}/L1/L2/L3
+ mkdir -p $B0/b{0,1,2,3,4,5}/L1/L2/L3
}
function export_allow_this_host_ipv6 () {
@@ -64,6 +64,9 @@ function export_allow_this_host_with_slash () {
}
function export_deny_this_host () {
+ if [[ "$1" && "$1" != "$V0" ]]; then
+ local EXPORT_DENY=$(echo $EXPORT_DENY | sed "s/$V0/$1/")
+ fi
printf "$EXPORT_DENY\n" > ${NFSDIR}/exports
}
@@ -134,6 +137,10 @@ function check_mount_failure {
fi
}
+function do_mount () {
+ mount_nfs $H0:/$1 $N0 nolock
+}
+
function small_write () {
dd if=/dev/zero of=$N0/test-small-write count=1 bs=1k 2>&1
if [ $? -ne 0 ]; then
@@ -377,9 +384,40 @@ TEST $CLI vol set $V0 nfs.auth-refresh-interval-sec 20
## Do a simple test to see if the volume option exists
TEST $CLI vol set $V0 nfs.auth-cache-ttl-sec 400
+## Test authentication in 1 of 2 (sub)volumes
+ME=$(hostname)
+TEST $CLI vol create $V1 replica 3 $ME:$B0/b3 $ME:$B0/b4 $ME:$B0/b5
+TEST $CLI vol set $V1 cluster.self-heal-daemon off
+TEST $CLI vol set $V1 nfs.disable off
+TEST $CLI vol set $V1 cluster.choose-local off
+TEST $CLI vol start $V1
+TEST $CLI volume info $V1;
+
+EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "2" is_nfs_export_available $V0
+EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available $V1
+TEST $CLI vol set $V0 nfs.exports-auth-enable on
+TEST $CLI vol set $V1 nfs.exports-auth-enable off
+# Deny the hosts, but only effective on $V0
+TEST export_deny_this_host $V0
+TEST netgroup_deny_this_host
+TEST export_deny_this_host $V1
+
+sleep $AUTH_REFRESH_INTERVAL
+TEST ! do_mount $V0 # Do a mount & test
+TEST do_mount $V1 # Do a mount & test
+
+TEST touch /tmp/foo
+TEST cp /tmp/foo $N0/
+
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" umount_nfs $N0
+
## Finish up
TEST $CLI volume stop $V0
TEST $CLI volume delete $V0;
TEST ! $CLI volume info $V0;
+TEST $CLI volume stop $V1
+TEST $CLI volume delete $V1;
+TEST ! $CLI volume info $V1;
+
cleanup
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 2344fd169f1..fdc9f46284a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -4493,6 +4493,19 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
+ if (! strcmp (vme->option, "!nfs.*.exports-auth-enable")) {
+ ret = gf_asprintf (&aa, "nfs.%s.exports-auth-enable",
+ volinfo->volname);
+
+ if (ret != -1) {
+ ret = xlator_set_option (xl, aa, vme->value);
+ GF_FREE (aa);
+ }
+
+ if (ret)
+ return -1;
+ }
+
if ((strcmp (vme->voltype, "nfs/server") == 0) &&
(vme->option && vme->option[0]!='!') ) {
ret = xlator_set_option (xl, vme->option, vme->value);
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 82513338d92..0f098646b30 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2434,8 +2434,8 @@ struct volopt_map_entry glusterd_volopt_map[] = {
/* Cli options for Export authentication on nfs mount */
{ .key = "nfs.exports-auth-enable",
.voltype = "nfs/server",
- .option = "nfs.exports-auth-enable",
- .type = GLOBAL_DOC,
+ .option = "!nfs.*.exports-auth-enable",
+ //.type = GLOBAL_DOC,
.op_version = GD_OP_VERSION_3_7_0
},
{ .key = "nfs.auth-refresh-interval-sec",
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index 7e008b40c85..2dbbc0fbc3b 100644
--- a/xlators/nfs/server/src/mount3.c
+++ b/xlators/nfs/server/src/mount3.c
@@ -24,6 +24,7 @@
#include "iatt.h"
#include "nfs-mem-types.h"
#include "nfs.h"
+#include "nfs3.h"
#include "common-utils.h"
#include "store.h"
#include "glfs-internal.h"
@@ -1169,7 +1170,8 @@ mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
mres->exp->expname, mres->resolveloc.path);
/* Check if this path is authorized to be mounted */
- authcode = mnt3_authenticate_request (ms, mres->req, NULL, NULL,
+ authcode = mnt3_authenticate_request (ms, mres->req, NULL,
+ mres->exp->vol->name,
mres->exp->fullpath,
&authorized_path,
&authorized_host,
@@ -2086,15 +2088,18 @@ mnt3_authenticate_request (struct mount3_state *ms, rpcsvc_request_t *req,
const char *path, char **authorized_path,
char **authorized_host, gf_boolean_t is_write_op)
{
- int auth_status_code = -EACCES;
- char *parent_path = NULL;
- const char *parent_old = NULL;
+ int auth_status_code = -EACCES;
+ char *parent_path = NULL;
+ const char *parent_old = NULL;
+ struct mnt3_export *exp = NULL;
+ struct nfs3_state *nfs3 = ms->nfs->nfs3state;
GF_VALIDATE_OR_GOTO (GF_MNT, ms, out);
GF_VALIDATE_OR_GOTO (GF_MNT, req, out);
+ GF_VALIDATE_OR_GOTO (GF_MNT, volname, out);
/* If this option is not set, just allow it through */
- if (!ms->nfs->exports_auth) {
+ if (!nfs3->exports_auth || !nfs3_is_exports_auth(nfs3, volname)) {
/* This function is called in a variety of use-cases (mount
* + each fop) so path/authorized_path are not always present.
* For the cases which it _is_ present we need to populate the
@@ -2219,8 +2224,8 @@ mnt3svc_mnt (rpcsvc_request_t *req)
/* The second authentication check is the exports/netgroups
* check.
*/
- authcode = mnt3_authenticate_request (ms, req, NULL, NULL, path, NULL,
- NULL, _gf_false);
+ authcode = mnt3_authenticate_request (ms, req, NULL, exp->vol->name,
+ path, NULL, NULL, FALSE);
if (authcode != 0) {
mntstat = MNT3ERR_ACCES;
gf_msg_debug (GF_MNT, 0, "Client mount not allowed");
@@ -3726,6 +3731,9 @@ __mnt3_mounted_exports_walk (dict_t *dict, char *key, data_t *val, void *tmp)
* and umounts them.
*
* @ms: The mountstate for this service that holds all the information we need
+ if (!nfs->nfs3state)
+ return NULL;
+
*
*/
void
@@ -3812,6 +3820,9 @@ _mnt3_auth_param_refresh_thread (void *argv)
/* Sleep before checking the file again */
sleep (mstate->nfs->auth_refresh_time_secs);
+ if (!mstate->nfs->nfs3state->exports_auth)
+ continue;
+
if (_mnt3_has_file_changed (exp_file_path, &exp_time)) {
gf_msg (GF_MNT, GF_LOG_INFO, 0, NFS_MSG_UPDATING_EXP,
"File %s changed, updating exports,",
@@ -3990,7 +4001,7 @@ mnt3svc_init (xlator_t *nfsx)
goto err;
}
- if (nfs->exports_auth) {
+ if (nfs->nfs3state->exports_auth) {
ret = _mnt3_init_auth_params (mstate);
if (ret < 0)
goto err;
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index d5087f195ca..f2e202d0510 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -369,24 +369,24 @@ nfs_add_all_initiators (struct nfs_state *nfs)
int ret = 0;
/* Add the initializers for all versions. */
- ret = nfs_add_initer (&nfs->versions, mnt3svc_init, _gf_true);
+ ret = nfs_add_initer (&nfs->versions, mnt1svc_init, _gf_true);
if (ret == -1) {
gf_msg (GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_PROT_INIT_ADD_FAIL,
- "Failed to add MOUNT3 protocol initializer");
+ "Failed to add MOUNT1 protocol initializer");
goto ret;
}
- ret = nfs_add_initer (&nfs->versions, mnt1svc_init, _gf_true);
+ ret = nfs_add_initer (&nfs->versions, nfs3svc_init, _gf_true);
if (ret == -1) {
gf_msg (GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_PROT_INIT_ADD_FAIL,
- "Failed to add MOUNT1 protocol initializer");
+ "Failed to add NFS3 protocol initializer");
goto ret;
}
- ret = nfs_add_initer (&nfs->versions, nfs3svc_init, _gf_true);
+ ret = nfs_add_initer (&nfs->versions, mnt3svc_init, _gf_true);
if (ret == -1) {
gf_msg (GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_PROT_INIT_ADD_FAIL,
- "Failed to add NFS3 protocol initializer");
+ "Failed to add MOUNT3 protocol initializer");
goto ret;
}
@@ -957,24 +957,22 @@ nfs_init_state (xlator_t *this)
}
nfs->exports_auth = GF_NFS_DEFAULT_EXPORT_AUTH;
- if (dict_get(this->options, "nfs.exports-auth-enable")) {
+ if (dict_get (this->options, "nfs.exports-auth-enable")) {
ret = dict_get_str (this->options, "nfs.exports-auth-enable",
&optstr);
if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL,
- "Failed to parse dict");
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
goto free_foppool;
}
ret = gf_string2boolean (optstr, &boolt);
if (ret < 0) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_PARSE_FAIL,
- "Failed to parse bool string");
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
+ "string");
goto free_foppool;
}
- if (boolt == _gf_true)
- nfs->exports_auth = 1;
+ nfs->exports_auth = boolt;
}
nfs->auth_refresh_time_secs = GF_NFS_DEFAULT_AUTH_REFRESH_INTERVAL_SEC;
@@ -1214,6 +1212,7 @@ nfs_reconfigure_state (xlator_t *this, dict_t *options)
"nfs.transport-type",
"nfs.mem-factor",
NULL};
+ char *exports_auth_enable = NULL;
GF_VALIDATE_OR_GOTO (GF_NFS, this, out);
GF_VALIDATE_OR_GOTO (GF_NFS, this->private, out);
@@ -1293,6 +1292,21 @@ nfs_reconfigure_state (xlator_t *this, dict_t *options)
"Reconfigured nfs.mount-rmtab path: %s", nfs->rmtab);
}
+ /* reconfig nfs.exports-auth-enable */
+ if (dict_get (options, "nfs.exports-auth-enable")) {
+ ret = dict_get_str (options, "nfs.exports-auth-enable",
+ &exports_auth_enable);
+ if (ret < 0) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to read "
+ "reconfigured option: nfs.exports-auth-enable");
+ goto out;
+ }
+ ret = gf_string2int (exports_auth_enable, &nfs->exports_auth);
+ if (ret < 0) {
+ goto out;
+ }
+ }
+
GF_OPTION_RECONF (OPT_SERVER_AUX_GIDS, optbool,
options, bool, out);
if (nfs->server_aux_gids != optbool) {
@@ -2099,7 +2113,7 @@ struct volume_options options[] = {
.description = "Sets the number of non-idempotent "
"requests to cache in drc"
},
- { .key = {"nfs.exports-auth-enable"},
+ { .key = {"nfs.*.exports-auth-enable"},
.type = GF_OPTION_TYPE_BOOL,
.description = "Set the option to 'on' to enable exports/netgroup "
"authentication in the NFS server and mount daemon."
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c
index 0b977092fbb..1edc2ac4429 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -3975,11 +3975,18 @@ nfs3_fh_auth_nfsop (nfs3_call_state_t *cs, gf_boolean_t is_write_op)
{
struct nfs_state *nfs = NULL;
struct mount3_state *ms = NULL;
+ int auth_status = -1;
nfs = (struct nfs_state *)cs->nfsx->private;
ms = (struct mount3_state *)nfs->mstate;
- return mnt3_authenticate_request (ms, cs->req, &cs->resolvefh, NULL,
- NULL, NULL, NULL, is_write_op);
+ auth_status = mnt3_authenticate_request (ms, cs->req, &cs->resolvefh,
+ cs->vol->name, NULL, NULL,
+ NULL, is_write_op);
+
+ if (auth_status != 0) {
+ cs->resolve_errno = auth_status;
+ }
+ return auth_status;
}
int
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index 5aa9ea4e76e..d7eaca14b38 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -210,6 +210,25 @@ out:
return ret;
}
+int
+nfs3_is_exports_auth (struct nfs3_state *nfs3, const char *volname)
+{
+ int ret = 0;
+ struct nfs3_export *exp = NULL;
+
+ GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
+
+ list_for_each_entry (exp, &nfs3->exports, explist) {
+ if (strcmp (exp->subvol->name, volname) == 0) {
+ ret = exp->exports_auth;
+ break;
+ }
+ }
+
+out:
+ return ret;
+}
+
#define nfs3_map_fh_to_volume(nfs3state, handle, req, volume, status, label) \
do { \
@@ -5624,6 +5643,35 @@ no_dvm:
(exp->trusted_sync == 0)?"no trusted_sync":"trusted_sync",
(exp->trusted_write == 0)?"no trusted_write":"trusted_write");
ret = 0;
+
+ ret = snprintf (searchkey, 1024, "nfs.%s.exports-auth-enable", name);
+ if (ret < 0) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "snprintf failed");
+ ret = -1;
+ goto err;
+ }
+
+ if (dict_get (options, searchkey)) {
+ ret = dict_get_str (options, searchkey, &optstr);
+ if (ret == -1) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
+ goto err;
+ }
+
+ ret = gf_string2boolean (optstr, &boolt);
+ if (ret < 0) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
+ "string");
+ goto err;
+ }
+
+ exp->exports_auth = boolt ? TRUE : FALSE;
+ if (boolt) {
+ struct nfs_state *priv = nfsx->private;
+ priv->nfs3state->exports_auth = boolt;
+ }
+ }
+
err:
return ret;
}
@@ -5730,6 +5778,7 @@ nfs3_init_state (xlator_t *nfsx)
goto ret;
}
+ nfs->nfs3state = nfs3;
nfs3->nfsx = nfsx;
nfs3->exportslist = nfsx->children;
INIT_LIST_HEAD (&nfs3->exports);
@@ -5752,7 +5801,6 @@ nfs3_init_state (xlator_t *nfsx)
goto free_localpool;
}
- nfs->nfs3state = nfs3;
ret = 0;
free_localpool:
diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h
index c6131222c2a..36d981c3eef 100644
--- a/xlators/nfs/server/src/nfs3.h
+++ b/xlators/nfs/server/src/nfs3.h
@@ -31,6 +31,7 @@
#define GF_NFS3_IOBPOOL_MULT GF_NFS_CONCURRENT_OPS_MULT
#define GF_NFS3_CLTABLE_BUCKETS_MULT 2
#define GF_NFS3_FDTABLE_BUCKETS_MULT 2
+#define GF_NFS3_DEFAULT_EXPORT_AUTH _gf_false
/* Static values used for FSINFO
@@ -99,6 +100,7 @@ struct nfs3_export {
int trusted_sync;
int trusted_write;
int rootlookedup;
+ int exports_auth;
};
#define GF_NFS3_DEFAULT_VOLACCESS (GF_NFS3_VOLACCESS_RW)
@@ -142,6 +144,9 @@ typedef struct nfs3_state {
gf_lock_t fdlrulock;
int fdcount;
uint32_t occ_logger;
+
+ /* Enable exports auth model */
+ gf_boolean_t exports_auth;
} nfs3_state_t;
typedef enum nfs3_lookup_type {
@@ -280,4 +285,7 @@ nfs3_reconfigure_state (xlator_t *nfsx, dict_t *options);
extern uint64_t
nfs3_request_xlator_deviceid (rpcsvc_request_t *req);
+extern int
+nfs3_is_exports_auth (struct nfs3_state *nfs3, const char *volname);
+
#endif