]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
nfs-utils: Update to 1.2.7.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 26 Jan 2013 19:49:16 +0000 (19:49 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 26 Jan 2013 19:49:16 +0000 (19:49 +0000)
With the update, there are a lot more changes coming.
systemd unit files are shipped and the service is finally
working like a charm.

18 files changed:
nfs-utils/nfs-lock.preconfig [new file with mode: 0644]
nfs-utils/nfs-utils.nm
nfs-utils/patches/nfs-utils-1.2.1-exp-subtree-warn-off.patch [new file with mode: 0644]
nfs-utils/patches/nfs-utils-1.2.1-statdpath-man.patch [new file with mode: 0644]
nfs-utils/patches/nfs-utils-1.2.3-sm-notify-res_init.patch [new file with mode: 0644]
nfs-utils/patches/nfs-utils-1.2.5-idmap-errmsg.patch [new file with mode: 0644]
nfs-utils/patches/nfs-utils.1.2.8.rc3.patch [new file with mode: 0644]
nfs-utils/systemd/nfs-blkmap.service [new file with mode: 0644]
nfs-utils/systemd/nfs-idmap.service [new file with mode: 0644]
nfs-utils/systemd/nfs-lock.service [new file with mode: 0644]
nfs-utils/systemd/nfs-mountd.service [new file with mode: 0644]
nfs-utils/systemd/nfs-rquotad.service [new file with mode: 0644]
nfs-utils/systemd/nfs-secure-server.service [new file with mode: 0644]
nfs-utils/systemd/nfs-secure.service [new file with mode: 0644]
nfs-utils/systemd/nfs-server.service [new file with mode: 0644]
nfs-utils/systemd/nfs.target [new file with mode: 0644]
nfs-utils/systemd/proc-fs-nfsd.mount [new file with mode: 0644]
nfs-utils/systemd/var-lib-nfs-rpc_pipefs.mount [new file with mode: 0644]

diff --git a/nfs-utils/nfs-lock.preconfig b/nfs-utils/nfs-lock.preconfig
new file mode 100644 (file)
index 0000000..71dec7e
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Make sure lockd is loaded
+modprobe -q lockd
index f40ad2ff94442e34b1d4f8509cb88ca026e0a1d9..d98f9cd8c922c80b5bef827a3e751c228a45dd35 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = nfs-utils
-version    = 1.2.2
-release    = 2
+version    = 1.2.7
+release    = 1
 
 groups     = Networking/Tools
 url        = http://nfs.sourceforge.net/
@@ -22,35 +22,108 @@ description
        which are mounted on that host.
 end
 
-source_dl  =
-sources    = %{thisapp}.tar.bz2
+source_dl  = http://www.kernel.org/pub/linux/utils/nfs-utils/%{version}/
+sources    = %{thisapp}.tar.xz
 
 build
        requires
+               autoconf
+               automake
                libblkid-devel
+               libdevmapper-devel
                libcap-devel
                libevent-devel
+               libgssglue-devel
+               libmount-devel
                libnfsidmap-devel
+               libtirpc-devel
+               libtool
+               shadow-utils
+               sqlite-devel
+               systemd-units
        end
 
        configure_options += \
                --without-tcp-wrappers \
-               --disable-static \
-               --enable-tirpc=no \
-               --enable-nfsv3 \
-               --enable-nfsv4 \
-               --with-krb5=no \
+               --without-krb5 \
                --disable-gss \
-               --with-rpcgen=internal \
-               --enable-mount
+               --enable-libmount-mount \
+               --enable-mountconfig \
+               --enable-ipv6 \
+               --with-statdpath=/var/lib/nfs/statd
+
+       prepare_cmds
+               sh autogen.sh
+
+               %{create_user}
+       end
+
+       install_cmds
+               mkdir -pv %{BUILDROOT}%{sysconfdir}
+               mkdir -pv %{BUILDROOT}/var/lib/nfs/v4recovery
+               mkdir -pv %{BUILDROOT}/etc/exports.d
+
+               install -s -m 755 tools/rpcdebug/rpcdebug %{BUILDROOT}%{sbindir}
+               install -m 644 utils/mount/nfsmount.conf %{BUILDROOT}%{sysconfdir}
+
+               mkdir -pv %{BUILDROOT}/var/lib/nfs/rpc_pipefs
+               touch %{BUILDROOT}/var/lib/nfs/rmtab
+
+               mkdir -pv %{BUILDROOT}/usr/lib/nfs-utils/scripts
+               install -m 755 %{DIR_SOURCE}/nfs-lock.preconfig \
+                       %{BUILDROOT}/usr/lib/nfs-utils/scripts/
+
+               mkdir -pv %{BUILDROOT}/var/lib/nfs/statd/sm{,.bak}
+               chown rpcuser:rpcuser -Rv %{BUILDROOT}/var/lib/nfs/statd
+       end
+end
+
+create_user
+       getent passwd rpcuser >/dev/null || useradd -l -c "RPC Service User" -r \
+               -s /sbin/nologin -u 29 -d /var/lib/nfs rpcuser
+       getent group rpcuser >/dev/null || groupadd -g 29 rpcuser 2>/dev/null
 end
 
 packages
        package %{name}
+               provides
+                       rpc.idmapd  = %{thisver}
+                       rpc.mountd  = %{thisver}
+                       rpc.nfsd    = %{thisver}
+                       rpc.statd   = %{thisver}
+                       rpc.gssd    = %{thisver}
+                       rpc.svggssd = %{thisver}
+               end
+
                requires
-                       libgssglue
+                       libnfsidmap >= 0.25
+                       quota
+                       rpcbind
                        util-linux
                end
+
+               nfsnobody_uid = 65534
+
+               script prein
+                       %{create_user}
+
+                       getent group nfsnobody >/dev/null || groupadd -g %{nfsnobody_uid} nfsnobody
+                       getent passwd nfsnobody >/dev/null || useradd -l -c "Anonymous NFS User" -r \
+                               -s /sbin/nologin -u %{nfsnobody_uid} -g %{nfsnobody_uid} \
+                               -d /var/lib/nfs nfsnobody
+               end
+
+               script postin
+                       systemctl daemon-reload >/dev/null 2>&1 || :
+               end
+
+               script postup
+                       systemctl daemon-reload >/dev/null 2>&1 || :
+               end
+
+               script postun
+                       systemctl daemon-reload >/dev/null 2>&1 || :
+               end
        end
 
        package %{name}-debuginfo
diff --git a/nfs-utils/patches/nfs-utils-1.2.1-exp-subtree-warn-off.patch b/nfs-utils/patches/nfs-utils-1.2.1-exp-subtree-warn-off.patch
new file mode 100644 (file)
index 0000000..14e376c
--- /dev/null
@@ -0,0 +1,12 @@
+diff -up nfs-utils-1.2.1/support/nfs/exports.c.orig nfs-utils-1.2.1/support/nfs/exports.c
+--- nfs-utils-1.2.1/support/nfs/exports.c.orig 2010-01-15 10:48:49.631894982 -0500
++++ nfs-utils-1.2.1/support/nfs/exports.c      2010-01-15 11:05:02.009874055 -0500
+@@ -483,7 +483,7 @@ static void fix_pseudoflavor_flags(struc
+ static int
+ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
+ {
+-      int     had_subtree_opt = 0;
++      int     had_subtree_opt = 1;
+       char    *flname = efname?efname:"command line";
+       int     flline = efp?efp->x_line:0;
+       unsigned int active = 0;
diff --git a/nfs-utils/patches/nfs-utils-1.2.1-statdpath-man.patch b/nfs-utils/patches/nfs-utils-1.2.1-statdpath-man.patch
new file mode 100644 (file)
index 0000000..8c2e0e2
--- /dev/null
@@ -0,0 +1,58 @@
+diff -up nfs-utils-1.2.1/utils/statd/sm-notify.man.save nfs-utils-1.2.1/utils/statd/sm-notify.man
+--- nfs-utils-1.2.1/utils/statd/sm-notify.man.save     2010-01-15 11:10:25.096874609 -0500
++++ nfs-utils-1.2.1/utils/statd/sm-notify.man  2010-01-15 11:14:12.636873981 -0500
+@@ -186,7 +186,7 @@ where NSM state information resides.
+ If this option is not specified,
+ .B sm-notify
+ uses
+-.I /var/lib/nfs
++.I /var/lib/nfs/statd
+ by default.
+ .IP
+ After starting,
+@@ -287,13 +287,13 @@ Currently, the
+ command supports sending notification only via datagram transport protocols.
+ .SH FILES
+ .TP 2.5i
+-.I /var/lib/nfs/sm
++.I /var/lib/nfs/statd/sm
+ directory containing monitor list
+ .TP 2.5i
+-.I /var/lib/nfs/sm.bak
++.I /var/lib/nfs/statd/sm.bak
+ directory containing notify list
+ .TP 2.5i
+-.I /var/lib/nfs/state
++.I /var/lib/nfs/statd/state
+ NSM state number for this host
+ .TP 2.5i
+ .I /proc/sys/fs/nfs/nsm_local_state
+diff -up nfs-utils-1.2.1/utils/statd/statd.man.save nfs-utils-1.2.1/utils/statd/statd.man
+--- nfs-utils-1.2.1/utils/statd/statd.man.save 2010-01-15 11:10:25.098906325 -0500
++++ nfs-utils-1.2.1/utils/statd/statd.man      2010-01-15 11:11:03.874769717 -0500
+@@ -232,7 +232,7 @@ where NSM state information resides.
+ If this option is not specified,
+ .B rpc.statd
+ uses
+-.I /var/lib/nfs
++.I /var/lib/nfs/statd
+ by default.
+ .IP
+ After starting,
+@@ -368,13 +368,13 @@ As long as at least one network transpor
+ will operate.
+ .SH FILES
+ .TP 2.5i
+-.I /var/lib/nfs/sm
++.I /var/lib/nfs/statd/sm
+ directory containing monitor list
+ .TP 2.5i
+-.I /var/lib/nfs/sm.bak
++.I /var/lib/nfs/statd/sm.bak
+ directory containing notify list
+ .TP 2.5i
+-.I /var/lib/nfs/state
++.I /var/lib/nfs/statd/state
+ NSM state number for this host
+ .TP 2.5i
+ .I /var/run/run.statd.pid
diff --git a/nfs-utils/patches/nfs-utils-1.2.3-sm-notify-res_init.patch b/nfs-utils/patches/nfs-utils-1.2.3-sm-notify-res_init.patch
new file mode 100644 (file)
index 0000000..3ce55eb
--- /dev/null
@@ -0,0 +1,21 @@
+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       2010-09-28 08:24:16.000000000 -0400
++++ nfs-utils-1.2.3/utils/statd/sm-notify.c    2010-10-15 16:44:43.487119601 -0400
+@@ -28,6 +28,9 @@
+ #include <netdb.h>
+ #include <errno.h>
+ #include <grp.h>
++#include <netinet/in.h>
++#include <arpa/nameser.h>
++#include <resolv.h>
+ #include "sockaddr.h"
+ #include "xlog.h"
+@@ -84,6 +87,7 @@ smn_lookup(const char *name)
+       };
+       int error;
++      res_init();
+       error = getaddrinfo(name, NULL, &hint, &ai);
+       if (error != 0) {
+               xlog(D_GENERAL, "getaddrinfo(3): %s", gai_strerror(error));
diff --git a/nfs-utils/patches/nfs-utils-1.2.5-idmap-errmsg.patch b/nfs-utils/patches/nfs-utils-1.2.5-idmap-errmsg.patch
new file mode 100644 (file)
index 0000000..8e00ed7
--- /dev/null
@@ -0,0 +1,12 @@
+diff -up nfs-utils-1.2.5/utils/nfsidmap/nfsidmap.c.orig nfs-utils-1.2.5/utils/nfsidmap/nfsidmap.c
+--- nfs-utils-1.2.5/utils/nfsidmap/nfsidmap.c.orig     2011-12-13 15:01:26.311660000 -0500
++++ nfs-utils-1.2.5/utils/nfsidmap/nfsidmap.c  2011-12-13 15:32:48.167354000 -0500
+@@ -261,7 +261,7 @@ int main(int argc, char **argv)
+       xlog_stderr(0);
+       if ((argc - optind) != 2) {
+-              xlog_err("Bad arg count. Check /etc/request-key.conf");
++              xlog_err("Bad arg count. Check /etc/request-key.d/id_resolver.conf");
+               xlog_warn(usage, progname);
+               return 1;
+       }
diff --git a/nfs-utils/patches/nfs-utils.1.2.8.rc3.patch b/nfs-utils/patches/nfs-utils.1.2.8.rc3.patch
new file mode 100644 (file)
index 0000000..7c332cc
--- /dev/null
@@ -0,0 +1,592 @@
+diff --git a/support/export/rmtab.c b/support/export/rmtab.c
+index 31c0f50..d16b3b3 100644
+--- a/support/export/rmtab.c
++++ b/support/export/rmtab.c
+@@ -1,7 +1,7 @@
+ /*
+- * support/export/rmntab.c
++ * support/export/rmtab.c
+  *
+- * Interface to the rmnt file.
++ * Interface to the rmtab file.
+  *
+  */
+@@ -12,7 +12,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+-#include "xmalloc.h"
++
+ #include "misc.h"
+ #include "nfslib.h"
+ #include "exportfs.h"
+diff --git a/support/export/xtab.c b/support/export/xtab.c
+index 2a43193..e953071 100644
+--- a/support/export/xtab.c
++++ b/support/export/xtab.c
+@@ -14,7 +14,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include "xmalloc.h"
++
+ #include "nfslib.h"
+ #include "exportfs.h"
+ #include "xio.h"
+diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
+index e641c45..61e07a8 100644
+--- a/support/nfs/cacheio.c
++++ b/support/nfs/cacheio.c
+@@ -162,11 +162,16 @@ int qword_eol(FILE *f)
+ {
+       int err;
+-      fprintf(f,"\n");
+-      err = fflush(f);
+-      if (err) {
+-              xlog_warn("qword_eol: fflush failed: errno %d (%s)",
++      err = fprintf(f,"\n");
++      if (err < 0) {
++              xlog_warn("qword_eol: fprintf failed: errno %d (%s)",
+                           errno, strerror(errno));
++      } else {
++              err = fflush(f);
++              if (err) {
++                      xlog_warn("qword_eol: fflush failed: errno %d (%s)",
++                                errno, strerror(errno));
++              }
+       }
+       /*
+        * We must send one line (and one line only) in a single write
+diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
+index ec251fa..d01ba2f 100644
+--- a/utils/gssd/gssd_proc.c
++++ b/utils/gssd/gssd_proc.c
+@@ -52,6 +52,7 @@
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <sys/fsuid.h>
++#include <sys/resource.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -250,21 +251,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
+       if ((p = strstr(buf, "port")) != NULL)
+               sscanf(p, "port: %127s\n", port);
+-      /* check service, program, and version */
+-      if (memcmp(service, "nfs", 3) != 0)
+-              return -1;
++      /* get program, and version numbers */
+       *prog = atoi(program + 1); /* skip open paren */
+       *vers = atoi(version);
+-      if (strlen(service) == 3 ) {
+-              if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) &&
+-                  (*vers != 4)))
+-                      goto fail;
+-      } else if (memcmp(service, "nfs4_cb", 7) == 0) {
+-              if (*vers != 1)
+-                      goto fail;
+-      }
+-
+       if (!addrstr_to_sockaddr(addr, address, port))
+               goto fail;
+@@ -398,10 +388,10 @@ process_clnt_dir_files(struct clnt_info * clp)
+ static int
+ get_poll_index(int *ind)
+ {
+-      int i;
++      unsigned int i;
+       *ind = -1;
+-      for (i=0; i<FD_ALLOC_BLOCK; i++) {
++      for (i=0; i<pollsize; i++) {
+               if (pollarray[i].events == 0) {
+                       *ind = i;
+                       break;
+@@ -483,9 +473,13 @@ fail_keep_client:
+ void
+ init_client_list(void)
+ {
++      struct rlimit rlim;
+       TAILQ_INIT(&clnt_list);
+       /* Eventually plan to grow/shrink poll array: */
+       pollsize = FD_ALLOC_BLOCK;
++      if (getrlimit(RLIMIT_NOFILE, &rlim) < 0 &&
++          rlim.rlim_cur != RLIM_INFINITY)
++              pollsize = rlim.rlim_cur;
+       pollarray = calloc(pollsize, sizeof(struct pollfd));
+ }
+@@ -567,9 +561,8 @@ process_pipedir(char *pipe_name)
+       update_old_clients(namelist, j, pipe_name);
+       for (i=0; i < j; i++) {
+-              if (i < FD_ALLOC_BLOCK
+-                              && !strncmp(namelist[i]->d_name, "clnt", 4)
+-                              && !find_client(namelist[i]->d_name, pipe_name))
++              if (!strncmp(namelist[i]->d_name, "clnt", 4)
++                  && !find_client(namelist[i]->d_name, pipe_name))
+                       process_clnt_dir(namelist[i]->d_name, pipe_name);
+               free(namelist[i]);
+       }
+@@ -962,12 +955,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+       printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
+-      if (tgtname) {
+-              if (clp->servicename) {
+-                      free(clp->servicename);
+-                      clp->servicename = strdup(tgtname);
+-              }
+-      }
+       token.length = 0;
+       token.value = NULL;
+       memset(&pd, 0, sizeof(struct authgss_private_data));
+@@ -1016,7 +1003,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+                       int success = 0;
+                       do {
+                               gssd_refresh_krb5_machine_credential(clp->servername,
+-                                                                   NULL, service);
++                                                                   NULL, service,
++                                                                   tgtname);
+                               /*
+                                * Get a list of credential cache names and try each
+                                * of them until one works or we've tried them all
+diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
+index 60ba594..aeb8f70 100644
+--- a/utils/gssd/krb5_util.c
++++ b/utils/gssd/krb5_util.c
+@@ -774,12 +774,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt,
+ }
+ /*
+- * Find a keytab entry to use for a given target hostname.
++ * Find a keytab entry to use for a given target realm.
+  * Tries to find the most appropriate keytab to use given the
+  * name of the host we are trying to connect with.
++ *
++ * Note: the tgtname contains a hostname in the realm that we
++ * are authenticating to. It may, or may not be the same as
++ * the server hostname.
+  */
+ static int
+-find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
++find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
+                 krb5_keytab_entry *kte, const char **svcnames)
+ {
+       krb5_error_code code;
+@@ -795,7 +799,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
+       /* Get full target hostname */
+-      retval = get_full_hostname(hostname, targethostname,
++      retval = get_full_hostname(tgtname, targethostname,
+                                  sizeof(targethostname));
+       if (retval)
+               goto out;
+@@ -1128,7 +1132,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
+               if (ple->ccname) {
+                       /* Make sure cred is up-to-date before returning it */
+                       retval = gssd_refresh_krb5_machine_credential(NULL, ple,
+-                              NULL);
++                              NULL, NULL);
+                       if (retval)
+                               continue;
+                       if (i + 1 > listsize) {
+@@ -1219,7 +1223,8 @@ gssd_destroy_krb5_machine_creds(void)
+ int
+ gssd_refresh_krb5_machine_credential(char *hostname,
+                                    struct gssd_k5_kt_princ *ple, 
+-                                       char *service)
++                                       char *service,
++                                       char *tgtname)
+ {
+       krb5_error_code code = 0;
+       krb5_context context;
+@@ -1258,7 +1263,10 @@ gssd_refresh_krb5_machine_credential(char *hostname,
+       if (ple == NULL) {
+               krb5_keytab_entry kte;
+-              code = find_keytab_entry(context, kt, hostname, &kte, svcnames);
++              if (tgtname == NULL)
++                      tgtname = hostname;
++
++              code = find_keytab_entry(context, kt, tgtname, &kte, svcnames);
+               if (code) {
+                       printerr(0, "ERROR: %s: no usable keytab entry found "
+                                "in keytab %s for connection with host %s\n",
+diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
+index cd6e107..9f41625 100644
+--- a/utils/gssd/krb5_util.h
++++ b/utils/gssd/krb5_util.h
+@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername);
+ void gssd_destroy_krb5_machine_creds(void);
+ int  gssd_refresh_krb5_machine_credential(char *hostname,
+                                         struct gssd_k5_kt_princ *ple, 
+-                                        char *service);
++                                        char *service,
++                                        char *tgtname);
+ char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
+ void gssd_k5_get_default_realm(char **def_realm);
+diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c
+index 6c34faf..1d44d34 100644
+--- a/utils/gssd/svcgssd_krb5.c
++++ b/utils/gssd/svcgssd_krb5.c
+@@ -38,6 +38,7 @@
+ #include <stdio.h>
+ #include <errno.h>
++#include <ctype.h>
+ #include <gssapi/gssapi.h>
+ #include <krb5.h>
+@@ -98,6 +99,12 @@ parse_enctypes(char *enctypes)
+       if (n == 0)
+               return ENOENT;
++      /* Skip pass any non digits */
++      while (*enctypes && isdigit(*enctypes) == 0)
++              enctypes++;
++      if (*enctypes == '\0')
++              return EINVAL;
++
+       /* Allocate space for enctypes array */
+       if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
+               return ENOMEM;
+diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
+index e80efb4..beba9c4 100644
+--- a/utils/idmapd/idmapd.c
++++ b/utils/idmapd/idmapd.c
+@@ -145,7 +145,6 @@ static void svrreopen(int, short, void *);
+ static int  nfsopen(struct idmap_client *);
+ static void nfscb(int, short, void *);
+ static void nfsdcb(int, short, void *);
+-static int  validateascii(char *, u_int32_t);
+ static int  addfield(char **, ssize_t *, char *);
+ static int  getfield(char **, char *, size_t);
+@@ -425,7 +424,8 @@ dirscancb(int UNUSED(fd), short UNUSED(which), void *data)
+                           pipefsdir, ents[i]->d_name);
+                       if ((ic->ic_dirfd = open(path, O_RDONLY, 0)) == -1) {
+-                              xlog_warn("dirscancb: open(%s): %s", path, strerror(errno));
++                              if (verbose > 0)
++                                      xlog_warn("dirscancb: open(%s): %s", path, strerror(errno));
+                               free(ic);
+                               goto out;
+                       }
+@@ -642,6 +642,8 @@ out:
+ static void
+ imconv(struct idmap_client *ic, struct idmap_msg *im)
+ {
++      u_int32_t len;
++
+       switch (im->im_conv) {
+       case IDMAP_CONV_IDTONAME:
+               idtonameres(im);
+@@ -652,10 +654,10 @@ imconv(struct idmap_client *ic, struct idmap_msg *im)
+                           im->im_id, im->im_name);
+               break;
+       case IDMAP_CONV_NAMETOID:
+-              if (validateascii(im->im_name, sizeof(im->im_name)) == -1) {
+-                      im->im_status |= IDMAP_STATUS_INVALIDMSG;
++              len = strnlen(im->im_name, IDMAP_NAMESZ - 1);
++              /* Check for NULL termination just to be careful */
++              if (im->im_name[len+1] != '\0')
+                       return;
+-              }
+               nametoidres(im);
+               if (verbose > 1)
+                       xlog_warn("%s %s: (%s) name \"%s\" -> id \"%d\"",
+@@ -855,25 +857,6 @@ nametoidres(struct idmap_msg *im)
+ }
+ static int
+-validateascii(char *string, u_int32_t len)
+-{
+-      u_int32_t i;
+-
+-      for (i = 0; i < len; i++) {
+-              if (string[i] == '\0')
+-                      break;
+-
+-              if (string[i] & 0x80)
+-                      return (-1);
+-      }
+-
+-      if ((i >= len) || string[i] != '\0')
+-              return (-1);
+-
+-      return (i + 1);
+-}
+-
+-static int
+ addfield(char **bpp, ssize_t *bsizp, char *fld)
+ {
+       char ch, *bp = *bpp;
+diff --git a/utils/mount/error.c b/utils/mount/error.c
+index 83ad1d2..f8fc13f 100644
+--- a/utils/mount/error.c
++++ b/utils/mount/error.c
+@@ -225,7 +225,7 @@ void mount_error(const char *spec, const char *mount_point, int error)
+       case ENOENT:
+               if (spec)
+                       nfs_error(_("%s: mounting %s failed, "
+-                              "reason given by server:\n  %s"),
++                              "reason given by server: %s"),
+                               progname, spec, strerror(error));
+               else
+                       nfs_error(_("%s: mount point %s does not exist"),
+diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
+index 9b4197b..8ee3024 100644
+--- a/utils/mount/stropts.c
++++ b/utils/mount/stropts.c
+@@ -666,6 +666,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
+               case EOPNOTSUPP:
+               case EHOSTUNREACH:
+               case ETIMEDOUT:
++              case EACCES:
+                       continue;
+               default:
+                       goto out;
+@@ -761,6 +762,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi)
+               case ECONNREFUSED:
+               case EHOSTUNREACH:
+               case ETIMEDOUT:
++              case EACCES:
+                       continue;
+               default:
+                       goto out;
+diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
+index 508040a..330cab5 100644
+--- a/utils/mountd/auth.c
++++ b/utils/mountd/auth.c
+@@ -10,10 +10,12 @@
+ #include <config.h>
+ #endif
++#include <sys/types.h>
+ #include <sys/stat.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <errno.h>
++#include <fcntl.h>
+ #include <unistd.h>
+ #include "sockaddr.h"
+@@ -21,7 +23,6 @@
+ #include "nfslib.h"
+ #include "exportfs.h"
+ #include "mountd.h"
+-#include "xmalloc.h"
+ #include "v4root.h"
+ enum auth_error
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index e950ec6..45012be 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -29,7 +29,6 @@
+ #include "nfslib.h"
+ #include "exportfs.h"
+ #include "mountd.h"
+-#include "xmalloc.h"
+ #include "fsloc.h"
+ #include "pseudoflavors.h"
+@@ -109,12 +108,10 @@ static void auth_unix_ip(FILE *f)
+               struct addrinfo *ai = NULL;
+               ai = client_resolve(tmp->ai_addr);
+-              if (ai == NULL)
+-                      goto out;
+-              client = client_compose(ai);
+-              freeaddrinfo(ai);
+-              if (!client)
+-                      goto out;
++              if (ai) {
++                      client = client_compose(ai);
++                      freeaddrinfo(ai);
++              }
+       }
+       qword_print(f, "nfsd");
+       qword_print(f, ipaddr);
+@@ -127,7 +124,6 @@ static void auth_unix_ip(FILE *f)
+       xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
+       free(client);
+-out:
+       freeaddrinfo(tmp);
+ }
+@@ -347,6 +343,30 @@ static char *next_mnt(void **v, char *p)
+       return me->mnt_dir;
+ }
++static int is_subdirectory(char *child, char *parent)
++{
++      size_t l = strlen(parent);
++
++      if (strcmp(parent, "/") == 0)
++              return 1;
++
++      return strcmp(child, parent) == 0
++              || (strncmp(child, parent, l) == 0 && child[l] == '/');
++}
++
++static int path_matches(nfs_export *exp, char *path)
++{
++      if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
++              return is_subdirectory(path, exp->m_export.e_path);
++      return strcmp(path, exp->m_export.e_path) == 0;
++}
++
++static int
++export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
++{
++      return path_matches(exp, path) && client_matches(exp, dom, ai);
++}
++
+ /* True iff e1 is a child of e2 and e2 has crossmnt set: */
+ static bool subexport(struct exportent *e1, struct exportent *e2)
+ {
+@@ -354,8 +374,7 @@ static bool subexport(struct exportent *e1, struct exportent *e2)
+       size_t l2 = strlen(p2);
+       return e2->e_flags & NFSEXP_CROSSMOUNT
+-             && strncmp(p1, p2, l2) == 0
+-             && p1[l2] == '/';
++              && is_subdirectory(p1, p2);
+ }
+ struct parsed_fsid {
+@@ -756,27 +775,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
+       return qword_eol(f);
+ }
+-static int is_subdirectory(char *child, char *parent)
+-{
+-      size_t l = strlen(parent);
+-
+-      return strcmp(child, parent) == 0
+-              || (strncmp(child, parent, l) == 0 && child[l] == '/');
+-}
+-
+-static int path_matches(nfs_export *exp, char *path)
+-{
+-      if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+-              return is_subdirectory(path, exp->m_export.e_path);
+-      return strcmp(path, exp->m_export.e_path) == 0;
+-}
+-
+-static int
+-export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
+-{
+-      return path_matches(exp, path) && client_matches(exp, dom, ai);
+-}
+-
+ static nfs_export *
+ lookup_export(char *dom, char *path, struct addrinfo *ai)
+ {
+@@ -830,6 +828,7 @@ lookup_export(char *dom, char *path, struct addrinfo *ai)
+ #ifdef HAVE_NFS_PLUGIN_H
+ #include <dlfcn.h>
++#include <link.h>
+ #include <nfs-plugin.h>
+ /*
+@@ -1094,6 +1093,7 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
+               struct addrinfo *ai)
+ {
+       struct exportent *exp;
++      struct link_map *map;
+       void *handle;
+       handle = dlopen("libnfsjunct.so", RTLD_NOW);
+@@ -1101,6 +1101,11 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
+               xlog(D_GENERAL, "%s: dlopen: %s", __func__, dlerror());
+               return NULL;
+       }
++
++      if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0)
++              xlog(D_GENERAL, "%s: loaded plug-in %s",
++                      __func__, map->l_name);
++
+       (void)dlerror();        /* Clear any error */
+       exp = invoke_junction_ops(handle, dom, pathname, ai);
+diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c
+index 9801b9c..4334340 100644
+--- a/utils/nfsdcltrack/nfsdcltrack.c
++++ b/utils/nfsdcltrack/nfsdcltrack.c
+@@ -379,6 +379,17 @@ cltrack_legacy_gracedone(void)
+       while ((entry = readdir(v4recovery))) {
+               int len;
++              /* skip "." and ".." */
++              if (entry->d_name[0] == '.') {
++                      switch (entry->d_name[1]) {
++                      case '\0':
++                              continue;
++                      case '.':
++                              if (entry->d_name[2] == '\0')
++                                      continue;
++                      }
++              }
++
+               /* borrow the clientid blob for this */
+               len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname,
+                               entry->d_name);
+diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c
+index 4ecb03c..fd576d9 100644
+--- a/utils/statd/rmtcall.c
++++ b/utils/statd/rmtcall.c
+@@ -68,21 +68,19 @@ statd_get_socket(void)
+ {
+       struct sockaddr_in      sin;
+       struct servent *se;
+-      int loopcnt = 100;
++      const int loopcnt = 100;
++      int i, tmp_sockets[loopcnt];
+       if (sockfd >= 0)
+               return sockfd;
+-      while (loopcnt-- > 0) {
+-
+-              if (sockfd >= 0) close(sockfd);
++      for (i = 0; i < loopcnt; ++i) {
+               if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+                       xlog(L_ERROR, "%s: Can't create socket: %m", __func__);
+-                      return -1;
++                      break;
+               }
+-
+               memset(&sin, 0, sizeof(sin));
+               sin.sin_family = AF_INET;
+               sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+@@ -96,7 +94,16 @@ statd_get_socket(void)
+               if (se == NULL)
+                       break;
+               /* rather not use that port, try again */
++
++              tmp_sockets[i] = sockfd;
+       }
++
++      while (--i >= 0)
++              close(tmp_sockets[i]);
++
++      if (sockfd < 0)
++              return -1;
++
+       FD_SET(sockfd, &SVC_FDSET);
+       return sockfd;
+ }
diff --git a/nfs-utils/systemd/nfs-blkmap.service b/nfs-utils/systemd/nfs-blkmap.service
new file mode 100644 (file)
index 0000000..6b5127b
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=pNFS block layout mapping daemon
+Wants=var-lib-nfs-rpc_pipefs.mount
+Requires=var-lib-nfs-rpc_pipefs.mount
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStart=/usr/sbin/blkmapd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/nfs-utils/systemd/nfs-idmap.service b/nfs-utils/systemd/nfs-idmap.service
new file mode 100644 (file)
index 0000000..e0c1803
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=NFSv4 ID-name mapping daemon
+BindTo=nfs-server.service
+After=nfs-server.service
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStart=/usr/sbin/rpc.idmapd
+
+[Install]
+WantedBy=nfs.target
diff --git a/nfs-utils/systemd/nfs-lock.service b/nfs-utils/systemd/nfs-lock.service
new file mode 100644 (file)
index 0000000..fa991e5
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=NFS file locking service.
+Requires=rpcbind.service network.target
+After=network.target named.service rpcbind.service
+Before=remote-fs-pre.target
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStartPre=/usr/lib/nfs-utils/scripts/nfs-lock.preconfig
+ExecStart=/sbin/rpc.statd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/nfs-utils/systemd/nfs-mountd.service b/nfs-utils/systemd/nfs-mountd.service
new file mode 100644 (file)
index 0000000..32e1638
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=NFS Mount Daemon
+BindTo=nfs-server.service
+After=nfs-server.service
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/rpc.mountd
+StandardError=syslog+console
+
+[Install]
+WantedBy=nfs.target
diff --git a/nfs-utils/systemd/nfs-rquotad.service b/nfs-utils/systemd/nfs-rquotad.service
new file mode 100644 (file)
index 0000000..ab1d207
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=NFS Remote Quota Server
+BindTo=nfs-server.service
+After=nfs-server.service
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStart=-/usr/sbin/rpc.rquotad
+
+[Install]
+WantedBy=nfs.target
diff --git a/nfs-utils/systemd/nfs-secure-server.service b/nfs-utils/systemd/nfs-secure-server.service
new file mode 100644 (file)
index 0000000..b88bab5
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=Secure NFS Server
+Requires=var-lib-nfs-rpc_pipefs.mount nfs-server.service
+After=syslog.target var-lib-nfs-rpc_pipefs.mount nfs-server.service 
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStart=/usr/sbin/rpc.svcgssd
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/nfs-utils/systemd/nfs-secure.service b/nfs-utils/systemd/nfs-secure.service
new file mode 100644 (file)
index 0000000..2a7dfb6
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=Secure NFS
+Requires=var-lib-nfs-rpc_pipefs.mount
+After=syslog.target var-lib-nfs-rpc_pipefs.mount
+
+[Service]
+Type=forking
+StandardError=syslog+console
+ExecStart=/usr/sbin/rpc.gssd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/nfs-utils/systemd/nfs-server.service b/nfs-utils/systemd/nfs-server.service
new file mode 100644 (file)
index 0000000..79d114e
--- /dev/null
@@ -0,0 +1,18 @@
+[Unit]
+Description=NFS Server
+Requires=proc-fs-nfsd.mount var-lib-nfs-rpc_pipefs.mount rpcbind.service
+Requires=nfs-idmap.service nfs-mountd.service nfs-rquotad.service
+After=network.target named.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+StandardError=syslog+console
+ExecStartPre=/usr/sbin/exportfs -r
+ExecStart=/usr/sbin/rpc.nfsd
+ExecStop=/usr/sbin/rpc.nfsd 0
+ExecStopPost=/usr/sbin/exportfs -f
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/nfs-utils/systemd/nfs.target b/nfs-utils/systemd/nfs.target
new file mode 100644 (file)
index 0000000..6c3262a
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Network File System Server
+Requires=var-lib-nfs-rpc_pipefs.mount proc-fs-nfsd.mount rpcbind.service
+After=network.target named.service 
+
+[Install]
+WantedBy=multi-user.target
diff --git a/nfs-utils/systemd/proc-fs-nfsd.mount b/nfs-utils/systemd/proc-fs-nfsd.mount
new file mode 100644 (file)
index 0000000..e5ee6fb
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=RPC Pipe File System 
+DefaultDependencies=no
+
+[Mount]
+What=sunrpc
+Where=/proc/fs/nfsd
+Type=nfsd
diff --git a/nfs-utils/systemd/var-lib-nfs-rpc_pipefs.mount b/nfs-utils/systemd/var-lib-nfs-rpc_pipefs.mount
new file mode 100644 (file)
index 0000000..d27e1a2
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=RPC Pipe File System 
+DefaultDependencies=no
+
+[Mount]
+What=sunrpc
+Where=/var/lib/nfs/rpc_pipefs
+Type=rpc_pipefs