diff --git a/nfs-utils-1.2.4-rc6.patch b/nfs-utils-1.2.4-rc8.patch similarity index 53% rename from nfs-utils-1.2.4-rc6.patch rename to nfs-utils-1.2.4-rc8.patch index 09590fc..645af3e 100644 --- a/nfs-utils-1.2.4-rc6.patch +++ b/nfs-utils-1.2.4-rc8.patch @@ -1,20 +1,6 @@ -diff --git a/.gitignore b/.gitignore -index 4bff9e3..f5b5cf0 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -64,6 +64,7 @@ tests/nsm_client/nlm_sm_inter.h - tests/nsm_client/nlm_sm_inter_clnt.c - tests/nsm_client/nlm_sm_inter_svc.c - tests/nsm_client/nlm_sm_inter_xdr.c -+utils/nfsidmap/nfsidmap - # cscope database files - cscope.* - # generic editor backup et al -diff --git a/aclocal/keyutils.m4 b/aclocal/keyutils.m4 -new file mode 100644 -index 0000000..84bc112 ---- /dev/null -+++ b/aclocal/keyutils.m4 +diff -up nfs-utils-1.2.3/aclocal/keyutils.m4.orig nfs-utils-1.2.3/aclocal/keyutils.m4 +--- nfs-utils-1.2.3/aclocal/keyutils.m4.orig 2011-04-20 08:48:36.334265405 -0400 ++++ nfs-utils-1.2.3/aclocal/keyutils.m4 2011-04-20 08:48:36.334265405 -0400 @@ -0,0 +1,11 @@ +dnl Checks for keyutils library and headers +dnl @@ -27,10 +13,9 @@ index 0000000..84bc112 + AC_CHECK_HEADERS([keyutils.h], , + [AC_MSG_ERROR([keyutils.h header not found.])]) +])dnl -diff --git a/aclocal/libnfsidmap.m4 b/aclocal/libnfsidmap.m4 -index cfcde2f..4faa923 100644 ---- a/aclocal/libnfsidmap.m4 -+++ b/aclocal/libnfsidmap.m4 +diff -up nfs-utils-1.2.3/aclocal/libnfsidmap.m4.orig nfs-utils-1.2.3/aclocal/libnfsidmap.m4 +--- nfs-utils-1.2.3/aclocal/libnfsidmap.m4.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/aclocal/libnfsidmap.m4 2011-04-20 08:48:36.334265405 -0400 @@ -14,4 +14,8 @@ AC_DEFUN([AC_LIBNFSIDMAP], [ [AC_DEFINE([HAVE_NFS4_SET_DEBUG], 1, [Define to 1 if you have the `nfs4_set_debug' function.])]) @@ -40,11 +25,23 @@ index cfcde2f..4faa923 100644 + [enable_nfsidmap=no]) + ])dnl -diff --git a/configure.ac b/configure.ac -index 3058be6..92833e3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -136,7 +136,7 @@ AC_ARG_ENABLE(tirpc, +diff -up nfs-utils-1.2.3/configure.ac.orig nfs-utils-1.2.3/configure.ac +--- nfs-utils-1.2.3/configure.ac.orig 2011-04-20 08:48:17.900406953 -0400 ++++ nfs-utils-1.2.3/configure.ac 2011-04-20 08:48:36.335265400 -0400 +@@ -140,11 +140,20 @@ AC_ARG_ENABLE(mount, + enable_mount=$enableval, + enable_mount=yes) + AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"]) ++ ++if test "$enable_mount" = yes; then ++ AC_ARG_ENABLE(libmount-mount, ++ [AC_HELP_STRING([--enable-libmount-mount], ++ [Link mount.nfs with libmount (EXPERIMENTAL)])], ++ enable_libmount=yes, ++ enable_libmount=no) ++fi ++ + AC_ARG_ENABLE(tirpc, [AC_HELP_STRING([--enable-tirpc], [enable use of TI-RPC @<:@default=yes@:>@])], enable_tirpc=$enableval, @@ -53,7 +50,7 @@ index 3058be6..92833e3 100644 AC_ARG_ENABLE(ipv6, [AC_HELP_STRING([--enable-ipv6], [enable support for IPv6 @<:@default=no@:>@])], -@@ -247,6 +247,12 @@ if test "$enable_nfsv4" = yes; then +@@ -255,6 +264,12 @@ if test "$enable_nfsv4" = yes; then dnl check for nfsidmap libraries and headers AC_LIBNFSIDMAP @@ -66,7 +63,21 @@ index 3058be6..92833e3 100644 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 -@@ -435,6 +441,7 @@ AC_CONFIG_FILES([ +@@ -287,6 +302,13 @@ AC_SUBST(LIBCRYPT) + AC_SUBST(LIBBSD) + AC_SUBST(LIBBLKID) + ++if test "$enable_libmount" != no; then ++ AC_CHECK_LIB(mount, mnt_context_do_mount, [LIBMOUNT="-lmount"], AC_MSG_ERROR([libmount needed])) ++ AC_CHECK_HEADER(libmount/libmount.h, , AC_MSG_ERROR([Cannot find libmount header file libmount/libmount.h])) ++fi ++AM_CONDITIONAL(CONFIG_LIBMOUNT, [test "$enable_libmount" = "yes"]) ++AC_SUBST(LIBMOUNT) ++ + if test "$enable_gss" = yes; then + dnl 'gss' requires getnameinfo - at least for gssd_proc.c + AC_CHECK_FUNC([getnameinfo], , [AC_MSG_ERROR([GSSAPI support requires 'getnameinfo' function])]) +@@ -446,6 +468,7 @@ AC_CONFIG_FILES([ utils/mountd/Makefile utils/nfsd/Makefile utils/nfsstat/Makefile @@ -74,10 +85,20 @@ index 3058be6..92833e3 100644 utils/showmount/Makefile utils/statd/Makefile tests/Makefile -diff --git a/support/export/client.c b/support/export/client.c -index dbfc2b1..ba2db8f 100644 ---- a/support/export/client.c -+++ b/support/export/client.c +diff -up nfs-utils-1.2.3/.gitignore.orig nfs-utils-1.2.3/.gitignore +--- nfs-utils-1.2.3/.gitignore.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/.gitignore 2011-04-20 08:48:36.333265412 -0400 +@@ -64,6 +64,7 @@ tests/nsm_client/nlm_sm_inter.h + tests/nsm_client/nlm_sm_inter_clnt.c + tests/nsm_client/nlm_sm_inter_svc.c + tests/nsm_client/nlm_sm_inter_xdr.c ++utils/nfsidmap/nfsidmap + # cscope database files + cscope.* + # generic editor backup et al +diff -up nfs-utils-1.2.3/support/export/client.c.orig nfs-utils-1.2.3/support/export/client.c +--- nfs-utils-1.2.3/support/export/client.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/export/client.c 2011-04-20 08:48:36.336265402 -0400 @@ -178,6 +178,7 @@ out_badprefix: static int init_netmask6(nfs_client *UNUSED(clp), const char *UNUSED(slash)) @@ -86,10 +107,9 @@ index dbfc2b1..ba2db8f 100644 } #endif /* IPV6_SUPPORTED */ -diff --git a/support/export/export.c b/support/export/export.c -index f528603..4fda30a 100644 ---- a/support/export/export.c -+++ b/support/export/export.c +diff -up nfs-utils-1.2.3/support/export/export.c.orig nfs-utils-1.2.3/support/export/export.c +--- nfs-utils-1.2.3/support/export/export.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/export/export.c 2011-04-20 08:48:36.336265402 -0400 @@ -38,6 +38,7 @@ export_free(nfs_export *exp) xfree(exp->m_export.e_sqgids); free(exp->m_export.e_mountpoint); @@ -98,10 +118,9 @@ index f528603..4fda30a 100644 xfree(exp->m_export.e_hostname); xfree(exp); -diff --git a/support/export/hostname.c b/support/export/hostname.c -index 3c55ce7..efcb75c 100644 ---- a/support/export/hostname.c -+++ b/support/export/hostname.c +diff -up nfs-utils-1.2.3/support/export/hostname.c.orig nfs-utils-1.2.3/support/export/hostname.c +--- nfs-utils-1.2.3/support/export/hostname.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/export/hostname.c 2011-04-20 08:48:36.337265398 -0400 @@ -30,10 +30,6 @@ #include "sockaddr.h" #include "exportfs.h" @@ -122,10 +141,31 @@ index 3c55ce7..efcb75c 100644 }; int error; -diff --git a/support/include/nfslib.h b/support/include/nfslib.h -index 3db5bec..cee826b 100644 ---- a/support/include/nfslib.h -+++ b/support/include/nfslib.h +diff -up nfs-utils-1.2.3/support/include/exportfs.h.orig nfs-utils-1.2.3/support/include/exportfs.h +--- nfs-utils-1.2.3/support/include/exportfs.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/include/exportfs.h 2011-04-20 08:48:36.338265391 -0400 +@@ -100,6 +100,7 @@ typedef struct mexport { + } nfs_export; + + #define HASH_TABLE_SIZE 1021 ++#define DEFAULT_TTL (30 * 60) + + typedef struct _exp_hash_entry { + nfs_export * p_first; +diff -up nfs-utils-1.2.3/support/include/misc.h.orig nfs-utils-1.2.3/support/include/misc.h +--- nfs-utils-1.2.3/support/include/misc.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/include/misc.h 2011-04-20 08:48:36.338265391 -0400 +@@ -17,4 +17,7 @@ int weakrandomkey(unsigned char *keyout, + + extern int is_mountpoint(char *path); + ++/* size of the file pointer buffers for rpc procfs files */ ++#define RPC_CHAN_BUF_SIZE 32768 ++ + #endif /* MISC_H */ +diff -up nfs-utils-1.2.3/support/include/nfslib.h.orig nfs-utils-1.2.3/support/include/nfslib.h +--- nfs-utils-1.2.3/support/include/nfslib.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/include/nfslib.h 2011-04-20 08:48:36.339265382 -0400 @@ -25,6 +25,12 @@ #ifndef _PATH_EXPORTS #define _PATH_EXPORTS "/etc/exports" @@ -139,7 +179,15 @@ index 3db5bec..cee826b 100644 #ifndef _PATH_IDMAPDCONF #define _PATH_IDMAPDCONF "/etc/idmapd.conf" #endif -@@ -163,6 +169,12 @@ void closeall(int min); +@@ -89,6 +95,7 @@ struct exportent { + char * e_fslocdata; + char * e_uuid; + struct sec_entry e_secinfo[SECFLAVOR_COUNT+1]; ++ unsigned int e_ttl; + }; + + struct rmtabent { +@@ -163,6 +170,12 @@ void closeall(int min); int svctcp_socket (u_long __number, int __reuse); int svcudp_socket (u_long __number); @@ -152,10 +200,9 @@ index 3db5bec..cee826b 100644 #define UNUSED(x) UNUSED_ ## x __attribute__((unused)) -diff --git a/support/include/rpcmisc.h b/support/include/rpcmisc.h -index c5847fa..0b06457 100644 ---- a/support/include/rpcmisc.h -+++ b/support/include/rpcmisc.h +diff -up nfs-utils-1.2.3/support/include/rpcmisc.h.orig nfs-utils-1.2.3/support/include/rpcmisc.h +--- nfs-utils-1.2.3/support/include/rpcmisc.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/include/rpcmisc.h 2011-04-20 08:48:36.339265382 -0400 @@ -31,7 +31,7 @@ struct rpc_dentry { struct rpc_dtable { @@ -165,24 +212,9 @@ index c5847fa..0b06457 100644 }; #define dtable_ent(func, vers, arg_type, res_type) \ -diff --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am -index 60400b2..05c2fc4 100644 ---- a/support/nfs/Makefile.am -+++ b/support/nfs/Makefile.am -@@ -5,7 +5,7 @@ libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \ - xlog.c xcommon.c wildmat.c nfsclient.c \ - nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \ - svc_socket.c cacheio.c closeall.c nfs_mntent.c conffile.c \ -- svc_create.c -+ svc_create.c atomicio.c strlcpy.c strlcat.c - - MAINTAINERCLEANFILES = Makefile.in - -diff --git a/support/nfs/atomicio.c b/support/nfs/atomicio.c -new file mode 100644 -index 0000000..5e760e6 ---- /dev/null -+++ b/support/nfs/atomicio.c +diff -up nfs-utils-1.2.3/support/nfs/atomicio.c.orig nfs-utils-1.2.3/support/nfs/atomicio.c +--- nfs-utils-1.2.3/support/nfs/atomicio.c.orig 2011-04-20 08:48:36.340265372 -0400 ++++ nfs-utils-1.2.3/support/nfs/atomicio.c 2011-04-20 08:48:36.340265372 -0400 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002 Marius Aamodt Eriksen @@ -238,11 +270,18 @@ index 0000000..5e760e6 + } + return pos; +} -diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c -index 24640f4..798e5f3 100644 ---- a/support/nfs/conffile.c -+++ b/support/nfs/conffile.c -@@ -271,9 +271,9 @@ conf_parse_line(int trans, char *line, size_t sz) +diff -up nfs-utils-1.2.3/support/nfs/conffile.c.orig nfs-utils-1.2.3/support/nfs/conffile.c +--- nfs-utils-1.2.3/support/nfs/conffile.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/nfs/conffile.c 2011-04-20 08:48:36.341265363 -0400 +@@ -251,6 +251,7 @@ conf_parse_line(int trans, char *line, s + } + /* Strip off any blanks before ']' */ + val = line; ++ j=0; + while (*val && !isblank(*val)) + val++, j++; + if (*val) +@@ -271,9 +272,9 @@ conf_parse_line(int trans, char *line, s if (ptr == NULL) return; line = ++ptr; @@ -254,11 +293,18 @@ index 24640f4..798e5f3 100644 xlog_warn("config file error: line %d: " "non-matched '\"', ignoring until next section", ln); } else { -diff --git a/support/nfs/exports.c b/support/nfs/exports.c -index a93941c..1744ed6 100644 ---- a/support/nfs/exports.c -+++ b/support/nfs/exports.c -@@ -332,6 +332,8 @@ dupexportent(struct exportent *dst, struct exportent *src) +diff -up nfs-utils-1.2.3/support/nfs/exports.c.orig nfs-utils-1.2.3/support/nfs/exports.c +--- nfs-utils-1.2.3/support/nfs/exports.c.orig 2011-04-20 08:48:17.904406924 -0400 ++++ nfs-utils-1.2.3/support/nfs/exports.c 2011-04-20 08:48:36.342265353 -0400 +@@ -107,6 +107,7 @@ static void init_exportent (struct expor + ee->e_nsquids = 0; + ee->e_nsqgids = 0; + ee->e_uuid = NULL; ++ ee->e_ttl = DEFAULT_TTL; + } + + struct exportent * +@@ -332,6 +333,8 @@ dupexportent(struct exportent *dst, stru dst->e_mountpoint = strdup(src->e_mountpoint); if (src->e_fslocdata) dst->e_fslocdata = strdup(src->e_fslocdata); @@ -267,11 +313,22 @@ index a93941c..1744ed6 100644 dst->e_hostname = NULL; } -diff --git a/support/nfs/rpcdispatch.c b/support/nfs/rpcdispatch.c -index 984c646..f7c27c9 100644 ---- a/support/nfs/rpcdispatch.c -+++ b/support/nfs/rpcdispatch.c -@@ -32,7 +32,12 @@ rpc_dispatch(struct svc_req *rqstp, SVCXPRT *transp, +diff -up nfs-utils-1.2.3/support/nfs/Makefile.am.orig nfs-utils-1.2.3/support/nfs/Makefile.am +--- nfs-utils-1.2.3/support/nfs/Makefile.am.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/nfs/Makefile.am 2011-04-20 08:48:36.340265372 -0400 +@@ -5,7 +5,7 @@ libnfs_a_SOURCES = exports.c rmtab.c xio + xlog.c xcommon.c wildmat.c nfsclient.c \ + nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \ + svc_socket.c cacheio.c closeall.c nfs_mntent.c conffile.c \ +- svc_create.c ++ svc_create.c atomicio.c strlcpy.c strlcat.c + + MAINTAINERCLEANFILES = Makefile.in + +diff -up nfs-utils-1.2.3/support/nfs/rpcdispatch.c.orig nfs-utils-1.2.3/support/nfs/rpcdispatch.c +--- nfs-utils-1.2.3/support/nfs/rpcdispatch.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/nfs/rpcdispatch.c 2011-04-20 08:48:36.343265345 -0400 +@@ -32,7 +32,12 @@ rpc_dispatch(struct svc_req *rqstp, SVCX return; } dtable += (rqstp->rq_vers - 1); @@ -285,11 +342,9 @@ index 984c646..f7c27c9 100644 svcerr_noproc(transp); return; } -diff --git a/support/nfs/strlcat.c b/support/nfs/strlcat.c -new file mode 100644 -index 0000000..daedd7a ---- /dev/null -+++ b/support/nfs/strlcat.c +diff -up nfs-utils-1.2.3/support/nfs/strlcat.c.orig nfs-utils-1.2.3/support/nfs/strlcat.c +--- nfs-utils-1.2.3/support/nfs/strlcat.c.orig 2011-04-20 08:48:36.343265345 -0400 ++++ nfs-utils-1.2.3/support/nfs/strlcat.c 2011-04-20 08:48:36.343265345 -0400 @@ -0,0 +1,76 @@ +/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */ + @@ -367,11 +422,9 @@ index 0000000..daedd7a + + return(dlen + (s - src)); /* count does not include NUL */ +} -diff --git a/support/nfs/strlcpy.c b/support/nfs/strlcpy.c -new file mode 100644 -index 0000000..a2653ee ---- /dev/null -+++ b/support/nfs/strlcpy.c +diff -up nfs-utils-1.2.3/support/nfs/strlcpy.c.orig nfs-utils-1.2.3/support/nfs/strlcpy.c +--- nfs-utils-1.2.3/support/nfs/strlcpy.c.orig 2011-04-20 08:48:36.344265339 -0400 ++++ nfs-utils-1.2.3/support/nfs/strlcpy.c 2011-04-20 08:48:36.344265339 -0400 @@ -0,0 +1,72 @@ +/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ + @@ -445,10 +498,9 @@ index 0000000..a2653ee + + return(s - src - 1); /* count does not include NUL */ +} -diff --git a/support/nfs/svc_create.c b/support/nfs/svc_create.c -index 59ba505..b3f75ed 100644 ---- a/support/nfs/svc_create.c -+++ b/support/nfs/svc_create.c +diff -up nfs-utils-1.2.3/support/nfs/svc_create.c.orig nfs-utils-1.2.3/support/nfs/svc_create.c +--- nfs-utils-1.2.3/support/nfs/svc_create.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/support/nfs/svc_create.c 2011-04-20 08:48:36.344265339 -0400 @@ -27,6 +27,7 @@ #include #include @@ -526,7 +578,7 @@ index 59ba505..b3f75ed 100644 /* * Set up an appropriate bind address, given @port and @nconf. * -@@ -98,17 +156,113 @@ svc_create_bindaddr(struct netconfig *nconf, const uint16_t port) +@@ -98,17 +156,113 @@ svc_create_bindaddr(struct netconfig *nc return ai; } @@ -643,7 +695,7 @@ index 59ba505..b3f75ed 100644 if (ai == NULL) return 0; -@@ -119,7 +273,7 @@ svc_create_nconf(const char *name, const rpcprog_t program, +@@ -119,7 +273,7 @@ svc_create_nconf(const char *name, const freeaddrinfo(ai); if (xprt == NULL) { xlog(D_GENERAL, "Failed to create listener xprt " @@ -652,7 +704,7 @@ index 59ba505..b3f75ed 100644 return 0; } -@@ -133,6 +287,93 @@ svc_create_nconf(const char *name, const rpcprog_t program, +@@ -133,6 +287,93 @@ svc_create_nconf(const char *name, const return 1; } @@ -746,7 +798,7 @@ index 59ba505..b3f75ed 100644 /** * nfs_svc_create - start up RPC svc listeners * @name: C string containing name of new service -@@ -145,8 +386,7 @@ svc_create_nconf(const char *name, const rpcprog_t program, +@@ -145,8 +386,7 @@ svc_create_nconf(const char *name, const * the RPC dispatcher. Returns the number of started network transports. */ unsigned int @@ -756,11 +808,10 @@ index 59ba505..b3f75ed 100644 void (*dispatch)(struct svc_req *, SVCXPRT *), const uint16_t port) { -diff --git a/support/nsm/file.c b/support/nsm/file.c -index f4baeb9..98b47bf 100644 ---- a/support/nsm/file.c -+++ b/support/nsm/file.c -@@ -126,7 +126,7 @@ exact_error_check(const ssize_t len, const size_t buflen) +diff -up nfs-utils-1.2.3/support/nsm/file.c.orig nfs-utils-1.2.3/support/nsm/file.c +--- nfs-utils-1.2.3/support/nsm/file.c.orig 2011-04-20 08:48:17.901406945 -0400 ++++ nfs-utils-1.2.3/support/nsm/file.c 2011-04-20 08:48:36.345265332 -0400 +@@ -127,7 +127,7 @@ exact_error_check(const ssize_t len, con * containing an appropriate pathname, or NULL if an error * occurs. Caller must free the returned result with free(3). */ @@ -769,7 +820,7 @@ index f4baeb9..98b47bf 100644 static char * nsm_make_record_pathname(const char *directory, const char *hostname) { -@@ -174,7 +174,7 @@ nsm_make_record_pathname(const char *directory, const char *hostname) +@@ -175,7 +175,7 @@ nsm_make_record_pathname(const char *dir * containing an appropriate pathname, or NULL if an error * occurs. Caller must free the returned result with free(3). */ @@ -778,7 +829,7 @@ index f4baeb9..98b47bf 100644 static char * nsm_make_pathname(const char *directory) { -@@ -204,7 +204,7 @@ nsm_make_pathname(const char *directory) +@@ -205,7 +205,7 @@ nsm_make_pathname(const char *directory) * containing an appropriate pathname, or NULL if an error * occurs. Caller must free the returned result with free(3). */ @@ -787,7 +838,7 @@ index f4baeb9..98b47bf 100644 static char * nsm_make_temp_pathname(const char *pathname) { -@@ -421,7 +421,7 @@ nsm_drop_privileges(const int pidfd) +@@ -422,7 +422,7 @@ nsm_drop_privileges(const int pidfd) */ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) { xlog(L_ERROR, "prctl(PR_SET_KEEPCAPS) failed: %m"); @@ -796,7 +847,7 @@ index f4baeb9..98b47bf 100644 } if (setgroups(0, NULL) == -1) { -@@ -568,9 +568,8 @@ nsm_retire_monitored_hosts(void) +@@ -569,9 +569,8 @@ nsm_retire_monitored_hosts(void) while ((de = readdir(dir)) != NULL) { char *src, *dst; @@ -807,7 +858,7 @@ index f4baeb9..98b47bf 100644 if (de->d_name[0] == '.') continue; -@@ -580,6 +579,20 @@ nsm_retire_monitored_hosts(void) +@@ -581,6 +580,20 @@ nsm_retire_monitored_hosts(void) continue; } @@ -828,7 +879,7 @@ index f4baeb9..98b47bf 100644 dst = nsm_make_record_pathname(NSM_NOTIFY_DIR, de->d_name); if (dst == NULL) { free(src); -@@ -634,7 +647,7 @@ nsm_priv_to_hex(const char *priv, char *buf, const size_t buflen) +@@ -635,7 +648,7 @@ nsm_priv_to_hex(const char *priv, char * /* * Returns the length in bytes of the created record. */ @@ -837,7 +888,7 @@ index f4baeb9..98b47bf 100644 static size_t nsm_create_monitor_record(char *buf, const size_t buflen, const struct sockaddr *sap, const struct mon *m) -@@ -784,7 +797,7 @@ out: +@@ -785,7 +798,7 @@ out: return result; } @@ -846,7 +897,7 @@ index f4baeb9..98b47bf 100644 static _Bool nsm_parse_line(char *line, struct sockaddr_in *sin, struct mon *m) { -@@ -846,7 +859,7 @@ nsm_read_line(const char *hostname, const time_t timestamp, char *line, +@@ -847,7 +860,7 @@ nsm_read_line(const char *hostname, cons } /* @@ -855,7 +906,7 @@ index f4baeb9..98b47bf 100644 * and invokes @func so caller can populate their in-core * database with this data. */ -@@ -863,10 +876,15 @@ nsm_load_host(const char *directory, const char *filename, nsm_populate_t func) +@@ -864,10 +877,15 @@ nsm_load_host(const char *directory, con if (path == NULL) goto out_err; @@ -872,7 +923,7 @@ index f4baeb9..98b47bf 100644 f = fopen(path, "r"); if (f == NULL) { -@@ -913,8 +931,6 @@ nsm_load_dir(const char *directory, nsm_populate_t func) +@@ -914,8 +932,6 @@ nsm_load_dir(const char *directory, nsm_ } while ((de = readdir(dir)) != NULL) { @@ -881,11 +932,10 @@ index f4baeb9..98b47bf 100644 if (de->d_name[0] == '.') continue; -diff --git a/tests/nsm_client/nsm_client.c b/tests/nsm_client/nsm_client.c -index 0d1159a..0fa3422 100644 ---- a/tests/nsm_client/nsm_client.c -+++ b/tests/nsm_client/nsm_client.c -@@ -205,7 +205,7 @@ nsm_client_get_rpcclient(const char *node) +diff -up nfs-utils-1.2.3/tests/nsm_client/nsm_client.c.orig nfs-utils-1.2.3/tests/nsm_client/nsm_client.c +--- nfs-utils-1.2.3/tests/nsm_client/nsm_client.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/tests/nsm_client/nsm_client.c 2011-04-20 08:48:36.346265324 -0400 +@@ -205,7 +205,7 @@ nsm_client_get_rpcclient(const char *nod { unsigned short port; struct addrinfo *ai; @@ -894,24 +944,9 @@ index 0d1159a..0fa3422 100644 int err; CLIENT *client = NULL; -diff --git a/utils/Makefile.am b/utils/Makefile.am -index 8665183..a0ea116 100644 ---- a/utils/Makefile.am -+++ b/utils/Makefile.am -@@ -4,6 +4,9 @@ OPTDIRS = - - if CONFIG_NFSV4 - OPTDIRS += idmapd -+if CONFIG_NFSIDMAP -+OPTDIRS += nfsidmap -+endif - endif - - if CONFIG_GSS -diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c -index b78957f..26d0504 100644 ---- a/utils/exportfs/exportfs.c -+++ b/utils/exportfs/exportfs.c +diff -up nfs-utils-1.2.3/utils/exportfs/exportfs.c.orig nfs-utils-1.2.3/utils/exportfs/exportfs.c +--- nfs-utils-1.2.3/utils/exportfs/exportfs.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/exportfs/exportfs.c 2011-04-20 08:48:36.347265316 -0400 @@ -25,6 +25,7 @@ #include #include @@ -920,7 +955,7 @@ index b78957f..26d0504 100644 #include "sockaddr.h" #include "misc.h" -@@ -41,6 +42,7 @@ static void error(nfs_export *exp, int err); +@@ -41,6 +42,7 @@ static void error(nfs_export *exp, int e static void usage(const char *progname); static void validate_export(nfs_export *exp); static int matchhostname(const char *hostname1, const char *hostname2); @@ -940,6 +975,15 @@ index b78957f..26d0504 100644 if (f_export) { if (f_all) export_all(f_verbose); +@@ -246,7 +250,7 @@ static void + exportfs(char *arg, char *options, int verbose) + { + struct exportent *eep; +- nfs_export *exp; ++ nfs_export *exp = NULL; + struct addrinfo *ai = NULL; + char *path; + char *hname = arg; @@ -485,6 +489,59 @@ out: return result; } @@ -1000,11 +1044,10 @@ index b78957f..26d0504 100644 static char dumpopt(char c, char *fmt, ...) { -diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man -index 089f75b..364f247 100644 ---- a/utils/exportfs/exportfs.man -+++ b/utils/exportfs/exportfs.man -@@ -37,11 +37,15 @@ when a client sends an NFS MOUNT request. +diff -up nfs-utils-1.2.3/utils/exportfs/exportfs.man.orig nfs-utils-1.2.3/utils/exportfs/exportfs.man +--- nfs-utils-1.2.3/utils/exportfs/exportfs.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/exportfs/exportfs.man 2011-04-20 08:48:36.348265308 -0400 +@@ -37,11 +37,15 @@ when a client sends an NFS MOUNT request .PP Normally the master export table is initialized with the contents of .I /etc/exports @@ -1020,7 +1063,7 @@ index 089f75b..364f247 100644 by using the .B exportfs command. -@@ -92,17 +96,24 @@ Specify a list of export options in the same manner as in +@@ -92,17 +96,24 @@ Specify a list of export options in the .B -i Ignore the .I /etc/exports @@ -1048,7 +1091,7 @@ index 089f75b..364f247 100644 kernel export table which are no longer valid. .TP .B -u -@@ -130,6 +141,8 @@ when adding new entries to the export table. When using +@@ -130,6 +141,8 @@ when adding new entries to the export ta .BR "exportfs -a" , all exports listed in .I /etc/exports @@ -1068,7 +1111,7 @@ index 089f75b..364f247 100644 .PP A system administrator may override options from these sources using the .B -o -@@ -188,6 +203,8 @@ to display the export options for each export. +@@ -188,6 +203,8 @@ to display the export options for each e .SH EXAMPLES The following adds all directories listed in .I /etc/exports @@ -1088,7 +1131,7 @@ index 089f75b..364f247 100644 .PP .nf .B "# exportfs -au -@@ -238,6 +257,13 @@ if they themselves are no longer valid they will be removed. +@@ -238,6 +257,13 @@ if they themselves are no longer valid t .I /etc/exports input file listing exports, export options, and access control lists .TP 2.5i @@ -1102,10 +1145,9 @@ index 089f75b..364f247 100644 .I /var/lib/nfs/etab master table of exports .TP 2.5i -diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man -index c726dd9..85e25d4 100644 ---- a/utils/exportfs/exports.man -+++ b/utils/exportfs/exports.man +diff -up nfs-utils-1.2.3/utils/exportfs/exports.man.orig nfs-utils-1.2.3/utils/exportfs/exports.man +--- nfs-utils-1.2.3/utils/exportfs/exports.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/exportfs/exports.man 2011-04-20 08:48:36.349265300 -0400 @@ -145,7 +145,9 @@ storage (see .IR async above). @@ -1117,7 +1159,7 @@ index c726dd9..85e25d4 100644 default. In all releases after 1.0.0, .I sync is the default, and -@@ -375,20 +377,6 @@ If the client asks for alternative locations for the export point, it +@@ -375,20 +377,6 @@ If the client asks for alternative locat will be given this list of alternatives. (Note that actual replication of the filesystem must be handled elsewhere.) @@ -1163,7 +1205,7 @@ index c726dd9..85e25d4 100644 .IP .SH EXAMPLE .PP -@@ -501,6 +507,7 @@ all three mounts with the `sync' option enabled. +@@ -501,6 +507,7 @@ all three mounts with the `sync' option '''entry. .SH FILES /etc/exports @@ -1171,11 +1213,44 @@ index c726dd9..85e25d4 100644 .SH SEE ALSO .BR exportfs (8), .BR netgroup (5), -diff --git a/utils/gssd/gss_util.c b/utils/gssd/gss_util.c -index 8fe1e9b..ee304cc 100644 ---- a/utils/gssd/gss_util.c -+++ b/utils/gssd/gss_util.c -@@ -138,6 +138,83 @@ display_status_1(char *m, u_int32_t code, int type, const gss_OID mech) +diff -up nfs-utils-1.2.3/utils/gssd/gssd.man.orig nfs-utils-1.2.3/utils/gssd/gssd.man +--- nfs-utils-1.2.3/utils/gssd/gssd.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/gssd.man 2011-04-20 08:48:36.351265286 -0400 +@@ -53,6 +53,8 @@ To be more consistent with other impleme + specific keytab entries. The search order for keytabs to be used + for "machine credentials" is now: + .br ++ $@ ++.br + root/@ + .br + nfs/@ +@@ -64,6 +66,9 @@ for "machine credentials" is now: + nfs/@ + .br + host/@ ++.IP ++If this search order does not use the correct key then provide a ++keytab file that contains only correct keys. + .TP + .B -p path + Tells +diff -up nfs-utils-1.2.3/utils/gssd/gssd_proc.c.orig nfs-utils-1.2.3/utils/gssd/gssd_proc.c +--- nfs-utils-1.2.3/utils/gssd/gssd_proc.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/gssd_proc.c 2011-04-20 08:48:36.351265286 -0400 +@@ -1245,7 +1245,7 @@ handle_gssd_upcall(struct clnt_info *clp + goto out; + if (sscanf(p, "enctypes=%s", enctypes) != 1) { + printerr(0, "WARNING: handle_gssd_upcall: " +- "failed to parse target name " ++ "failed to parse encryption types " + "in upcall string '%s'\n", lbuf); + goto out; + } +diff -up nfs-utils-1.2.3/utils/gssd/gss_util.c.orig nfs-utils-1.2.3/utils/gssd/gss_util.c +--- nfs-utils-1.2.3/utils/gssd/gss_util.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/gss_util.c 2011-04-20 08:48:36.350265293 -0400 +@@ -138,6 +138,83 @@ display_status_1(char *m, u_int32_t code } } #endif @@ -1259,58 +1334,59 @@ index 8fe1e9b..ee304cc 100644 static void display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech) -@@ -175,8 +252,8 @@ display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech) +@@ -175,8 +252,9 @@ display_status_2(char *m, u_int32_t majo if (major == GSS_S_CREDENTIALS_EXPIRED) msg_verbosity = 1; - printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s - %s\n", - m, maj, min); -+ printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s (%s) - %s(%s)\n", ++ ++ printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s (%s) - %s\n", + m, gss_display_error(major), maj, min); if (maj_gss_buf.length != 0) (void) gss_release_buffer(&min_stat1, &maj_gss_buf); -diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man -index 0a23cd6..073379d 100644 ---- a/utils/gssd/gssd.man -+++ b/utils/gssd/gssd.man -@@ -53,6 +53,8 @@ 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/@ -@@ -64,6 +66,9 @@ for "machine credentials" is now: - nfs/@ - .br - host/@ -+.IP -+If this search order does not use the correct key then provide a -+keytab file that contains only correct keys. - .TP - .B -p path - Tells -diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c -index c301d46..41328c9 100644 ---- a/utils/gssd/gssd_proc.c -+++ b/utils/gssd/gssd_proc.c -@@ -1245,7 +1245,7 @@ handle_gssd_upcall(struct clnt_info *clp) - goto out; - if (sscanf(p, "enctypes=%s", enctypes) != 1) { - printerr(0, "WARNING: handle_gssd_upcall: " -- "failed to parse target name " -+ "failed to parse encryption types " - "in upcall string '%s'\n", lbuf); - goto out; - } -diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c -index f071600..4b13fa1 100644 ---- a/utils/gssd/krb5_util.c -+++ b/utils/gssd/krb5_util.c -@@ -768,6 +768,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, +@@ -199,20 +277,25 @@ gssd_acquire_cred(char *server_name, con + u_int32_t ignore_maj_stat, ignore_min_stat; + gss_buffer_desc pbuf; + +- name.value = (void *)server_name; +- name.length = strlen(server_name); +- +- maj_stat = gss_import_name(&min_stat, &name, +- oid, +- &target_name); ++ /* If server_name is NULL, get cred for GSS_C_NO_NAME */ ++ if (server_name == NULL) { ++ target_name = GSS_C_NO_NAME; ++ } else { ++ name.value = (void *)server_name; ++ name.length = strlen(server_name); + +- if (maj_stat != GSS_S_COMPLETE) { +- pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid); +- return (FALSE); ++ maj_stat = gss_import_name(&min_stat, &name, ++ oid, ++ &target_name); ++ ++ if (maj_stat != GSS_S_COMPLETE) { ++ pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid); ++ return (FALSE); ++ } + } + +- maj_stat = gss_acquire_cred(&min_stat, target_name, 0, +- GSS_C_NULL_OID_SET, GSS_C_ACCEPT, ++ maj_stat = gss_acquire_cred(&min_stat, target_name, GSS_C_INDEFINITE, ++ GSS_C_NO_OID_SET, GSS_C_ACCEPT, + &gssd_creds, NULL, NULL); + + if (maj_stat != GSS_S_COMPLETE) { +diff -up nfs-utils-1.2.3/utils/gssd/krb5_util.c.orig nfs-utils-1.2.3/utils/gssd/krb5_util.c +--- nfs-utils-1.2.3/utils/gssd/krb5_util.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/krb5_util.c 2011-04-20 08:48:36.352265279 -0400 +@@ -768,6 +768,7 @@ find_keytab_entry(krb5_context context, krb5_error_code code; char **realmnames = NULL; char myhostname[NI_MAXHOST], targethostname[NI_MAXHOST]; @@ -1318,7 +1394,7 @@ index f071600..4b13fa1 100644 int i, j, retval; char *default_realm = NULL; char *realm; -@@ -789,6 +790,14 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, +@@ -789,6 +790,14 @@ find_keytab_entry(krb5_context context, printerr(1, "%s while getting local hostname\n", k5err); goto out; } @@ -1333,7 +1409,7 @@ index f071600..4b13fa1 100644 retval = get_full_hostname(myhostname, myhostname, sizeof(myhostname)); if (retval) goto out; -@@ -833,32 +842,47 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, +@@ -833,32 +842,47 @@ find_keytab_entry(krb5_context context, if (strcmp(realm, default_realm) == 0) tried_default = 1; for (j = 0; svcnames[j] != NULL; j++) { @@ -1398,7 +1474,7 @@ index f071600..4b13fa1 100644 retval = 0; goto out; } -@@ -870,6 +894,8 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname, +@@ -870,6 +894,8 @@ find_keytab_entry(krb5_context context, */ for (j = 0; svcnames[j] != NULL; j++) { int found = 0; @@ -1407,7 +1483,7 @@ index f071600..4b13fa1 100644 code = gssd_search_krb5_keytab(context, kt, realm, svcnames[j], &found, kte); if (!code && found) { -@@ -1160,7 +1186,7 @@ gssd_refresh_krb5_machine_credential(char *hostname, +@@ -1160,7 +1186,7 @@ gssd_refresh_krb5_machine_credential(cha krb5_keytab kt = NULL;; int retval = 0; char *k5err = NULL; @@ -1416,11 +1492,35 @@ index f071600..4b13fa1 100644 /* * If a specific service name was specified, use it. -diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c -index 9b463f3..17af2da 100644 ---- a/utils/gssd/svcgssd.c -+++ b/utils/gssd/svcgssd.c -@@ -267,6 +267,7 @@ main(int argc, char *argv[]) +diff -up nfs-utils-1.2.3/utils/gssd/Makefile.am.orig nfs-utils-1.2.3/utils/gssd/Makefile.am +--- nfs-utils-1.2.3/utils/gssd/Makefile.am.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/Makefile.am 2011-04-20 08:48:36.349265300 -0400 +@@ -51,7 +51,9 @@ svcgssd_SOURCES = \ + svcgssd_main_loop.c \ + svcgssd_mech2file.c \ + svcgssd_proc.c \ ++ svcgssd_krb5.c \ + \ ++ svcgssd_krb5.h \ + svcgssd.h + + svcgssd_LDADD = \ +diff -up nfs-utils-1.2.3/utils/gssd/svcgssd.c.orig nfs-utils-1.2.3/utils/gssd/svcgssd.c +--- nfs-utils-1.2.3/utils/gssd/svcgssd.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/svcgssd.c 2011-04-20 08:48:36.353265271 -0400 +@@ -262,11 +262,19 @@ main(int argc, char *argv[]) + "/etc/krb5.keytab?\n"); + exit(1); + } ++ } else { ++ status = gssd_acquire_cred(NULL, ++ (const gss_OID)GSS_C_NT_HOSTBASED_SERVICE); ++ if (status == FALSE) { ++ printerr(0, "unable to obtain nameless credentials\n"); ++ exit(1); ++ } + } + if (!fg) release_parent(); @@ -1428,11 +1528,280 @@ index 9b463f3..17af2da 100644 gssd_run(); printerr(0, "gssd_run returned!\n"); abort(); -diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c -index 3894078..0ecbab6 100644 ---- a/utils/gssd/svcgssd_proc.c -+++ b/utils/gssd/svcgssd_proc.c -@@ -241,7 +241,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred) +diff -up nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.c.orig nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.c +--- nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.c.orig 2011-04-20 08:48:36.354265263 -0400 ++++ nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.c 2011-04-20 08:48:36.354265263 -0400 +@@ -0,0 +1,200 @@ ++/* ++ * COPYRIGHT (c) 2011 ++ * The Regents of the University of Michigan ++ * ALL RIGHTS RESERVED ++ * ++ * Permission is granted to use, copy, create derivative works ++ * and redistribute this software and such derivative works ++ * for any purpose, so long as the name of The University of ++ * Michigan is not used in any advertising or publicity ++ * pertaining to the use of distribution of this software ++ * without specific, written prior authorization. If the ++ * above copyright notice or any other identification of the ++ * University of Michigan is included in any copy of any ++ * portion of this software, then the disclaimer below must ++ * also be included. ++ * ++ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION ++ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY ++ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF ++ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ++ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ++ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR ++ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN ++ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGES. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif /* HAVE_CONFIG_H */ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include "gss_util.h" ++#include "gss_oids.h" ++#include "err_util.h" ++#include "svcgssd_krb5.h" ++ ++#define MYBUFLEN 1024 ++ ++char *supported_enctypes_filename = "/proc/fs/nfsd/supported_krb5_enctypes"; ++int parsed_num_enctypes = 0; ++krb5_enctype *parsed_enctypes = NULL; ++char *cached_enctypes = NULL; ++ ++/*==========================*/ ++/*=== Internal routines ===*/ ++/*==========================*/ ++ ++/* ++ * Parse the supported encryption type information ++ */ ++static int ++parse_enctypes(char *enctypes) ++{ ++ int n = 0; ++ char *curr, *comma; ++ int i; ++ ++ /* Don't parse the same string over and over... */ ++ if (cached_enctypes && strcmp(cached_enctypes, enctypes) == 0) ++ return 0; ++ ++ /* Free any existing cached_enctypes */ ++ free(cached_enctypes); ++ ++ if (parsed_enctypes != NULL) { ++ free(parsed_enctypes); ++ parsed_enctypes = NULL; ++ parsed_num_enctypes = 0; ++ } ++ ++ /* count the number of commas */ ++ for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) { ++ comma = strchr(curr, ','); ++ if (comma != NULL) ++ n++; ++ else ++ break; ++ } ++ ++ /* If no more commas and we're not at the end, there's one more value */ ++ if (*curr != '\0') ++ n++; ++ ++ /* Empty string, return an error */ ++ if (n == 0) ++ return ENOENT; ++ ++ /* Allocate space for enctypes array */ ++ if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) { ++ return ENOMEM; ++ } ++ ++ /* Now parse each value into the array */ ++ for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) { ++ parsed_enctypes[i++] = atoi(curr); ++ comma = strchr(curr, ','); ++ if (comma == NULL) ++ break; ++ } ++ ++ parsed_num_enctypes = n; ++ if ((cached_enctypes = malloc(strlen(enctypes)+1))) ++ strcpy(cached_enctypes, enctypes); ++ ++ return 0; ++} ++ ++static void ++get_kernel_supported_enctypes(void) ++{ ++ FILE *s_e; ++ int ret; ++ char buffer[MYBUFLEN + 1]; ++ ++ memset(buffer, '\0', sizeof(buffer)); ++ ++ s_e = fopen(supported_enctypes_filename, "r"); ++ if (s_e == NULL) ++ goto out_clean_parsed; ++ ++ ret = fread(buffer, 1, MYBUFLEN, s_e); ++ if (ret < 0) { ++ fclose(s_e); ++ goto out_clean_parsed; ++ } ++ fclose(s_e); ++ if (parse_enctypes(buffer)) { ++ goto out_clean_parsed; ++ } ++out: ++ return; ++ ++out_clean_parsed: ++ if (parsed_enctypes != NULL) { ++ free(parsed_enctypes); ++ parsed_num_enctypes = 0; ++ } ++ goto out; ++} ++ ++/*==========================*/ ++/*=== External routines ===*/ ++/*==========================*/ ++ ++/* ++ * Get encryption types supported by the kernel, and then ++ * call gss_krb5_set_allowable_enctypes() to limit the ++ * encryption types negotiated. ++ * ++ * Returns: ++ * 0 => all went well ++ * -1 => there was an error ++ */ ++ ++int ++svcgssd_limit_krb5_enctypes(void) ++{ ++#ifdef HAVE_SET_ALLOWABLE_ENCTYPES ++ u_int maj_stat, min_stat; ++ krb5_enctype default_enctypes[] = { ENCTYPE_DES_CBC_CRC, ++ ENCTYPE_DES_CBC_MD5, ++ ENCTYPE_DES_CBC_MD4 }; ++ int default_num_enctypes = ++ sizeof(default_enctypes) / sizeof(default_enctypes[0]); ++ krb5_enctype *enctypes; ++ int num_enctypes; ++ ++ get_kernel_supported_enctypes(); ++ ++ if (parsed_enctypes != NULL) { ++ enctypes = parsed_enctypes; ++ num_enctypes = parsed_num_enctypes; ++ } else { ++ enctypes = default_enctypes; ++ num_enctypes = default_num_enctypes; ++ } ++ ++ maj_stat = gss_set_allowable_enctypes(&min_stat, gssd_creds, ++ &krb5oid, num_enctypes, enctypes); ++ if (maj_stat != GSS_S_COMPLETE) { ++ printerr(1, "WARNING: gss_set_allowable_enctypes failed\n"); ++ pgsserr("svcgssd_limit_krb5_enctypes: gss_set_allowable_enctypes", ++ maj_stat, min_stat, &krb5oid); ++ return -1; ++ } ++#endif ++ return 0; ++} +diff -up nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.h.orig nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.h +--- nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.h.orig 2011-04-20 08:48:36.354265263 -0400 ++++ nfs-utils-1.2.3/utils/gssd/svcgssd_krb5.h 2011-04-20 08:48:36.354265263 -0400 +@@ -0,0 +1,36 @@ ++/* ++ * COPYRIGHT (c) 2011 ++ * The Regents of the University of Michigan ++ * ALL RIGHTS RESERVED ++ * ++ * Permission is granted to use, copy, create derivative works ++ * and redistribute this software and such derivative works ++ * for any purpose, so long as the name of The University of ++ * Michigan is not used in any advertising or publicity ++ * pertaining to the use of distribution of this software ++ * without specific, written prior authorization. If the ++ * above copyright notice or any other identification of the ++ * University of Michigan is included in any copy of any ++ * portion of this software, then the disclaimer below must ++ * also be included. ++ * ++ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION ++ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY ++ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF ++ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ++ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ++ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR ++ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN ++ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGES. ++ */ ++ ++#ifndef SVCGSSD_KRB5_H ++#define SVCGSSD_KRB5_H ++ ++int svcgssd_limit_krb5_enctypes(void); ++ ++#endif /* SVCGSSD_KRB5_H */ +diff -up nfs-utils-1.2.3/utils/gssd/svcgssd_proc.c.orig nfs-utils-1.2.3/utils/gssd/svcgssd_proc.c +--- nfs-utils-1.2.3/utils/gssd/svcgssd_proc.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/gssd/svcgssd_proc.c 2011-04-20 08:48:36.355265255 -0400 +@@ -56,7 +56,9 @@ + #include "gss_util.h" + #include "err_util.h" + #include "context.h" ++#include "misc.h" + #include "gss_oids.h" ++#include "svcgssd_krb5.h" + + extern char * mech2file(gss_OID mech); + #define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel" +@@ -70,6 +72,7 @@ struct svc_cred { + int cr_ngroups; + gid_t cr_groups[NGROUPS]; + }; ++static char vbuf[RPC_CHAN_BUF_SIZE]; + + static int + do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, +@@ -91,6 +94,7 @@ do_svc_downcall(gss_buffer_desc *out_han + SVCGSSD_CONTEXT_CHANNEL, strerror(errno)); + goto out_err; + } ++ setvbuf(f, vbuf, _IOLBF, RPC_CHAN_BUF_SIZE); + qword_printhex(f, out_handle->value, out_handle->length); + /* XXX are types OK for the rest of this? */ + /* For context cache, use the actual context endtime */ +@@ -241,7 +245,7 @@ get_ids(gss_name_t client_name, gss_OID "file for name '%s'\n", sname); goto out_free; } @@ -1441,10 +1810,34 @@ index 3894078..0ecbab6 100644 res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid); if (res < 0) { /* -diff --git a/utils/idmapd/Makefile.am b/utils/idmapd/Makefile.am -index 4218048..4328e41 100644 ---- a/utils/idmapd/Makefile.am -+++ b/utils/idmapd/Makefile.am +@@ -443,6 +447,10 @@ handle_nullreq(FILE *f) { + memcpy(&ctx, in_handle.value, in_handle.length); + } + ++ if (svcgssd_limit_krb5_enctypes()) { ++ goto out_err; ++ } ++ + maj_stat = gss_accept_sec_context(&min_stat, &ctx, gssd_creds, + &in_tok, GSS_C_NO_CHANNEL_BINDINGS, &client_name, + &mech, &out_tok, &ret_flags, NULL, NULL); +diff -up nfs-utils-1.2.3/utils/idmapd/idmapd.c.orig nfs-utils-1.2.3/utils/idmapd/idmapd.c +--- nfs-utils-1.2.3/utils/idmapd/idmapd.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/idmapd/idmapd.c 2011-04-20 08:48:36.356265247 -0400 +@@ -158,10 +158,6 @@ static int nfsdopenone(struct idmap_clie + static void nfsdreopen_one(struct idmap_client *); + static void nfsdreopen(void); + +-size_t strlcat(char *, const char *, size_t); +-size_t strlcpy(char *, const char *, size_t); +-ssize_t atomicio(ssize_t (*f) (int, void*, size_t), +- int, void *, size_t); + void mydaemon(int, int); + void release_parent(void); + +diff -up nfs-utils-1.2.3/utils/idmapd/Makefile.am.orig nfs-utils-1.2.3/utils/idmapd/Makefile.am +--- nfs-utils-1.2.3/utils/idmapd/Makefile.am.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/idmapd/Makefile.am 2011-04-20 08:48:36.355265255 -0400 @@ -11,12 +11,8 @@ EXTRA_DIST = \ idmapd.conf @@ -1458,255 +1851,254 @@ index 4218048..4328e41 100644 nfs_idmap.h \ queue.h -diff --git a/utils/idmapd/atomicio.c b/utils/idmapd/atomicio.c -deleted file mode 100644 -index 1fb1ff9..0000000 ---- a/utils/idmapd/atomicio.c -+++ /dev/null -@@ -1,64 +0,0 @@ --/* -- * Copyright (c) 2002 Marius Aamodt Eriksen -- * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include --#include --#include -- --#ifdef HAVE_CONFIG_H --#include "config.h" --#endif /* HAVE_CONFIG_H */ -- --/* -- * ensure all of data on socket comes through. f==read || f==write -- */ --ssize_t --atomicio( -- ssize_t (*f) (int, void*, size_t), -- int fd, -- void *_s, -- size_t n) --{ -- char *s = _s; -- ssize_t res; -- size_t pos = 0; -- -- while (n > pos) { -- res = (f) (fd, s + pos, n - pos); -- switch (res) { -- case -1: -- if (errno == EINTR || errno == EAGAIN) -- continue; -- case 0: -- if (pos != 0) -- return (pos); -- return (res); -- default: -- pos += res; -- } -- } -- return (pos); --} -diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c -index b76607a..76a56ef 100644 ---- a/utils/idmapd/idmapd.c -+++ b/utils/idmapd/idmapd.c -@@ -158,10 +158,6 @@ static int nfsdopenone(struct idmap_client *); - static void nfsdreopen_one(struct idmap_client *); - static void nfsdreopen(void); +diff -up nfs-utils-1.2.3/utils/Makefile.am.orig nfs-utils-1.2.3/utils/Makefile.am +--- nfs-utils-1.2.3/utils/Makefile.am.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/Makefile.am 2011-04-20 08:48:36.347265316 -0400 +@@ -4,6 +4,9 @@ OPTDIRS = --size_t strlcat(char *, const char *, size_t); --size_t strlcpy(char *, const char *, size_t); --ssize_t atomicio(ssize_t (*f) (int, void*, size_t), -- int, void *, size_t); - void mydaemon(int, int); - void release_parent(void); + if CONFIG_NFSV4 + OPTDIRS += idmapd ++if CONFIG_NFSIDMAP ++OPTDIRS += nfsidmap ++endif + endif -diff --git a/utils/idmapd/strlcat.c b/utils/idmapd/strlcat.c -deleted file mode 100644 -index daedd7a..0000000 ---- a/utils/idmapd/strlcat.c -+++ /dev/null -@@ -1,76 +0,0 @@ --/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */ + if CONFIG_GSS +diff -up nfs-utils-1.2.3/utils/mountd/cache.c.orig nfs-utils-1.2.3/utils/mountd/cache.c +--- nfs-utils-1.2.3/utils/mountd/cache.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mountd/cache.c 2011-04-20 08:48:36.368265155 -0400 +@@ -64,6 +64,7 @@ enum nfsd_fsid { + */ + static int cache_export_ent(char *domain, struct exportent *exp, char *p); + ++#define INITIAL_MANAGED_GROUPS 100 + + char *lbuf = NULL; + int lbuflen = 0; +@@ -114,7 +115,7 @@ static void auth_unix_ip(FILE *f) + + qword_print(f, "nfsd"); + qword_print(f, ipaddr); +- qword_printint(f, time(0)+30*60); ++ qword_printuint(f, time(0) + DEFAULT_TTL); + if (use_ipaddr) + qword_print(f, ipaddr); + else if (client) +@@ -134,11 +135,21 @@ static void auth_unix_gid(FILE *f) + */ + uid_t uid; + struct passwd *pw; +- gid_t glist[100], *groups = glist; +- int ngroups = 100; ++ static gid_t *groups = NULL; ++ static int groups_len = 0; ++ gid_t *more_groups; ++ int ngroups = 0; + int rv, i; + char *cp; + ++ if (groups_len == 0) { ++ groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS); ++ if (!groups) ++ return; ++ ++ groups_len = ngroups = INITIAL_MANAGED_GROUPS; ++ } ++ + if (readline(fileno(f), &lbuf, &lbuflen) != 1) + return; + +@@ -151,17 +162,20 @@ static void auth_unix_gid(FILE *f) + rv = -1; + else { + rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); +- if (rv == -1 && ngroups >= 100) { +- groups = malloc(sizeof(gid_t)*ngroups); +- if (!groups) ++ if (rv == -1 && ngroups >= groups_len) { ++ more_groups = realloc(groups, sizeof(gid_t)*ngroups); ++ if (!more_groups) + rv = -1; +- else ++ else { ++ groups = more_groups; ++ groups_len = ngroups; + rv = getgrouplist(pw->pw_name, pw->pw_gid, + groups, &ngroups); ++ } + } + } + qword_printuint(f, uid); +- qword_printuint(f, time(0)+30*60); ++ qword_printuint(f, time(0) + DEFAULT_TTL); + if (rv >= 0) { + qword_printuint(f, ngroups); + for (i=0; i -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. The name of the author may not be used to endorse or promote products -- * derived from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#if defined(LIBC_SCCS) && !defined(lint) --static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $"; --#endif /* LIBC_SCCS and not lint */ -- --#include --#include -- --#ifdef HAVE_CONFIG_H --#include "config.h" --#endif /* HAVE_CONFIG_H */ -- --/* -- * Appends src to string dst of size siz (unlike strncat, siz is the -- * full size of dst, not space left). At most siz-1 characters -- * will be copied. Always NUL terminates (unless siz <= strlen(dst)). -- * Returns strlen(src) + MIN(siz, strlen(initial dst)). -- * If retval >= siz, truncation occurred. -- */ --size_t --strlcat(char *dst, -- const char *src, -- size_t siz) --{ -- register char *d = dst; -- register const char *s = src; -- register size_t n = siz; -- size_t dlen; -- -- /* Find the end of dst and adjust bytes left but don't go past end */ -- while (n-- != 0 && *d != '\0') -- d++; -- dlen = d - dst; -- n = siz - dlen; -- -- if (n == 0) -- return(dlen + strlen(s)); -- while (*s != '\0') { -- if (n != 1) { -- *d++ = *s; -- n--; -- } -- s++; +- if (groups != glist) +- free(groups); + } + + #if USE_BLKID +@@ -644,11 +655,11 @@ static int dump_to_cache(FILE *f, char * + { + qword_print(f, domain); + qword_print(f, path); +- qword_printint(f, time(0)+30*60); + if (exp) { + int different_fs = strcmp(path, exp->e_path) != 0; + int flag_mask = different_fs ? ~NFSEXP_FSID : ~0; + ++ qword_printuint(f, time(0) + exp->e_ttl); + qword_printint(f, exp->e_flags & flag_mask); + qword_printint(f, exp->e_anonuid); + qword_printint(f, exp->e_anongid); +@@ -667,7 +678,8 @@ static int dump_to_cache(FILE *f, char * + qword_print(f, "uuid"); + qword_printhex(f, u, 16); + } - } -- *d = '\0'; -- -- return(dlen + (s - src)); /* count does not include NUL */ --} -diff --git a/utils/idmapd/strlcpy.c b/utils/idmapd/strlcpy.c -deleted file mode 100644 -index a2653ee..0000000 ---- a/utils/idmapd/strlcpy.c -+++ /dev/null -@@ -1,72 +0,0 @@ --/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ -- --/* -- * Copyright (c) 1998 Todd C. Miller -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. The name of the author may not be used to endorse or promote products -- * derived from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#if defined(LIBC_SCCS) && !defined(lint) --static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $"; --#endif /* LIBC_SCCS and not lint */ -- --#include --#include -- --#ifdef HAVE_CONFIG_H --#include "config.h" --#endif /* HAVE_CONFIG_H */ -- --/* -- * Copy src to string dst of size siz. At most siz-1 characters -- * will be copied. Always NUL terminates (unless siz == 0). -- * Returns strlen(src); if retval >= siz, truncation occurred. -- */ --size_t --strlcpy(char *dst, -- const char *src, -- size_t siz) --{ -- register char *d = dst; -- register const char *s = src; -- register size_t n = siz; -- -- /* Copy as many bytes as will fit */ -- if (n != 0 && --n != 0) { -- do { -- if ((*d++ = *s++) == 0) -- break; -- } while (--n != 0); ++ } else ++ qword_printuint(f, time(0) + DEFAULT_TTL); + return qword_eol(f); + } + +@@ -813,6 +825,7 @@ struct { + char *cache_name; + void (*cache_handle)(FILE *f); + FILE *f; ++ char vbuf[RPC_CHAN_BUF_SIZE]; + } cachelist[] = { + { "auth.unix.ip", auth_unix_ip, NULL}, + { "auth.unix.gid", auth_unix_gid, NULL}, +@@ -836,6 +849,10 @@ void cache_open(void) + continue; + sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name); + cachelist[i].f = fopen(path, "r+"); ++ if (cachelist[i].f != NULL) { ++ setvbuf(cachelist[i].f, cachelist[i].vbuf, _IOLBF, ++ RPC_CHAN_BUF_SIZE); ++ } + } + } + +@@ -874,8 +891,8 @@ int cache_process_req(fd_set *readfds) + + /* + * Give IP->domain and domain+path->options to kernel +- * % echo nfsd $IP $[now+30*60] $domain > /proc/net/rpc/auth.unix.ip/channel +- * % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel ++ * % echo nfsd $IP $[now+DEFAULT_TTL] $domain > /proc/net/rpc/auth.unix.ip/channel ++ * % echo $domain $path $[now+DEFAULT_TTL] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel + */ + + static int cache_export_ent(char *domain, struct exportent *exp, char *path) +@@ -955,7 +972,7 @@ int cache_export(nfs_export *exp, char * + qword_print(f, "nfsd"); + qword_print(f, + host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf))); +- qword_printint(f, time(0)+30*60); ++ qword_printuint(f, time(0) + exp->m_export.e_ttl); + qword_print(f, exp->m_client->m_hostname); + err = qword_eol(f); + +diff -up nfs-utils-1.2.3/utils/mountd/mountd.c.orig nfs-utils-1.2.3/utils/mountd/mountd.c +--- nfs-utils-1.2.3/utils/mountd/mountd.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mountd/mountd.c 2011-04-20 08:48:36.369265148 -0400 +@@ -99,12 +99,9 @@ static int version_any(void) + static void + unregister_services (void) + { +- if (version2()) { +- nfs_svc_unregister(MOUNTPROG, MOUNTVERS); +- nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX); - } -- -- /* Not enough room in dst, add NUL and traverse rest of src */ -- if (n == 0) { -- if (siz != 0) -- *d = '\0'; /* NUL-terminate dst */ -- while (*s++) -- ; -- } -- -- return(s - src - 1); /* count does not include NUL */ --} -diff --git a/utils/mount/fstab.c b/utils/mount/fstab.c -index 051fa38..a742e64 100644 ---- a/utils/mount/fstab.c -+++ b/utils/mount/fstab.c +- if (version3()) +- nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3); ++ nfs_svc_unregister(MOUNTPROG, MOUNTVERS); ++ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX); ++ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3); + } + + static void +@@ -840,6 +837,7 @@ main(int argc, char **argv) + if (new_cache) + cache_open(); + ++ unregister_services(); + if (version2()) { + listeners += nfs_svc_create("mountd", MOUNTPROG, + MOUNTVERS, mount_dispatch, port); +diff -up nfs-utils-1.2.3/utils/mountd/mountd.man.orig nfs-utils-1.2.3/utils/mountd/mountd.man +--- nfs-utils-1.2.3/utils/mountd/mountd.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mountd/mountd.man 2011-04-20 08:48:36.370265140 -0400 +@@ -106,11 +106,11 @@ This option can be used to request that + .B rpc.mountd + do not offer certain versions of NFS. The current version of + .B rpc.mountd +-can support both NFS version 2 and the newer version 3. If the +-NFS kernel module was compiled without support for NFSv3, ++can support both NFS version 2, 3 and 4. If the ++either one of these version should not be offered, + .B rpc.mountd + must be invoked with the option +-.B "\-\-no-nfs-version 3" . ++.B "\-\-no-nfs-version " . + .TP + .B \-n " or " \-\-no-tcp + Don't advertise TCP for mount. +diff -up nfs-utils-1.2.3/utils/mountd/rmtab.c.orig nfs-utils-1.2.3/utils/mountd/rmtab.c +--- nfs-utils-1.2.3/utils/mountd/rmtab.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mountd/rmtab.c 2011-04-20 08:48:36.370265140 -0400 +@@ -205,6 +205,7 @@ mountlist_list(void) + } + if (stb.st_mtime != last_mtime) { + mountlist_freeall(mlist); ++ mlist = NULL; + last_mtime = stb.st_mtime; + + setrmtabent("r"); +diff -up nfs-utils-1.2.3/utils/mountd/v4root.c.orig nfs-utils-1.2.3/utils/mountd/v4root.c +--- nfs-utils-1.2.3/utils/mountd/v4root.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mountd/v4root.c 2011-04-20 08:48:36.371265132 -0400 +@@ -144,8 +144,11 @@ static int v4root_add_parents(nfs_export + char *ptr; + + path = strdup(exp->m_export.e_path); +- if (!path) ++ if (!path) { ++ xlog(L_WARNING, "v4root_add_parents: Unable to create " ++ "pseudo export for '%s'", exp->m_export.e_path); + return -ENOMEM; ++ } + for (ptr = path + 1; ptr; ptr = strchr(ptr, '/')) { + int ret; + char saved; +@@ -173,7 +176,7 @@ void + v4root_set() + { + nfs_export *exp; +- int i, ret; ++ int i; + + if (!v4root_needed) + return; +@@ -189,7 +192,7 @@ v4root_set() + */ + continue; + +- ret = v4root_add_parents(exp); ++ v4root_add_parents(exp); + /* XXX: error handling! */ + } + } +diff -up nfs-utils-1.2.3/utils/mount/fstab.c.orig nfs-utils-1.2.3/utils/mount/fstab.c +--- nfs-utils-1.2.3/utils/mount/fstab.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/fstab.c 2011-04-20 08:48:36.357265239 -0400 @@ -364,19 +364,22 @@ lock_mtab (void) { /* Repeat until it was us who made the link */ while (!we_created_lockfile) { @@ -1762,116 +2154,49 @@ index 051fa38..a742e64 100644 (void) unlink(linktargetfile); close(lockfile_fd); die (EX_FILEIO, _("Cannot create link %s\n" -diff --git a/utils/mount/mount.c b/utils/mount/mount.c -index 82b9169..a19af53 100644 ---- a/utils/mount/mount.c -+++ b/utils/mount/mount.c -@@ -209,7 +209,7 @@ static char *fix_opts_string(int flags, const char *extra_opts) - } - if (flags & MS_USERS) - new_opts = xstrconcat3(new_opts, ",users", ""); -- +diff -up nfs-utils-1.2.3/utils/mount/Makefile.am.orig nfs-utils-1.2.3/utils/mount/Makefile.am +--- nfs-utils-1.2.3/utils/mount/Makefile.am.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/Makefile.am 2011-04-20 08:48:36.357265239 -0400 +@@ -9,17 +9,17 @@ man5_MANS = nfs.man + + sbin_PROGRAMS = mount.nfs + EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS) +-mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \ ++mount_common = error.c network.c fstab.c token.c \ + parse_opt.c parse_dev.c \ + nfsmount.c nfs4mount.c stropts.c\ + nfsumount.c \ + mount_constants.h error.h network.h fstab.h token.h \ + parse_opt.h parse_dev.h \ + nfs4_mount.h nfs_mount4.h stropts.h version.h \ +- mount_config.h ++ mount_config.h utils.c utils.h + + if MOUNT_CONFIG +-mount_nfs_SOURCES += configfile.c ++mount_common += configfile.c + man5_MANS += nfsmount.conf.man + EXTRA_DIST += nfsmount.conf + endif +@@ -27,6 +27,15 @@ endif + mount_nfs_LDADD = ../../support/nfs/libnfs.a \ + ../../support/export/libexport.a + ++mount_nfs_SOURCES = $(mount_common) + - for (om = opt_map; om->opt != NULL; om++) { - if (om->skip) - continue; -@@ -224,6 +224,20 @@ static char *fix_opts_string(int flags, const char *extra_opts) - return new_opts; - } - -+static void -+init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type, -+ int flags, char *opts) -+{ -+ mnt->mnt_fsname = fsname; -+ mnt->mnt_dir = dir; -+ mnt->mnt_type = type; -+ mnt->mnt_opts = fix_opts_string(flags & ~MS_NOMTAB, opts); ++if CONFIG_LIBMOUNT ++mount_nfs_SOURCES += mount_libmount.c ++mount_nfs_LDADD += $(LIBMOUNT) ++else ++mount_nfs_SOURCES += mount.c ++endif + -+ /* these are always zero for NFS */ -+ mnt->mnt_freq = 0; -+ mnt->mnt_passno = 0; -+} -+ - /* Create mtab with a root entry. */ - static void - create_mtab (void) { -@@ -245,11 +259,8 @@ create_mtab (void) { - if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) { - char *extra_opts; - parse_opts (fstab->m.mnt_opts, &flags, &extra_opts); -- mnt.mnt_dir = "/"; -- mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname); -- mnt.mnt_type = fstab->m.mnt_type; -- mnt.mnt_opts = fix_opts_string (flags, extra_opts); -- mnt.mnt_freq = mnt.mnt_passno = 0; -+ init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/", -+ fstab->m.mnt_type, flags, extra_opts); - free(extra_opts); + MAINTAINERCLEANFILES = Makefile.in - if (nfs_addmntent (mfp, &mnt) == 1) { -@@ -273,17 +284,12 @@ create_mtab (void) { - } - - static int add_mtab(char *spec, char *mount_point, char *fstype, -- int flags, char *opts, int freq, int pass) -+ int flags, char *opts) - { - struct mntent ment; - int result = EX_SUCCESS; - -- ment.mnt_fsname = spec; -- ment.mnt_dir = mount_point; -- ment.mnt_type = fstype; -- ment.mnt_opts = fix_opts_string(flags, opts); -- ment.mnt_freq = freq; -- ment.mnt_passno = pass; -+ init_mntent(&ment, spec, mount_point, fstype, flags, opts); - - if (!nomtab && mtab_does_not_exist()) { - if (verbose > 1) -@@ -321,7 +327,7 @@ static int add_mtab(char *spec, char *mount_point, char *fstype, - return result; - } - --void mount_usage(void) -+static void mount_usage(void) - { - printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"), - progname); -@@ -337,7 +343,7 @@ void mount_usage(void) - printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n")); - } - --static void parse_opt(const char *opt, int *mask, char *extra_opts, int len) -+static void parse_opt(const char *opt, int *mask, char *extra_opts, size_t len) - { - const struct opt_map *om; - -@@ -371,7 +377,7 @@ static void parse_opts(const char *options, int *flags, char **extra_opts) - if (options != NULL) { - char *opts = xstrdup(options); - char *opt, *p; -- int len = strlen(opts) + 1; /* include room for a null */ -+ size_t len = strlen(opts) + 1; /* include room for a null */ - int open_quote = 0; - - *extra_opts = xmalloc(len); -@@ -441,9 +447,7 @@ static int try_mount(char *spec, char *mount_point, int flags, - if (!fake) - print_one(spec, mount_point, fs_type, mount_opts); - -- ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts, -- 0, 0 /* these are always zero for NFS */ ); -- return ret; -+ return add_mtab(spec, mount_point, fs_type, flags, *extra_opts); - } - - int main(int argc, char *argv[]) -diff --git a/utils/mount/mount_config.h b/utils/mount/mount_config.h -index 3023306..69ffd1e 100644 ---- a/utils/mount/mount_config.h -+++ b/utils/mount/mount_config.h + install-exec-hook: +diff -up nfs-utils-1.2.3/utils/mount/mount_config.h.orig nfs-utils-1.2.3/utils/mount/mount_config.h +--- nfs-utils-1.2.3/utils/mount/mount_config.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/mount_config.h 2011-04-20 08:48:36.359265224 -0400 @@ -1,7 +1,7 @@ -#ifndef _LINUX_MOUNT__CONFIG_H -#define _LINUX_MOUNT_CONFIG__H @@ -1900,7 +2225,7 @@ index 3023306..69ffd1e 100644 { xlog_open(program); /* -@@ -32,19 +30,22 @@ inline void mount_config_init(char *program) +@@ -32,19 +30,22 @@ inline void mount_config_init(char *prog */ conf_init(); } @@ -1928,11 +2253,10 @@ index 3023306..69ffd1e 100644 -#endif + +#endif /* _LINUX_MOUNT_CONFIG_H */ -diff --git a/utils/mount/mount_constants.h b/utils/mount/mount_constants.h -index cbfb099..4d050d8 100644 ---- a/utils/mount/mount_constants.h -+++ b/utils/mount/mount_constants.h -@@ -64,4 +64,8 @@ if we have a stack or plain mount - mount atop of it, forming a stack. */ +diff -up nfs-utils-1.2.3/utils/mount/mount_constants.h.orig nfs-utils-1.2.3/utils/mount/mount_constants.h +--- nfs-utils-1.2.3/utils/mount/mount_constants.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/mount_constants.h 2011-04-20 08:48:36.359265224 -0400 +@@ -64,4 +64,8 @@ if we have a stack or plain mount - moun #define MS_MGC_MSK 0xffff0000 /* magic flag number mask */ #endif @@ -1941,10 +2265,633 @@ index cbfb099..4d050d8 100644 +#define MS_NOMTAB (MS_REMOUNT) + #endif /* _NFS_UTILS_MOUNT_CONSTANTS_H */ -diff --git a/utils/mount/network.c b/utils/mount/network.c -index d612427..9b6504d 100644 ---- a/utils/mount/network.c -+++ b/utils/mount/network.c +diff -up nfs-utils-1.2.3/utils/mount/mount.c.orig nfs-utils-1.2.3/utils/mount/mount.c +--- nfs-utils-1.2.3/utils/mount/mount.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/mount.c 2011-04-20 08:48:36.358265231 -0400 +@@ -47,7 +47,7 @@ + #include "mount.h" + #include "error.h" + #include "stropts.h" +-#include "version.h" ++#include "utils.h" + + char *progname; + int nfs_mount_data_version; +@@ -150,49 +150,6 @@ static const struct opt_map opt_map[] = + static void parse_opts(const char *options, int *flags, char **extra_opts); + + /* +- * Choose the version of the nfs_mount_data structure that is appropriate +- * for the kernel that is doing the mount. +- * +- * NFS_MOUNT_VERSION: maximum version supported by these sources +- * nfs_mount_data_version: maximum version supported by the running kernel +- */ +-static void discover_nfs_mount_data_version(void) +-{ +- unsigned int kernel_version = linux_version_code(); +- +- if (kernel_version) { +- if (kernel_version < MAKE_VERSION(2, 1, 32)) +- nfs_mount_data_version = 1; +- else if (kernel_version < MAKE_VERSION(2, 2, 18)) +- nfs_mount_data_version = 3; +- else if (kernel_version < MAKE_VERSION(2, 3, 0)) +- nfs_mount_data_version = 4; +- else if (kernel_version < MAKE_VERSION(2, 3, 99)) +- nfs_mount_data_version = 3; +- else if (kernel_version < MAKE_VERSION(2, 6, 3)) +- nfs_mount_data_version = 4; +- else +- nfs_mount_data_version = 6; +- } +- if (nfs_mount_data_version > NFS_MOUNT_VERSION) +- nfs_mount_data_version = NFS_MOUNT_VERSION; +- else +- if (kernel_version > MAKE_VERSION(2, 6, 22)) +- string++; +-} +- +-static void print_one(char *spec, char *node, char *type, char *opts) +-{ +- if (!verbose) +- return; +- +- if (opts) +- printf(_("%s on %s type %s (%s)\n"), spec, node, type, opts); +- else +- printf(_("%s on %s type %s\n"), spec, node, type); +-} +- +-/* + * Build a canonical mount option string for /etc/mtab. + */ + static char *fix_opts_string(int flags, const char *extra_opts) +@@ -209,7 +166,7 @@ static char *fix_opts_string(int flags, + } + if (flags & MS_USERS) + new_opts = xstrconcat3(new_opts, ",users", ""); +- ++ + for (om = opt_map; om->opt != NULL; om++) { + if (om->skip) + continue; +@@ -224,6 +181,20 @@ static char *fix_opts_string(int flags, + return new_opts; + } + ++static void ++init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type, ++ int flags, char *opts) ++{ ++ mnt->mnt_fsname = fsname; ++ mnt->mnt_dir = dir; ++ mnt->mnt_type = type; ++ mnt->mnt_opts = fix_opts_string(flags & ~MS_NOMTAB, opts); ++ ++ /* these are always zero for NFS */ ++ mnt->mnt_freq = 0; ++ mnt->mnt_passno = 0; ++} ++ + /* Create mtab with a root entry. */ + static void + create_mtab (void) { +@@ -245,11 +216,8 @@ create_mtab (void) { + if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) { + char *extra_opts; + parse_opts (fstab->m.mnt_opts, &flags, &extra_opts); +- mnt.mnt_dir = "/"; +- mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname); +- mnt.mnt_type = fstab->m.mnt_type; +- mnt.mnt_opts = fix_opts_string (flags, extra_opts); +- mnt.mnt_freq = mnt.mnt_passno = 0; ++ init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/", ++ fstab->m.mnt_type, flags, extra_opts); + free(extra_opts); + + if (nfs_addmntent (mfp, &mnt) == 1) { +@@ -273,17 +241,12 @@ create_mtab (void) { + } + + static int add_mtab(char *spec, char *mount_point, char *fstype, +- int flags, char *opts, int freq, int pass) ++ int flags, char *opts) + { + struct mntent ment; + int result = EX_SUCCESS; + +- ment.mnt_fsname = spec; +- ment.mnt_dir = mount_point; +- ment.mnt_type = fstype; +- ment.mnt_opts = fix_opts_string(flags, opts); +- ment.mnt_freq = freq; +- ment.mnt_passno = pass; ++ init_mntent(&ment, spec, mount_point, fstype, flags, opts); + + if (!nomtab && mtab_does_not_exist()) { + if (verbose > 1) +@@ -321,23 +284,7 @@ static int add_mtab(char *spec, char *mo + return result; + } + +-void mount_usage(void) +-{ +- printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"), +- progname); +- printf(_("options:\n")); +- printf(_("\t-r\t\tMount file system readonly\n")); +- printf(_("\t-v\t\tVerbose\n")); +- printf(_("\t-V\t\tPrint version\n")); +- printf(_("\t-w\t\tMount file system read-write\n")); +- printf(_("\t-f\t\tFake mount, do not actually mount\n")); +- printf(_("\t-n\t\tDo not update /etc/mtab\n")); +- printf(_("\t-s\t\tTolerate sloppy mount options rather than fail\n")); +- printf(_("\t-h\t\tPrint this help\n")); +- printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n")); +-} +- +-static void parse_opt(const char *opt, int *mask, char *extra_opts, int len) ++static void parse_opt(const char *opt, int *mask, char *extra_opts, size_t len) + { + const struct opt_map *om; + +@@ -371,7 +318,7 @@ static void parse_opts(const char *optio + if (options != NULL) { + char *opts = xstrdup(options); + char *opt, *p; +- int len = strlen(opts) + 1; /* include room for a null */ ++ size_t len = strlen(opts) + 1; /* include room for a null */ + int open_quote = 0; + + *extra_opts = xmalloc(len); +@@ -397,26 +344,6 @@ static void parse_opts(const char *optio + } + } + +-static int chk_mountpoint(char *mount_point) +-{ +- struct stat sb; +- +- if (stat(mount_point, &sb) < 0){ +- mount_error(NULL, mount_point, errno); +- return 1; +- } +- if (S_ISDIR(sb.st_mode) == 0){ +- mount_error(NULL, mount_point, ENOTDIR); +- return 1; +- } +- if (access(mount_point, X_OK) < 0) { +- mount_error(NULL, mount_point, errno); +- return 1; +- } +- +- return 0; +-} +- + static int try_mount(char *spec, char *mount_point, int flags, + char *fs_type, char **extra_opts, char *mount_opts, + int fake, int bg) +@@ -441,9 +368,7 @@ static int try_mount(char *spec, char *m + if (!fake) + print_one(spec, mount_point, fs_type, mount_opts); + +- ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts, +- 0, 0 /* these are always zero for NFS */ ); +- return ret; ++ return add_mtab(spec, mount_point, fs_type, flags, *extra_opts); + } + + int main(int argc, char *argv[]) +@@ -455,7 +380,7 @@ int main(int argc, char *argv[]) + + progname = basename(argv[0]); + +- discover_nfs_mount_data_version(); ++ nfs_mount_data_version = discover_nfs_mount_data_version(&string); + + if(!strncmp(progname, "umount", strlen("umount"))) + exit(nfsumount(argc, argv)); +diff -up nfs-utils-1.2.3/utils/mount/mount_libmount.c.orig nfs-utils-1.2.3/utils/mount/mount_libmount.c +--- nfs-utils-1.2.3/utils/mount/mount_libmount.c.orig 2011-04-20 08:48:36.360265217 -0400 ++++ nfs-utils-1.2.3/utils/mount/mount_libmount.c 2011-04-20 08:48:36.360265217 -0400 +@@ -0,0 +1,413 @@ ++/* ++ * mount_libmount.c -- Linux NFS [u]mount based on libmount ++ * ++ * Copyright (C) 2011 Karel Zak ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 021110-1307, USA. ++ * ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "nls.h" ++#include "mount_config.h" ++ ++#include "nfs_mount.h" ++#include "nfs4_mount.h" ++#include "stropts.h" ++#include "version.h" ++#include "xcommon.h" ++ ++#include "error.h" ++#include "utils.h" ++ ++char *progname; ++int nfs_mount_data_version; ++int verbose; ++int sloppy; ++int string; ++int nomtab; ++ ++#define FOREGROUND (0) ++#define BACKGROUND (1) ++ ++/* ++ * Store mount options to mtab (or /dev/.mount/utab), called from mount.nfs. ++ * ++ * Note that on systems without /etc/mtab the fs-specific options are not ++ * managed by libmount at all. We have to use "mount attributes" that are ++ * private for mount. helpers. ++ */ ++static void store_mount_options(struct libmnt_fs *fs, const char *opts) ++{ ++ mnt_fs_set_fs_options(fs, opts); /* for mtab */ ++ mnt_fs_set_attributes(fs, opts); /* for non-mtab systems */ ++} ++ ++/* ++ * Retrieve mount options from mtab (or /dev/.mount/utab) called from umount.nfs. ++ * ++ * The result can passed to free(). ++ */ ++char *retrieve_mount_options(struct libmnt_fs *fs) ++{ ++ const char *opts; ++ ++ if (!fs) ++ return NULL; ++ ++ opts = mnt_fs_get_attributes(fs); /* /dev/.mount/utab */ ++ if (opts) ++ return strdup(opts); ++ ++ return mnt_fs_strdup_options(fs); /* /etc/mtab */ ++} ++ ++static int try_mount(struct libmnt_context *cxt, int bg) ++{ ++ struct libmnt_fs *fs; ++ const char *p; ++ char *src = NULL, *tgt = NULL, *type = NULL, *opts = NULL; ++ unsigned long flags = 0; ++ int fake, ret = 0; ++ ++ fs = mnt_context_get_fs(cxt); ++ ++ /* libmount returns read-only pointers (const char) ++ * so, reallocate for nfsmount() functions. ++ */ ++ if ((p = mnt_fs_get_source(fs))) /* spec */ ++ src = strdup(p); ++ if ((p = mnt_fs_get_target(fs))) /* mountpoint */ ++ tgt = strdup(p); ++ if ((p = mnt_fs_get_fstype(fs))) /* FS type */ ++ type = strdup(p); ++ if ((p = mnt_fs_get_fs_options(fs))) /* mount options */ ++ opts = strdup(p); ++ ++ mnt_context_get_mflags(cxt, &flags); /* mount(2) flags */ ++ fake = mnt_context_is_fake(cxt); ++ ++ if (string) ++ ret = nfsmount_string(src, tgt, type, flags, &opts, fake, bg); ++ ++ else if (strcmp(type, "nfs4") == 0) ++ ret = nfs4mount(src, tgt, flags, &opts, fake, bg); ++ else ++ ret = nfsmount(src, tgt, flags, &opts, fake, bg); ++ ++ /* Store mount options if not called with mount --no-mtab */ ++ if (!ret && !mnt_context_is_nomtab(cxt)) ++ store_mount_options(fs, opts); ++ ++ free(src); ++ free(tgt); ++ free(type); ++ free(opts); ++ ++ return ret; ++} ++ ++/* returns: error = -1, success = 0 , unknown = 1 */ ++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; ++ ++ if (!src || !tgt) ++ return -1; ++ ++ if (!mnt_fs_is_kernel(fs)) { ++ struct libmnt_table *tb = mnt_new_table_from_file("/proc/mounts"); ++ ++ if (!tb) ++ return -1; ++ fs = mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD); ++ } ++ ++ if (fs) { ++ const char *type = mnt_fs_get_fstype(fs); ++ if (type && strcmp(type, "nfs4") == 0) ++ rc = 0; ++ } ++ mnt_free_table(tb); ++ return rc; ++} ++ ++static int umount_main(struct libmnt_context *cxt, int argc, char **argv) ++{ ++ int rc, c; ++ char *spec = NULL, *opts = NULL; ++ ++ static const struct option longopts[] = { ++ { "force", 0, 0, 'f' }, ++ { "help", 0, 0, 'h' }, ++ { "no-mtab", 0, 0, 'n' }, ++ { "verbose", 0, 0, 'v' }, ++ { "read-only", 0, 0, 'r' }, ++ { "lazy", 0, 0, 'l' }, ++ { "types", 1, 0, 't' }, ++ { NULL, 0, 0, 0 } ++ }; ++ ++ mnt_context_init_helper(cxt, MNT_ACT_UMOUNT, 0); ++ ++ while ((c = getopt_long (argc, argv, "fvnrlh", longopts, NULL)) != -1) { ++ ++ rc = mnt_context_helper_setopt(cxt, c, optarg); ++ if (rc == 0) /* valid option */ ++ continue; ++ if (rc < 0) /* error (probably ENOMEM) */ ++ goto err; ++ /* rc==1 means unknow option */ ++ umount_usage(); ++ return EX_USAGE; ++ } ++ ++ if (optind < argc) ++ spec = argv[optind++]; ++ ++ if (!spec || (*spec != '/' && strchr(spec,':') == NULL)) { ++ nfs_error(_("%s: no mount point provided"), progname); ++ return EX_USAGE; ++ } ++ ++ 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); ++ if (rc) { ++ nfs_error(_("%s: failed to prepare umount: %s\n"), ++ progname, strerror(-rc)); ++ goto err; ++ } ++ ++ opts = retrieve_mount_options(mnt_context_get_fs(cxt)); ++ ++ if (!mnt_context_is_lazy(cxt)) { ++ if (opts) { ++ /* we have full FS description (e.g. from mtab or /proc) */ ++ switch (is_vers4(cxt)) { ++ case 0: ++ /* We ignore the error from nfs_umount23. ++ * If the actual umount succeeds (in del_mtab), ++ * we don't want to signal an error, as that ++ * could cause /sbin/mount to retry! ++ */ ++ nfs_umount23(mnt_context_get_source(cxt), opts); ++ break; ++ case 1: /* unknown */ ++ break; ++ default: /* error */ ++ goto err; ++ } ++ } else ++ /* strange, no entry in mtab or /proc not mounted */ ++ nfs_umount23(spec, "tcp,v3"); ++ } ++ ++ rc = mnt_context_do_umount(cxt); /* call umount(2) syscall */ ++ mnt_context_finalize_mount(cxt); /* mtab update */ ++ ++ if (rc && !mnt_context_get_status(cxt)) { ++ /* mnt_context_do_umount() returns errno if umount(2) failed */ ++ umount_error(rc, spec); ++ goto err; ++ } ++ ++ free(opts); ++ return EX_SUCCESS; ++err: ++ free(opts); ++ return EX_FAIL; ++} ++ ++static int mount_main(struct libmnt_context *cxt, int argc, char **argv) ++{ ++ int rc, c; ++ struct libmnt_fs *fs; ++ char *spec = NULL, *mount_point = NULL, *opts = NULL; ++ ++ static const struct option longopts[] = { ++ { "fake", 0, 0, 'f' }, ++ { "help", 0, 0, 'h' }, ++ { "no-mtab", 0, 0, 'n' }, ++ { "read-only", 0, 0, 'r' }, ++ { "ro", 0, 0, 'r' }, ++ { "verbose", 0, 0, 'v' }, ++ { "version", 0, 0, 'V' }, ++ { "read-write", 0, 0, 'w' }, ++ { "rw", 0, 0, 'w' }, ++ { "options", 1, 0, 'o' }, ++ { "sloppy", 0, 0, 's' }, ++ { NULL, 0, 0, 0 } ++ }; ++ ++ mount_config_init(progname); ++ mnt_context_init_helper(cxt, MNT_ACT_MOUNT, 0); ++ ++ while ((c = getopt_long(argc, argv, "fhnrVvwo:s", longopts, NULL)) != -1) { ++ ++ rc = mnt_context_helper_setopt(cxt, c, optarg); ++ if (rc == 0) /* valid option */ ++ continue; ++ if (rc < 0) /* error (probably ENOMEM) */ ++ goto err; ++ /* rc==1 means unknow option */ ++ switch (c) { ++ case 'V': ++ printf("%s: ("PACKAGE_STRING")\n", progname); ++ return EX_SUCCESS; ++ case 'h': ++ default: ++ mount_usage(); ++ return EX_USAGE; ++ } ++ } ++ ++ if (optind < argc) ++ spec = argv[optind++]; ++ if (optind < argc) ++ mount_point = argv[optind++]; ++ ++ if (!mount_point) { ++ nfs_error(_("%s: no mount point provided"), progname); ++ goto err; ++ } ++ if (!spec) { ++ nfs_error(_("%s: no mount spec provided"), progname); ++ goto err; ++ } ++ ++ if (geteuid() != 0) { ++ nfs_error(_("%s: not installed setuid - " ++ "\"user\" NFS mounts not supported."), progname); ++ goto err; ++ } ++ ++ verbose = mnt_context_is_verbose(cxt); ++ sloppy = mnt_context_is_sloppy(cxt); ++ nomtab = mnt_context_is_nomtab(cxt); ++ ++ if (strcmp(progname, "mount.nfs4") == 0) ++ mnt_context_set_fstype(cxt, "nfs4"); ++ else ++ mnt_context_set_fstype(cxt, "nfs"); /* default */ ++ ++ rc = mnt_context_set_source(cxt, spec); ++ if (!rc) ++ mnt_context_set_target(cxt, mount_point); ++ if (rc) { ++ nfs_error(_("%s: failed to set spec or mountpoint: %s"), ++ progname, strerror(errno)); ++ goto err; ++ } ++ ++ mount_point = mnt_resolve_path(mount_point, ++ mnt_context_get_cache(cxt)); ++ ++ if (chk_mountpoint(mount_point)) ++ goto err; ++ /* ++ * Concatenate mount options from the configuration file ++ */ ++ fs = mnt_context_get_fs(cxt); ++ if (fs) { ++ opts = mnt_fs_strdup_options(fs); ++ ++ opts = mount_config_opts(spec, mount_point, opts); ++ mnt_fs_set_options(fs, opts); ++ } ++ ++ rc = mnt_context_prepare_mount(cxt); ++ if (rc) { ++ nfs_error(_("%s: failed to prepare mount: %s\n"), ++ progname, strerror(-rc)); ++ goto err; ++ } ++ ++ rc = try_mount(cxt, FOREGROUND); ++ ++ if (rc == EX_BG) { ++ printf(_("%s: backgrounding \"%s\"\n"), ++ progname, mnt_context_get_source(cxt)); ++ printf(_("%s: mount options: \"%s\"\n"), ++ progname, opts); ++ ++ fflush(stdout); ++ ++ if (daemon(0, 0)) { ++ nfs_error(_("%s: failed to start " ++ "background process: %s\n"), ++ progname, strerror(errno)); ++ exit(EX_FAIL); ++ } ++ ++ rc = try_mount(cxt, BACKGROUND); ++ ++ if (verbose && rc) ++ printf(_("%s: giving up \"%s\"\n"), ++ progname, mnt_context_get_source(cxt)); ++ } ++ ++ mnt_context_set_syscall_status(cxt, rc == EX_SUCCESS ? 0 : -1); ++ mnt_context_finalize_mount(cxt); /* mtab update */ ++ return rc; ++err: ++ return EX_FAIL; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ struct libmnt_context *cxt; ++ int rc; ++ ++ mnt_init_debug(0); ++ cxt = mnt_new_context(); ++ if (!cxt) { ++ nfs_error(_("Can't initilize libmount: %s"), ++ strerror(errno)); ++ rc = EX_FAIL; ++ goto done; ++ } ++ ++ progname = basename(argv[0]); ++ nfs_mount_data_version = discover_nfs_mount_data_version(&string); ++ ++ if(strncmp(progname, "umount", 6) == 0) ++ rc = umount_main(cxt, argc, argv); ++ else ++ rc = mount_main(cxt, argc, argv); ++done: ++ mnt_free_context(cxt); ++ return rc; ++} +diff -up nfs-utils-1.2.3/utils/mount/network.c.orig nfs-utils-1.2.3/utils/mount/network.c +--- nfs-utils-1.2.3/utils/mount/network.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/network.c 2011-04-20 08:48:36.361265209 -0400 @@ -59,6 +59,8 @@ #define CONNECT_TIMEOUT (20) #define MOUNT_TIMEOUT (30) @@ -1954,7 +2901,7 @@ index d612427..9b6504d 100644 extern int nfs_mount_data_version; extern char *progname; extern int verbose; -@@ -208,9 +210,6 @@ int nfs_lookup(const char *hostname, const sa_family_t family, +@@ -208,9 +210,6 @@ int nfs_lookup(const char *hostname, con { struct addrinfo *gai_results; struct addrinfo gai_hint = { @@ -1964,7 +2911,7 @@ index d612427..9b6504d 100644 .ai_family = family, }; socklen_t len = *salen; -@@ -428,12 +427,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot, +@@ -428,12 +427,12 @@ static int get_socket(struct sockaddr_in if (bindresvport(so, &laddr) < 0) goto err_bindresvport; } else { @@ -1979,7 +2926,7 @@ index d612427..9b6504d 100644 timeout); if (cc < 0) goto err_connect; -@@ -756,11 +755,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr, +@@ -756,11 +755,12 @@ int nfs_probe_bothports(const struct soc */ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) { @@ -2005,7 +2952,7 @@ index d612427..9b6504d 100644 program, (rpcvers_t)1, IPPROTO_UDP); } -@@ -901,7 +901,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen, +@@ -901,7 +901,7 @@ int nfs_advise_umount(const struct socka */ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp) { @@ -2014,7 +2961,7 @@ index d612427..9b6504d 100644 socklen_t salen = sizeof(mnt_server->saddr); struct pmap *pmap = &mnt_server->pmap; CLIENT *clnt; -@@ -1011,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog, +@@ -1011,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr, struct sockaddr_in *caddr) { CLIENT *clnt = NULL; @@ -2028,7 +2975,7 @@ index d612427..9b6504d 100644 sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE); if (sock == RPC_ANYSOCK) { if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) { -@@ -1058,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog, +@@ -1058,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr, return 0; } memset(&clnt_res, 0, sizeof(clnt_res)); @@ -2051,23 +2998,57 @@ index d612427..9b6504d 100644 return 1; else return 0; -@@ -1103,13 +1103,13 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen, +@@ -1095,7 +1095,7 @@ static int nfs_ca_sockname(const struct + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_ANY_INIT, + }; +- int sock; ++ int sock, result = 0; + + sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) +@@ -1103,28 +1103,26 @@ static int nfs_ca_sockname(const struct switch (sap->sa_family) { case AF_INET: - if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { -+ if (bind(sock, SAFE_SOCKADDR(&sin), sizeof(sin)) < 0) { - close(sock); - return 0; - } +- close(sock); +- return 0; +- } ++ if (bind(sock, SAFE_SOCKADDR(&sin), sizeof(sin)) < 0) ++ goto out; break; case AF_INET6: - if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) { -+ if (bind(sock, SAFE_SOCKADDR(&sin6), sizeof(sin6)) < 0) { - close(sock); - return 0; - } -@@ -1346,7 +1346,7 @@ nfs_nfs_port(struct mount_options *options, unsigned long *port) +- close(sock); +- return 0; +- } ++ if (bind(sock, SAFE_SOCKADDR(&sin6), sizeof(sin6)) < 0) ++ goto out; + break; + default: + errno = EAFNOSUPPORT; +- return 0; ++ goto out; + } + +- if (connect(sock, sap, salen) < 0) { +- close(sock); +- return 0; +- } ++ if (connect(sock, sap, salen) < 0) ++ goto out; + +- return !getsockname(sock, buf, buflen); ++ result = !getsockname(sock, buf, buflen); ++ ++out: ++ close(sock); ++ return result; + } + + /* +@@ -1346,7 +1344,7 @@ nfs_nfs_port(struct mount_options *optio case PO_NOT_FOUND: break; case PO_FOUND: @@ -2076,7 +3057,7 @@ index d612427..9b6504d 100644 *port = tmp; return 1; } -@@ -1518,7 +1518,11 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol) +@@ -1518,7 +1516,11 @@ nfs_mount_protocol(struct mount_options * set @protocol to zero. The pmap protocol value will * be filled in later by an rpcbind query in this case. */ @@ -2089,7 +3070,7 @@ index d612427..9b6504d 100644 } /* -@@ -1534,7 +1538,7 @@ nfs_mount_port(struct mount_options *options, unsigned long *port) +@@ -1534,7 +1536,7 @@ nfs_mount_port(struct mount_options *opt case PO_NOT_FOUND: break; case PO_FOUND: @@ -2098,11 +3079,93 @@ index d612427..9b6504d 100644 *port = tmp; return 1; } -diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man -index 55d4b55..be91a25 100644 ---- a/utils/mount/nfs.man -+++ b/utils/mount/nfs.man -@@ -69,10 +69,9 @@ for details on specifying raw IPv6 addresses. +@@ -1622,3 +1624,71 @@ int nfs_options2pmap(struct mount_option + + return 1; + } ++ ++/* ++ * Discover mount server's hostname/address by examining mount options ++ * ++ * Returns a pointer to a string that the caller must free, on ++ * success; otherwise NULL is returned. ++ */ ++static char *nfs_umount_hostname(struct mount_options *options, ++ char *hostname) ++{ ++ char *option; ++ ++ option = po_get(options, "mountaddr"); ++ if (option) ++ goto out; ++ option = po_get(options, "mounthost"); ++ if (option) ++ goto out; ++ option = po_get(options, "addr"); ++ if (option) ++ goto out; ++ ++ return hostname; ++ ++out: ++ free(hostname); ++ return strdup(option); ++} ++ ++ ++/* ++ * Returns EX_SUCCESS if mount options and device name have been ++ * parsed successfully; otherwise EX_FAIL. ++ */ ++int nfs_umount_do_umnt(struct mount_options *options, ++ char **hostname, char **dirname) ++{ ++ union nfs_sockaddr address; ++ struct sockaddr *sap = &address.sa; ++ socklen_t salen = sizeof(address); ++ struct pmap nfs_pmap, mnt_pmap; ++ sa_family_t family; ++ ++ if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap)) ++ return EX_FAIL; ++ ++ /* Skip UMNT call for vers=4 mounts */ ++ if (nfs_pmap.pm_vers == 4) ++ return EX_SUCCESS; ++ ++ *hostname = nfs_umount_hostname(options, *hostname); ++ if (!*hostname) { ++ nfs_error(_("%s: out of memory"), progname); ++ return EX_FAIL; ++ } ++ ++ if (!nfs_mount_proto_family(options, &family)) ++ return 0; ++ if (!nfs_lookup(*hostname, family, sap, &salen)) ++ /* nfs_lookup reports any errors */ ++ return EX_FAIL; ++ ++ if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0) ++ /* nfs_advise_umount reports any errors */ ++ return EX_FAIL; ++ ++ return EX_SUCCESS; ++} +diff -up nfs-utils-1.2.3/utils/mount/network.h.orig nfs-utils-1.2.3/utils/mount/network.h +--- nfs-utils-1.2.3/utils/mount/network.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/network.h 2011-04-20 08:48:36.362265201 -0400 +@@ -75,4 +75,7 @@ int nfs_advise_umount(const struct socka + CLIENT *mnt_openclnt(clnt_addr_t *, int *); + void mnt_closeclnt(CLIENT *, int); + ++int nfs_umount_do_umnt(struct mount_options *options, ++ char **hostname, char **dirname); ++ + #endif /* _NFS_UTILS_MOUNT_NETWORK_H */ +diff -up nfs-utils-1.2.3/utils/mount/nfs.man.orig nfs-utils-1.2.3/utils/mount/nfs.man +--- nfs-utils-1.2.3/utils/mount/nfs.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/nfs.man 2011-04-20 08:48:36.363265193 -0400 +@@ -69,10 +69,9 @@ for details on specifying raw IPv6 addre .P The .I fstype @@ -2116,7 +3179,7 @@ index 55d4b55..be91a25 100644 .SH "MOUNT OPTIONS" Refer to .BR mount (8) -@@ -464,9 +463,9 @@ by other clients, but can impact application and server performance. +@@ -464,9 +463,9 @@ by other clients, but can impact applica .IP The DATA AND METADATA COHERENCE section contains a detailed discussion of these trade-offs. @@ -2137,7 +3200,7 @@ index 55d4b55..be91a25 100644 the server, trying version 4 first, version 3 second, and version 2 last. .TP 1.5i .BI vers= n -@@ -717,9 +716,53 @@ If this option is not specified, the NFS client uses READDIRPLUS requests +@@ -717,9 +716,53 @@ If this option is not specified, the NFS on NFS version 3 mounts to read small directories. Some applications perform better if the client uses only READDIR requests for all directories. @@ -2193,7 +3256,7 @@ index 55d4b55..be91a25 100644 .TP 1.5i .BI proto= netid The transport protocol name and protocol family the NFS client uses -@@ -1480,32 +1523,54 @@ of Access Control Lists that are semantically richer than POSIX ACLs. +@@ -1480,32 +1523,54 @@ of Access Control Lists that are semanti NFS version 4 ACLs are not fully compatible with POSIX ACLs; as such, some translation between the two is required in an environment that mixes POSIX ACLs and NFS version 4. @@ -2243,11 +3306,11 @@ index 55d4b55..be91a25 100644 +MNT operation. +These options are stored on disk by the NFS mount subcommand, +and can be erased by a remount. - .P ++.P +To ensure that the saved mount options are not erased during a remount, +specify either the local mount directory, or the server hostname and +export pathname, but not both, during a remount. For example, -+.P + .P +.NF +.TA 2.5i + mount -o remount,ro /mnt @@ -2264,11 +3327,10 @@ index 55d4b55..be91a25 100644 Before 2.4.7, the Linux NFS client did not support NFS over TCP. .P Before 2.4.20, the Linux NFS client used a heuristic -diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c -index 1514340..02d40ff 100644 ---- a/utils/mount/nfsumount.c -+++ b/utils/mount/nfsumount.c -@@ -31,12 +31,16 @@ +diff -up nfs-utils-1.2.3/utils/mount/nfsumount.c.orig nfs-utils-1.2.3/utils/mount/nfsumount.c +--- nfs-utils-1.2.3/utils/mount/nfsumount.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/nfsumount.c 2011-04-20 08:48:36.364265185 -0400 +@@ -31,11 +31,16 @@ #include "nls.h" #include "mount_constants.h" @@ -2278,14 +3340,14 @@ index 1514340..02d40ff 100644 #include "network.h" #include "parse_opt.h" #include "parse_dev.h" - ++#include "utils.h" ++ +#define MOUNTSFILE "/proc/mounts" +#define LINELEN (4096) -+ + #if !defined(MNT_FORCE) /* dare not try to include -- lots of errors */ - #define MNT_FORCE 1 -@@ -109,7 +113,7 @@ static int del_mtab(const char *spec, const char *node) +@@ -109,7 +114,7 @@ static int del_mtab(const char *spec, co res = try_remount(spec, node); if (res) goto writemtab; @@ -2294,7 +3356,7 @@ index 1514340..02d40ff 100644 } else umnt_err = errno; } -@@ -127,7 +131,7 @@ static int del_mtab(const char *spec, const char *node) +@@ -127,7 +132,7 @@ static int del_mtab(const char *spec, co } if (res >= 0) @@ -2303,22 +3365,107 @@ index 1514340..02d40ff 100644 if (umnt_err) umount_error(umnt_err, node); -@@ -241,6 +245,91 @@ static int nfs_umount23(const char *devname, char *string) - return result; +@@ -135,110 +140,88 @@ static int del_mtab(const char *spec, co } -+/* + /* +- * Discover mount server's hostname/address by examining mount options +- * +- * Returns a pointer to a string that the caller must free, on +- * success; otherwise NULL is returned. +- */ +-static char *nfs_umount_hostname(struct mount_options *options, +- char *hostname) +-{ +- char *option; +- +- option = po_get(options, "mountaddr"); +- if (option) +- goto out; +- option = po_get(options, "mounthost"); +- if (option) +- goto out; +- option = po_get(options, "addr"); +- if (option) +- goto out; +- +- return hostname; +- +-out: +- free(hostname); +- return strdup(option); +-} +- +-/* +- * Returns EX_SUCCESS if mount options and device name have been +- * parsed successfully; otherwise EX_FAIL. +- */ +-static int nfs_umount_do_umnt(struct mount_options *options, +- char **hostname, char **dirname) +-{ +- union { +- struct sockaddr sa; +- struct sockaddr_in s4; +- struct sockaddr_in6 s6; +- } address; +- struct sockaddr *sap = &address.sa; +- socklen_t salen = sizeof(address); +- struct pmap nfs_pmap, mnt_pmap; +- sa_family_t family; +- +- if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap)) +- return EX_FAIL; +- +- /* Skip UMNT call for vers=4 mounts */ +- if (nfs_pmap.pm_vers == 4) +- return EX_SUCCESS; +- +- *hostname = nfs_umount_hostname(options, *hostname); +- if (!*hostname) { +- nfs_error(_("%s: out of memory"), progname); +- return EX_FAIL; +- } +- +- if (!nfs_mount_proto_family(options, &family)) +- return 0; +- if (!nfs_lookup(*hostname, family, sap, &salen)) +- /* nfs_lookup reports any errors */ +- return EX_FAIL; +- +- if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0) +- /* nfs_advise_umount reports any errors */ +- return EX_FAIL; +- +- return EX_SUCCESS; +-} +- +-/* +- * Pick up certain mount options used during the original mount +- * from /etc/mtab. The basics include the server's IP address and +- * the server pathname of the share to unregister. + * Detect NFSv4 mounts. -+ * + * +- * These options might also describe the mount port, mount protocol +- * version, and transport protocol used to punch through a firewall. +- * We will need this information to get through the firewall again +- * to do the umount. + * Consult /proc/mounts to determine if the mount point + * is an NFSv4 mount. The kernel is authoritative about + * what type of mount this is. -+ * + * +- * Note that option parsing failures won't necessarily cause the +- * umount request to fail. Those values will be left zero in the +- * pmap tuple. If the GETPORT call later fails to disambiguate them, +- * then we fail. + * Returns 1 if "mc" is an NFSv4 mount, zero if not, and + * -1 if some error occurred. -+ */ + */ +-static int nfs_umount23(const char *devname, char *string) +static int nfs_umount_is_vers4(const struct mntentchn *mc) -+{ + { +- char *hostname, *dirname; +- struct mount_options *options; +- int result = EX_FAIL; + char buffer[LINELEN], *next; + int retval; + FILE *f; @@ -2368,17 +3515,28 @@ index 1514340..02d40ff 100644 + if (rc && version == 4) + goto out_nfs4; + } -+ + +- if (!nfs_parse_devname(devname, &hostname, &dirname)) +- return EX_USAGE; + goto out_nfs; + } + if (retval == -1) + fprintf(stderr, "%s was not found in %s\n", + mc->m.mnt_dir, MOUNTSFILE); -+ + +- options = po_split(string); +- if (options) { +- result = nfs_umount_do_umnt(options, &hostname, &dirname); +- po_destroy(options); +- } else +- nfs_error(_("%s: option parsing error"), progname); +out: + fclose(f); + return retval; -+ + +- free(hostname); +- free(dirname); +- return result; +out_nfs4: + if (verbose) + fprintf(stderr, "NFSv4 mount point detected\n"); @@ -2390,12 +3548,28 @@ index 1514340..02d40ff 100644 + fprintf(stderr, "Legacy NFS mount point detected\n"); + retval = 0; + goto out; -+} -+ + } + static struct option umount_longopts[] = +@@ -251,17 +234,6 @@ static struct option umount_longopts[] = + { NULL, 0, 0, 0 } + }; + +-static void umount_usage(void) +-{ +- printf(_("usage: %s dir [-fvnrlh]\n"), progname); +- printf(_("options:\n\t-f\t\tforce unmount\n")); +- printf(_("\t-v\tverbose\n")); +- printf(_("\t-n\tDo not update /etc/mtab\n")); +- printf(_("\t-r\tremount\n")); +- printf(_("\t-l\tlazy unmount\n")); +- printf(_("\t-h\tprint this help\n\n")); +-} +- + int nfsumount(int argc, char *argv[]) { - { "force", 0, 0, 'f' }, -@@ -362,16 +451,25 @@ int nfsumount(int argc, char *argv[]) + int c, ret; +@@ -362,16 +334,25 @@ int nfsumount(int argc, char *argv[]) } } @@ -2430,11 +3604,10 @@ index 1514340..02d40ff 100644 } else if (*spec != '/') { if (!lazy) ret = nfs_umount23(spec, "tcp,v3"); -diff --git a/utils/mount/parse_opt.c b/utils/mount/parse_opt.c -index f0918f7..ab869d9 100644 ---- a/utils/mount/parse_opt.c -+++ b/utils/mount/parse_opt.c -@@ -508,7 +508,7 @@ po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *va +diff -up nfs-utils-1.2.3/utils/mount/parse_opt.c.orig nfs-utils-1.2.3/utils/mount/parse_opt.c +--- nfs-utils-1.2.3/utils/mount/parse_opt.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/parse_opt.c 2011-04-20 08:48:36.365265177 -0400 +@@ -508,7 +508,7 @@ po_found_t po_get_numeric(struct mount_o int po_rightmost(struct mount_options *options, const char *keys[]) { struct mount_option *option; @@ -2443,10 +3616,9 @@ index f0918f7..ab869d9 100644 if (options) { for (option = options->tail; option; option = option->prev) { -diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c -index 50a1a2a..f1aa503 100644 ---- a/utils/mount/stropts.c -+++ b/utils/mount/stropts.c +diff -up nfs-utils-1.2.3/utils/mount/stropts.c.orig nfs-utils-1.2.3/utils/mount/stropts.c +--- nfs-utils-1.2.3/utils/mount/stropts.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/stropts.c 2011-04-20 08:48:36.366265169 -0400 @@ -49,10 +49,6 @@ #include "parse_dev.h" #include "conffile.h" @@ -2458,7 +3630,7 @@ index 50a1a2a..f1aa503 100644 #ifndef NFS_PROGRAM #define NFS_PROGRAM (100003) #endif -@@ -114,7 +110,7 @@ static void nfs_default_version(struct nfsmount_info *mi) +@@ -114,7 +110,7 @@ static void nfs_default_version(struct n } } #else @@ -2467,7 +3639,7 @@ index 50a1a2a..f1aa503 100644 #endif /* MOUNT_CONFIG */ /* -@@ -123,10 +119,12 @@ inline void nfs_default_version(struct nfsmount_info *mi) {} +@@ -123,10 +119,12 @@ inline void nfs_default_version(struct n * Returns a time_t timeout timestamp, in seconds. */ static time_t nfs_parse_retry_option(struct mount_options *options, @@ -2481,7 +3653,7 @@ index 50a1a2a..f1aa503 100644 switch (po_get_numeric(options, "retry", &tmp)) { case PO_NOT_FOUND: break; -@@ -135,6 +133,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options, +@@ -135,6 +133,7 @@ static time_t nfs_parse_retry_option(str timeout_minutes = tmp; break; } @@ -2489,7 +3661,7 @@ index 50a1a2a..f1aa503 100644 case PO_BAD_VALUE: if (verbose) nfs_error(_("%s: invalid retry timeout was specified; " -@@ -142,7 +141,7 @@ static time_t nfs_parse_retry_option(struct mount_options *options, +@@ -142,7 +141,7 @@ static time_t nfs_parse_retry_option(str break; } @@ -2498,7 +3670,7 @@ index 50a1a2a..f1aa503 100644 } /* -@@ -343,7 +342,6 @@ static int nfs_validate_options(struct nfsmount_info *mi) +@@ -343,7 +342,6 @@ static int nfs_validate_options(struct n { struct addrinfo hint = { .ai_protocol = (int)IPPROTO_UDP, @@ -2506,7 +3678,7 @@ index 50a1a2a..f1aa503 100644 }; sa_family_t family; int error; -@@ -570,16 +568,18 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts) +@@ -570,16 +568,18 @@ static int nfs_sys_mount(struct nfsmount char *options = NULL; int result; @@ -2546,11 +3718,229 @@ index 50a1a2a..f1aa503 100644 for (ai = mi->address; ai != NULL; ai = ai->ai_next) { ret = nfs_do_mount_v4(mi, ai->ai_addr, ai->ai_addrlen); -diff --git a/utils/mount/version.h b/utils/mount/version.h -index 46552a1..af61a6f 100644 ---- a/utils/mount/version.h -+++ b/utils/mount/version.h -@@ -42,9 +42,9 @@ static inline unsigned int linux_version_code(void) +diff -up nfs-utils-1.2.3/utils/mount/utils.c.orig nfs-utils-1.2.3/utils/mount/utils.c +--- nfs-utils-1.2.3/utils/mount/utils.c.orig 2011-04-20 08:48:36.367265162 -0400 ++++ nfs-utils-1.2.3/utils/mount/utils.c 2011-04-20 08:48:36.367265162 -0400 +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2010 Karel Zak ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 021110-1307, USA. ++ * ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sockaddr.h" ++#include "nfs_mount.h" ++#include "nls.h" ++#include "xcommon.h" ++#include "version.h" ++#include "error.h" ++#include "utils.h" ++#include "mount.h" ++#include "network.h" ++#include "parse_dev.h" ++ ++extern int verbose; ++extern char *progname; ++ ++/* ++ * Choose the version of the nfs_mount_data structure that is appropriate ++ * for the kernel that is doing the mount. ++ * ++ * NFS_MOUNT_VERSION: maximum version supported by these sources ++ * nfs_mount_data_version: maximum version supported by the running kernel ++ */ ++int discover_nfs_mount_data_version(int *string_ver) ++{ ++ unsigned int kernel_version = linux_version_code(); ++ int ver = 0; ++ ++ *string_ver = 0; ++ ++ if (kernel_version) { ++ if (kernel_version < MAKE_VERSION(2, 1, 32)) ++ ver = 1; ++ else if (kernel_version < MAKE_VERSION(2, 2, 18)) ++ ver = 3; ++ else if (kernel_version < MAKE_VERSION(2, 3, 0)) ++ ver = 4; ++ else if (kernel_version < MAKE_VERSION(2, 3, 99)) ++ ver = 3; ++ else if (kernel_version < MAKE_VERSION(2, 6, 3)) ++ ver = 4; ++ else ++ ver = 6; ++ } ++ if (ver > NFS_MOUNT_VERSION) ++ ver = NFS_MOUNT_VERSION; ++ else ++ if (kernel_version > MAKE_VERSION(2, 6, 22)) ++ (*string_ver)++; ++ ++ return ver; ++} ++ ++void print_one(char *spec, char *node, char *type, char *opts) ++{ ++ if (!verbose) ++ return; ++ ++ if (opts) ++ printf(_("%s on %s type %s (%s)\n"), spec, node, type, opts); ++ else ++ printf(_("%s on %s type %s\n"), spec, node, type); ++} ++ ++void mount_usage(void) ++{ ++ printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"), ++ progname); ++ printf(_("options:\n")); ++ printf(_("\t-r\t\tMount file system readonly\n")); ++ printf(_("\t-v\t\tVerbose\n")); ++ printf(_("\t-V\t\tPrint version\n")); ++ printf(_("\t-w\t\tMount file system read-write\n")); ++ printf(_("\t-f\t\tFake mount, do not actually mount\n")); ++ printf(_("\t-n\t\tDo not update /etc/mtab\n")); ++ printf(_("\t-s\t\tTolerate sloppy mount options rather than fail\n")); ++ printf(_("\t-h\t\tPrint this help\n")); ++ printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n")); ++} ++ ++void umount_usage(void) ++{ ++ printf(_("usage: %s dir [-fvnrlh]\n"), progname); ++ printf(_("options:\n\t-f\t\tforce unmount\n")); ++ printf(_("\t-v\tverbose\n")); ++ printf(_("\t-n\tDo not update /etc/mtab\n")); ++ printf(_("\t-r\tremount\n")); ++ printf(_("\t-l\tlazy unmount\n")); ++ printf(_("\t-h\tprint this help\n\n")); ++} ++ ++int chk_mountpoint(const char *mount_point) ++{ ++ struct stat sb; ++ ++ if (stat(mount_point, &sb) < 0){ ++ mount_error(NULL, mount_point, errno); ++ return 1; ++ } ++ if (S_ISDIR(sb.st_mode) == 0){ ++ mount_error(NULL, mount_point, ENOTDIR); ++ return 1; ++ } ++ if (access(mount_point, X_OK) < 0) { ++ mount_error(NULL, mount_point, errno); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Pick up certain mount options used during the original mount ++ * from /etc/mtab. The basics include the server's IP address and ++ * the server pathname of the share to unregister. ++ * ++ * These options might also describe the mount port, mount protocol ++ * version, and transport protocol used to punch through a firewall. ++ * We will need this information to get through the firewall again ++ * to do the umount. ++ * ++ * Note that option parsing failures won't necessarily cause the ++ * umount request to fail. Those values will be left zero in the ++ * pmap tuple. If the GETPORT call later fails to disambiguate them, ++ * then we fail. ++ */ ++int nfs_umount23(const char *devname, char *string) ++{ ++ char *hostname = NULL, *dirname = NULL; ++ struct mount_options *options; ++ int result = EX_FAIL; ++ ++ if (!nfs_parse_devname(devname, &hostname, &dirname)) ++ return EX_USAGE; ++ ++ options = po_split(string); ++ if (options) { ++ result = nfs_umount_do_umnt(options, &hostname, &dirname); ++ po_destroy(options); ++ } else ++ nfs_error(_("%s: option parsing error"), progname); ++ ++ free(hostname); ++ free(dirname); ++ return result; ++} +diff -up nfs-utils-1.2.3/utils/mount/utils.h.orig nfs-utils-1.2.3/utils/mount/utils.h +--- nfs-utils-1.2.3/utils/mount/utils.h.orig 2011-04-20 08:48:36.367265162 -0400 ++++ nfs-utils-1.2.3/utils/mount/utils.h 2011-04-20 08:48:36.367265162 -0400 +@@ -0,0 +1,36 @@ ++/* ++ * utils.h -- misc utils for mount and umount ++ * ++ * Copyright (C) 2010 Karel Zak ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 021110-1307, USA. ++ * ++ */ ++ ++#ifndef _NFS_UTILS_MOUNT_UTILS_H ++#define _NFS_UTILS_MOUNT_UTILS_H ++ ++#include "parse_opt.h" ++ ++int discover_nfs_mount_data_version(int *string_ver); ++void print_one(char *spec, char *node, char *type, char *opts); ++void mount_usage(void); ++void umount_usage(void); ++int chk_mountpoint(const char *mount_point); ++ ++int nfs_umount23(const char *devname, char *string); ++ ++#endif /* !_NFS_UTILS_MOUNT_UTILS_H */ +diff -up nfs-utils-1.2.3/utils/mount/version.h.orig nfs-utils-1.2.3/utils/mount/version.h +--- nfs-utils-1.2.3/utils/mount/version.h.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/mount/version.h 2011-04-20 08:48:36.368265155 -0400 +@@ -42,9 +42,9 @@ static inline unsigned int linux_version if (uname(&my_utsname)) return 0; @@ -2563,70 +3953,9 @@ index 46552a1..af61a6f 100644 return MAKE_VERSION(p, q, r); } -diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c -index d309950..035624c 100644 ---- a/utils/mountd/mountd.c -+++ b/utils/mountd/mountd.c -@@ -99,12 +99,9 @@ static int version_any(void) - static void - unregister_services (void) - { -- if (version2()) { -- nfs_svc_unregister(MOUNTPROG, MOUNTVERS); -- nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX); -- } -- if (version3()) -- nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3); -+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS); -+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_POSIX); -+ nfs_svc_unregister(MOUNTPROG, MOUNTVERS_NFSV3); - } - - static void -@@ -840,6 +837,7 @@ main(int argc, char **argv) - if (new_cache) - cache_open(); - -+ unregister_services(); - if (version2()) { - listeners += nfs_svc_create("mountd", MOUNTPROG, - MOUNTVERS, mount_dispatch, port); -diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man -index 4bb96e8..016a357 100644 ---- a/utils/mountd/mountd.man -+++ b/utils/mountd/mountd.man -@@ -106,11 +106,11 @@ This option can be used to request that - .B rpc.mountd - do not offer certain versions of NFS. The current version of - .B rpc.mountd --can support both NFS version 2 and the newer version 3. If the --NFS kernel module was compiled without support for NFSv3, -+can support both NFS version 2, 3 and 4. If the -+either one of these version should not be offered, - .B rpc.mountd - must be invoked with the option --.B "\-\-no-nfs-version 3" . -+.B "\-\-no-nfs-version " . - .TP - .B \-n " or " \-\-no-tcp - Don't advertise TCP for mount. -diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c -index d339296..527377f 100644 ---- a/utils/mountd/rmtab.c -+++ b/utils/mountd/rmtab.c -@@ -205,6 +205,7 @@ mountlist_list(void) - } - if (stb.st_mtime != last_mtime) { - mountlist_freeall(mlist); -+ mlist = NULL; - last_mtime = stb.st_mtime; - - setrmtabent("r"); -diff --git a/utils/nfsidmap/Makefile.am b/utils/nfsidmap/Makefile.am -new file mode 100644 -index 0000000..f837b91 ---- /dev/null -+++ b/utils/nfsidmap/Makefile.am +diff -up nfs-utils-1.2.3/utils/nfsidmap/Makefile.am.orig nfs-utils-1.2.3/utils/nfsidmap/Makefile.am +--- nfs-utils-1.2.3/utils/nfsidmap/Makefile.am.orig 2011-04-20 08:48:36.371265132 -0400 ++++ nfs-utils-1.2.3/utils/nfsidmap/Makefile.am 2011-04-20 08:48:36.372265124 -0400 @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in + @@ -2637,11 +3966,9 @@ index 0000000..f837b91 +nfsidmap_LDADD = -lnfsidmap -lkeyutils + +MAINTAINERCLEANFILES = Makefile.in -diff --git a/utils/nfsidmap/nfsidmap.c b/utils/nfsidmap/nfsidmap.c -new file mode 100644 -index 0000000..2d87381 ---- /dev/null -+++ b/utils/nfsidmap/nfsidmap.c +diff -up nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c.orig nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c +--- nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c.orig 2011-04-20 08:48:36.372265124 -0400 ++++ nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.c 2011-04-20 08:48:36.372265124 -0400 @@ -0,0 +1,118 @@ + +#include @@ -2761,11 +4088,9 @@ index 0000000..2d87381 + free(arg); + return rc; +} -diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man -new file mode 100644 -index 0000000..6c1a2d4 ---- /dev/null -+++ b/utils/nfsidmap/nfsidmap.man +diff -up nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man.orig nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man +--- nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man.orig 2011-04-20 08:48:36.373265116 -0400 ++++ nfs-utils-1.2.3/utils/nfsidmap/nfsidmap.man 2011-04-20 08:48:36.373265116 -0400 @@ -0,0 +1,60 @@ +.\" +.\"@(#)nfsidmap(8) - The NFS idmapper upcall program @@ -2827,11 +4152,10 @@ index 0000000..6c1a2d4 +/usr/sbin/nfsidmap will handle gid, user, and group lookups. +.SH AUTHOR +Bryan Schumaker, -diff --git a/utils/nfsstat/nfsstat.c b/utils/nfsstat/nfsstat.c -index bacef8e..f31bb81 100644 ---- a/utils/nfsstat/nfsstat.c -+++ b/utils/nfsstat/nfsstat.c -@@ -46,7 +46,7 @@ static unsigned int cltproc3info[CLTPROC3_SZ+2], +diff -up nfs-utils-1.2.3/utils/nfsstat/nfsstat.c.orig nfs-utils-1.2.3/utils/nfsstat/nfsstat.c +--- nfs-utils-1.2.3/utils/nfsstat/nfsstat.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/nfsstat/nfsstat.c 2011-04-20 08:48:36.374265108 -0400 +@@ -46,7 +46,7 @@ static unsigned int cltproc3info[CLTPROC static unsigned int srvproc4info[SRVPROC4_SZ+2], srvproc4info_old[SRVPROC4_SZ+2]; /* NFSv4 call counts ([0] == 2) */ static unsigned int cltproc4info[CLTPROC4_SZ+2], @@ -2892,7 +4216,7 @@ index bacef8e..f31bb81 100644 if (opt_prt & PRNT_NET) { if (opt_sleep && !has_rpcstats(srvnetinfo, 4)) { } else { -@@ -582,31 +582,29 @@ print_server_stats(int opt_srv, int opt_prt) +@@ -582,31 +582,29 @@ print_server_stats(int opt_srv, int opt_ printf("\n"); } if (opt_prt & PRNT_CALLS) { @@ -2934,7 +4258,7 @@ index bacef8e..f31bb81 100644 print_callstats( LABEL_srvproc4, nfssrvproc4name, srvproc4info + 1, sizeof(nfssrvproc4name)/sizeof(char *)); -@@ -618,11 +616,8 @@ print_server_stats(int opt_srv, int opt_prt) +@@ -618,11 +616,8 @@ print_server_stats(int opt_srv, int opt_ } } static void @@ -2947,7 +4271,7 @@ index bacef8e..f31bb81 100644 if (opt_prt & PRNT_NET) { if (opt_sleep && !has_rpcstats(cltnetinfo, 4)) { ; -@@ -644,31 +639,28 @@ print_client_stats(int opt_clt, int opt_prt) +@@ -644,31 +639,28 @@ print_client_stats(int opt_clt, int opt_ } } if (opt_prt & PRNT_CALLS) { @@ -3090,11 +4414,10 @@ index bacef8e..f31bb81 100644 } static int has_rpcstats(const unsigned int *info, int size) -diff --git a/utils/nfsstat/nfsstat.man b/utils/nfsstat/nfsstat.man -index 52215a9..cd573b0 100644 ---- a/utils/nfsstat/nfsstat.man -+++ b/utils/nfsstat/nfsstat.man -@@ -30,10 +30,12 @@ Print only NFS v2 statistics. The default is to only print information +diff -up nfs-utils-1.2.3/utils/nfsstat/nfsstat.man.orig nfs-utils-1.2.3/utils/nfsstat/nfsstat.man +--- nfs-utils-1.2.3/utils/nfsstat/nfsstat.man.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/nfsstat/nfsstat.man 2011-04-20 08:48:36.374265108 -0400 +@@ -30,10 +30,12 @@ Print only NFS v2 statistics. The defaul about the versions of \fBNFS\fR that have non-zero counts. .TP .B \-3 @@ -3109,10 +4432,9 @@ index 52215a9..cd573b0 100644 .TP .B \-m, \-\-mounts Print information about each of the mounted \fBNFS\fR file systems. -diff --git a/utils/statd/hostname.c b/utils/statd/hostname.c -index 38f2265..616a3cb 100644 ---- a/utils/statd/hostname.c -+++ b/utils/statd/hostname.c +diff -up nfs-utils-1.2.3/utils/statd/hostname.c.orig nfs-utils-1.2.3/utils/statd/hostname.c +--- nfs-utils-1.2.3/utils/statd/hostname.c.orig 2010-09-28 08:24:16.000000000 -0400 ++++ nfs-utils-1.2.3/utils/statd/hostname.c 2011-04-20 08:48:36.375265101 -0400 @@ -39,10 +39,6 @@ #include "statd.h" #include "xlog.h" @@ -3124,11 +4446,10 @@ index 38f2265..616a3cb 100644 /** * statd_present_address - convert sockaddr to presentation address * @sap: pointer to socket address to convert -diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c -index 437e37a..1f490b0 100644 ---- a/utils/statd/sm-notify.c -+++ b/utils/statd/sm-notify.c -@@ -34,8 +34,9 @@ +diff -up nfs-utils-1.2.3/utils/statd/sm-notify.c.orig nfs-utils-1.2.3/utils/statd/sm-notify.c +--- nfs-utils-1.2.3/utils/statd/sm-notify.c.orig 2011-04-20 08:48:17.906406908 -0400 ++++ nfs-utils-1.2.3/utils/statd/sm-notify.c 2011-04-20 08:48:36.376265094 -0400 +@@ -37,8 +37,9 @@ #include "nsm.h" #include "nfsrpc.h" @@ -3140,7 +4461,7 @@ index 437e37a..1f490b0 100644 #endif #define NSM_TIMEOUT 2 -@@ -78,7 +79,6 @@ smn_lookup(const char *name) +@@ -81,7 +82,6 @@ smn_lookup(const char *name) { struct addrinfo *ai = NULL; struct addrinfo hint = { @@ -3148,7 +4469,7 @@ index 437e37a..1f490b0 100644 .ai_family = (nsm_family == AF_INET ? AF_INET: AF_UNSPEC), .ai_protocol = (int)IPPROTO_UDP, }; -@@ -253,6 +253,7 @@ smn_bind_address(const char *srcaddr, const char *srcport) +@@ -257,6 +257,7 @@ smn_bind_address(const char *srcaddr, co if (srcaddr == NULL) hint.ai_flags |= AI_PASSIVE; @@ -3156,3 +4477,15 @@ index 437e37a..1f490b0 100644 if (srcport == NULL) error = getaddrinfo(srcaddr, "", &hint, &ai); else +diff -up nfs-utils-1.2.3/utils/statd/statd.man.orig nfs-utils-1.2.3/utils/statd/statd.man +--- nfs-utils-1.2.3/utils/statd/statd.man.orig 2011-04-20 08:48:17.897406977 -0400 ++++ nfs-utils-1.2.3/utils/statd/statd.man 2011-04-20 08:48:36.376265094 -0400 +@@ -12,7 +12,7 @@ + .SH NAME + rpc.statd \- NSM service daemon + .SH SYNOPSIS +-.BI "rpc.statd [-dh?FLNvVw] [-H " prog "] [-n " my-name "] [-o " outgoing-port "] [-p " listener-port "] [-P " path " ] ++.BI "rpc.statd [-dh?FLNvV] [-H " prog "] [-n " my-name "] [-o " outgoing-port "] [-p " listener-port "] [-P " path " ] + .SH DESCRIPTION + File locks are not part of persistent file system state. + Lock state is thus lost when a host reboots. diff --git a/nfs-utils.spec b/nfs-utils.spec index c3ce62a..4ab9f3d 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser Name: nfs-utils URL: http://sourceforge.net/projects/nfs Version: 1.2.3 -Release: 12%{?dist} +Release: 13%{?dist} Epoch: 1 # group all 32bit related archs @@ -17,7 +17,7 @@ Source13: rpcgssd.init Source14: rpcsvcgssd.init Source15: nfs.sysconfig -Patch001: nfs-utils-1.2.4-rc7.patch +Patch001: nfs-utils-1.2.4-rc8.patch Patch100: nfs-utils-1.2.1-statdpath-man.patch Patch101: nfs-utils-1.2.2-statdpath.patch @@ -254,6 +254,9 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Wed Apr 20 2011 Steve Dickson 1.2.3-13 +- Updated to latest upstream release: nfs-utils-1-2-4-rc8 + * Wed Apr 6 2011 Steve Dickson 1.2.3-12 - Updated to latest upstream release: nfs-utils-1-2-4-rc7 - Enabled the libmount code.