diff options
author | Niels de Vos <ndevos@redhat.com> | 2017-07-06 17:04:17 +0200 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2017-07-09 09:14:22 +0000 |
commit | e304f48fa262e5cdbe181fb3fee5dfb9c893108c (patch) | |
tree | 433aa5ca96c57789cad383f15fb34a4fc49ba657 /xlators/nfs/server/src/mount3.c | |
parent | b81997264f079983fa02bd5fa2b3715224942b00 (diff) |
nfs: add permission checking for mounting over WebNFS
Solaris 10 uses WebNFS and not the MOUNT protocol. All permission checks
for allowing/denying clients to mount are done through the MNT handlers.
These handlers will not give out a filehandle to the NFS-client when
mounting is denied. This prevents clients from successful mounting.
However, over WebNFS a well known 'root-filehandle' is used directly
with the NFSv3 protocol.
When WebNFS was used, no permission checks (the "nfs.export-dir" option)
were applied. Now the WebNFS mount-handler in Gluster/NFS calls the
mnt3_parse_dir_exports() function that takes care of the permission
checking.
BUG: 1468291
Change-Id: Ic9dfd092473ba9c1c7b5fa38401cf9c0aa8395bb
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: https://review.gluster.org/17718
Smoke: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: soumya k <skoduri@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Diffstat (limited to 'xlators/nfs/server/src/mount3.c')
-rw-r--r-- | xlators/nfs/server/src/mount3.c | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index 12f52e4f5d0..2eaaea5c639 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -945,7 +945,7 @@ err: * we need to strip out the volume name first. */ char * -__volume_subdir (char *dirpath, char **volname) +mnt3_get_volume_subdir (char *dirpath, char **volname) { char *subdir = NULL; int volname_len = 0; @@ -1024,10 +1024,6 @@ mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *buf, dict_t *xattr, struct iatt *postparent); -int -mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms, - char *subdir); - int32_t mnt3_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, @@ -1310,7 +1306,8 @@ mnt3_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* After the resolving the symlink , parsing should be done * for the populated mount path */ - ret = mnt3_parse_dir_exports (mres->req, mres->mstate, real_loc); + ret = mnt3_parse_dir_exports (mres->req, mres->mstate, real_loc, + _gf_true); if (ret) { gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_RESOLVE_ERROR, @@ -1518,7 +1515,8 @@ mnt3_verify_auth (struct sockaddr_in *client_addr, struct mnt3_export *export) int mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms, - struct mnt3_export *exp, char *subdir) + struct mnt3_export *exp, char *subdir, + gf_boolean_t send_reply) { mnt3_resolve_t *mres = NULL; int ret = -EFAULT; @@ -1541,6 +1539,10 @@ mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms, } } + /* no reply is needed (WebNFS permissions checking), just return */ + if (!send_reply) + return 0; /* no error, mnt3_verify_auth() allowed it */ + mres = GF_CALLOC (1, sizeof (mnt3_resolve_t), gf_nfs_mt_mnt3_resolve); if (!mres) { gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, @@ -1585,11 +1587,11 @@ mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms, if ((!req) || (!ms) || (!exp)) return ret; - volume_subdir = __volume_subdir (exp->expname, NULL); + volume_subdir = mnt3_get_volume_subdir (exp->expname, NULL); if (!volume_subdir) goto err; - ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir); + ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir, _gf_true); if (ret < 0) { gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL, "Failed to resolve export dir: %s", exp->expname); @@ -1686,7 +1688,7 @@ err: return ret; } -static int +int mnt3_check_client_net_tcp (rpcsvc_request_t *req, char *volname) { rpcsvc_t *svc = NULL; @@ -1772,25 +1774,41 @@ err: int mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms, - char *subdir) + char *path, gf_boolean_t send_reply) { char volname[1024] = {0, }; struct mnt3_export *exp = NULL; char *volname_ptr = NULL; + char *subdir = NULL; int ret = -ENOENT; struct nfs_state *nfs = NULL; - if ((!ms) || (!subdir)) + if ((!ms) || (!path)) return -1; volname_ptr = volname; - subdir = __volume_subdir (subdir, &volname_ptr); - if (!subdir) + subdir = mnt3_get_volume_subdir (path, &volname_ptr); + if (!subdir) { + gf_msg_trace (GF_MNT, 0, "Could not parse volname/subdir from " + "%s", path); goto err; + } - exp = mnt3_mntpath_to_export (ms, volname, _gf_false); - if (!exp) - goto err; + /* first try to match the full export/subdir */ + exp = mnt3_mntpath_to_export (ms, path, _gf_false); + if (!exp) { + gf_msg_trace (GF_MNT, 0, "Could not find exact matching export " + "for path=%s", path); + /* if no exact match is found, look for a fallback */ + exp = mnt3_mntpath_to_export (ms, volname, _gf_true); + if (!exp) { + gf_msg_trace (GF_MNT, 0, "Could not find export for " + "volume %s", volname); + goto err; + } + } + gf_msg_trace (GF_MNT, 0, "volume %s and export %s will be used for " + "path %s", exp->vol->name, exp->expname, path); nfs = (struct nfs_state *)ms->nfsx->private; if (!nfs) @@ -1809,7 +1827,7 @@ mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms, goto err; } - ret = mnt3_resolve_subdir (req, ms, exp, subdir); + ret = mnt3_resolve_subdir (req, ms, exp, subdir, send_reply); if (ret < 0) { gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL, "Failed to resolve export dir: %s", subdir); @@ -1852,7 +1870,7 @@ mnt3_find_export (rpcsvc_request_t *req, char *path, struct mnt3_export **e) goto err; } - ret = mnt3_parse_dir_exports (req, ms, path); + ret = mnt3_parse_dir_exports (req, ms, path, _gf_true); err: return ret; @@ -2939,7 +2957,7 @@ nfs3_rootfh (struct svc_req *req, xlator_t *nfsx, * 3. If a subdir is exported using nfs.export-dir, * then the mount type would be MNT3_EXPTYPE_DIR, * so make sure to find the proper path to be - * resolved using __volume_subdir() + * resolved using mnt3_get_volume_subdir() * 3. Make sure subdir export is allowed. */ ms = __mnt3udp_get_mstate(nfsx); @@ -2962,7 +2980,7 @@ nfs3_rootfh (struct svc_req *req, xlator_t *nfsx, return NULL; } - path = __volume_subdir (path, &volptr); + path = mnt3_get_volume_subdir (path, &volptr); if (exp == NULL) exp = mnt3_mntpath_to_export (ms, volname , _gf_false); } |