From 21e208b092edf3074f56bc425ed0830243724857 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 12 Jul 2018 18:42:44 +1000 Subject: [PATCH] fix bug in nfsv4 opendir where it stripped off the final path component Signed-off-by: Ronnie Sahlberg --- lib/nfs_v4.c | 2 +- tests/CMakeLists.txt | 1 + tests/Makefile.am | 2 +- tests/prog_opendir.c | 99 ++++++++++++++++++++++++++++++++++++++ tests/test_0460_opendir.sh | 58 ++++++++++++++++++++++ 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 tests/prog_opendir.c create mode 100755 tests/test_0460_opendir.sh diff --git a/lib/nfs_v4.c b/lib/nfs_v4.c index 5675493..5e720d7 100644 --- a/lib/nfs_v4.c +++ b/lib/nfs_v4.c @@ -3536,7 +3536,7 @@ nfs4_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, struct nfs4_cb_data *data; struct nfsdir *nfsdir; - data = init_cb_data_split_path(nfs, path); + data = init_cb_data_full_path(nfs, path); if (data == NULL) { return -1; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe3c836..39cda0e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES prog_access prog_mount prog_open_read prog_open_write + prog_opendir prog_rename prog_rmdir prog_stat diff --git a/tests/Makefile.am b/tests/Makefile.am index 774dc00..179fed5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,7 +7,7 @@ LDADD = ../lib/libnfs.la noinst_PROGRAMS = prog_access prog_access2 prog_chmod prog_chown prog_create \ prog_fchmod prog_fchown prog_fstat prog_ftruncate prog_lchmod \ prog_lchown prog_link prog_lseek prog_lstat prog_mkdir \ - prog_mknod prog_mount prog_open_read prog_open_write \ + prog_mknod prog_mount prog_opendir prog_open_read prog_open_write \ prog_rename prog_rmdir prog_stat prog_statvfs prog_symlink \ prog_timeout prog_truncate prog_unlink prog_utimes diff --git a/tests/prog_opendir.c b/tests/prog_opendir.c new file mode 100644 index 0000000..b556999 --- /dev/null +++ b/tests/prog_opendir.c @@ -0,0 +1,99 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) by Ronnie Sahlberg 2017 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#define _FILE_OFFSET_BITS 64 +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnfs.h" + +void usage(void) +{ + fprintf(stderr, "Usage: prog_opendir \n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + struct nfs_context *nfs = NULL; + struct nfs_url *url = NULL; + struct nfsdirent *nfsdirent; + struct nfsdir *nfsdir; + int ret = 0; + + if (argc != 4) { + usage(); + } + + nfs = nfs_init_context(); + if (nfs == NULL) { + printf("failed to init context\n"); + exit(1); + } + + nfs_set_timeout(nfs, 300); + + url = nfs_parse_url_full(nfs, argv[1]); + if (url == NULL) { + fprintf(stderr, "%s\n", nfs_get_error(nfs)); + exit(1); + } + + if (nfs_mount(nfs, url->server, url->path) != 0) { + fprintf(stderr, "Failed to mount nfs share : %s\n", + nfs_get_error(nfs)); + ret = 1; + goto finished; + } + + if (nfs_chdir(nfs, argv[2]) != 0) { + fprintf(stderr, "Failed to chdir to \"%s\" : %s\n", + argv[2], nfs_get_error(nfs)); + ret = 1; + goto finished; + } + + if (nfs_opendir(nfs, argv[3], &nfsdir)) { + fprintf(stderr, "Failed to opendir() : %s\n", + nfs_get_error(nfs)); + ret = 1; + goto finished; + } + + while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { + if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { + continue; + } + printf("%s\n", nfsdirent->name); + } + nfs_closedir(nfs, nfsdir); + +finished: + nfs_destroy_url(url); + nfs_destroy_context(nfs); + + return ret; +} diff --git a/tests/test_0460_opendir.sh b/tests/test_0460_opendir.sh new file mode 100755 index 0000000..871c769 --- /dev/null +++ b/tests/test_0460_opendir.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# +# NFS servers generally want us to be root in order to create device nodes. +# We can lie and impersonate root by setting uid=0 in the URL. + +. ./functions.sh + +echo "NFSv${VERS} Basic opendir test." + +start_share + +mkdir "${TESTDIR}/subdir" +mkdir "${TESTDIR}/subdir/subdir2" +touch "${TESTDIR}/subdir/subdir2/file" + +echo -n "Open '.' in the root directory (1)... " +./prog_opendir "${TESTURL}/?uid=0&version=${VERS}" "." "." > "${TESTDIR}/output" || failure +success + +echo -n "Check the directory listing ... " +grep "^subdir$" "${TESTDIR}/output" >/dev/null || failure +success + +echo -n "Open a subdir in the root directory (2)... " +./prog_opendir "${TESTURL}/?uid=0&version=${VERS}" "." "subdir" > "${TESTDIR}/output" || failure +success + +echo -n "Check the directory listing ... " +grep "^subdir2$" "${TESTDIR}/output" >/dev/null || failure +success + +echo -n "Open '.' in a subdir (3)... " +./prog_opendir "${TESTURL}/?uid=0&version=${VERS}" "subdir" "." > "${TESTDIR}/output" || failure +success + +echo -n "Check the directory listing ... " +grep "^subdir2$" "${TESTDIR}/output" >/dev/null || failure +success + +echo -n "Open 'subdir2' in a subdir (4)... " +./prog_opendir "${TESTURL}/?uid=0&version=${VERS}" "subdir" "subdir2" > "${TESTDIR}/output" || failure +success + +echo -n "Check the directory listing ... " +grep "^file$" "${TESTDIR}/output" >/dev/null || failure +success + +echo -n "Open '..' in a subdir (5)... " +./prog_opendir "${TESTURL}/?uid=0&version=${VERS}" "subdir/subdir2" ".." > "${TESTDIR}/output" || failure +success + +echo -n "Check the directory listing ... " +grep "^subdir2$" "${TESTDIR}/output" >/dev/null || failure +success + +stop_share + +exit 0