diff --git a/.gitignore b/.gitignore index 14e1115..74b0c79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ x86_64 -nfs-utils-1.2.5 -nfs-utils-1.2.6 -nfs-utils-1.2.7 -/nfs-utils-1.2.5.tar.bz2 -/nfs-utils-1.2.6.tar.bz2 -/nfs-utils-1.2.7.tar.bz2 +Makefile +/nfs-utils-1.2.8 +/nfs-utils-1.2.8.tar.bz2 diff --git a/nfs-utils-1.2.7-nfsd-v41.patch b/nfs-utils-1.2.7-nfsd-v41.patch deleted file mode 100644 index f15ca3d..0000000 --- a/nfs-utils-1.2.7-nfsd-v41.patch +++ /dev/null @@ -1,111 +0,0 @@ -commit e79baddaa1d8cf24cce929e14f6f91ac0d5e15d0 -Author: Trond Myklebust -Date: Mon Mar 25 16:07:59 2013 -0400 - - nfsd: Add support for the -V and --nfs-version optional arguments - - Add command line options to enable those NFS versions that are - currently disabled by default. We choose to use the options '-V' - and '--nfs-version' for compatibility with rpc.mountd. - - Acked-by: J. Bruce Fields - Signed-off-by: Trond Myklebust - Signed-off-by: Steve Dickson - -diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h -index 320880e..174c2dd 100644 ---- a/support/include/nfs/nfs.h -+++ b/support/include/nfs/nfs.h -@@ -52,6 +52,7 @@ struct nfs_fh_old { - #define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & NFSCTL_UDPBIT) - #define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & NFSCTL_TCPBIT) - -+#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << ((_v) - 1))) - #define NFSCTL_UDPSET(_cltbits) ((_cltbits) |= NFSCTL_UDPBIT) - #define NFSCTL_TCPSET(_cltbits) ((_cltbits) |= NFSCTL_TCPBIT) - -diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c -index 2a3f5cc..e87c0a9 100644 ---- a/utils/nfsd/nfsd.c -+++ b/utils/nfsd/nfsd.c -@@ -38,6 +38,7 @@ static struct option longopts[] = - { "host", 1, 0, 'H' }, - { "help", 0, 0, 'h' }, - { "no-nfs-version", 1, 0, 'N' }, -+ { "nfs-version", 1, 0, 'V' }, - { "no-tcp", 0, 0, 'T' }, - { "no-udp", 0, 0, 'U' }, - { "port", 1, 0, 'P' }, -@@ -119,7 +120,7 @@ main(int argc, char **argv) - xlog_syslog(0); - xlog_stderr(1); - -- while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) { -+ while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:sTU", longopts, NULL)) != EOF) { - switch(c) { - case 'd': - xlog_config(D_ALL, 1); -@@ -175,6 +176,27 @@ main(int argc, char **argv) - exit(1); - } - break; -+ case 'V': -+ switch((c = strtol(optarg, &p, 0))) { -+ case 4: -+ if (*p == '.') { -+ int i = atoi(p+1); -+ if (i != 1) { -+ fprintf(stderr, "%s: unsupported minor version\n", optarg); -+ exit(1); -+ } -+ minorvers41 = 1; -+ break; -+ } -+ case 3: -+ case 2: -+ NFSCTL_VERSET(versbits, c); -+ break; -+ default: -+ fprintf(stderr, "%s: Unsupported version\n", optarg); -+ exit(1); -+ } -+ break; - case 's': - xlog_syslog(1); - xlog_stderr(0); -@@ -312,7 +334,7 @@ static void - usage(const char *prog) - { - fprintf(stderr, "Usage:\n" -- "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n", -+ "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version] [-V|--nfs-version version] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n", - prog); - exit(2); - } -diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man -index 1cf9296..7de0867 100644 ---- a/utils/nfsd/nfsd.man -+++ b/utils/nfsd/nfsd.man -@@ -47,7 +47,7 @@ This option can be used to request that - .B rpc.nfsd - does not offer certain versions of NFS. The current version of - .B rpc.nfsd --can support both NFS version 2,3 and the newer version 4. -+can support NFS versions 2,3,4 and the newer version 4.1. - .TP - .B \-s " or " \-\-syslog - By default, -@@ -67,6 +67,13 @@ Disable - .B rpc.nfsd - from accepting UDP connections from clients. - .TP -+.B \-V " or " \-\-nfs-version vers -+This option can be used to request that -+.B rpc.nfsd -+offer certain versions of NFS. The current version of -+.B rpc.nfsd -+can support NFS versions 2,3,4 and the newer version 4.1. -+.TP - .I nproc - specify the number of NFS server threads. By default, just one - thread is started. However, for optimum performance several threads diff --git a/nfs-utils-1.2.7-rc4.patch b/nfs-utils-1.2.7-rc4.patch deleted file mode 100644 index 9a5e8e7..0000000 --- a/nfs-utils-1.2.7-rc4.patch +++ /dev/null @@ -1,720 +0,0 @@ -diff --git a/README b/README -index 348f5d4..e55b2dd 100644 ---- a/README -+++ b/README -@@ -1,4 +1,4 @@ --This is version 1.1.0 of nfs-utils, the Linux NFS utility package. -+This is version 1.2.6 of nfs-utils, the Linux NFS utility package. - - - 0. PROJECT RESOURCES -diff --git a/aclocal/libcap.m4 b/aclocal/libcap.m4 -index 68a624c..f8a0ed1 100644 ---- a/aclocal/libcap.m4 -+++ b/aclocal/libcap.m4 -@@ -3,7 +3,7 @@ dnl - AC_DEFUN([AC_LIBCAP], [ - - dnl look for prctl -- AC_CHECK_FUNC([prctl], , ) -+ AC_CHECK_FUNC([prctl], , AC_MSG_ERROR([prctl syscall is not available])) - - AC_ARG_ENABLE([caps], - [AS_HELP_STRING([--disable-caps], [Disable capabilities support])]) -diff --git a/aclocal/libsqlite3.m4 b/aclocal/libsqlite3.m4 -index 73d1e46..8c38993 100644 ---- a/aclocal/libsqlite3.m4 -+++ b/aclocal/libsqlite3.m4 -@@ -29,5 +29,4 @@ AC_DEFUN([AC_SQLITE3_VERS], [ - LIBS="$saved_LIBS"]) - - AC_MSG_RESULT($libsqlite3_cv_is_recent) -- AM_CONDITIONAL(CONFIG_SQLITE3, [test "$libsqlite3_cv_is_recent" = "yes"]) - ])dnl -diff --git a/configure.ac b/configure.ac -index 9ba53e2..18ee11a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -278,8 +278,6 @@ if test "$enable_nfsv4" = yes; then - fi - fi - -- AM_CONDITIONAL(CONFIG_NFSDCLD, [test "$enable_nfsdcld" = "yes" ]) -- - dnl librpcsecgss already has a dependency on libgssapi, - dnl but we need to make sure we get the right version - if test "$enable_gss" = yes; then -@@ -293,6 +291,7 @@ if test "$enable_nfsv41" = yes; then - fi - - dnl enable nfsidmap when its support by libnfsidmap -+AM_CONDITIONAL(CONFIG_NFSDCLD, [test "$enable_nfsdcld" = "yes" ]) - AM_CONDITIONAL(CONFIG_NFSIDMAP, [test "$ac_cv_header_keyutils_h$ac_cv_lib_nfsidmap_nfs4_owner_to_uid" = "yesyes"]) - - -@@ -393,7 +392,7 @@ AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \ - gethostbyaddr gethostbyname gethostname getmntent \ - getnameinfo getrpcbyname getifaddrs \ - gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \ -- realpath rmdir select socket strcasecmp strchr strdup \ -+ ppoll realpath rmdir select socket strcasecmp strchr strdup \ - strerror strrchr strtol strtoul sigprocmask]) - - -diff --git a/support/include/nfs/debug.h b/support/include/nfs/debug.h -index dbec5ba..80a1b1d 100644 ---- a/support/include/nfs/debug.h -+++ b/support/include/nfs/debug.h -@@ -79,6 +79,7 @@ enum { - #define NFSDBG_FSCACHE 0x0800 - #define NFSDBG_PNFS 0x1000 - #define NFSDBG_PNFS_LD 0x2000 -+#define NFSDBG_STATE 0x4000 - #define NFSDBG_ALL 0xFFFF - - #endif /* _NFS_DEBUG_H */ -diff --git a/support/nsm/file.c b/support/nsm/file.c -index 5dd52c1..4711c2c 100644 ---- a/support/nsm/file.c -+++ b/support/nsm/file.c -@@ -338,10 +338,10 @@ nsm_is_default_parentdir(void) - * - * Returns true if successful, or false if some error occurred. - */ -+#ifdef HAVE_SYS_CAPABILITY_H - static _Bool - nsm_clear_capabilities(void) - { --#ifdef HAVE_SYS_CAPABILITY_H - cap_t caps; - - caps = cap_from_text("cap_net_bind_service=ep"); -@@ -357,10 +357,60 @@ nsm_clear_capabilities(void) - } - - (void)cap_free(caps); --#endif - return true; - } - -+#define CAP_BOUND_PROCFILE "/proc/sys/kernel/cap-bound" -+static _Bool -+prune_bounding_set(void) -+{ -+#ifdef PR_CAPBSET_DROP -+ int ret; -+ unsigned long i; -+ struct stat st; -+ -+ /* -+ * Prior to kernel 2.6.25, the capabilities bounding set was a global -+ * value. Check to see if /proc/sys/kernel/cap-bound exists and don't -+ * bother to clear the bounding set if it does. -+ */ -+ ret = stat(CAP_BOUND_PROCFILE, &st); -+ if (!ret) { -+ xlog(L_WARNING, "%s exists. Not attempting to clear " -+ "capabilities bounding set.", -+ CAP_BOUND_PROCFILE); -+ return true; -+ } else if (errno != ENOENT) { -+ /* Warn, but attempt to clear the bounding set anyway. */ -+ xlog(L_WARNING, "Unable to stat %s: %m", CAP_BOUND_PROCFILE); -+ } -+ -+ /* prune the bounding set to nothing */ -+ for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >=0 ; ++i) { -+ ret = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); -+ if (ret) { -+ xlog(L_ERROR, "Unable to prune capability %lu from " -+ "bounding set: %m", i); -+ return false; -+ } -+ } -+#endif /* PR_CAPBSET_DROP */ -+ return true; -+} -+#else /* !HAVE_SYS_CAPABILITY_H */ -+static _Bool -+nsm_clear_capabilities(void) -+{ -+ return true; -+} -+ -+static _Bool -+prune_bounding_set(void) -+{ -+ return true; -+} -+#endif /* HAVE_SYS_CAPABILITY_H */ -+ - /** - * nsm_drop_privileges - drop root privileges - * @pidfd: file descriptor of a pid file -@@ -393,6 +443,9 @@ nsm_drop_privileges(const int pidfd) - return false; - } - -+ if (!prune_bounding_set()) -+ return false; -+ - if (st.st_uid == 0) { - xlog_warn("Running as root. " - "chown %s to choose different user", nsm_base_dirname); -diff --git a/tests/nsm_client/Makefile.am b/tests/nsm_client/Makefile.am -index 4bf0a45..4c15346 100644 ---- a/tests/nsm_client/Makefile.am -+++ b/tests/nsm_client/Makefile.am -@@ -13,7 +13,7 @@ nsm_client_SOURCES = $(GENFILES) nsm_client.c - - BUILT_SOURCES = $(GENFILES) - nsm_client_LDADD = ../../support/nfs/libnfs.a \ -- ../../support/nsm/libnsm.a $(LIBCAP) -+ ../../support/nsm/libnsm.a $(LIBCAP) $(LIBTIRPC) - - if CONFIG_RPCGEN - RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen -diff --git a/tools/rpcdebug/rpcdebug.c b/tools/rpcdebug/rpcdebug.c -index 444616d..d6e10d3 100644 ---- a/tools/rpcdebug/rpcdebug.c -+++ b/tools/rpcdebug/rpcdebug.c -@@ -170,6 +170,7 @@ static struct flagmap { - FLAG(NFS, FSCACHE), - FLAG(NFS, PNFS), - FLAG(NFS, PNFS_LD), -+ FLAG(NFS, STATE), - FLAG(NFS, ALL), - - /* nfsd */ -diff --git a/utils/blkmapd/device-process.c b/utils/blkmapd/device-process.c -index 652a7a8..5fe3dff 100644 ---- a/utils/blkmapd/device-process.c -+++ b/utils/blkmapd/device-process.c -@@ -49,28 +49,6 @@ - - #include "device-discovery.h" - --static char *pretty_sig(char *sig, uint32_t siglen) --{ -- static char rs[100]; -- uint64_t sigval; -- unsigned int i; -- -- if (siglen <= sizeof(sigval)) { -- sigval = 0; -- for (i = 0; i < siglen; i++) -- sigval |= ((unsigned char *)sig)[i] << (i * 8); -- sprintf(rs, "0x%0llx", (unsigned long long) sigval); -- } else { -- if (siglen > sizeof rs - 4) { -- siglen = sizeof rs - 4; -- sprintf(&rs[siglen], "..."); -- } else -- rs[siglen] = '\0'; -- memcpy(rs, sig, siglen); -- } -- return rs; --} -- - uint32_t *blk_overflow(uint32_t * p, uint32_t * end, size_t nbytes) - { - uint32_t *q = p + ((nbytes + 3) >> 2); -@@ -109,9 +87,6 @@ static int decode_blk_signature(uint32_t **pp, uint32_t * end, - * for mapping, then thrown away. - */ - comp->bs_string = (char *)p; -- BL_LOG_INFO("%s: si_comps[%d]: bs_length %d, bs_string %s\n", -- __func__, i, siglen, -- pretty_sig(comp->bs_string, siglen)); - p += ((siglen + 3) >> 2); - } - *pp = p; -@@ -152,10 +127,6 @@ read_cmp_blk_sig(struct bl_disk *disk, int fd, struct bl_sig_comp *comp) - } - - ret = memcmp(sig, comp->bs_string, siglen); -- if (!ret) -- BL_LOG_INFO("%s: %s sig %s at %lld\n", __func__, dev_name, -- pretty_sig(sig, siglen), -- (long long)comp->bs_offset); - - out: - if (sig) -diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c -index a3323d7..9f79541 100644 ---- a/utils/exportfs/exportfs.c -+++ b/utils/exportfs/exportfs.c -@@ -40,7 +40,7 @@ static void unexportfs(char *arg, int verbose); - static void exports_update(int verbose); - static void dump(int verbose); - static void error(nfs_export *exp, int err); --static void usage(const char *progname); -+static void usage(const char *progname, int n); - static void validate_export(nfs_export *exp); - static int matchhostname(const char *hostname1, const char *hostname2); - static void export_d_read(const char *dname); -@@ -105,11 +105,17 @@ main(int argc, char **argv) - - export_errno = 0; - -- while ((c = getopt(argc, argv, "aio:ruvf")) != EOF) { -+ while ((c = getopt(argc, argv, "afhio:ruv")) != EOF) { - switch(c) { - case 'a': - f_all = 1; - break; -+ case 'f': -+ force_flush = 1; -+ break; -+ case 'h': -+ usage(progname, 0); -+ break; - case 'i': - f_ignore = 1; - break; -@@ -126,11 +132,8 @@ main(int argc, char **argv) - case 'v': - f_verbose = 1; - break; -- case 'f': -- force_flush = 1; -- break; - default: -- usage(progname); -+ usage(progname, 1); - break; - } - } -@@ -723,8 +726,8 @@ error(nfs_export *exp, int err) - } - - static void --usage(const char *progname) -+usage(const char *progname, int n) - { -- fprintf(stderr, "usage: %s [-aruv] [host:/path]\n", progname); -- exit(1); -+ fprintf(stderr, "usage: %s [-afhioruv] [host:/path]\n", progname); -+ exit(n); - } -diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h -index 28a8206..71a140b 100644 ---- a/utils/gssd/gssd.h -+++ b/utils/gssd/gssd.h -@@ -81,8 +81,10 @@ struct clnt_info { - char *protocol; - int krb5_fd; - int krb5_poll_index; -+ int krb5_close_me; - int gssd_fd; - int gssd_poll_index; -+ int gssd_close_me; - struct sockaddr_storage addr; - }; - -diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c -index cec09ea..ccf7fe5 100644 ---- a/utils/gssd/gssd_main_loop.c -+++ b/utils/gssd/gssd_main_loop.c -@@ -55,16 +55,14 @@ - #include "err_util.h" - - extern struct pollfd *pollarray; --extern int pollsize; -+extern unsigned long pollsize; - - #define POLL_MILLISECS 500 - - static volatile int dir_changed = 1; - --static void dir_notify_handler(int sig, siginfo_t *si, void *data) -+static void dir_notify_handler(__attribute__((unused))int sig) - { -- printerr(2, "dir_notify_handler: sig %d si %p data %p\n", sig, si, data); -- - dir_changed = 1; - } - -@@ -78,8 +76,10 @@ scan_poll_results(int ret) - { - i = clp->gssd_poll_index; - if (i >= 0 && pollarray[i].revents) { -- if (pollarray[i].revents & POLLHUP) -+ if (pollarray[i].revents & POLLHUP) { -+ clp->gssd_close_me = 1; - dir_changed = 1; -+ } - if (pollarray[i].revents & POLLIN) - handle_gssd_upcall(clp); - pollarray[clp->gssd_poll_index].revents = 0; -@@ -89,8 +89,10 @@ scan_poll_results(int ret) - } - i = clp->krb5_poll_index; - if (i >= 0 && pollarray[i].revents) { -- if (pollarray[i].revents & POLLHUP) -+ if (pollarray[i].revents & POLLHUP) { -+ clp->krb5_close_me = 1; - dir_changed = 1; -+ } - if (pollarray[i].revents & POLLIN) - handle_krb5_upcall(clp); - pollarray[clp->krb5_poll_index].revents = 0; -@@ -99,7 +101,7 @@ scan_poll_results(int ret) - break; - } - } --}; -+} - - static int - topdirs_add_entry(struct dirent *dent) -@@ -119,11 +121,13 @@ topdirs_add_entry(struct dirent *dent) - } - snprintf(tdi->dirname, PATH_MAX, "%s/%s", pipefs_dir, dent->d_name); - tdi->fd = open(tdi->dirname, O_RDONLY); -- if (tdi->fd != -1) { -- fcntl(tdi->fd, F_SETSIG, DNOTIFY_SIGNAL); -- fcntl(tdi->fd, F_NOTIFY, -- DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT); -+ if (tdi->fd == -1) { -+ printerr(0, "ERROR: failed to open %s\n", tdi->dirname); -+ free(tdi); -+ return -1; - } -+ fcntl(tdi->fd, F_SETSIG, DNOTIFY_SIGNAL); -+ fcntl(tdi->fd, F_NOTIFY, DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT); - - TAILQ_INSERT_HEAD(&topdirs_list, tdi, list); - return 0; -@@ -175,17 +179,52 @@ out_err: - return -1; - } - -+#ifdef HAVE_PPOLL -+static void gssd_poll(struct pollfd *fds, unsigned long nfds) -+{ -+ sigset_t emptyset; -+ int ret; -+ -+ sigemptyset(&emptyset); -+ ret = ppoll(fds, nfds, NULL, &emptyset); -+ if (ret < 0) { -+ if (errno != EINTR) -+ printerr(0, "WARNING: error return from poll\n"); -+ } else if (ret == 0) { -+ printerr(0, "WARNING: unexpected timeout\n"); -+ } else { -+ scan_poll_results(ret); -+ } -+} -+#else /* !HAVE_PPOLL */ -+static void gssd_poll(struct pollfd *fds, unsigned long nfds) -+{ -+ int ret; -+ -+ /* race condition here: dir_changed could be set before we -+ * enter the poll, and we'd never notice if it weren't for the -+ * timeout. */ -+ ret = poll(fds, nfds, POLL_MILLISECS); -+ if (ret < 0) { -+ if (errno != EINTR) -+ printerr(0, "WARNING: error return from poll\n"); -+ } else if (ret == 0) { -+ /* timeout */ -+ } else { /* ret > 0 */ -+ scan_poll_results(ret); -+ } -+} -+#endif /* !HAVE_PPOLL */ -+ - void - gssd_run() - { -- int ret; -- struct sigaction dn_act; -+ struct sigaction dn_act = { -+ .sa_handler = dir_notify_handler -+ }; - sigset_t set; - -- /* Taken from linux/Documentation/dnotify.txt: */ -- dn_act.sa_sigaction = dir_notify_handler; - sigemptyset(&dn_act.sa_mask); -- dn_act.sa_flags = SA_SIGINFO; - sigaction(DNOTIFY_SIGNAL, &dn_act, NULL); - - /* just in case the signal is blocked... */ -@@ -207,19 +246,7 @@ gssd_run() - exit(1); - } - } -- /* race condition here: dir_changed could be set before we -- * enter the poll, and we'd never notice if it weren't for the -- * timeout. */ -- ret = poll(pollarray, pollsize, POLL_MILLISECS); -- if (ret < 0) { -- if (errno != EINTR) -- printerr(0, -- "WARNING: error return from poll\n"); -- } else if (ret == 0) { -- /* timeout */ -- } else { /* ret > 0 */ -- scan_poll_results(ret); -- } -+ gssd_poll(pollarray, pollsize); - } - topdirs_free_list(); - -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index aa39435..e393d59 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -104,7 +104,7 @@ - - struct pollfd * pollarray; - --int pollsize; /* the size of pollaray (in pollfd's) */ -+unsigned long pollsize; /* the size of pollaray (in pollfd's) */ - - /* - * convert a presentation address string to a sockaddr_storage struct. Returns -@@ -340,6 +340,25 @@ process_clnt_dir_files(struct clnt_info * clp) - char gname[PATH_MAX]; - char info_file_name[PATH_MAX]; - -+ if (clp->gssd_close_me) { -+ printerr(2, "Closing 'gssd' pipe for %s\n", clp->dirname); -+ close(clp->gssd_fd); -+ memset(&pollarray[clp->gssd_poll_index], 0, -+ sizeof(struct pollfd)); -+ clp->gssd_fd = -1; -+ clp->gssd_poll_index = -1; -+ clp->gssd_close_me = 0; -+ } -+ if (clp->krb5_close_me) { -+ printerr(2, "Closing 'krb5' pipe for %s\n", clp->dirname); -+ close(clp->krb5_fd); -+ memset(&pollarray[clp->krb5_poll_index], 0, -+ sizeof(struct pollfd)); -+ clp->krb5_fd = -1; -+ clp->krb5_poll_index = -1; -+ clp->krb5_close_me = 0; -+ } -+ - if (clp->gssd_fd == -1) { - snprintf(gname, sizeof(gname), "%s/gssd", clp->dirname); - clp->gssd_fd = open(gname, O_RDWR); -diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am -index 7627854..5810936 100644 ---- a/utils/mount/Makefile.am -+++ b/utils/mount/Makefile.am -@@ -1,7 +1,7 @@ - ## Process this file with automake to produce Makefile.in - - # These binaries go in /sbin (not /usr/sbin), and that cannot be --# overriden at config time. -+# overridden at config time. - sbindir = /sbin - - man8_MANS = mount.nfs.man umount.nfs.man -diff --git a/utils/mount/mount_libmount.c b/utils/mount/mount_libmount.c -index e8f17a9..701d41e 100644 ---- a/utils/mount/mount_libmount.c -+++ b/utils/mount/mount_libmount.c -@@ -140,14 +140,14 @@ static int try_mount(struct libmnt_context *cxt, int bg) - return ret; - } - --/* returns: error = -1, success = 0 , unknown = 1 */ -+/* returns: error = -1, success = 1 , not vers4 == 0 */ - static int is_vers4(struct libmnt_context *cxt) - { - struct libmnt_fs *fs = mnt_context_get_fs(cxt); - struct libmnt_table *tb = NULL; - const char *src = mnt_context_get_source(cxt), - *tgt = mnt_context_get_target(cxt); -- int rc = 1; -+ int rc = 0; - - if (!src || !tgt) - return -1; -@@ -163,7 +163,7 @@ static int is_vers4(struct libmnt_context *cxt) - if (fs) { - const char *type = mnt_fs_get_fstype(fs); - if (type && strcmp(type, "nfs4") == 0) -- rc = 0; -+ rc = 1; - } - mnt_free_table(tb); - return rc; -@@ -173,6 +173,7 @@ static int umount_main(struct libmnt_context *cxt, int argc, char **argv) - { - int rc, c; - char *spec = NULL, *opts = NULL; -+ int ret = EX_FAIL; - - static const struct option longopts[] = { - { "force", 0, 0, 'f' }, -@@ -209,8 +210,6 @@ static int umount_main(struct libmnt_context *cxt, int argc, char **argv) - - if (mnt_context_set_target(cxt, spec)) - goto err; -- if (mnt_context_set_fstype_pattern(cxt, "nfs,nfs4")) /* restrict filesystems */ -- goto err; - - /* read mtab/fstab, evaluate permissions, etc. */ - rc = mnt_context_prepare_umount(cxt); -@@ -220,6 +219,14 @@ static int umount_main(struct libmnt_context *cxt, int argc, char **argv) - goto err; - } - -+ if (mnt_context_get_fstype(cxt) && -+ !mnt_match_fstype(mnt_context_get_fstype(cxt), "nfs,nfs4")) { -+ -+ nfs_error(_("%s: %s: is not an NFS filesystem"), progname, spec); -+ ret = EX_USAGE; -+ goto err; -+ } -+ - opts = retrieve_mount_options(mnt_context_get_fs(cxt)); - - if (!mnt_context_is_lazy(cxt)) { -@@ -244,6 +251,7 @@ static int umount_main(struct libmnt_context *cxt, int argc, char **argv) - nfs_umount23(spec, "tcp,v3"); - } - -+ ret = EX_FILEIO; - rc = mnt_context_do_umount(cxt); /* call umount(2) syscall */ - mnt_context_finalize_mount(cxt); /* mtab update */ - -@@ -252,12 +260,10 @@ static int umount_main(struct libmnt_context *cxt, int argc, char **argv) - umount_error(rc, spec); - goto err; - } -- -- free(opts); -- return EX_SUCCESS; -+ ret = EX_SUCCESS; - err: - free(opts); -- return EX_FAIL; -+ return ret; - } - - static int mount_main(struct libmnt_context *cxt, int argc, char **argv) -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index e09aa7c..0aa9a75 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -665,6 +665,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) - case ECONNREFUSED: - case EOPNOTSUPP: - case EHOSTUNREACH: -+ case ETIMEDOUT: - continue; - default: - goto out; -@@ -752,6 +753,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) - switch (errno) { - case ECONNREFUSED: - case EHOSTUNREACH: -+ case ETIMEDOUT: - continue; - default: - goto out; -diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c -index 708eb61..726b50d 100644 ---- a/utils/mountd/v4root.c -+++ b/utils/mountd/v4root.c -@@ -62,6 +62,8 @@ void set_pseudofs_security(struct exportent *pseudo, struct exportent *source) - - if (source->e_flags & NFSEXP_INSECURE_PORT) - pseudo->e_flags |= NFSEXP_INSECURE_PORT; -+ if ((source->e_flags & NFSEXP_ROOTSQUASH) == 0) -+ pseudo->e_flags &= ~NFSEXP_ROOTSQUASH; - for (se = source->e_secinfo; se->flav; se++) { - struct sec_entry *new; - -@@ -92,7 +94,8 @@ v4root_create(char *path, nfs_export *export) - exp = export_create(&eep, 0); - if (exp == NULL) - return NULL; -- xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path); -+ xlog(D_CALL, "v4root_create: path '%s' flags 0x%x", -+ exp->m_export.e_path, exp->m_export.e_flags); - return &exp->m_export; - } - -diff --git a/utils/nfsdcld/nfsdcld.c b/utils/nfsdcld/nfsdcld.c -index e7af4e3..473d069 100644 ---- a/utils/nfsdcld/nfsdcld.c -+++ b/utils/nfsdcld/nfsdcld.c -@@ -102,8 +102,8 @@ cld_set_caps(void) - } - - /* prune the bounding set to nothing */ -- for (i = 0; i <= CAP_LAST_CAP; ++i) { -- ret = prctl(PR_CAPBSET_DROP, i); -+ for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0 ; ++i) { -+ ret = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); - if (ret) { - xlog(L_ERROR, "Unable to prune capability %lu from " - "bounding set: %m", i); -diff --git a/utils/nfsidmap/nfsidmap.c b/utils/nfsidmap/nfsidmap.c -index cf11551..e14543c 100644 ---- a/utils/nfsidmap/nfsidmap.c -+++ b/utils/nfsidmap/nfsidmap.c -@@ -12,6 +12,7 @@ - - #include - #include "xlog.h" -+#include "conffile.h" - - int verbose = 0; - char *usage="Usage: %s [-v] [-c || [-u|-g|-r key] || [-t timeout] key desc]"; -@@ -26,6 +27,10 @@ char *usage="Usage: %s [-v] [-c || [-u|-g|-r key] || [-t timeout] key desc]"; - #define DEFAULT_KEYRING "id_resolver" - #endif - -+#ifndef PATH_IDMAPDCONF -+#define PATH_IDMAPDCONF "/etc/idmapd.conf" -+#endif -+ - static int keyring_clear(char *keyring); - - #define UIDKEYS 0x1 -@@ -267,6 +272,13 @@ int main(int argc, char **argv) - } - } - -+ if (nfs4_init_name_mapping(PATH_IDMAPDCONF)) { -+ xlog_err("Unable to create name to user id mappings."); -+ return 1; -+ } -+ if (!verbose) -+ verbose = conf_get_num("General", "Verbosity", 0); -+ - if (keystr) { - rc = key_revoke(keystr, keymask); - return rc; -diff --git a/utils/osd_login/Makefile.am b/utils/osd_login/Makefile.am -index adc493a..20c2d8c 100644 ---- a/utils/osd_login/Makefile.am -+++ b/utils/osd_login/Makefile.am -@@ -1,12 +1,9 @@ - ## Process this file with automake to produce Makefile.in - --OSD_LOGIN_FILES= osd_login -+# These binaries go in /sbin (not /usr/sbin), and that cannot be -+# overridden at config time. -+sbindir = /sbin - --EXTRA_DIST= $(OSD_LOGIN_FILES) -- --all-local: $(OSD_LOGIN_FILES) -- --install-data-hook: -- $(INSTALL) --mode 755 osd_login $(DESTDIR)/sbin/osd_login -+sbin_SCRIPTS = osd_login - - MAINTAINERCLEANFILES = Makefile.in diff --git a/nfs-utils.1.2.7-rc1.patch b/nfs-utils.1.2.7-rc1.patch deleted file mode 100644 index cc63336..0000000 --- a/nfs-utils.1.2.7-rc1.patch +++ /dev/null @@ -1,283 +0,0 @@ -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index ec251fa..d01ba2f 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -250,21 +251,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername, - if ((p = strstr(buf, "port")) != NULL) - sscanf(p, "port: %127s\n", port); - -- /* check service, program, and version */ -- if (memcmp(service, "nfs", 3) != 0) -- return -1; -+ /* get program, and version numbers */ - *prog = atoi(program + 1); /* skip open paren */ - *vers = atoi(version); - -- if (strlen(service) == 3 ) { -- if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) && -- (*vers != 4))) -- goto fail; -- } else if (memcmp(service, "nfs4_cb", 7) == 0) { -- if (*vers != 1) -- goto fail; -- } -- - if (!addrstr_to_sockaddr(addr, address, port)) - goto fail; - -@@ -398,10 +388,10 @@ process_clnt_dir_files(struct clnt_info * clp) - static int - get_poll_index(int *ind) - { -- int i; -+ unsigned int i; - - *ind = -1; -- for (i=0; id_name, "clnt", 4) -- && !find_client(namelist[i]->d_name, pipe_name)) -+ if (!strncmp(namelist[i]->d_name, "clnt", 4) -+ && !find_client(namelist[i]->d_name, pipe_name)) - process_clnt_dir(namelist[i]->d_name, pipe_name); - free(namelist[i]); - } -@@ -962,12 +955,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - - printerr(1, "handling krb5 upcall (%s)\n", clp->dirname); - -- if (tgtname) { -- if (clp->servicename) { -- free(clp->servicename); -- clp->servicename = strdup(tgtname); -- } -- } - token.length = 0; - token.value = NULL; - memset(&pd, 0, sizeof(struct authgss_private_data)); -@@ -1016,7 +1003,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - int success = 0; - do { - gssd_refresh_krb5_machine_credential(clp->servername, -- NULL, service); -+ NULL, service, -+ tgtname); - /* - * Get a list of credential cache names and try each - * of them until one works or we've tried them all -diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c -index 60ba594..aeb8f70 100644 ---- a/utils/gssd/krb5_util.c -+++ b/utils/gssd/krb5_util.c -@@ -774,12 +774,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt, - } - - /* -- * Find a keytab entry to use for a given target hostname. -+ * Find a keytab entry to use for a given target realm. - * Tries to find the most appropriate keytab to use given the - * name of the host we are trying to connect with. -+ * -+ * Note: the tgtname contains a hostname in the realm that we -+ * are authenticating to. It may, or may not be the same as -+ * the server hostname. - */ - static int --find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, -+find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname, - krb5_keytab_entry *kte, const char **svcnames) - { - krb5_error_code code; -@@ -795,7 +799,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, - - - /* Get full target hostname */ -- retval = get_full_hostname(hostname, targethostname, -+ retval = get_full_hostname(tgtname, targethostname, - sizeof(targethostname)); - if (retval) - goto out; -@@ -1128,7 +1132,7 @@ gssd_get_krb5_machine_cred_list(char ***list) - if (ple->ccname) { - /* Make sure cred is up-to-date before returning it */ - retval = gssd_refresh_krb5_machine_credential(NULL, ple, -- NULL); -+ NULL, NULL); - if (retval) - continue; - if (i + 1 > listsize) { -@@ -1219,7 +1223,8 @@ gssd_destroy_krb5_machine_creds(void) - int - gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service) -+ char *service, -+ char *tgtname) - { - krb5_error_code code = 0; - krb5_context context; -@@ -1258,7 +1263,10 @@ gssd_refresh_krb5_machine_credential(char *hostname, - if (ple == NULL) { - krb5_keytab_entry kte; - -- code = find_keytab_entry(context, kt, hostname, &kte, svcnames); -+ if (tgtname == NULL) -+ tgtname = hostname; -+ -+ code = find_keytab_entry(context, kt, tgtname, &kte, svcnames); - if (code) { - printerr(0, "ERROR: %s: no usable keytab entry found " - "in keytab %s for connection with host %s\n", -diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h -index cd6e107..9f41625 100644 ---- a/utils/gssd/krb5_util.h -+++ b/utils/gssd/krb5_util.h -@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername); - void gssd_destroy_krb5_machine_creds(void); - int gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service); -+ char *service, -+ char *tgtname); - char *gssd_k5_err_msg(krb5_context context, krb5_error_code code); - void gssd_k5_get_default_realm(char **def_realm); - -diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c -index 6c34faf..1d44d34 100644 ---- a/utils/gssd/svcgssd_krb5.c -+++ b/utils/gssd/svcgssd_krb5.c -@@ -38,6 +38,7 @@ - - #include - #include -+#include - #include - #include - -@@ -98,6 +99,12 @@ parse_enctypes(char *enctypes) - if (n == 0) - return ENOENT; - -+ /* Skip pass any non digits */ -+ while (*enctypes && isdigit(*enctypes) == 0) -+ enctypes++; -+ if (*enctypes == '\0') -+ return EINVAL; -+ - /* Allocate space for enctypes array */ - if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) { - return ENOMEM; -diff --git a/utils/mount/error.c b/utils/mount/error.c -index 83ad1d2..f8fc13f 100644 ---- a/utils/mount/error.c -+++ b/utils/mount/error.c -@@ -225,7 +225,7 @@ void mount_error(const char *spec, const char *mount_point, int error) - case ENOENT: - if (spec) - nfs_error(_("%s: mounting %s failed, " -- "reason given by server:\n %s"), -+ "reason given by server: %s"), - progname, spec, strerror(error)); - else - nfs_error(_("%s: mount point %s does not exist"), -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 9b4197b..8ee3024 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -666,6 +666,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) - case EOPNOTSUPP: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -@@ -761,6 +762,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) - case ECONNREFUSED: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c -index e950ec6..c13f305 100644 ---- a/utils/mountd/cache.c -+++ b/utils/mountd/cache.c -@@ -109,12 +109,10 @@ static void auth_unix_ip(FILE *f) - struct addrinfo *ai = NULL; - - ai = client_resolve(tmp->ai_addr); -- if (ai == NULL) -- goto out; -- client = client_compose(ai); -- freeaddrinfo(ai); -- if (!client) -- goto out; -+ if (ai) { -+ client = client_compose(ai); -+ freeaddrinfo(ai); -+ } - } - qword_print(f, "nfsd"); - qword_print(f, ipaddr); -@@ -127,7 +125,6 @@ static void auth_unix_ip(FILE *f) - xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT"); - - free(client); --out: - freeaddrinfo(tmp); - - } -diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c -index 9801b9c..4334340 100644 ---- a/utils/nfsdcltrack/nfsdcltrack.c -+++ b/utils/nfsdcltrack/nfsdcltrack.c -@@ -379,6 +379,17 @@ cltrack_legacy_gracedone(void) - while ((entry = readdir(v4recovery))) { - int len; - -+ /* skip "." and ".." */ -+ if (entry->d_name[0] == '.') { -+ switch (entry->d_name[1]) { -+ case '\0': -+ continue; -+ case '.': -+ if (entry->d_name[2] == '\0') -+ continue; -+ } -+ } -+ - /* borrow the clientid blob for this */ - len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname, - entry->d_name); diff --git a/nfs-utils.1.2.8.rc3.patch b/nfs-utils.1.2.8.rc3.patch deleted file mode 100644 index 7c332cc..0000000 --- a/nfs-utils.1.2.8.rc3.patch +++ /dev/null @@ -1,592 +0,0 @@ -diff --git a/support/export/rmtab.c b/support/export/rmtab.c -index 31c0f50..d16b3b3 100644 ---- a/support/export/rmtab.c -+++ b/support/export/rmtab.c -@@ -1,7 +1,7 @@ - /* -- * support/export/rmntab.c -+ * support/export/rmtab.c - * -- * Interface to the rmnt file. -+ * Interface to the rmtab file. - * - */ - -@@ -12,7 +12,7 @@ - #include - #include - #include --#include "xmalloc.h" -+ - #include "misc.h" - #include "nfslib.h" - #include "exportfs.h" -diff --git a/support/export/xtab.c b/support/export/xtab.c -index 2a43193..e953071 100644 ---- a/support/export/xtab.c -+++ b/support/export/xtab.c -@@ -14,7 +14,7 @@ - #include - #include - #include --#include "xmalloc.h" -+ - #include "nfslib.h" - #include "exportfs.h" - #include "xio.h" -diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c -index e641c45..61e07a8 100644 ---- a/support/nfs/cacheio.c -+++ b/support/nfs/cacheio.c -@@ -162,11 +162,16 @@ int qword_eol(FILE *f) - { - int err; - -- fprintf(f,"\n"); -- err = fflush(f); -- if (err) { -- xlog_warn("qword_eol: fflush failed: errno %d (%s)", -+ err = fprintf(f,"\n"); -+ if (err < 0) { -+ xlog_warn("qword_eol: fprintf failed: errno %d (%s)", - errno, strerror(errno)); -+ } else { -+ err = fflush(f); -+ if (err) { -+ xlog_warn("qword_eol: fflush failed: errno %d (%s)", -+ errno, strerror(errno)); -+ } - } - /* - * We must send one line (and one line only) in a single write -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index ec251fa..d01ba2f 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -250,21 +251,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername, - if ((p = strstr(buf, "port")) != NULL) - sscanf(p, "port: %127s\n", port); - -- /* check service, program, and version */ -- if (memcmp(service, "nfs", 3) != 0) -- return -1; -+ /* get program, and version numbers */ - *prog = atoi(program + 1); /* skip open paren */ - *vers = atoi(version); - -- if (strlen(service) == 3 ) { -- if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) && -- (*vers != 4))) -- goto fail; -- } else if (memcmp(service, "nfs4_cb", 7) == 0) { -- if (*vers != 1) -- goto fail; -- } -- - if (!addrstr_to_sockaddr(addr, address, port)) - goto fail; - -@@ -398,10 +388,10 @@ process_clnt_dir_files(struct clnt_info * clp) - static int - get_poll_index(int *ind) - { -- int i; -+ unsigned int i; - - *ind = -1; -- for (i=0; id_name, "clnt", 4) -- && !find_client(namelist[i]->d_name, pipe_name)) -+ if (!strncmp(namelist[i]->d_name, "clnt", 4) -+ && !find_client(namelist[i]->d_name, pipe_name)) - process_clnt_dir(namelist[i]->d_name, pipe_name); - free(namelist[i]); - } -@@ -962,12 +955,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - - printerr(1, "handling krb5 upcall (%s)\n", clp->dirname); - -- if (tgtname) { -- if (clp->servicename) { -- free(clp->servicename); -- clp->servicename = strdup(tgtname); -- } -- } - token.length = 0; - token.value = NULL; - memset(&pd, 0, sizeof(struct authgss_private_data)); -@@ -1016,7 +1003,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - int success = 0; - do { - gssd_refresh_krb5_machine_credential(clp->servername, -- NULL, service); -+ NULL, service, -+ tgtname); - /* - * Get a list of credential cache names and try each - * of them until one works or we've tried them all -diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c -index 60ba594..aeb8f70 100644 ---- a/utils/gssd/krb5_util.c -+++ b/utils/gssd/krb5_util.c -@@ -774,12 +774,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt, - } - - /* -- * Find a keytab entry to use for a given target hostname. -+ * Find a keytab entry to use for a given target realm. - * Tries to find the most appropriate keytab to use given the - * name of the host we are trying to connect with. -+ * -+ * Note: the tgtname contains a hostname in the realm that we -+ * are authenticating to. It may, or may not be the same as -+ * the server hostname. - */ - static int --find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, -+find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname, - krb5_keytab_entry *kte, const char **svcnames) - { - krb5_error_code code; -@@ -795,7 +799,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, - - - /* Get full target hostname */ -- retval = get_full_hostname(hostname, targethostname, -+ retval = get_full_hostname(tgtname, targethostname, - sizeof(targethostname)); - if (retval) - goto out; -@@ -1128,7 +1132,7 @@ gssd_get_krb5_machine_cred_list(char ***list) - if (ple->ccname) { - /* Make sure cred is up-to-date before returning it */ - retval = gssd_refresh_krb5_machine_credential(NULL, ple, -- NULL); -+ NULL, NULL); - if (retval) - continue; - if (i + 1 > listsize) { -@@ -1219,7 +1223,8 @@ gssd_destroy_krb5_machine_creds(void) - int - gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service) -+ char *service, -+ char *tgtname) - { - krb5_error_code code = 0; - krb5_context context; -@@ -1258,7 +1263,10 @@ gssd_refresh_krb5_machine_credential(char *hostname, - if (ple == NULL) { - krb5_keytab_entry kte; - -- code = find_keytab_entry(context, kt, hostname, &kte, svcnames); -+ if (tgtname == NULL) -+ tgtname = hostname; -+ -+ code = find_keytab_entry(context, kt, tgtname, &kte, svcnames); - if (code) { - printerr(0, "ERROR: %s: no usable keytab entry found " - "in keytab %s for connection with host %s\n", -diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h -index cd6e107..9f41625 100644 ---- a/utils/gssd/krb5_util.h -+++ b/utils/gssd/krb5_util.h -@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername); - void gssd_destroy_krb5_machine_creds(void); - int gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service); -+ char *service, -+ char *tgtname); - char *gssd_k5_err_msg(krb5_context context, krb5_error_code code); - void gssd_k5_get_default_realm(char **def_realm); - -diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c -index 6c34faf..1d44d34 100644 ---- a/utils/gssd/svcgssd_krb5.c -+++ b/utils/gssd/svcgssd_krb5.c -@@ -38,6 +38,7 @@ - - #include - #include -+#include - #include - #include - -@@ -98,6 +99,12 @@ parse_enctypes(char *enctypes) - if (n == 0) - return ENOENT; - -+ /* Skip pass any non digits */ -+ while (*enctypes && isdigit(*enctypes) == 0) -+ enctypes++; -+ if (*enctypes == '\0') -+ return EINVAL; -+ - /* Allocate space for enctypes array */ - if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) { - return ENOMEM; -diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c -index e80efb4..beba9c4 100644 ---- a/utils/idmapd/idmapd.c -+++ b/utils/idmapd/idmapd.c -@@ -145,7 +145,6 @@ static void svrreopen(int, short, void *); - static int nfsopen(struct idmap_client *); - static void nfscb(int, short, void *); - static void nfsdcb(int, short, void *); --static int validateascii(char *, u_int32_t); - static int addfield(char **, ssize_t *, char *); - static int getfield(char **, char *, size_t); - -@@ -425,7 +424,8 @@ dirscancb(int UNUSED(fd), short UNUSED(which), void *data) - pipefsdir, ents[i]->d_name); - - if ((ic->ic_dirfd = open(path, O_RDONLY, 0)) == -1) { -- xlog_warn("dirscancb: open(%s): %s", path, strerror(errno)); -+ if (verbose > 0) -+ xlog_warn("dirscancb: open(%s): %s", path, strerror(errno)); - free(ic); - goto out; - } -@@ -642,6 +642,8 @@ out: - static void - imconv(struct idmap_client *ic, struct idmap_msg *im) - { -+ u_int32_t len; -+ - switch (im->im_conv) { - case IDMAP_CONV_IDTONAME: - idtonameres(im); -@@ -652,10 +654,10 @@ imconv(struct idmap_client *ic, struct idmap_msg *im) - im->im_id, im->im_name); - break; - case IDMAP_CONV_NAMETOID: -- if (validateascii(im->im_name, sizeof(im->im_name)) == -1) { -- im->im_status |= IDMAP_STATUS_INVALIDMSG; -+ len = strnlen(im->im_name, IDMAP_NAMESZ - 1); -+ /* Check for NULL termination just to be careful */ -+ if (im->im_name[len+1] != '\0') - return; -- } - nametoidres(im); - if (verbose > 1) - xlog_warn("%s %s: (%s) name \"%s\" -> id \"%d\"", -@@ -855,25 +857,6 @@ nametoidres(struct idmap_msg *im) - } - - static int --validateascii(char *string, u_int32_t len) --{ -- u_int32_t i; -- -- for (i = 0; i < len; i++) { -- if (string[i] == '\0') -- break; -- -- if (string[i] & 0x80) -- return (-1); -- } -- -- if ((i >= len) || string[i] != '\0') -- return (-1); -- -- return (i + 1); --} -- --static int - addfield(char **bpp, ssize_t *bsizp, char *fld) - { - char ch, *bp = *bpp; -diff --git a/utils/mount/error.c b/utils/mount/error.c -index 83ad1d2..f8fc13f 100644 ---- a/utils/mount/error.c -+++ b/utils/mount/error.c -@@ -225,7 +225,7 @@ void mount_error(const char *spec, const char *mount_point, int error) - case ENOENT: - if (spec) - nfs_error(_("%s: mounting %s failed, " -- "reason given by server:\n %s"), -+ "reason given by server: %s"), - progname, spec, strerror(error)); - else - nfs_error(_("%s: mount point %s does not exist"), -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 9b4197b..8ee3024 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -666,6 +666,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) - case EOPNOTSUPP: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -@@ -761,6 +762,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) - case ECONNREFUSED: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c -index 508040a..330cab5 100644 ---- a/utils/mountd/auth.c -+++ b/utils/mountd/auth.c -@@ -10,10 +10,12 @@ - #include - #endif - -+#include - #include - #include - #include - #include -+#include - #include - - #include "sockaddr.h" -@@ -21,7 +23,6 @@ - #include "nfslib.h" - #include "exportfs.h" - #include "mountd.h" --#include "xmalloc.h" - #include "v4root.h" - - enum auth_error -diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c -index e950ec6..45012be 100644 ---- a/utils/mountd/cache.c -+++ b/utils/mountd/cache.c -@@ -29,7 +29,6 @@ - #include "nfslib.h" - #include "exportfs.h" - #include "mountd.h" --#include "xmalloc.h" - #include "fsloc.h" - #include "pseudoflavors.h" - -@@ -109,12 +108,10 @@ static void auth_unix_ip(FILE *f) - struct addrinfo *ai = NULL; - - ai = client_resolve(tmp->ai_addr); -- if (ai == NULL) -- goto out; -- client = client_compose(ai); -- freeaddrinfo(ai); -- if (!client) -- goto out; -+ if (ai) { -+ client = client_compose(ai); -+ freeaddrinfo(ai); -+ } - } - qword_print(f, "nfsd"); - qword_print(f, ipaddr); -@@ -127,7 +124,6 @@ static void auth_unix_ip(FILE *f) - xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT"); - - free(client); --out: - freeaddrinfo(tmp); - - } -@@ -347,6 +343,30 @@ static char *next_mnt(void **v, char *p) - return me->mnt_dir; - } - -+static int is_subdirectory(char *child, char *parent) -+{ -+ size_t l = strlen(parent); -+ -+ if (strcmp(parent, "/") == 0) -+ return 1; -+ -+ return strcmp(child, parent) == 0 -+ || (strncmp(child, parent, l) == 0 && child[l] == '/'); -+} -+ -+static int path_matches(nfs_export *exp, char *path) -+{ -+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) -+ return is_subdirectory(path, exp->m_export.e_path); -+ return strcmp(path, exp->m_export.e_path) == 0; -+} -+ -+static int -+export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai) -+{ -+ return path_matches(exp, path) && client_matches(exp, dom, ai); -+} -+ - /* True iff e1 is a child of e2 and e2 has crossmnt set: */ - static bool subexport(struct exportent *e1, struct exportent *e2) - { -@@ -354,8 +374,7 @@ static bool subexport(struct exportent *e1, struct exportent *e2) - size_t l2 = strlen(p2); - - return e2->e_flags & NFSEXP_CROSSMOUNT -- && strncmp(p1, p2, l2) == 0 -- && p1[l2] == '/'; -+ && is_subdirectory(p1, p2); - } - - struct parsed_fsid { -@@ -756,27 +775,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex - return qword_eol(f); - } - --static int is_subdirectory(char *child, char *parent) --{ -- size_t l = strlen(parent); -- -- return strcmp(child, parent) == 0 -- || (strncmp(child, parent, l) == 0 && child[l] == '/'); --} -- --static int path_matches(nfs_export *exp, char *path) --{ -- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) -- return is_subdirectory(path, exp->m_export.e_path); -- return strcmp(path, exp->m_export.e_path) == 0; --} -- --static int --export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai) --{ -- return path_matches(exp, path) && client_matches(exp, dom, ai); --} -- - static nfs_export * - lookup_export(char *dom, char *path, struct addrinfo *ai) - { -@@ -830,6 +828,7 @@ lookup_export(char *dom, char *path, struct addrinfo *ai) - - #ifdef HAVE_NFS_PLUGIN_H - #include -+#include - #include - - /* -@@ -1094,6 +1093,7 @@ static struct exportent *lookup_junction(char *dom, const char *pathname, - struct addrinfo *ai) - { - struct exportent *exp; -+ struct link_map *map; - void *handle; - - handle = dlopen("libnfsjunct.so", RTLD_NOW); -@@ -1101,6 +1101,11 @@ static struct exportent *lookup_junction(char *dom, const char *pathname, - xlog(D_GENERAL, "%s: dlopen: %s", __func__, dlerror()); - return NULL; - } -+ -+ if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0) -+ xlog(D_GENERAL, "%s: loaded plug-in %s", -+ __func__, map->l_name); -+ - (void)dlerror(); /* Clear any error */ - - exp = invoke_junction_ops(handle, dom, pathname, ai); -diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c -index 9801b9c..4334340 100644 ---- a/utils/nfsdcltrack/nfsdcltrack.c -+++ b/utils/nfsdcltrack/nfsdcltrack.c -@@ -379,6 +379,17 @@ cltrack_legacy_gracedone(void) - while ((entry = readdir(v4recovery))) { - int len; - -+ /* skip "." and ".." */ -+ if (entry->d_name[0] == '.') { -+ switch (entry->d_name[1]) { -+ case '\0': -+ continue; -+ case '.': -+ if (entry->d_name[2] == '\0') -+ continue; -+ } -+ } -+ - /* borrow the clientid blob for this */ - len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname, - entry->d_name); -diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c -index 4ecb03c..fd576d9 100644 ---- a/utils/statd/rmtcall.c -+++ b/utils/statd/rmtcall.c -@@ -68,21 +68,19 @@ statd_get_socket(void) - { - struct sockaddr_in sin; - struct servent *se; -- int loopcnt = 100; -+ const int loopcnt = 100; -+ int i, tmp_sockets[loopcnt]; - - if (sockfd >= 0) - return sockfd; - -- while (loopcnt-- > 0) { -- -- if (sockfd >= 0) close(sockfd); -+ for (i = 0; i < loopcnt; ++i) { - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - xlog(L_ERROR, "%s: Can't create socket: %m", __func__); -- return -1; -+ break; - } - -- - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -@@ -96,7 +94,16 @@ statd_get_socket(void) - if (se == NULL) - break; - /* rather not use that port, try again */ -+ -+ tmp_sockets[i] = sockfd; - } -+ -+ while (--i >= 0) -+ close(tmp_sockets[i]); -+ -+ if (sockfd < 0) -+ return -1; -+ - FD_SET(sockfd, &SVC_FDSET); - return sockfd; - } diff --git a/nfs-utils.1.2.8.rc4.patch b/nfs-utils.1.2.8.rc4.patch deleted file mode 100644 index 69f47a2..0000000 --- a/nfs-utils.1.2.8.rc4.patch +++ /dev/null @@ -1,1575 +0,0 @@ -diff --git a/README b/README -index 61702f7..7034c00 100644 ---- a/README -+++ b/README -@@ -1,4 +1,4 @@ --This is version 1.2.6 of nfs-utils, the Linux NFS utility package. -+This is nfs-utils, the Linux NFS userland utility package. - - - 0. PROJECT RESOURCES -diff --git a/aclocal/librpcsecgss.m4 b/aclocal/librpcsecgss.m4 -index d1dd25e..e833141 100644 ---- a/aclocal/librpcsecgss.m4 -+++ b/aclocal/librpcsecgss.m4 -@@ -14,6 +14,8 @@ AC_DEFUN([AC_LIBRPCSECGSS], [ - [AC_DEFINE([HAVE_AUTHGSS_SET_DEBUG_LEVEL], 1, - [Define to 1 if you have the `authgss_set_debug_level' function.])]) - -+ AC_DEFINE([HAVE_AUTHGSS_FREE_PRIVATE_DATA], 1, -+ [Define to 1 if your rpcsec library provides authgss_free_private_data,]) - fi - - ])dnl -diff --git a/aclocal/libtirpc.m4 b/aclocal/libtirpc.m4 -index 19b8361..b823364 100644 ---- a/aclocal/libtirpc.m4 -+++ b/aclocal/libtirpc.m4 -@@ -24,6 +24,13 @@ AC_DEFUN([AC_LIBTIRPC], [ - fi - - if test "$enable_tirpc" != "no"; then -+ -+ dnl Check if library contains authgss_free_private_data -+ AC_CHECK_LIB([tirpc], [authgss_free_private_data], [have_free_private_data=yes], -+ [have_free_private_data=no]) -+ fi -+ -+ if test "$enable_tirpc" != "no"; then - dnl also must have the headers installed where we expect - dnl look for headers; add -I compiler option if found - AC_CHECK_HEADERS([${tirpc_header_dir}/netconfig.h], -@@ -42,6 +49,10 @@ AC_DEFUN([AC_LIBTIRPC], [ - AC_DEFINE([HAVE_LIBTIRPC], 1, - [Define to 1 if you have and wish to use libtirpc.]) - LIBTIRPC="-ltirpc" -+ if test "$have_free_private_data" = "yes"; then -+ AC_DEFINE([HAVE_AUTHGSS_FREE_PRIVATE_DATA], 1, -+ [Define to 1 if your rpcsec library provides authgss_free_private_data,]) -+ fi - else - LIBTIRPC="" - fi -diff --git a/configure.ac b/configure.ac -index f461219..cc7f3b4 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -358,7 +358,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \ - stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \ - sys/param.h sys/socket.h sys/time.h sys/vfs.h \ - syslog.h unistd.h com_err.h et/com_err.h \ -- ifaddrs.h nfs-plugin.h]) -+ ifaddrs.h nfs-plugin.h libio.h]) - - dnl ************************************************************* - dnl Checks for typedefs, structures, and compiler characteristics -diff --git a/support/export/rmtab.c b/support/export/rmtab.c -index 31c0f50..d16b3b3 100644 ---- a/support/export/rmtab.c -+++ b/support/export/rmtab.c -@@ -1,7 +1,7 @@ - /* -- * support/export/rmntab.c -+ * support/export/rmtab.c - * -- * Interface to the rmnt file. -+ * Interface to the rmtab file. - * - */ - -@@ -12,7 +12,7 @@ - #include - #include - #include --#include "xmalloc.h" -+ - #include "misc.h" - #include "nfslib.h" - #include "exportfs.h" -diff --git a/support/export/xtab.c b/support/export/xtab.c -index 2a43193..e953071 100644 ---- a/support/export/xtab.c -+++ b/support/export/xtab.c -@@ -14,7 +14,7 @@ - #include - #include - #include --#include "xmalloc.h" -+ - #include "nfslib.h" - #include "exportfs.h" - #include "xio.h" -diff --git a/support/include/sockaddr.h b/support/include/sockaddr.h -index 72766db..a1c30f9 100644 ---- a/support/include/sockaddr.h -+++ b/support/include/sockaddr.h -@@ -20,7 +20,13 @@ - #ifndef NFS_UTILS_SOCKADDR_H - #define NFS_UTILS_SOCKADDR_H - -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#ifdef HAVE_LIBIO_H - #include -+#endif - #include - #include - #include -diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c -index e641c45..61e07a8 100644 ---- a/support/nfs/cacheio.c -+++ b/support/nfs/cacheio.c -@@ -162,11 +162,16 @@ int qword_eol(FILE *f) - { - int err; - -- fprintf(f,"\n"); -- err = fflush(f); -- if (err) { -- xlog_warn("qword_eol: fflush failed: errno %d (%s)", -+ err = fprintf(f,"\n"); -+ if (err < 0) { -+ xlog_warn("qword_eol: fprintf failed: errno %d (%s)", - errno, strerror(errno)); -+ } else { -+ err = fflush(f); -+ if (err) { -+ xlog_warn("qword_eol: fflush failed: errno %d (%s)", -+ errno, strerror(errno)); -+ } - } - /* - * We must send one line (and one line only) in a single write -diff --git a/support/nfs/exports.c b/support/nfs/exports.c -index 84a2b08..6c08a2b 100644 ---- a/support/nfs/exports.c -+++ b/support/nfs/exports.c -@@ -643,6 +643,8 @@ bad_option: - cp++; - } - -+ if (ep->e_secinfo[0].flav == NULL) -+ secinfo_addflavor(find_flavor("sys"), ep); - fix_pseudoflavor_flags(ep); - ep->e_squids = squids; - ep->e_sqgids = sqgids; -diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py -index d909632..dfbef87 100644 ---- a/tools/nfs-iostat/nfs-iostat.py -+++ b/tools/nfs-iostat/nfs-iostat.py -@@ -3,6 +3,8 @@ - """Emulate iostat for NFS mount points using /proc/self/mountstats - """ - -+from __future__ import print_function -+ - __copyright__ = """ - Copyright (C) 2005, Chuck Lever - -@@ -201,9 +203,9 @@ class DeviceData: - result = DeviceData() - - # copy self into result -- for key, value in self.__nfs_data.iteritems(): -+ for key, value in self.__nfs_data.items(): - result.__nfs_data[key] = value -- for key, value in self.__rpc_data.iteritems(): -+ for key, value in self.__rpc_data.items(): - result.__rpc_data[key] = value - - # compute the difference of each item in the list -@@ -233,9 +235,9 @@ class DeviceData: - client_bytes_read = float(nfs_stats['serverreadbytes'] - nfs_stats['directreadbytes']) - ratio = ((app_bytes_read - client_bytes_read) * 100) / app_bytes_read - -- print -- print 'app bytes: %f client bytes %f' % (app_bytes_read, client_bytes_read) -- print 'Data cache hit ratio: %4.2f%%' % ratio -+ print() -+ print('app bytes: %f client bytes %f' % (app_bytes_read, client_bytes_read)) -+ print('Data cache hit ratio: %4.2f%%' % ratio) - - def __print_attr_cache_stats(self, sample_time): - """Print attribute cache efficiency stats -@@ -255,13 +257,13 @@ class DeviceData: - data_invalidates = float(nfs_stats['datainvalidates']) - attr_invalidates = float(nfs_stats['attrinvalidates']) - -- print -- print '%d inode revalidations, hitting in cache %4.2f%% of the time' % \ -- (revalidates, ratio) -- print '%d open operations (mandatory GETATTR requests)' % opens -+ print() -+ print('%d inode revalidations, hitting in cache %4.2f%% of the time' % \ -+ (revalidates, ratio)) -+ print('%d open operations (mandatory GETATTR requests)' % opens) - if getattr_ops != 0: -- print '%4.2f%% of GETATTRs resulted in data cache invalidations' % \ -- ((data_invalidates * 100) / getattr_ops) -+ print('%4.2f%% of GETATTRs resulted in data cache invalidations' % \ -+ ((data_invalidates * 100) / getattr_ops)) - - def __print_dir_cache_stats(self, sample_time): - """Print directory stats -@@ -277,13 +279,13 @@ class DeviceData: - lookups = nfs_stats['vfslookup'] - getdents = nfs_stats['vfsreaddir'] - -- print -- print '%d open operations (pathname lookups)' % opens -- print '%d dentry revalidates and %d vfs lookup requests' % \ -- (dentry_revals, lookups), -- print 'resulted in %d LOOKUPs on the wire' % lookup_ops -- print '%d vfs getdents calls resulted in %d READDIRs on the wire' % \ -- (getdents, readdir_ops) -+ print() -+ print('%d open operations (pathname lookups)' % opens) -+ print('%d dentry revalidates and %d vfs lookup requests' % \ -+ (dentry_revals, lookups)) -+ print('resulted in %d LOOKUPs on the wire' % lookup_ops) -+ print('%d vfs getdents calls resulted in %d READDIRs on the wire' % \ -+ (getdents, readdir_ops)) - - def __print_page_stats(self, sample_time): - """Print page cache stats -@@ -297,33 +299,33 @@ class DeviceData: - vfswritepages = nfs_stats['vfswritepages'] - pages_written = nfs_stats['writepages'] - -- print -- print '%d nfs_readpage() calls read %d pages' % \ -- (vfsreadpage, vfsreadpage) -- print '%d nfs_readpages() calls read %d pages' % \ -- (vfsreadpages, pages_read - vfsreadpage), -+ print() -+ print('%d nfs_readpage() calls read %d pages' % \ -+ (vfsreadpage, vfsreadpage)) -+ print('%d nfs_readpages() calls read %d pages' % \ -+ (vfsreadpages, pages_read - vfsreadpage)) - if vfsreadpages != 0: -- print '(%.1f pages per call)' % \ -- (float(pages_read - vfsreadpage) / vfsreadpages) -+ print('(%.1f pages per call)' % \ -+ (float(pages_read - vfsreadpage) / vfsreadpages)) - else: -- print -- -- print -- print '%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage'] -- print '%d nfs_writepage() calls wrote %d pages' % \ -- (vfswritepage, vfswritepage) -- print '%d nfs_writepages() calls wrote %d pages' % \ -- (vfswritepages, pages_written - vfswritepage), -+ print() -+ -+ print() -+ print('%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage']) -+ print('%d nfs_writepage() calls wrote %d pages' % \ -+ (vfswritepage, vfswritepage)) -+ print('%d nfs_writepages() calls wrote %d pages' % \ -+ (vfswritepages, pages_written - vfswritepage)) - if (vfswritepages) != 0: -- print '(%.1f pages per call)' % \ -- (float(pages_written - vfswritepage) / vfswritepages) -+ print('(%.1f pages per call)' % \ -+ (float(pages_written - vfswritepage) / vfswritepages)) - else: -- print -+ print() - - congestionwaits = nfs_stats['congestionwait'] - if congestionwaits != 0: -- print -- print '%d congestion waits' % congestionwaits -+ print() -+ print('%d congestion waits' % congestionwaits) - - def __print_rpc_op_stats(self, op, sample_time): - """Print generic stats for one RPC op -@@ -351,15 +353,15 @@ class DeviceData: - exe_per_op = 0.0 - - op += ':' -- print '%s' % op.lower().ljust(15), -- print ' ops/s\t\t kB/s\t\t kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)' -+ print('%s' % op.lower().ljust(15)) -+ print(' ops/s\t\t kB/s\t\t kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)') - -- print '\t\t%7.3f' % (ops / sample_time), -- print '\t%7.3f' % (kilobytes / sample_time), -- print '\t%7.3f' % kb_per_op, -- print ' %7d (%3.1f%%)' % (retrans, retrans_percent), -- print '\t%7.3f' % rtt_per_op, -- print '\t%7.3f' % exe_per_op -+ print('\t\t%7.3f' % (ops / sample_time)) -+ print('\t%7.3f' % (kilobytes / sample_time)) -+ print('\t%7.3f' % kb_per_op) -+ print(' %7d (%3.1f%%)' % (retrans, retrans_percent)) -+ print('\t%7.3f' % rtt_per_op) -+ print('\t%7.3f' % exe_per_op) - - def ops(self, sample_time): - sends = float(self.__rpc_data['rpcsends']) -@@ -384,14 +386,14 @@ class DeviceData: - else: - backlog = 0.0 - -- print -- print '%s mounted on %s:' % \ -- (self.__nfs_data['export'], self.__nfs_data['mountpoint']) -- print -+ print() -+ print('%s mounted on %s:' % \ -+ (self.__nfs_data['export'], self.__nfs_data['mountpoint'])) -+ print() - -- print ' op/s\t\trpc bklog' -- print '%7.2f' % (sends / sample_time), -- print '\t%7.2f' % backlog -+ print(' op/s\t\trpc bklog') -+ print('%7.2f' % (sends / sample_time)) -+ print('\t%7.2f' % backlog) - - if which == 0: - self.__print_rpc_op_stats('READ', sample_time) -@@ -424,7 +426,7 @@ def parse_stats_file(filename): - ms_dict = dict() - key = '' - -- f = file(filename) -+ f = open(filename) - for line in f.readlines(): - words = line.split() - if len(words) == 0: -@@ -494,7 +496,7 @@ def list_nfs_mounts(givenlist, mountstats): - if stats.is_nfs_mountpoint(): - list += [device] - else: -- for device, descr in mountstats.iteritems(): -+ for device, descr in mountstats.items(): - stats = DeviceData() - stats.parse_stats(descr) - if stats.is_nfs_mountpoint(): -@@ -527,7 +529,7 @@ client are listed. - usage="usage: %prog [ [ ] ] [ ] [ ]", - description=mydescription, - version='version %s' % Iostats_version) -- parser.set_defaults(which=0, sort=False, list=sys.maxint) -+ parser.set_defaults(which=0, sort=False, list=sys.maxsize) - - statgroup = OptionGroup(parser, "Statistics Options", - 'File I/O is displayed unless one of the following is specified:') -@@ -572,29 +574,29 @@ client are listed. - try: - interval = int(arg) - except: -- print 'Illegal value %s' % arg -+ print('Illegal value %s' % arg) - return - if interval > 0: - interval_seen = True - else: -- print 'Illegal value %s' % arg -+ print('Illegal value %s' % arg) - return - elif not count_seen: - try: - count = int(arg) - except: -- print 'Ilegal value %s' % arg -+ print('Ilegal value %s' % arg) - return - if count > 0: - count_seen = True - else: -- print 'Illegal value %s' % arg -+ print('Illegal value %s' % arg) - return - - # make certain devices contains only NFS mount points - devices = list_nfs_mounts(origdevices, mountstats) - if len(devices) == 0: -- print 'No NFS mount points were found' -+ print('No NFS mount points were found') - return - - -@@ -616,7 +618,7 @@ client are listed. - # we need to recheck the devices list when reparsing - devices = list_nfs_mounts(origdevices,mountstats) - if len(devices) == 0: -- print 'No NFS mount points were found' -+ print('No NFS mount points were found') - return - count -= 1 - else: -@@ -630,7 +632,7 @@ client are listed. - # we need to recheck the devices list when reparsing - devices = list_nfs_mounts(origdevices,mountstats) - if len(devices) == 0: -- print 'No NFS mount points were found' -+ print('No NFS mount points were found') - return - - # -@@ -641,7 +643,7 @@ prog = os.path.basename(sys.argv[0]) - try: - iostat_command(prog) - except KeyboardInterrupt: -- print 'Caught ^C... exiting' -+ print('Caught ^C... exiting') - sys.exit(1) - - sys.exit(0) -diff --git a/tools/rpcdebug/Makefile.am b/tools/rpcdebug/Makefile.am -index 39b70c9..b0a3e1f 100644 ---- a/tools/rpcdebug/Makefile.am -+++ b/tools/rpcdebug/Makefile.am -@@ -1,15 +1,9 @@ - ## Process this file with automake to produce Makefile.in - --CC=$(CC_FOR_BUILD) --LIBTOOL = @LIBTOOL@ --tag=CC -- - man8_MANS = rpcdebug.man - EXTRA_DIST = $(man8_MANS) - - sbin_PROGRAMS = rpcdebug - rpcdebug_SOURCES = rpcdebug.c --rpcdebug_CFLAGS=$(CFLAGS_FOR_BUILD) --rpcdebug_CPPFLAGS=$(CPPFLAGS_FOR_BUILD) -I$(top_srcdir)/support/include --rpcdebug_LDFLAGS=$(LDFLAGS_FOR_BUILD) - - MAINTAINERCLEANFILES = Makefile.in -diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c -index a3292c9..0be2517 100644 ---- a/utils/gssd/gssd.c -+++ b/utils/gssd/gssd.c -@@ -147,7 +147,7 @@ main(int argc, char *argv[]) - #ifdef HAVE_SET_ALLOWABLE_ENCTYPES - limit_to_legacy_enctypes = 1; - #else -- errx(1, "Setting encryption type not support by Kerberos libraries."); -+ errx(1, "Encryption type limits not supported by Kerberos libraries."); - #endif - break; - default: -diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man -index c74b7e8..79d9bf9 100644 ---- a/utils/gssd/gssd.man -+++ b/utils/gssd/gssd.man -@@ -2,22 +2,197 @@ - .\" rpc.gssd(8) - .\" - .\" Copyright (C) 2003 J. Bruce Fields --.TH rpc.gssd 8 "14 Mar 2007" -+.\" -+.TH rpc.gssd 8 "20 Feb 2013" - .SH NAME --rpc.gssd \- rpcsec_gss daemon -+rpc.gssd \- RPCSEC_GSS daemon - .SH SYNOPSIS --.B "rpc.gssd [-f] [-n] [-k keytab] [-l] [-p pipefsdir] [-v] [-r] [-d ccachedir]" -+.B rpc.gssd -+.RB [ \-fMnlvr ] -+.RB [ \-k -+.IR keytab ] -+.RB [ \-p -+.IR pipefsdir ] -+.RB [ \-d -+.IR ccachedir ] -+.RB [ \-t -+.IR timeout ] -+.RB [ \-R -+.IR realm ] -+.SH INTRODUCTION -+The RPCSEC_GSS protocol, defined in RFC 5403, is used to provide -+strong security for RPC-based protocols such as NFS. -+.P -+Before exchanging RPC requests using RPCSEC_GSS, an RPC client must -+establish a GSS -+.IR "security context" . -+A security context is shared state on each -+end of a network transport that enables GSS-API security services. -+.P -+Security contexts are established using -+.IR "security credentials" . -+A credential grants temporary access to a secure network service, -+much as a railway ticket grants temporary access to use a rail service. -+.P -+A user typically obtains a credential by providing a password to the -+.BR kinit (1) -+command, or via a PAM library at login time. -+A credential acquired with a -+.I user principal -+is known as a -+.I user credential -+(see -+.BR kerberos (1) -+for more on principals). -+.P -+For certain operations, a credential is required -+which represents no user, -+is otherwise unprivileged, -+and is always available. -+This is referred to as a -+.IR "machine credential" . -+.P -+Machine credentials are typically established using a -+.IR "service principal" , -+whose encrypted password, called its -+.IR key , -+is stored in a file, called a -+.IR keytab , -+to avoid requiring a user prompt. -+A machine credential effectively does not expire because the system -+can renew it as needed without user intervention. -+.P -+Once obtained, credentials are typically stored in local temporary files -+with well-known pathnames. - .SH DESCRIPTION --The rpcsec_gss protocol gives a means of using the gss-api generic security --api to provide security for protocols using rpc (in particular, nfs). Before --exchanging any rpc requests using rpcsec_gss, the rpc client must first --establish a security context. The linux kernel's implementation of rpcsec_gss --depends on the userspace daemon -+To establish GSS security contexts using these credential files, -+the Linux kernel RPC client depends on a userspace daemon called -+.BR rpc.gssd . -+The -+.B rpc.gssd -+daemon uses the rpc_pipefs filesystem to communicate with the kernel. -+.SS User Credentials -+When a user authenticates using a command such as -+.BR kinit (1), -+the resulting credential is stored in a file with a well-known name -+constructed using the user's UID. -+.P -+To interact with an NFS server -+on behalf of a particular Kerberos-authenticated user, -+the Linux kernel RPC client requests that -+.B rpc.gssd -+initialize a security context with the credential -+in that user's credential file. -+.P -+Typically, credential files are placed in -+.IR /tmp . -+However, -+.B rpc.gssd -+can search for credential files in more than one directory. -+See the description of the -+.B -d -+option for details. -+.SS Machine Credentials -+A user credential is established by a user and -+is then shared with the kernel and -+.BR rpc.gssd . -+A machine credential is established by -+.B rpc.gssd -+for the kernel when there is no user. -+Therefore -+.B rpc.gssd -+must already have the materials on hand to establish this credential -+without requiring user intervention. -+.P -+.B rpc.gssd -+searches the local system's keytab for a principal and key to use -+to establish the machine credential. -+By default, - .B rpc.gssd --to establish security contexts. The -+assumes the file -+.I /etc/krb5.keytab -+contains principals and keys that can be used to obtain machine credentials. -+.P -+.B rpc.gssd -+searches in the following order for a principal to use. -+The first matching credential is used. -+For the search, and are replaced with the local -+system's hostname and Kerberos realm. -+.sp -+ $@ -+.br -+ root/@ -+.br -+ nfs/@ -+.br -+ host/@ -+.br -+ root/@ -+.br -+ nfs/@ -+.br -+ host/@ -+.sp -+The entries match on the service name and realm, but ignore the hostname. -+These can be used if a principal matching the local host's name is not found. -+.P -+Note that the first principal in the search order is a user principal -+that enables Kerberized NFS when the local system is joined -+to an Active Directory domain using Samba. -+A password for this principal must be provided in the local system's keytab. -+.P -+You can specify another keytab by using the -+.B -k -+option if -+.I /etc/krb5.keytab -+does not exist or does not provide one of these principals. -+.SS Credentials for UID 0 -+UID 0 is a special case. -+By default -+.B rpc.gssd -+uses the system's machine credentials for UID 0 accesses -+that require GSS authentication. -+This limits the privileges of the root user -+when accessing network resources that require authentication. -+.P -+Specify the -+.B -n -+option when starting - .B rpc.gssd --daemon uses files in the rpc_pipefs filesystem to communicate with the kernel. -- -+if you'd like to force the root user to obtain a user credential -+rather than use the local system's machine credential. -+.P -+When -+.B -n -+is specified, -+the kernel continues to request a GSS context established -+with a machine credential for NFSv4 operations, -+such as SETCLIENTID or RENEW, that manage state. -+If -+.B rpc.gssd -+cannot obtain a machine credential (say, the local system has -+no keytab), NFSv4 operations that require machine credentials will fail. -+.SS Encryption types -+A realm administrator can choose to add keys encoded in a number of different -+encryption types to the local system's keytab. -+For instance, a host/ principal might have keys for the -+.BR aes256-cts-hmac-sha1-96 , -+.BR aes128-cts-hmac-sha1-96 , -+.BR des3-cbc-sha1 ", and" -+.BR arcfour-hmac " encryption types." -+This permits -+.B rpc.gssd -+to choose an appropriate encryption type that the target NFS server -+supports. -+.P -+These encryption types are stronger than legacy single-DES encryption types. -+To interoperate in environments where servers support -+only weak encryption types, -+you can restrict your client to use only single-DES encryption types -+by specifying the -+.B -l -+option when starting -+.BR rpc.gssd . - .SH OPTIONS - .TP - .B -f -@@ -26,115 +201,76 @@ Runs - in the foreground and sends output to stderr (as opposed to syslogd) - .TP - .B -n --By default, --.B rpc.gssd --treats accesses by the user with UID 0 specially, and uses --"machine credentials" for all accesses by that user which --require Kerberos authentication. --With the \-n option, "machine credentials" will not be used --for accesses by UID 0. Instead, credentials must be obtained --manually like all other users. Use of this option means that --"root" must manually obtain Kerberos credentials before --attempting to mount an nfs filesystem requiring Kerberos --authentication. -+When specified, UID 0 is forced to obtain user credentials -+which are used instead of the local system's machine credentials. - .TP --.B -k keytab -+.BI "-k " keytab - Tells - .B rpc.gssd - to use the keys found in - .I keytab --to obtain "machine credentials". --The default value is "/etc/krb5.keytab". --.IP --Previous versions of --.B rpc.gssd --used only "nfs/*" keys found within the keytab. --To be more consistent with other implementations, we now look for --specific keytab entries. The search order for keytabs to be used --for "machine credentials" is now: --.br -- $@ --.br -- root/@ --.br -- nfs/@ --.br -- host/@ --.br -- root/@ --.br -- nfs/@ --.br -- host/@ --.IP --If this search order does not use the correct key then provide a --keytab file that contains only correct keys. -+to obtain machine credentials. -+The default value is -+.IR /etc/krb5.keytab . - .TP - .B -l --Tells -+When specified, restricts - .B rpc.gssd --to limit session keys to Single DES even if the kernel supports stronger --encryption types. Service ticket encryption is still governed by what --the KDC believes the target server supports. This way the client can --access a server that has strong keys in its keytab for ticket decryption --but whose kernel only supports Single DES. --.IP --The alternative is to put only Single DES keys in the server's keytab --and limit encryption types for its principal to Single DES on the KDC --which will cause service tickets for this server to be encrypted using --only Single DES and (as a side-effect) contain only Single DES session --keys. --.IP --This legacy behaviour is only required for older servers --(pre nfs-utils-1.2.4). If the server has a recent kernel, Kerberos --implementation and nfs-utils it will work just fine with stronger --encryption. --.IP --.B Note: --This option is only available with Kerberos libraries that --support setable encryption types. -+to sessions to weak encryption types such as -+.BR des-cbc-crc . -+This option is available only when the local system's Kerberos library -+supports settable encryption types. - .TP --.B -p path -+.BI "-p " path - Tells - .B rpc.gssd - where to look for the rpc_pipefs filesystem. The default value is --"/var/lib/nfs/rpc_pipefs". -+.IR /var/lib/nfs/rpc_pipefs . - .TP --.B -d directory --Tells -+.BI "-d " search-path -+This option specifies a colon separated list of directories that -+.B rpc.gssd -+searches for credential files. The default value is -+.IR /tmp:/run/user/%U . -+The literal sequence "%U" can be specified to substitue the UID -+of the user for whom credentials are being searched. -+.TP -+.B -M -+By default, machine credentials are stored in files in the first -+directory in the credential directory search path (see the -+.B -d -+option). When -+.B -M -+is set, - .B rpc.gssd --where to look for Kerberos credential files. The default value is --"/tmp:/run/user/%U". --This can also be a colon separated list of directories to be searched for --Kerberos credential files. The sequence "%U", if used, is replaced with --the UID of the user for whom credentials are being searched. --Note that if machine credentials are being --stored in files, then the first directory on this list is where the --machine credentials are stored. -+stores machine credentials in memory instead. - .TP - .B -v - Increases the verbosity of the output (can be specified multiple times). - .TP - .B -r --If the rpcsec_gss library supports setting debug level, -+If the RPCSEC_GSS library supports setting debug level, - increases the verbosity of the output (can be specified multiple times). - .TP --.B -R realm -+.BI "-R " realm - Kerberos tickets from this - .I realm - will be preferred when scanning available credentials cache files to be - used to create a context. By default, the default realm, as configured - in the Kerberos configuration file, is preferred. - .TP --.B -t timeout --Timeout, in seconds, for kernel gss contexts. This option allows you to force -+.BI "-t " timeout -+Timeout, in seconds, for kernel GSS contexts. This option allows you to force - new kernel contexts to be negotiated after - .I timeout - seconds, which allows changing Kerberos tickets and identities frequently. - The default is no explicit timeout, which means the kernel context will live - the lifetime of the Kerberos service ticket used in its creation. - .SH SEE ALSO --.BR rpc.svcgssd(8) -+.BR rpc.svcgssd (8), -+.BR kerberos (1), -+.BR kinit (1), -+.BR krb5.conf (5) - .SH AUTHORS - .br - Dug Song -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index ec251fa..698f86f 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -168,7 +169,7 @@ sockaddr_to_hostname(const struct sockaddr *sa, const char *addr) - { - socklen_t addrlen; - int err; -- char *hostname; -+ char *hostname; - char hbuf[NI_MAXHOST]; - - switch (sa->sa_family) { -@@ -250,21 +251,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername, - if ((p = strstr(buf, "port")) != NULL) - sscanf(p, "port: %127s\n", port); - -- /* check service, program, and version */ -- if (memcmp(service, "nfs", 3) != 0) -- return -1; -+ /* get program, and version numbers */ - *prog = atoi(program + 1); /* skip open paren */ - *vers = atoi(version); - -- if (strlen(service) == 3 ) { -- if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) && -- (*vers != 4))) -- goto fail; -- } else if (memcmp(service, "nfs4_cb", 7) == 0) { -- if (*vers != 1) -- goto fail; -- } -- - if (!addrstr_to_sockaddr(addr, address, port)) - goto fail; - -@@ -398,10 +388,10 @@ process_clnt_dir_files(struct clnt_info * clp) - static int - get_poll_index(int *ind) - { -- int i; -+ unsigned int i; - - *ind = -1; -- for (i=0; id_name, "clnt", 4) -- && !find_client(namelist[i]->d_name, pipe_name)) -+ if (!strncmp(namelist[i]->d_name, "clnt", 4) -+ && !find_client(namelist[i]->d_name, pipe_name)) - process_clnt_dir(namelist[i]->d_name, pipe_name); - free(namelist[i]); - } -@@ -715,7 +708,7 @@ out_err: - - /* - * If the port isn't already set, do an rpcbind query to the remote server -- * using the program and version and get the port. -+ * using the program and version and get the port. - * - * Newer kernels send the value of the port= mount option in the "info" - * file for the upcall or '0' for NFSv2/3. For NFSv4 it sends the value -@@ -962,12 +955,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - - printerr(1, "handling krb5 upcall (%s)\n", clp->dirname); - -- if (tgtname) { -- if (clp->servicename) { -- free(clp->servicename); -- clp->servicename = strdup(tgtname); -- } -- } - token.length = 0; - token.value = NULL; - memset(&pd, 0, sizeof(struct authgss_private_data)); -@@ -1016,7 +1003,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - int success = 0; - do { - gssd_refresh_krb5_machine_credential(clp->servername, -- NULL, service); -+ NULL, service, -+ tgtname); - /* - * Get a list of credential cache names and try each - * of them until one works or we've tried them all -@@ -1025,7 +1013,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - printerr(0, "ERROR: No credentials found " - "for connection to server %s\n", - clp->servername); -- goto out_return_error; -+ goto out_return_error; - } - for (ccname = credlist; ccname && *ccname; ccname++) { - gssd_setup_krb5_machine_gss_ccache(*ccname); -@@ -1035,12 +1023,12 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - /* Success! */ - success++; - break; -- } -+ } - printerr(2, "WARNING: Failed to create machine krb5 context " - "with credentials cache %s for server %s\n", - *ccname, clp->servername); - } -- gssd_free_krb5_machine_cred_list(credlist); -+ gssd_free_krb5_machine_cred_list(credlist); - if (!success) { - if(nocache == 0) { - nocache++; -@@ -1090,7 +1078,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname, - out: - if (token.value) - free(token.value); --#ifndef HAVE_LIBTIRPC -+#ifdef HAVE_AUTHGSS_FREE_PRIVATE_DATA - if (pd.pd_ctx_hndl.length != 0) - authgss_free_private_data(&pd); - #endif -@@ -1237,6 +1225,6 @@ out: - free(enctypes); - free(target); - free(service); -- return; -+ return; - } - -diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c -index 60ba594..20b55b3 100644 ---- a/utils/gssd/krb5_util.c -+++ b/utils/gssd/krb5_util.c -@@ -169,13 +169,13 @@ select_krb5_ccache(const struct dirent *d) - - /* - * Look in directory "dirname" for files that look like they -- * are Kerberos Credential Cache files for a given UID. Return -- * non-zero and the dirent pointer for the entry most likely to be -- * what we want. Otherwise, return zero and no dirent pointer. -- * The caller is responsible for freeing the dirent if one is returned. -+ * are Kerberos Credential Cache files for a given UID. - * -- * Returns 0 if a valid-looking entry was found and a non-zero error -- * code otherwise. -+ * Returns 0 if a valid-looking entry is found. "*cctype" is -+ * set to the name of the cache type. A pointer to the dirent -+ * is planted in "*d". Caller must free "*d" with free(3). -+ * -+ * Otherwise, a negative errno is returned. - */ - static int - gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, -@@ -350,6 +350,11 @@ gssd_get_single_krb5_cred(krb5_context context, - - memset(&my_creds, 0, sizeof(my_creds)); - -+ /* -+ * Workaround for clock skew among NFS server, NFS client and KDC -+ * 300 because clock skew must be within 300sec for kerberos -+ */ -+ now += 300; - if (ple->ccname && ple->endtime > now && !nocache) { - printerr(2, "INFO: Credentials in CC '%s' are good until %d\n", - ple->ccname, ple->endtime); -@@ -774,12 +779,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt, - } - - /* -- * Find a keytab entry to use for a given target hostname. -+ * Find a keytab entry to use for a given target realm. - * Tries to find the most appropriate keytab to use given the - * name of the host we are trying to connect with. -+ * -+ * Note: the tgtname contains a hostname in the realm that we -+ * are authenticating to. It may, or may not be the same as -+ * the server hostname. - */ - static int --find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, -+find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname, - krb5_keytab_entry *kte, const char **svcnames) - { - krb5_error_code code; -@@ -795,14 +804,14 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, - - - /* Get full target hostname */ -- retval = get_full_hostname(hostname, targethostname, -+ retval = get_full_hostname(tgtname, targethostname, - sizeof(targethostname)); - if (retval) - goto out; - - /* Get full local hostname */ -- retval = gethostname(myhostname, sizeof(myhostname)); -- if (retval) { -+ if (gethostname(myhostname, sizeof(myhostname)) == -1) { -+ retval = errno; - k5err = gssd_k5_err_msg(context, retval); - printerr(1, "%s while getting local hostname\n", k5err); - goto out; -@@ -1033,7 +1042,7 @@ err_cache: - * given only a UID. We really need more information, but we - * do the best we can. - * -- * Returns 0 if a ccache was found, and a non-zero error code otherwise. -+ * Returns 0 if a ccache was found, or a negative errno otherwise. - */ - int - gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirpattern) -@@ -1078,7 +1087,7 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirpattern) - printerr(2, "using %s as credentials cache for client with " - "uid %u for server %s\n", buf, uid, servername); - gssd_set_krb5_ccache_name(buf); -- return err; -+ return 0; - } - - /* -@@ -1128,7 +1137,7 @@ gssd_get_krb5_machine_cred_list(char ***list) - if (ple->ccname) { - /* Make sure cred is up-to-date before returning it */ - retval = gssd_refresh_krb5_machine_credential(NULL, ple, -- NULL); -+ NULL, NULL); - if (retval) - continue; - if (i + 1 > listsize) { -@@ -1208,9 +1217,9 @@ gssd_destroy_krb5_machine_creds(void) - "cache '%s'\n", k5err, ple->ccname); - } - } -+ krb5_free_context(context); - out: - free(k5err); -- krb5_free_context(context); - } - - /* -@@ -1219,7 +1228,8 @@ gssd_destroy_krb5_machine_creds(void) - int - gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service) -+ char *service, -+ char *tgtname) - { - krb5_error_code code = 0; - krb5_context context; -@@ -1252,19 +1262,22 @@ gssd_refresh_krb5_machine_credential(char *hostname, - k5err = gssd_k5_err_msg(context, code); - printerr(0, "ERROR: %s: %s while resolving keytab '%s'\n", - __func__, k5err, keytabfile); -- goto out; -+ goto out_free_context; - } - - if (ple == NULL) { - krb5_keytab_entry kte; - -- code = find_keytab_entry(context, kt, hostname, &kte, svcnames); -+ if (tgtname == NULL) -+ tgtname = hostname; -+ -+ code = find_keytab_entry(context, kt, tgtname, &kte, svcnames); - if (code) { - printerr(0, "ERROR: %s: no usable keytab entry found " - "in keytab %s for connection with host %s\n", - __FUNCTION__, keytabfile, hostname); - retval = code; -- goto out; -+ goto out_free_kt; - } - - ple = get_ple_by_princ(context, kte.principal); -@@ -1280,14 +1293,15 @@ gssd_refresh_krb5_machine_credential(char *hostname, - __FUNCTION__, pname ? pname : "", - hostname); - if (pname) k5_free_unparsed_name(context, pname); -- goto out; -+ goto out_free_kt; - } - } - retval = gssd_get_single_krb5_cred(context, kt, ple, 0); --out: -- if (kt) -- krb5_kt_close(context, kt); -+out_free_kt: -+ krb5_kt_close(context, kt); -+out_free_context: - krb5_free_context(context); -+out: - free(k5err); - return retval; - } -diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h -index cd6e107..9f41625 100644 ---- a/utils/gssd/krb5_util.h -+++ b/utils/gssd/krb5_util.h -@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername); - void gssd_destroy_krb5_machine_creds(void); - int gssd_refresh_krb5_machine_credential(char *hostname, - struct gssd_k5_kt_princ *ple, -- char *service); -+ char *service, -+ char *tgtname); - char *gssd_k5_err_msg(krb5_context context, krb5_error_code code); - void gssd_k5_get_default_realm(char **def_realm); - -diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c -index 6c34faf..1d44d34 100644 ---- a/utils/gssd/svcgssd_krb5.c -+++ b/utils/gssd/svcgssd_krb5.c -@@ -38,6 +38,7 @@ - - #include - #include -+#include - #include - #include - -@@ -98,6 +99,12 @@ parse_enctypes(char *enctypes) - if (n == 0) - return ENOENT; - -+ /* Skip pass any non digits */ -+ while (*enctypes && isdigit(*enctypes) == 0) -+ enctypes++; -+ if (*enctypes == '\0') -+ return EINVAL; -+ - /* Allocate space for enctypes array */ - if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) { - return ENOMEM; -diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c -index e80efb4..beba9c4 100644 ---- a/utils/idmapd/idmapd.c -+++ b/utils/idmapd/idmapd.c -@@ -145,7 +145,6 @@ static void svrreopen(int, short, void *); - static int nfsopen(struct idmap_client *); - static void nfscb(int, short, void *); - static void nfsdcb(int, short, void *); --static int validateascii(char *, u_int32_t); - static int addfield(char **, ssize_t *, char *); - static int getfield(char **, char *, size_t); - -@@ -425,7 +424,8 @@ dirscancb(int UNUSED(fd), short UNUSED(which), void *data) - pipefsdir, ents[i]->d_name); - - if ((ic->ic_dirfd = open(path, O_RDONLY, 0)) == -1) { -- xlog_warn("dirscancb: open(%s): %s", path, strerror(errno)); -+ if (verbose > 0) -+ xlog_warn("dirscancb: open(%s): %s", path, strerror(errno)); - free(ic); - goto out; - } -@@ -642,6 +642,8 @@ out: - static void - imconv(struct idmap_client *ic, struct idmap_msg *im) - { -+ u_int32_t len; -+ - switch (im->im_conv) { - case IDMAP_CONV_IDTONAME: - idtonameres(im); -@@ -652,10 +654,10 @@ imconv(struct idmap_client *ic, struct idmap_msg *im) - im->im_id, im->im_name); - break; - case IDMAP_CONV_NAMETOID: -- if (validateascii(im->im_name, sizeof(im->im_name)) == -1) { -- im->im_status |= IDMAP_STATUS_INVALIDMSG; -+ len = strnlen(im->im_name, IDMAP_NAMESZ - 1); -+ /* Check for NULL termination just to be careful */ -+ if (im->im_name[len+1] != '\0') - return; -- } - nametoidres(im); - if (verbose > 1) - xlog_warn("%s %s: (%s) name \"%s\" -> id \"%d\"", -@@ -855,25 +857,6 @@ nametoidres(struct idmap_msg *im) - } - - static int --validateascii(char *string, u_int32_t len) --{ -- u_int32_t i; -- -- for (i = 0; i < len; i++) { -- if (string[i] == '\0') -- break; -- -- if (string[i] & 0x80) -- return (-1); -- } -- -- if ((i >= len) || string[i] != '\0') -- return (-1); -- -- return (i + 1); --} -- --static int - addfield(char **bpp, ssize_t *bsizp, char *fld) - { - char ch, *bp = *bpp; -diff --git a/utils/mount/error.c b/utils/mount/error.c -index 83ad1d2..f8fc13f 100644 ---- a/utils/mount/error.c -+++ b/utils/mount/error.c -@@ -225,7 +225,7 @@ void mount_error(const char *spec, const char *mount_point, int error) - case ENOENT: - if (spec) - nfs_error(_("%s: mounting %s failed, " -- "reason given by server:\n %s"), -+ "reason given by server: %s"), - progname, spec, strerror(error)); - else - nfs_error(_("%s: mount point %s does not exist"), -diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man -index c15de98..374ac06 100644 ---- a/utils/mount/nfs.man -+++ b/utils/mount/nfs.man -@@ -347,6 +347,13 @@ using an automounter (refer to - .BR automount (8) - for details). - .TP 1.5i -+.BR rdirplus " / " nordirplus -+Selects whether to use NFS v3 or v4 READDIRPLUS requests. -+If this option is not specified, the NFS client uses READDIRPLUS requests -+on NFS v3 or v4 mounts to read small directories. -+Some applications perform better if the client uses only READDIR requests -+for all directories. -+.TP 1.5i - .BI retry= n - The number of minutes that the - .BR mount (8) -@@ -708,13 +715,6 @@ Disabling the NFSACL sideband protocol may be necessary - if the negotiation causes problems on the client or server. - Refer to the SECURITY CONSIDERATIONS section for more details. - .TP 1.5i --.BR rdirplus " / " nordirplus --Selects whether to use NFS version 3 READDIRPLUS requests. --If this option is not specified, the NFS client uses READDIRPLUS requests --on NFS version 3 mounts to read small directories. --Some applications perform better if the client uses only READDIR requests --for all directories. --.TP 1.5i - .BR local_lock= mechanism - Specifies whether to use local locking for any or both of the flock and the - POSIX locking mechanisms. -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 9b4197b..8ee3024 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c -@@ -666,6 +666,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) - case EOPNOTSUPP: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -@@ -761,6 +762,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) - case ECONNREFUSED: - case EHOSTUNREACH: - case ETIMEDOUT: -+ case EACCES: - continue; - default: - goto out; -diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c -index 508040a..330cab5 100644 ---- a/utils/mountd/auth.c -+++ b/utils/mountd/auth.c -@@ -10,10 +10,12 @@ - #include - #endif - -+#include - #include - #include - #include - #include -+#include - #include - - #include "sockaddr.h" -@@ -21,7 +23,6 @@ - #include "nfslib.h" - #include "exportfs.h" - #include "mountd.h" --#include "xmalloc.h" - #include "v4root.h" - - enum auth_error -diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c -index e950ec6..978698d 100644 ---- a/utils/mountd/cache.c -+++ b/utils/mountd/cache.c -@@ -29,7 +29,6 @@ - #include "nfslib.h" - #include "exportfs.h" - #include "mountd.h" --#include "xmalloc.h" - #include "fsloc.h" - #include "pseudoflavors.h" - -@@ -109,12 +108,10 @@ static void auth_unix_ip(FILE *f) - struct addrinfo *ai = NULL; - - ai = client_resolve(tmp->ai_addr); -- if (ai == NULL) -- goto out; -- client = client_compose(ai); -- freeaddrinfo(ai); -- if (!client) -- goto out; -+ if (ai) { -+ client = client_compose(ai); -+ freeaddrinfo(ai); -+ } - } - qword_print(f, "nfsd"); - qword_print(f, ipaddr); -@@ -127,7 +124,6 @@ static void auth_unix_ip(FILE *f) - xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT"); - - free(client); --out: - freeaddrinfo(tmp); - - } -@@ -347,6 +343,30 @@ static char *next_mnt(void **v, char *p) - return me->mnt_dir; - } - -+static int is_subdirectory(char *child, char *parent) -+{ -+ size_t l = strlen(parent); -+ -+ if (strcmp(parent, "/") == 0) -+ return 1; -+ -+ return strcmp(child, parent) == 0 -+ || (strncmp(child, parent, l) == 0 && child[l] == '/'); -+} -+ -+static int path_matches(nfs_export *exp, char *path) -+{ -+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) -+ return is_subdirectory(path, exp->m_export.e_path); -+ return strcmp(path, exp->m_export.e_path) == 0; -+} -+ -+static int -+export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai) -+{ -+ return path_matches(exp, path) && client_matches(exp, dom, ai); -+} -+ - /* True iff e1 is a child of e2 and e2 has crossmnt set: */ - static bool subexport(struct exportent *e1, struct exportent *e2) - { -@@ -354,8 +374,8 @@ static bool subexport(struct exportent *e1, struct exportent *e2) - size_t l2 = strlen(p2); - - return e2->e_flags & NFSEXP_CROSSMOUNT -- && strncmp(p1, p2, l2) == 0 -- && p1[l2] == '/'; -+ && strncmp(p1, p2, l2) == 0 -+ && p1[l2] == '/'; - } - - struct parsed_fsid { -@@ -756,27 +776,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex - return qword_eol(f); - } - --static int is_subdirectory(char *child, char *parent) --{ -- size_t l = strlen(parent); -- -- return strcmp(child, parent) == 0 -- || (strncmp(child, parent, l) == 0 && child[l] == '/'); --} -- --static int path_matches(nfs_export *exp, char *path) --{ -- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) -- return is_subdirectory(path, exp->m_export.e_path); -- return strcmp(path, exp->m_export.e_path) == 0; --} -- --static int --export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai) --{ -- return path_matches(exp, path) && client_matches(exp, dom, ai); --} -- - static nfs_export * - lookup_export(char *dom, char *path, struct addrinfo *ai) - { -@@ -830,6 +829,7 @@ lookup_export(char *dom, char *path, struct addrinfo *ai) - - #ifdef HAVE_NFS_PLUGIN_H - #include -+#include - #include - - /* -@@ -1094,6 +1094,7 @@ static struct exportent *lookup_junction(char *dom, const char *pathname, - struct addrinfo *ai) - { - struct exportent *exp; -+ struct link_map *map; - void *handle; - - handle = dlopen("libnfsjunct.so", RTLD_NOW); -@@ -1101,6 +1102,11 @@ static struct exportent *lookup_junction(char *dom, const char *pathname, - xlog(D_GENERAL, "%s: dlopen: %s", __func__, dlerror()); - return NULL; - } -+ -+ if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0) -+ xlog(D_GENERAL, "%s: loaded plug-in %s", -+ __func__, map->l_name); -+ - (void)dlerror(); /* Clear any error */ - - exp = invoke_junction_ops(handle, dom, pathname, ai); -diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c -index 726b50d..34d098a 100644 ---- a/utils/mountd/v4root.c -+++ b/utils/mountd/v4root.c -@@ -55,7 +55,8 @@ static nfs_export pseudo_root = { - .m_warned = 0, - }; - --void set_pseudofs_security(struct exportent *pseudo, struct exportent *source) -+static void -+set_pseudofs_security(struct exportent *pseudo, struct exportent *source) - { - struct sec_entry *se; - int i; -@@ -121,7 +122,8 @@ v4root_support(void) - return 0; - } - --int pseudofs_update(char *hostname, char *path, nfs_export *source) -+static int -+pseudofs_update(char *hostname, char *path, nfs_export *source) - { - nfs_export *exp; - -diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c -index 9801b9c..4334340 100644 ---- a/utils/nfsdcltrack/nfsdcltrack.c -+++ b/utils/nfsdcltrack/nfsdcltrack.c -@@ -379,6 +379,17 @@ cltrack_legacy_gracedone(void) - while ((entry = readdir(v4recovery))) { - int len; - -+ /* skip "." and ".." */ -+ if (entry->d_name[0] == '.') { -+ switch (entry->d_name[1]) { -+ case '\0': -+ continue; -+ case '.': -+ if (entry->d_name[2] == '\0') -+ continue; -+ } -+ } -+ - /* borrow the clientid blob for this */ - len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname, - entry->d_name); -diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c -index 4ecb03c..fd576d9 100644 ---- a/utils/statd/rmtcall.c -+++ b/utils/statd/rmtcall.c -@@ -68,21 +68,19 @@ statd_get_socket(void) - { - struct sockaddr_in sin; - struct servent *se; -- int loopcnt = 100; -+ const int loopcnt = 100; -+ int i, tmp_sockets[loopcnt]; - - if (sockfd >= 0) - return sockfd; - -- while (loopcnt-- > 0) { -- -- if (sockfd >= 0) close(sockfd); -+ for (i = 0; i < loopcnt; ++i) { - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - xlog(L_ERROR, "%s: Can't create socket: %m", __func__); -- return -1; -+ break; - } - -- - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -@@ -96,7 +94,16 @@ statd_get_socket(void) - if (se == NULL) - break; - /* rather not use that port, try again */ -+ -+ tmp_sockets[i] = sockfd; - } -+ -+ while (--i >= 0) -+ close(tmp_sockets[i]); -+ -+ if (sockfd < 0) -+ return -1; -+ - FD_SET(sockfd, &SVC_FDSET); - return sockfd; - } diff --git a/nfs-utils.spec b/nfs-utils.spec index d169a76..5a9b31a 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -1,8 +1,8 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS server Name: nfs-utils URL: http://sourceforge.net/projects/nfs -Version: 1.2.7 -Release: 6%{?dist} +Version: 1.2.8 +Release: 0%{?dist} Epoch: 1 # group all 32bit related archs @@ -36,9 +36,6 @@ Source51: nfs-server.preconfig Source52: nfs-server.postconfig %define nfs_configs %{SOURCE50} %{SOURCE51} %{SOURCE52} -Patch001: nfs-utils.1.2.8.rc4.patch -Patch002: nfs-utils-1.2.7-nfsd-v41.patch - Patch100: nfs-utils-1.2.1-statdpath-man.patch Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch Patch102: nfs-utils-1.2.3-sm-notify-res_init.patch @@ -65,7 +62,7 @@ Provides: start-statd = %{epoch}:%{version}-%{release} License: MIT and GPLv2 and GPLv2+ and BSD Requires: rpcbind, sed, gawk, sh-utils, fileutils, textutils, grep Requires: kmod, keyutils, quota -BuildRequires: libgssglue-devel libevent-devel libcap-devel +BuildRequires: libevent-devel libcap-devel BuildRequires: libnfsidmap-devel libtirpc-devel libblkid-devel BuildRequires: krb5-libs >= 1.4 autoconf >= 2.57 openldap-devel >= 2.2 BuildRequires: automake, libtool, glibc-headers, device-mapper-devel @@ -73,8 +70,8 @@ BuildRequires: krb5-devel, tcp_wrappers-devel, libmount-devel BuildRequires: fedfs-utils-devel >= 0.8.0-7, sqlite-devel Requires(pre): shadow-utils >= 4.0.3-25 Requires(pre): /sbin/chkconfig /sbin/nologin -Requires: libnfsidmap libgssglue libevent -Requires: libtirpc libblkid libcap libmount +Requires: libnfsidmap libevent +Requires: libtirpc >= 0.2.3-1 libblkid libcap libmount Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -94,9 +91,6 @@ This package also contains the mount.nfs and umount.nfs program. %prep %setup -q -%patch001 -p1 -%patch002 -p1 - %patch100 -p1 %patch101 -p1 %patch102 -p1 @@ -300,6 +294,10 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Tue Apr 23 2013 Steve Dickson 1.2.8-0 +- Updated to latest upstream release: 1.2.8 +- Removed the libgssglue dependency + * Mon Apr 1 2013 Steve Dickson 1.2.7-6 - Added v4.1 support rpc.nfsd (bz 947073) diff --git a/sources b/sources index fef4248..29a5b2c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -3b5ca797197765dc0c3a4122720c7716 nfs-utils-1.2.7.tar.bz2 +fb48630b7c145fb9d6602a79c6eaab11 nfs-utils-1.2.8.tar.bz2