]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Merge branch 'upstream'
authorBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 01:49:26 +0000 (02:49 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 01:49:26 +0000 (02:49 +0100)
Conflicts:
Makefile.in
aclocal.m4
configure
linux-nfs/Makefile.in
support/Makefile.in
support/export/Makefile.in
support/include/Makefile.in
support/include/config.h.in
support/include/nfs/Makefile.in
support/include/rpcsvc/Makefile.in
support/include/sys/Makefile.in
support/include/sys/fs/Makefile.in
support/misc/Makefile.in
support/nfs/Makefile.in
tools/Makefile.in
tools/locktest/Makefile.in
tools/nlmtest/Makefile.in
tools/rpcdebug/Makefile.in
tools/rpcgen/Makefile.in
utils/Makefile.in
utils/exportfs/Makefile.in
utils/gssd/Makefile.in
utils/idmapd/Makefile.in
utils/mount/Makefile.in
utils/mountd/Makefile.in
utils/nfsd/Makefile.in
utils/nfsstat/Makefile.in
utils/rquotad/Makefile.in
utils/showmount/Makefile.in
utils/statd/Makefile.in

95 files changed:
Makefile.am
Makefile.in
NEWS
aclocal.m4
aclocal/kerberos5.m4
compile [new file with mode: 0755]
configure
configure.ac [new file with mode: 0644]
configure.in [deleted file]
linux-nfs/Makefile.in
support/Makefile.in
support/export/Makefile.am
support/export/Makefile.in
support/export/client.c
support/export/export.c
support/export/nfsctl.c
support/include/Makefile.in
support/include/config.h.in
support/include/conn.h
support/include/exportfs.h
support/include/fstab.h
support/include/nfs/Makefile.in
support/include/nfs/nfs.h
support/include/nfs_mntent.h
support/include/nfslib.h
support/include/rpcsvc/Makefile.in
support/include/sys/Makefile.in
support/include/sys/fs/Makefile.in
support/misc/Makefile.in
support/nfs/Makefile.am
support/nfs/Makefile.in
support/nfs/conn.c
support/nfs/exports.c
support/nfs/fstab.c
support/nfs/lockdsvc.c [deleted file]
support/nfs/nfs_mntent.c
support/nfs/rpcmisc.c
support/nfs/svc_socket.c
tools/Makefile.am
tools/Makefile.in
tools/getiversion/Makefile.am [deleted file]
tools/getiversion/getiversion.c [deleted file]
tools/locktest/Makefile.in
tools/nlmtest/Makefile.in
tools/rpcdebug/Makefile.in
tools/rpcgen/Makefile.in
utils/Makefile.am
utils/Makefile.in
utils/exportfs/Makefile.in
utils/exportfs/exportfs.c
utils/exportfs/exports.man
utils/gssd/Makefile.in
utils/gssd/gssd.c
utils/gssd/gssd.h
utils/gssd/gssd.man
utils/gssd/gssd_main_loop.c
utils/gssd/gssd_proc.c
utils/gssd/krb5_util.c
utils/idmapd/Makefile.in
utils/lockd/Makefile.am [deleted file]
utils/lockd/lockd.c [deleted file]
utils/lockd/lockd.man [deleted file]
utils/mount/Makefile.am
utils/mount/Makefile.in
utils/mount/mount.c
utils/mount/nfs.man [new file with mode: 0644]
utils/mount/nfs4mount.c
utils/mount/nfs_mount.h
utils/mount/nfsmount.c
utils/mount/nfsumount.c
utils/mountd/Makefile.in
utils/mountd/cache.c
utils/mountd/mountd.c
utils/mountd/svc_run.c
utils/nfsd/Makefile.in
utils/nfsstat/Makefile.in
utils/rquotad/Makefile.am
utils/rquotad/Makefile.in
utils/showmount/Makefile.in
utils/statd/Makefile.am
utils/statd/Makefile.in
utils/statd/callback.c
utils/statd/monitor.c
utils/statd/notify.c [deleted file]
utils/statd/notlist.h
utils/statd/rmtcall.c
utils/statd/simu.c
utils/statd/sm-notify.c [new file with mode: 0644]
utils/statd/sm-notify.man [new file with mode: 0644]
utils/statd/start-statd [new file with mode: 0644]
utils/statd/statd.c
utils/statd/statd.h
utils/statd/statd.man
utils/statd/state.c [deleted file]
utils/statd/svc_run.c

index c04e9de8b10b567cda47c0a8e6935022eb940f07..ec8e832ae962bdf1b1428a4c57f78fbea5d30e8a 100644 (file)
@@ -50,7 +50,7 @@ install-data-hook:
        mkdir -p $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak
        touch $(DESTDIR)$(statedir)/state
        chmod go-rwx $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
-       chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
+       -chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
 
 uninstall-hook:
        rm $(DESTDIR)$(statedir)/xtab
index aa32357d21a43d333c4656c963d90c27950fa903..41514d53595cdddbbb5056544263b646a05d4aa4 100644 (file)
@@ -34,14 +34,14 @@ host_triplet = @host@
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
-       ChangeLog INSTALL NEWS config.guess config.sub depcomp \
+       ChangeLog INSTALL NEWS compile config.guess config.sub depcomp \
        install-sh ltmain.sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -154,6 +154,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -213,6 +214,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
@@ -696,7 +698,7 @@ install-data-hook:
        mkdir -p $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak
        touch $(DESTDIR)$(statedir)/state
        chmod go-rwx $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
-       chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
+       -chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
 
 uninstall-hook:
        rm $(DESTDIR)$(statedir)/xtab
diff --git a/NEWS b/NEWS
index adb9e663dd091b0c92e2da28cce8aa6a11d05025..fe3571a4db1b274e377b0d1d51bb8094e35d4d97 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1 +1,43 @@
-This is a dummy news file to make automake happy.
+Significant changes for nfs-utils 1.1.0 - March/April 2007
+
+ - rpc.lockd is gone.  One 3 old kernel releases need it.
+ - /sbin/{u,}mount.nfs{,4} is now installed so 'mount' will
+   use these to mount nfs filesystems instead of internal code.
+  + mount.nfs will check for 'statd' to be running when mounting
+    a filesystem which requires it.  If it is not running it will
+    run "/usr/sbin/start-statd" to try to start it.
+    If statd is not running and cannot be started, mount.nfs will
+    refuse to mount the filesystem and will suggest the 'nolock'
+    option.
+ - Substantial changes to statd
+  + The 'notify' process that must happen at boot has been split
+    into a separate program "sm-notify".  It ensures that it
+    only runs once even if you restart statd.  This is correct
+    behaviour.
+  + statd stores state in the files in /var/lib/nfs/sm/ so that
+    if you kill and restart it, it will restore that state and
+    continue working correctly.
+  + statd makes more use of DNS lookup and should handle
+    multi-homed peers better.
+ - If you export a directory as 'crossmnt', all filesystems
+   mounted beneath are automatically exported with the same
+   options (unless explicitly exported with different options).
+ - subtree_check is no-longer the default.  The default is now
+   no_subtree_check.
+ - By default the system 'rpcgen' is used while building
+   nfs-utils rather than the internal one.
+
+
+Further notes on statd:
+
+ statd should be installed in /usr/sbin, not /sbin.
+ If you need to mount /usr via nfs, use 'nolock'
+
+ At boot time, run "/usr/sbin/sm-notify".
+ Run "statd" only when starting the NFS server.
+ "statd" should be run before starting the NFS server.
+ You do not need to start statd at boot time incase an
+ NFS filesystem is mounted.  mount.nfs will take care of that.
+
+ Make sure /usr/sbin/start-statd will run statd with required
+ arguments.
index 31a9f5d3ed9eb351a39d95e5c9c17646d6547d42..e90a163bfd26d5f701a25d8816cc98bd5c2e3384 100644 (file)
@@ -7133,6 +7133,40 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
 # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
index 1dac9f01aad0e0b27089152a3c92de7f70c3e7a6..b83e12236be86f3b9e06ee22b8b6feae9cc0e231 100644 (file)
@@ -36,6 +36,8 @@ AC_DEFUN([AC_KERBEROS_V5],[
       AC_DEFINE_UNQUOTED(KRB5_VERSION, $K5VERS, [Define this as the Kerberos version number])
       if test -f $dir/include/gssapi/gssapi_krb5.h -a \
                 \( -f $dir/lib/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.so -o \
                    -f $dir/lib/libgssapi_krb5.so \) ; then
          AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])
          KRBDIR="$dir"
diff --git a/compile b/compile
new file mode 100755 (executable)
index 0000000..1b1d232
--- /dev/null
+++ b/compile
@@ -0,0 +1,142 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+       # configure might choose to run compile as `compile cc -o foo foo.c'.
+       # So we strip `-o arg' only if arg is an object.
+       eat=1
+       case $2 in
+         *.o | *.obj)
+           ofile=$2
+           ;;
+         *)
+           set x "$@" -o "$2"
+           shift
+           ;;
+       esac
+       ;;
+      *.c)
+       cfile=$1
+       set x "$@" "$1"
+       shift
+       ;;
+      *)
+       set x "$@" "$1"
+       shift
+       ;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
index bcf3b6b98aa5aa16d26be4894b091a66d36f1c9c..0f561fff42014bdd002f9db621823b229a999386 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.0.11.
+# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.0-rc1.
 #
 # Report bugs to <nfs@lists.sf.net>.
 #
@@ -728,11 +728,10 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='linux nfs-utils'
 PACKAGE_TARNAME='nfs-utils'
-PACKAGE_VERSION='1.0.11'
-PACKAGE_STRING='linux nfs-utils 1.0.11'
+PACKAGE_VERSION='1.1.0-rc1'
+PACKAGE_STRING='linux nfs-utils 1.1.0-rc1'
 PACKAGE_BUGREPORT='nfs@lists.sf.net'
 
-ac_unique_file="tools/getiversion/getiversion.c"
 ac_default_prefix=/usr
 ac_unique_file="support/include/config.h.in"
 # Factoring default headers for most tests.
@@ -844,6 +843,7 @@ MAINT
 RELEASE
 statedir
 statduser
+startstatd
 enable_nfsv3
 IDMAPD
 enable_nfsv4
@@ -858,6 +858,9 @@ kprefix
 secure_statd
 CONFIG_RQUOTAD_TRUE
 CONFIG_RQUOTAD_FALSE
+RPCGEN_PATH
+CONFIG_RPCGEN_TRUE
+CONFIG_RPCGEN_FALSE
 CONFIG_MOUNT_TRUE
 CONFIG_MOUNT_FALSE
 CC
@@ -1447,7 +1450,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures linux nfs-utils 1.0.11 to adapt to many kinds of systems.
+\`configure' configures linux nfs-utils 1.1.0-rc1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1517,7 +1520,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of linux nfs-utils 1.0.11:";;
+     short | recursive ) echo "Configuration of linux nfs-utils 1.1.0-rc1:";;
    esac
   cat <<\_ACEOF
 
@@ -1532,10 +1535,13 @@ Optional Features:
   --enable-kprefix        install progs as rpc.knfsd etc
   --enable-secure-statd   Only lockd can use statd (security)
   --enable-rquotad        enable rquotad [default=yes]
+  --without-uuid          Exclude uuid support and so avoid possibly buggy
+                          libblkid
   --enable-mount          Create mount.nfs and don't use the util-linux
                           mount(8) functionality. [default=no]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
+  --disable-largefile     omit support for large files
   --enable-shared[=PKGS]  build shared libraries [default=yes]
   --enable-static[=PKGS]  build static libraries [default=yes]
   --enable-fast-install[=PKGS]
@@ -1549,6 +1555,10 @@ Optional Packages:
   --with-statedir=/foo    use state dir /foo /var/lib/nfs
   --with-statduser=rpcuser
                           statd to run under [rpcuser or nobody]
+  --with-start-statd=scriptname
+                          When an nfs filesystems is mounted with locking, run
+                          this script
+  --with-rpcgen=internal  use internal rpcgen instead of system one
   --with-tcp-wrappers[=PATH]      Enable tcpwrappers support
                  (optionally in PATH)
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
@@ -1644,7 +1654,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-linux nfs-utils configure 1.0.11
+linux nfs-utils configure 1.1.0-rc1
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1658,7 +1668,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by linux nfs-utils $as_me 1.0.11, which was
+It was created by linux nfs-utils $as_me 1.1.0-rc1, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2126,7 +2136,6 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
-
 am__api_version='1.10'
 
 # Find a good install program.  We prefer a C program (faster),
@@ -2433,7 +2442,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='nfs-utils'
- VERSION='1.0.11'
+ VERSION='1.1.0-rc1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2639,6 +2648,21 @@ else
 fi
 
 
+
+# Check whether --with-start-statd was given.
+if test "${with_start_statd+set}" = set; then
+  withval=$with_start_statd; startstatd=$withval
+else
+  startstatd=/usr/sbin/start-statd
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define START_STATD "$startstatd"
+_ACEOF
+
 # Check whether --enable-nfsv3 was given.
 if test "${enable_nfsv3+set}" = set; then
   enableval=$enable_nfsv3; enable_nfsv3=$enableval
@@ -2727,7 +2751,7 @@ fi
 if test "${enable_secure_statd+set}" = set; then
   enableval=$enable_secure_statd; test "$enableval" = "yes" && secure_statd=yes
 else
-  secure_statd=no
+  secure_statd=yes
 fi
 
        if test "$secure_statd" = yes; then
@@ -2759,11 +2783,46 @@ else
 fi
 
 
+# Check whether --with-rpcgen was given.
+if test "${with_rpcgen+set}" = set; then
+  withval=$with_rpcgen; rpcgen_path=$withval
+else
+  rpcgen_path=yes
+fi
+
+       RPCGEN_PATH=
+       if test "$rpcgen_path" == "yes"; then
+           for p in /usr/local/bin/rpcgen /usr/bin/rpcgen /bin/rpcgen
+           do if test -f $p ; then RPCGEN_PATH=$p ; break; fi ; done
+       elif test "$rpcgen_path" != "internal"; then
+           RPCGEN_PATH=$rpcgen_path
+       fi
+
+        if test "$RPCGEN_PATH" == ""; then
+  CONFIG_RPCGEN_TRUE=
+  CONFIG_RPCGEN_FALSE='#'
+else
+  CONFIG_RPCGEN_TRUE='#'
+  CONFIG_RPCGEN_FALSE=
+fi
+
+# Check whether --enable-uuid was given.
+if test "${enable_uuid+set}" = set; then
+  enableval=$enable_uuid; if test "$enableval" = "yes" ; then use_blkid=1; else use_blkid=0; fi
+else
+  use_blkid=1
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_BLKID $use_blkid
+_ACEOF
+
 # Check whether --enable-mount was given.
 if test "${enable_mount+set}" = set; then
   enableval=$enable_mount; enable_mount=$enableval
 else
-  enable_mount=no
+  enable_mount=yes
 fi
 
         if test "$enable_mount" = "yes"; then
@@ -3982,6 +4041,358 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
 
 
 
+# Arrange for large-file support
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+  { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+        # IRIX 6.2 and later do not support large files by default,
+        # so use the C compiler's -n32 option if that helps.
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+        rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+        CC="$CC -n32"
+        rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_largefile_CC=' -n32'; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+        break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_file_offset_bits=no; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_file_offset_bits=64; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_file_offset_bits=unknown
+  break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -f conftest*
+  if test $ac_cv_sys_file_offset_bits = unknown; then
+    { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_large_files=no; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_large_files=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_large_files=unknown
+  break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -f conftest*
+  fi
+fi
+
+
 
 ac_config_headers="$ac_config_headers support/include/config.h"
 
@@ -6295,7 +6706,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6298 "configure"' > conftest.$ac_ext
+  echo '#line 6709 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8324,11 +8735,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8327: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8738: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8331: \$? = $ac_status" >&5
+   echo "$as_me:8742: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8592,11 +9003,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8595: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9006: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8599: \$? = $ac_status" >&5
+   echo "$as_me:9010: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8696,11 +9107,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8699: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9110: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8703: \$? = $ac_status" >&5
+   echo "$as_me:9114: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10993,7 +11404,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10996 "configure"
+#line 11407 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11093,7 +11504,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 11096 "configure"
+#line 11507 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13429,11 +13840,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13432: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13843: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13436: \$? = $ac_status" >&5
+   echo "$as_me:13847: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13533,11 +13944,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13536: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13947: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13540: \$? = $ac_status" >&5
+   echo "$as_me:13951: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15094,11 +15505,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15097: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15508: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15101: \$? = $ac_status" >&5
+   echo "$as_me:15512: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15198,11 +15609,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15201: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15612: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15205: \$? = $ac_status" >&5
+   echo "$as_me:15616: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17385,11 +17796,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17388: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17799: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17392: \$? = $ac_status" >&5
+   echo "$as_me:17803: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17653,11 +18064,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17656: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18067: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17660: \$? = $ac_status" >&5
+   echo "$as_me:18071: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17757,11 +18168,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17760: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18171: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:17764: \$? = $ac_status" >&5
+   echo "$as_me:18175: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -20408,6 +20819,132 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 
 
 
+if test "x$CC" != xcc; then
+  { echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5
+echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6; }
+else
+  { echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5
+echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6; }
+fi
+set dummy $CC; ac_cc=`echo $2 |
+                     sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+   test -f conftest2.$ac_objext && { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&5'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        test -f conftest2.$ac_objext && { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); };
+      then
+       # cc works too.
+       :
+      else
+       # cc exists but doesn't like -o.
+       eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_MINUS_C_MINUS_O 1
+_ACEOF
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
 
 if test "x$cross_compiling" = "xno"; then
        CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
@@ -22118,7 +22655,8 @@ if test $ac_cv_lib_bsd_daemon = yes; then
 fi
 
 fi
-{ echo "$as_me:$LINENO: checking for blkid_get_cache in -lblkid" >&5
+if test "$use_blkid" = 1; then
+   { echo "$as_me:$LINENO: checking for blkid_get_cache in -lblkid" >&5
 echo $ECHO_N "checking for blkid_get_cache in -lblkid... $ECHO_C" >&6; }
 if test "${ac_cv_lib_blkid_blkid_get_cache+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -22187,7 +22725,7 @@ echo "$as_me: error: libblkid needed" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
-if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
+   if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
   { echo "$as_me:$LINENO: checking for blkid/blkid.h" >&5
 echo $ECHO_N "checking for blkid/blkid.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
@@ -22326,6 +22864,7 @@ echo "$as_me: error: Cannot file libblkid header file blkid/blkid.h" >&2;}
 fi
 
 
+fi
 
 
 
@@ -22738,6 +23277,8 @@ _ACEOF
 
       if test -f $dir/include/gssapi/gssapi_krb5.h -a \
                 \( -f $dir/lib/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.so -o \
                    -f $dir/lib/libgssapi_krb5.so \) ; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -28975,7 +29516,7 @@ esac
 
 my_am_cflags="-Wall $ARCHFLAGS -pipe"
 
-AM_CPPFLAGS="-I\${top_srcdir}/support/include -D_FILE_OFFSET_BITS=64"
+AM_CPPFLAGS="-I\${top_srcdir}/support/include"
 
 AM_CFLAGS="$my_am_cflags"
 
@@ -28984,7 +29525,7 @@ AM_CFLAGS="$my_am_cflags"
 ACLOCAL_AMFLAGS="-I $ac_macro_dir \$(ACLOCAL_FLAGS)"
 
 
-ac_config_files="$ac_config_files Makefile linux-nfs/Makefile support/Makefile support/export/Makefile support/include/nfs/Makefile support/include/rpcsvc/Makefile support/include/sys/fs/Makefile support/include/sys/Makefile support/include/Makefile support/misc/Makefile support/nfs/Makefile tools/Makefile tools/getiversion/Makefile tools/locktest/Makefile tools/nlmtest/Makefile tools/rpcdebug/Makefile tools/rpcgen/Makefile utils/Makefile utils/exportfs/Makefile utils/gssd/Makefile utils/idmapd/Makefile utils/lockd/Makefile utils/mount/Makefile utils/mountd/Makefile utils/nfsd/Makefile utils/nfsstat/Makefile utils/rquotad/Makefile utils/showmount/Makefile utils/statd/Makefile"
+ac_config_files="$ac_config_files Makefile linux-nfs/Makefile support/Makefile support/export/Makefile support/include/nfs/Makefile support/include/rpcsvc/Makefile support/include/sys/fs/Makefile support/include/sys/Makefile support/include/Makefile support/misc/Makefile support/nfs/Makefile tools/Makefile tools/locktest/Makefile tools/nlmtest/Makefile tools/rpcdebug/Makefile tools/rpcgen/Makefile utils/Makefile utils/exportfs/Makefile utils/gssd/Makefile utils/idmapd/Makefile utils/mount/Makefile utils/mountd/Makefile utils/nfsd/Makefile utils/nfsstat/Makefile utils/rquotad/Makefile utils/showmount/Makefile utils/statd/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -29110,6 +29651,13 @@ echo "$as_me: error: conditional \"CONFIG_RQUOTAD\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${CONFIG_RPCGEN_TRUE}" && test -z "${CONFIG_RPCGEN_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"CONFIG_RPCGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"CONFIG_RPCGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${CONFIG_MOUNT_TRUE}" && test -z "${CONFIG_MOUNT_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"CONFIG_MOUNT\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -29445,7 +29993,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by linux nfs-utils $as_me 1.0.11, which was
+This file was extended by linux nfs-utils $as_me 1.1.0-rc1, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -29498,7 +30046,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-linux nfs-utils config.status 1.0.11
+linux nfs-utils config.status 1.1.0-rc1
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -29626,7 +30174,6 @@ do
     "support/misc/Makefile") CONFIG_FILES="$CONFIG_FILES support/misc/Makefile" ;;
     "support/nfs/Makefile") CONFIG_FILES="$CONFIG_FILES support/nfs/Makefile" ;;
     "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
-    "tools/getiversion/Makefile") CONFIG_FILES="$CONFIG_FILES tools/getiversion/Makefile" ;;
     "tools/locktest/Makefile") CONFIG_FILES="$CONFIG_FILES tools/locktest/Makefile" ;;
     "tools/nlmtest/Makefile") CONFIG_FILES="$CONFIG_FILES tools/nlmtest/Makefile" ;;
     "tools/rpcdebug/Makefile") CONFIG_FILES="$CONFIG_FILES tools/rpcdebug/Makefile" ;;
@@ -29635,7 +30182,6 @@ do
     "utils/exportfs/Makefile") CONFIG_FILES="$CONFIG_FILES utils/exportfs/Makefile" ;;
     "utils/gssd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/gssd/Makefile" ;;
     "utils/idmapd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/idmapd/Makefile" ;;
-    "utils/lockd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/lockd/Makefile" ;;
     "utils/mount/Makefile") CONFIG_FILES="$CONFIG_FILES utils/mount/Makefile" ;;
     "utils/mountd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/mountd/Makefile" ;;
     "utils/nfsd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/nfsd/Makefile" ;;
@@ -29778,6 +30324,7 @@ MAINT!$MAINT$ac_delim
 RELEASE!$RELEASE$ac_delim
 statedir!$statedir$ac_delim
 statduser!$statduser$ac_delim
+startstatd!$startstatd$ac_delim
 enable_nfsv3!$enable_nfsv3$ac_delim
 IDMAPD!$IDMAPD$ac_delim
 enable_nfsv4!$enable_nfsv4$ac_delim
@@ -29792,16 +30339,15 @@ kprefix!$kprefix$ac_delim
 secure_statd!$secure_statd$ac_delim
 CONFIG_RQUOTAD_TRUE!$CONFIG_RQUOTAD_TRUE$ac_delim
 CONFIG_RQUOTAD_FALSE!$CONFIG_RQUOTAD_FALSE$ac_delim
+RPCGEN_PATH!$RPCGEN_PATH$ac_delim
+CONFIG_RPCGEN_TRUE!$CONFIG_RPCGEN_TRUE$ac_delim
+CONFIG_RPCGEN_FALSE!$CONFIG_RPCGEN_FALSE$ac_delim
 CONFIG_MOUNT_TRUE!$CONFIG_MOUNT_TRUE$ac_delim
 CONFIG_MOUNT_FALSE!$CONFIG_MOUNT_FALSE$ac_delim
 CC!$CC$ac_delim
 CFLAGS!$CFLAGS$ac_delim
 LDFLAGS!$LDFLAGS$ac_delim
 CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-DEPDIR!$DEPDIR$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -29843,6 +30389,10 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+DEPDIR!$DEPDIR$ac_delim
 am__include!$am__include$ac_delim
 am__quote!$am__quote$ac_delim
 AMDEP_TRUE!$AMDEP_TRUE$ac_delim
@@ -29901,7 +30451,7 @@ ACLOCAL_AMFLAGS!$ACLOCAL_AMFLAGS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 56; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 60; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..65a2d02
--- /dev/null
@@ -0,0 +1,372 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+AC_INIT([linux nfs-utils],[1.1.0-rc1],[nfs@lists.sf.net],[nfs-utils])
+AC_CANONICAL_BUILD([])
+AC_CANONICAL_HOST([])
+AC_CONFIG_MACRO_DIR(aclocal)
+AM_INIT_AUTOMAKE
+AC_PREREQ(2.59)
+AC_PREFIX_DEFAULT(/usr)
+AM_MAINTAINER_MODE
+
+dnl *************************************************************
+dnl * Define the set of applicable options
+dnl *************************************************************
+AC_ARG_WITH(release,
+       [AC_HELP_STRING([--with-release=XXX], [set release to XXX [1]])],
+       RELEASE=$withval,
+       RELEASE=1)
+       AC_SUBST(RELEASE)
+AC_ARG_WITH(statedir,
+       [  --with-statedir=/foo    use state dir /foo [/var/lib/nfs]],
+       statedir=$withval,
+       statedir=/var/lib/nfs)
+       AC_SUBST(statedir)
+AC_ARG_WITH(statduser,
+       [AC_HELP_STRING([--with-statduser=rpcuser],
+                        [statd to run under @<:@rpcuser or nobody@:>@]
+       )],
+       statduser=$withval,
+       if test "x$cross_compiling" = "xno"; then
+               if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
+                       statduser=rpcuser
+               else
+                       statduser=nobody
+               fi
+       else
+               statduser=nobody
+       fi)
+       AC_SUBST(statduser)
+AC_ARG_WITH(start-statd,
+       [AC_HELP_STRING([--with-start-statd=scriptname],
+                       [When an nfs filesystems is mounted with locking, run this script]
+       )],
+       startstatd=$withval,
+       startstatd=/usr/sbin/start-statd
+       )
+       AC_SUBST(startstatd)
+       AC_DEFINE_UNQUOTED(START_STATD, "$startstatd", [Define this to a script which can start statd on mount])
+AC_ARG_ENABLE(nfsv3,
+       [AC_HELP_STRING([--enable-nfsv3],
+                        [enable support for NFSv3 @<:@default=yes@:>@])],
+       enable_nfsv3=$enableval,
+       enable_nfsv3=yes)
+       if test "$enable_nfsv3" = yes; then
+               AC_DEFINE(NFS3_SUPPORTED, 1, [Define this if you want NFSv3 support compiled in])
+       else
+               enable_nfsv3=
+       fi
+       AC_SUBST(enable_nfsv3)
+AC_ARG_ENABLE(nfsv4,
+       [AC_HELP_STRING([--enable-nfsv4],
+                        [enable support for NFSv4 @<:@default=yes@:>@])],
+       enable_nfsv4=$enableval,
+       enable_nfsv4=yes)
+       if test "$enable_nfsv4" = yes; then
+               AC_DEFINE(NFS4_SUPPORTED, 1, [Define this if you want NFSv4 support compiled in])
+               IDMAPD=idmapd
+       else
+               enable_nfsv4=
+               IDMAPD=
+       fi
+       AC_SUBST(IDMAPD)
+       AC_SUBST(enable_nfsv4)
+       AM_CONDITIONAL(CONFIG_NFSV4, [test "$enable_nfsv4" = "yes"])
+AC_ARG_ENABLE(gss,
+       [AC_HELP_STRING([--enable-gss],
+                        [enable support for rpcsec_gss @<:@default=yes@:>@])],
+       enable_gss=$enableval,
+       enable_gss=yes)
+       if test "$enable_gss" = yes; then
+               AC_DEFINE(GSS_SUPPORTED, 1, [Define this if you want rpcsec_gss support compiled in])
+               GSSD=gssd
+               SVCGSSD=svcgssd
+       else
+               enable_gss=
+               GSSD=
+               SVCGSSD=
+       fi
+       AC_SUBST(GSSD)
+       AC_SUBST(SVCGSSD)
+       AC_SUBST(enable_gss)
+       AM_CONDITIONAL(CONFIG_GSS, [test "$enable_gss" = "yes"])
+AC_ARG_ENABLE(kprefix,
+       [AC_HELP_STRING([--enable-kprefix], [install progs as rpc.knfsd etc])],
+       test "$enableval" = "yes" && kprefix=k,
+       kprefix=)
+       AC_SUBST(kprefix)
+AC_ARG_ENABLE(secure-statd,
+       [AC_HELP_STRING([--enable-secure-statd],
+                        [Only lockd can use statd (security)])],
+       test "$enableval" = "yes" && secure_statd=yes,
+       secure_statd=yes)
+       if test "$secure_statd" = yes; then
+               AC_DEFINE(RESTRICTED_STATD, 1, [Define this if you want to enable various security checks in statd. These checks basically keep anyone but lockd from using this service.])
+       fi
+       AC_SUBST(secure_statd)
+AC_ARG_ENABLE(rquotad,
+       [AC_HELP_STRING([--enable-rquotad],
+                        [enable rquotad @<:@default=yes@:>@])],
+       enable_rquotad=$enableval,
+       enable_rquotad=yes)
+       if test "$enable_rquotad" = yes; then
+               RQUOTAD=rquotad
+       else
+               RQUOTAD=
+       fi
+       AM_CONDITIONAL(CONFIG_RQUOTAD, [test "$enable_rquotad" = "yes"])
+AC_ARG_WITH(rpcgen,
+       [AC_HELP_STRING([--with-rpcgen=internal], [use internal rpcgen instead of system one])],
+       rpcgen_path=$withval,
+       rpcgen_path=yes )
+       RPCGEN_PATH=
+       if test "$rpcgen_path" == "yes"; then
+           for p in /usr/local/bin/rpcgen /usr/bin/rpcgen /bin/rpcgen
+           do if test -f $p ; then RPCGEN_PATH=$p ; break; fi ; done
+       elif test "$rpcgen_path" != "internal"; then
+           RPCGEN_PATH=$rpcgen_path
+       fi
+       AC_SUBST(RPCGEN_PATH)
+       AM_CONDITIONAL(CONFIG_RPCGEN, [test "$RPCGEN_PATH" == ""])
+AC_ARG_ENABLE(uuid,
+       [AC_HELP_STRING([--without-uuid], [Exclude uuid support and so avoid possibly buggy libblkid])],
+       if test "$enableval" = "yes" ; then use_blkid=1; else use_blkid=0; fi,
+       use_blkid=1)
+       AC_DEFINE_UNQUOTED(USE_BLKID, $use_blkid, [Define if you want to use blkid to find uuid of filesystems])
+AC_ARG_ENABLE(mount,
+       [AC_HELP_STRING([--enable-mount],
+                       [Create mount.nfs and don't use the util-linux mount(8) functionality. @<:@default=no@:>@])],
+       enable_mount=$enableval,
+       enable_mount=yes)
+       AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
+
+# Check whether user wants TCP wrappers support
+AC_TCP_WRAPPERS
+
+# Arrange for large-file support
+AC_SYS_LARGEFILE
+
+AC_CONFIG_SRCDIR([support/include/config.h.in])
+AC_CONFIG_HEADERS([support/include/config.h])
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+AM_PROG_CC_C_O
+
+if test "x$cross_compiling" = "xno"; then
+       CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
+else
+       CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
+fi
+
+AC_SUBST(CC_FOR_BUILD)
+
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(LD, ld)
+
+AC_HEADER_STDC([])
+AC_GNULIBC
+AC_BSD_SIGNALS
+
+dnl *************************************************************
+dnl * Check for required libraries
+dnl *************************************************************
+AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBNSL="-lnsl"])])
+AC_SUBST(LIBNSL)
+
+AC_CHECK_FUNC(connect, ,
+      AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"],
+                AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL))
+
+AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"])
+if test "$enable_nfsv4" = yes; then
+    AC_CHECK_LIB(event, event_dispatch, [libevent=1], AC_MSG_ERROR([libevent needed for nfsv4 support]))
+    AC_CHECK_LIB(nfsidmap, nfs4_init_name_mapping, [libnfsidmap=1], AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
+    AC_CHECK_HEADERS(event.h, ,AC_MSG_ERROR([libevent needed for nfsv4 support]))
+    AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
+    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
+     PKG_CHECK_MODULES(RPCSECGSS, librpcsecgss >= 0.10, ,
+      [AC_MSG_ERROR([Unable to locate information required to use librpcsecgss.  If you have pkgconfig installed, you might try setting environment variable PKG_CONFIG_PATH to /usr/local/lib/pkgconfig])
+      ]
+     )
+    PKG_CHECK_MODULES(GSSAPI, libgssapi >= 0.9)
+    fi
+
+fi
+if test "$knfsd_cv_glibc2" = no; then
+    AC_CHECK_LIB(bsd, daemon, [LIBBSD="-lbsd"])
+fi
+if test "$use_blkid" = 1; then
+   AC_CHECK_LIB(blkid, blkid_get_cache, [LIBBLKID="-lblkid"], AC_MSG_ERROR([libblkid needed]))
+   AC_CHECK_HEADER(blkid/blkid.h, , AC_MSG_ERROR([Cannot file libblkid header file blkid/blkid.h]))
+fi
+AC_SUBST(LIBSOCKET)
+AC_SUBST(LIBCRYPT)
+AC_SUBST(LIBBSD)
+AC_SUBST(LIBBLKID)
+
+if test "$enable_gss" = yes; then
+  dnl 'gss' also depends on nfsidmap.h - at least for svcgssd_proc.c
+  AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for gss support]))
+  AC_CHECK_HEADERS(spkm3.h, ,AC_MSG_WARN([could not locate SPKM3 header; will not have SPKM3 support]))
+  dnl the nfs4_set_debug function doesn't appear in all version of the library
+  AC_CHECK_LIB(nfsidmap, nfs4_set_debug,
+              AC_DEFINE(HAVE_NFS4_SET_DEBUG,1,
+                        [Whether nfs4_set_debug() is present in libnfsidmap]),)
+
+  dnl Check for Kerberos V5
+  AC_KERBEROS_V5
+
+  dnl This is not done until here because we need to have KRBLIBS set
+  dnl ("librpcsecgss=1" is so that it doesn't get added to LIBS)
+  AC_CHECK_LIB(rpcsecgss, authgss_create_default, [librpcsecgss=1], AC_MSG_ERROR([librpcsecgss needed for nfsv4 support]), -lgssapi -ldl)
+  AC_CHECK_LIB(rpcsecgss, authgss_set_debug_level,
+              AC_DEFINE(HAVE_AUTHGSS_SET_DEBUG_LEVEL, 1, [Define this if the rpcsec_gss library has the function authgss_set_debug_level]),, -lgssapi -ldl)
+
+fi
+
+dnl *************************************************************
+dnl Check for headers
+dnl *************************************************************
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \
+                 malloc.h memory.h netdb.h netinet/in.h paths.h \
+                 stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \
+                 sys/param.h sys/socket.h sys/time.h sys/vfs.h \
+                 syslog.h unistd.h com_err.h et/com_err.h \
+                 ifaddrs.h])
+
+dnl *************************************************************
+dnl Checks for typedefs, structures, and compiler characteristics
+dnl *************************************************************
+AC_C_CONST
+AC_TYPE_UID_T
+AC_C_INLINE
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl *************************************************************
+dnl Check for functions
+dnl *************************************************************
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_GETGROUPS
+AC_FUNC_GETMNTENT
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_LSTAT
+AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
+AC_HEADER_MAJOR
+#AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+#AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_FUNC_STAT
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
+               gethostbyaddr gethostbyname gethostname getmntent \
+               gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
+               realpath rmdir select socket strcasecmp strchr strdup \
+               strerror strrchr strtol strtoul sigprocmask])
+
+
+dnl *************************************************************
+dnl Check for data sizes (XXX These should go away with libgssapi pkg-config)
+dnl *************************************************************
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(socklen_t)
+
+
+dnl *************************************************************
+dnl Export some path names to config.h
+dnl *************************************************************
+AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!])
+
+if test "x$cross_compiling" = "xno"; then
+       CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"}
+       CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-"$CXXFLAGS"}
+       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-"$CPPFLAGS"}
+       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-"$LDFLAGS"}
+else
+       CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-""}
+       CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-""}
+       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
+       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
+fi
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+AC_SUBST(CFLAGS_FOR_BUILD)
+AC_SUBST(CXXFLAGS_FOR_BUILD)
+AC_SUBST(CPPFLAGS_FOR_BUILD)
+AC_SUBST(LDFLAGS_FOR_BUILD)
+
+dnl *************************************************************
+dnl Set up "global" CFLAGS
+dnl *************************************************************
+dnl Use architecture-specific compile flags
+dnl (We use $host and not $build in case we are cross-compiling)
+dnl *************************************************************
+case $host in
+  alpha*)
+    ARCHFLAGS="-mno-fp-regs -ffixed-8" ;;
+  *)
+    ARCHFLAGS="" ;;
+esac
+
+my_am_cflags="-Wall $ARCHFLAGS -pipe"
+
+AC_SUBST([AM_CPPFLAGS], ["-I\${top_srcdir}/support/include"])
+AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
+
+# Make sure that $ACLOCAL_FLAGS are used during a rebuild
+AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
+
+AC_CONFIG_FILES([
+       Makefile
+       linux-nfs/Makefile
+       support/Makefile
+       support/export/Makefile
+       support/include/nfs/Makefile
+       support/include/rpcsvc/Makefile
+       support/include/sys/fs/Makefile
+       support/include/sys/Makefile
+       support/include/Makefile
+       support/misc/Makefile
+       support/nfs/Makefile
+       tools/Makefile
+       tools/locktest/Makefile
+       tools/nlmtest/Makefile
+       tools/rpcdebug/Makefile
+       tools/rpcgen/Makefile
+       utils/Makefile
+       utils/exportfs/Makefile
+       utils/gssd/Makefile
+       utils/idmapd/Makefile
+       utils/mount/Makefile
+       utils/mountd/Makefile
+       utils/nfsd/Makefile
+       utils/nfsstat/Makefile
+       utils/rquotad/Makefile
+       utils/showmount/Makefile
+       utils/statd/Makefile])
+AC_OUTPUT
+
diff --git a/configure.in b/configure.in
deleted file mode 100644 (file)
index 61e5be2..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-dnl
-AC_INIT([linux nfs-utils],[1.0.11],[nfs@lists.sf.net],[nfs-utils])
-AC_CANONICAL_BUILD([])
-AC_CANONICAL_HOST([])
-AC_CONFIG_SRCDIR(tools/getiversion/getiversion.c)
-AC_CONFIG_MACRO_DIR(aclocal)
-AM_INIT_AUTOMAKE
-AC_PREREQ(2.59)
-AC_PREFIX_DEFAULT(/usr)
-AM_MAINTAINER_MODE
-
-dnl *************************************************************
-dnl * Define the set of applicable options
-dnl *************************************************************
-AC_ARG_WITH(release,
-       [AC_HELP_STRING([--with-release=XXX], [set release to XXX [1]])],
-       RELEASE=$withval,
-       RELEASE=1)
-       AC_SUBST(RELEASE)
-AC_ARG_WITH(statedir,
-       [  --with-statedir=/foo    use state dir /foo [/var/lib/nfs]],
-       statedir=$withval,
-       statedir=/var/lib/nfs)
-       AC_SUBST(statedir)
-AC_ARG_WITH(statduser,
-       [AC_HELP_STRING([--with-statduser=rpcuser],
-                        [statd to run under @<:@rpcuser or nobody@:>@]
-       )],
-       statduser=$withval,
-       if test "x$cross_compiling" = "xno"; then
-               if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
-                       statduser=rpcuser
-               else
-                       statduser=nobody
-               fi
-       else
-               statduser=nobody
-       fi)
-       AC_SUBST(statduser)
-AC_ARG_ENABLE(nfsv3,
-       [AC_HELP_STRING([--enable-nfsv3],
-                        [enable support for NFSv3 @<:@default=yes@:>@])],
-       enable_nfsv3=$enableval,
-       enable_nfsv3=yes)
-       if test "$enable_nfsv3" = yes; then
-               AC_DEFINE(NFS3_SUPPORTED, 1, [Define this if you want NFSv3 support compiled in])
-       else
-               enable_nfsv3=
-       fi
-       AC_SUBST(enable_nfsv3)
-AC_ARG_ENABLE(nfsv4,
-       [AC_HELP_STRING([--enable-nfsv4],
-                        [enable support for NFSv4 @<:@default=yes@:>@])],
-       enable_nfsv4=$enableval,
-       enable_nfsv4=yes)
-       if test "$enable_nfsv4" = yes; then
-               AC_DEFINE(NFS4_SUPPORTED, 1, [Define this if you want NFSv4 support compiled in])
-               IDMAPD=idmapd
-       else
-               enable_nfsv4=
-               IDMAPD=
-       fi
-       AC_SUBST(IDMAPD)
-       AC_SUBST(enable_nfsv4)
-       AM_CONDITIONAL(CONFIG_NFSV4, [test "$enable_nfsv4" = "yes"])
-AC_ARG_ENABLE(gss,
-       [AC_HELP_STRING([--enable-gss],
-                        [enable support for rpcsec_gss @<:@default=yes@:>@])],
-       enable_gss=$enableval,
-       enable_gss=yes)
-       if test "$enable_gss" = yes; then
-               AC_DEFINE(GSS_SUPPORTED, 1, [Define this if you want rpcsec_gss support compiled in])
-               GSSD=gssd
-               SVCGSSD=svcgssd
-       else
-               enable_gss=
-               GSSD=
-               SVCGSSD=
-       fi
-       AC_SUBST(GSSD)
-       AC_SUBST(SVCGSSD)
-       AC_SUBST(enable_gss)
-       AM_CONDITIONAL(CONFIG_GSS, [test "$enable_gss" = "yes"])
-AC_ARG_ENABLE(kprefix,
-       [AC_HELP_STRING([--enable-kprefix], [install progs as rpc.knfsd etc])],
-       test "$enableval" = "yes" && kprefix=k,
-       kprefix=)
-       AC_SUBST(kprefix)
-AC_ARG_ENABLE(secure-statd,
-       [AC_HELP_STRING([--enable-secure-statd],
-                        [Only lockd can use statd (security)])],
-       test "$enableval" = "yes" && secure_statd=yes,
-       secure_statd=no)
-       if test "$secure_statd" = yes; then
-               AC_DEFINE(RESTRICTED_STATD, 1, [Define this if you want to enable various security checks in statd. These checks basically keep anyone but lockd from using this service.])
-       fi
-       AC_SUBST(secure_statd)
-AC_ARG_ENABLE(rquotad,
-       [AC_HELP_STRING([--enable-rquotad],
-                        [enable rquotad @<:@default=yes@:>@])],
-       enable_rquotad=$enableval,
-       enable_rquotad=yes)
-       if test "$enable_rquotad" = yes; then
-               RQUOTAD=rquotad
-       else
-               RQUOTAD=
-       fi
-       AM_CONDITIONAL(CONFIG_RQUOTAD, [test "$enable_rquotad" = "yes"])
-
-AC_ARG_ENABLE(mount,
-       [AC_HELP_STRING([--enable-mount],
-                       [Create mount.nfs and don't use the util-linux mount(8) functionality. @<:@default=no@:>@])],
-       enable_mount=$enableval,
-       enable_mount=no)
-       AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
-
-# Check whether user wants TCP wrappers support
-AC_TCP_WRAPPERS
-
-AC_CONFIG_SRCDIR([support/include/config.h.in])
-AC_CONFIG_HEADERS([support/include/config.h])
-
-# Checks for programs.
-AC_PROG_CXX
-AC_PROG_CC
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-AC_PROG_LIBTOOL
-
-if test "x$cross_compiling" = "xno"; then
-       CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
-else
-       CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
-fi
-
-AC_SUBST(CC_FOR_BUILD)
-
-AC_CHECK_TOOL(AR, ar)
-AC_CHECK_TOOL(LD, ld)
-
-AC_HEADER_STDC([])
-AC_GNULIBC
-AC_BSD_SIGNALS
-
-dnl *************************************************************
-dnl * Check for required libraries
-dnl *************************************************************
-AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBNSL="-lnsl"])])
-AC_SUBST(LIBNSL)
-
-AC_CHECK_FUNC(connect, ,
-      AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"],
-                AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL))
-
-AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"])
-if test "$enable_nfsv4" = yes; then
-    AC_CHECK_LIB(event, event_dispatch, [libevent=1], AC_MSG_ERROR([libevent needed for nfsv4 support]))
-    AC_CHECK_LIB(nfsidmap, nfs4_init_name_mapping, [libnfsidmap=1], AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
-    AC_CHECK_HEADERS(event.h, ,AC_MSG_ERROR([libevent needed for nfsv4 support]))
-    AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
-    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
-     PKG_CHECK_MODULES(RPCSECGSS, librpcsecgss >= 0.10, ,
-      [AC_MSG_ERROR([Unable to locate information required to use librpcsecgss.  If you have pkgconfig installed, you might try setting environment variable PKG_CONFIG_PATH to /usr/local/lib/pkgconfig])
-      ]
-     )
-    PKG_CHECK_MODULES(GSSAPI, libgssapi >= 0.9)
-    fi
-
-fi
-if test "$knfsd_cv_glibc2" = no; then
-    AC_CHECK_LIB(bsd, daemon, [LIBBSD="-lbsd"])
-fi
-AC_CHECK_LIB(blkid, blkid_get_cache, [LIBBLKID="-lblkid"], AC_MSG_ERROR([libblkid needed]))
-AC_CHECK_HEADER(blkid/blkid.h, , AC_MSG_ERROR([Cannot file libblkid header file blkid/blkid.h]))
-AC_SUBST(LIBSOCKET)
-AC_SUBST(LIBCRYPT)
-AC_SUBST(LIBBSD)
-AC_SUBST(LIBBLKID)
-
-if test "$enable_gss" = yes; then
-  dnl 'gss' also depends on nfsidmap.h - at least for svcgssd_proc.c
-  AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for gss support]))
-  AC_CHECK_HEADERS(spkm3.h, ,AC_MSG_WARN([could not locate SPKM3 header; will not have SPKM3 support]))
-  dnl the nfs4_set_debug function doesn't appear in all version of the library
-  AC_CHECK_LIB(nfsidmap, nfs4_set_debug,
-              AC_DEFINE(HAVE_NFS4_SET_DEBUG,1,
-                        [Whether nfs4_set_debug() is present in libnfsidmap]),)
-
-  dnl Check for Kerberos V5
-  AC_KERBEROS_V5
-
-  dnl This is not done until here because we need to have KRBLIBS set
-  dnl ("librpcsecgss=1" is so that it doesn't get added to LIBS)
-  AC_CHECK_LIB(rpcsecgss, authgss_create_default, [librpcsecgss=1], AC_MSG_ERROR([librpcsecgss needed for nfsv4 support]), -lgssapi -ldl)
-  AC_CHECK_LIB(rpcsecgss, authgss_set_debug_level,
-              AC_DEFINE(HAVE_AUTHGSS_SET_DEBUG_LEVEL, 1, [Define this if the rpcsec_gss library has the function authgss_set_debug_level]),, -lgssapi -ldl)
-
-fi
-
-dnl *************************************************************
-dnl Check for headers
-dnl *************************************************************
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \
-                 malloc.h memory.h netdb.h netinet/in.h paths.h \
-                 stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \
-                 sys/param.h sys/socket.h sys/time.h sys/vfs.h \
-                 syslog.h unistd.h com_err.h et/com_err.h \
-                 ifaddrs.h])
-
-dnl *************************************************************
-dnl Checks for typedefs, structures, and compiler characteristics
-dnl *************************************************************
-AC_C_CONST
-AC_TYPE_UID_T
-AC_C_INLINE
-AC_TYPE_OFF_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_HEADER_TIME
-AC_STRUCT_TM
-
-dnl *************************************************************
-dnl Check for functions
-dnl *************************************************************
-AC_FUNC_ALLOCA
-AC_FUNC_CLOSEDIR_VOID
-AC_FUNC_ERROR_AT_LINE
-AC_FUNC_FORK
-AC_FUNC_GETGROUPS
-AC_FUNC_GETMNTENT
-AC_PROG_GCC_TRADITIONAL
-AC_FUNC_LSTAT
-AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
-AC_HEADER_MAJOR
-#AC_FUNC_MALLOC
-AC_FUNC_MEMCMP
-#AC_FUNC_REALLOC
-AC_FUNC_SELECT_ARGTYPES
-AC_TYPE_SIGNAL
-AC_FUNC_STAT
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
-               gethostbyaddr gethostbyname gethostname getmntent \
-               gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
-               realpath rmdir select socket strcasecmp strchr strdup \
-               strerror strrchr strtol strtoul sigprocmask])
-
-
-dnl *************************************************************
-dnl Check for data sizes (XXX These should go away with libgssapi pkg-config)
-dnl *************************************************************
-AC_CHECK_SIZEOF(short)
-AC_CHECK_SIZEOF(int)
-AC_CHECK_SIZEOF(long)
-AC_CHECK_SIZEOF(size_t)
-AC_CHECK_SIZEOF(socklen_t)
-
-
-dnl *************************************************************
-dnl Export some path names to config.h
-dnl *************************************************************
-AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!])
-
-if test "x$cross_compiling" = "xno"; then
-       CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"}
-       CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-"$CXXFLAGS"}
-       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-"$CPPFLAGS"}
-       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-"$LDFLAGS"}
-else
-       CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-""}
-       CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-""}
-       CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
-       LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
-fi
-
-AC_SUBST(CFLAGS)
-AC_SUBST(CXXFLAGS)
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-
-AC_SUBST(CFLAGS_FOR_BUILD)
-AC_SUBST(CXXFLAGS_FOR_BUILD)
-AC_SUBST(CPPFLAGS_FOR_BUILD)
-AC_SUBST(LDFLAGS_FOR_BUILD)
-
-dnl *************************************************************
-dnl Set up "global" CFLAGS
-dnl *************************************************************
-dnl Use architecture-specific compile flags
-dnl (We use $host and not $build in case we are cross-compiling)
-dnl *************************************************************
-case $host in
-  alpha*)
-    ARCHFLAGS="-mno-fp-regs -ffixed-8" ;;
-  *)
-    ARCHFLAGS="" ;;
-esac
-
-my_am_cflags="-Wall $ARCHFLAGS -pipe"
-
-AC_SUBST([AM_CPPFLAGS], ["-I\${top_srcdir}/support/include -D_FILE_OFFSET_BITS=64"])
-AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
-
-# Make sure that $ACLOCAL_FLAGS are used during a rebuild
-AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
-
-AC_CONFIG_FILES([
-       Makefile
-       linux-nfs/Makefile
-       support/Makefile
-       support/export/Makefile
-       support/include/nfs/Makefile
-       support/include/rpcsvc/Makefile
-       support/include/sys/fs/Makefile
-       support/include/sys/Makefile
-       support/include/Makefile
-       support/misc/Makefile
-       support/nfs/Makefile
-       tools/Makefile
-       tools/getiversion/Makefile
-       tools/locktest/Makefile
-       tools/nlmtest/Makefile
-       tools/rpcdebug/Makefile
-       tools/rpcgen/Makefile
-       utils/Makefile
-       utils/exportfs/Makefile
-       utils/gssd/Makefile
-       utils/idmapd/Makefile
-       utils/lockd/Makefile
-       utils/mount/Makefile
-       utils/mountd/Makefile
-       utils/nfsd/Makefile
-       utils/nfsstat/Makefile
-       utils/rquotad/Makefile
-       utils/showmount/Makefile
-       utils/statd/Makefile])
-AC_OUTPUT
-
index 8bb936c0d7c1883e649eef4689ec11a4c50582f2..a0e0b7df88df84a8eed01926ca87ecfd91def72c 100644 (file)
@@ -39,7 +39,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -128,6 +128,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -187,6 +188,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 49d346da3e122e23ad75136c52163e07b5de1fb4..2759d3d109335b335caed4b5d088979a569d5731 100644 (file)
@@ -38,7 +38,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -139,6 +139,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -198,6 +199,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 7a6a441c6c2f508135609a1b60e583c557dcf182..1ea15397c3a99ef76bb3dc906f3fa48ba9342d91 100644 (file)
@@ -1,6 +1,5 @@
 ## Process this file with automake to produce Makefile.in
 
-RPCGEN         = $(top_builddir)/tools/rpcgen/rpcgen
 
 GENFILES_CLNT  = mount_clnt.c
 GENFILES_XDR   = mount_xdr.c
@@ -22,8 +21,13 @@ dist-hook:
          rm ${distdir}/$$f; \
        done
 
+if CONFIG_RPCGEN
+RPCGEN         = $(top_builddir)/tools/rpcgen/rpcgen
 $(RPCGEN):
        make -C $(top_srcdir)/tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
 
 $(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
index 8d1c34283bf92e7bc889560dd5144d4856823f0c..8effbc7e0632e0ddfca2ebdbc646801de90328da 100644 (file)
@@ -41,7 +41,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -153,6 +153,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -212,13 +213,13 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 GENFILES_CLNT = mount_clnt.c
 GENFILES_XDR = mount_xdr.c
 GENFILES_H = mount.h
@@ -230,6 +231,8 @@ libexport_a_SOURCES = client.c export.c hostname.c nfsctl.c rmtab.c \
 
 BUILT_SOURCES = $(GENFILES)
 noinst_HEADERS = mount.h
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 MAINTAINERCLEANFILES = Makefile.in
 CLEANFILES = $(GENFILES) $(top_builddir)/support/include/mount.h
 all: $(BUILT_SOURCES)
@@ -505,9 +508,8 @@ dist-hook:
        for f in $(GENFILES); do \
          rm ${distdir}/$$f; \
        done
-
-$(RPCGEN):
-       make -C $(top_srcdir)/tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@   make -C $(top_srcdir)/tools/rpcgen all
 
 $(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
index 33dfdb004efac38fa08269906abbf4b045351d45..686c7448c425171ee6fec5a322d93231f07796e1 100644 (file)
@@ -329,6 +329,7 @@ add_name(char *old, char *add)
                strcat(new, ",");
                strcat(new, cp);
        }
+       free(old);
        return new;
 }
 
index a4b0788e4f6977057be760769e1b680c9440cc64..74e1d1b1bc46c68ace868e87775eed3580e46372 100644 (file)
@@ -90,6 +90,7 @@ export_init(nfs_export *exp, nfs_client *clp, struct exportent *nep)
        exp->m_xtabent = 0;
        exp->m_mayexport = 0;
        exp->m_changed = 0;
+       exp->m_warned = 0;
        exp->m_client = clp;
        clp->m_count++;
 }
@@ -115,6 +116,7 @@ export_dup(nfs_export *exp, struct hostent *hp)
        new->m_exported = 0;
        new->m_xtabent = 0;
        new->m_changed = 0;
+       new->m_warned = 0;
        export_add(new);
 
        return new;
index b74334cb8126be21a06f1e5049ba5976c2a5648c..32d92bdcfd779675bccecae7685ece968792996c 100644 (file)
@@ -92,12 +92,6 @@ expsetup(struct nfsctl_export *exparg, nfs_export *exp, int unexport)
        if (stat(exp->m_export.m_path, &stb) < 0)
                return 0;
 
-       if (exp->m_export.e_maptype != CLE_MAP_IDENT) {
-               xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)",
-                    exp->m_export.m_path);
-               errno = EINVAL;
-               return 0;
-       }
        memset(exparg, 0, sizeof(*exparg));
        strncpy(exparg->ex_path, exp->m_export.m_path,
                sizeof (exparg->ex_path) - 1);
index 72ced488474ffe00d45eade160b4a9240ec6b4e7..f5f9204ffed7c017db6b38a00abbbabaf757ae34 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -142,6 +142,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -201,6 +202,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index f288aa0fe8ebc4d817cd6c71134229cadaa9d39c..19ff77c968209b9632871988099ed2cee06819e8 100644 (file)
@@ -1,4 +1,4 @@
-/* support/include/config.h.in.  Generated from configure.in by autoheader.  */
+/* support/include/config.h.in.  Generated from configure.ac by autoheader.  */
 
 /* Define to 1 if the `closedir' function returns void instead of `int'. */
 #undef CLOSEDIR_VOID
    definitions in config.mk! */
 #undef NFS_STATEDIR
 
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
 /* Name of package */
 #undef PACKAGE
 
        STACK_DIRECTION = 0 => direction of growth unknown */
 #undef STACK_DIRECTION
 
+/* Define this to a script which can start statd on mount */
+#undef START_STATD
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
+/* Define if you want to use blkid to find uuid of filesystems */
+#undef USE_BLKID
+
 /* Define this if the private function, gss_krb5_cache_name, must be used to
    tell the Kerberos library which credentials cache to use. Otherwise, this
    is done by setting the KRB5CCNAME environment variable */
 /* Version number of package */
 #undef VERSION
 
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
index 1761dc4442ddd6e2cf0a1e4c520cf3fd8346614b..11f16ab1be812a95d832ca8a9a743900e97b4b11 100644 (file)
@@ -35,7 +35,7 @@ int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int,
              struct sockaddr_in *);
 u_long nfsvers_to_mnt(const u_long);
 u_long mntvers_to_nfs(const u_long);
-int get_socket(struct sockaddr_in *, u_int, int);
+int get_socket(struct sockaddr_in *, u_int, int, int);
 CLIENT * mnt_openclnt(clnt_addr_t *, int *);
 void mnt_closeclnt(CLIENT *, int);
 
index 458611b8f5ac3d3b0056c056b08079bd0040b965..431b5ce7701c0036668d8a61b31367f7b654c44f 100644 (file)
@@ -47,7 +47,9 @@ typedef struct mexport {
        int                     m_exported;     /* known to knfsd. -1 means not sure */
        int                     m_xtabent  : 1, /* xtab entry exists */
                                m_mayexport: 1, /* derived from xtabbed */
-                               m_changed  : 1; /* options (may) have changed */
+                               m_changed  : 1, /* options (may) have changed */
+                               m_warned   : 1; /* warned about multiple exports
+                                                * matching one client */
 } nfs_export;
 
 extern nfs_client *            clientlist[MCL_MAXTYPES];
index 52af7435fefd0aec7f8ab15726f72b3773574eb3..64c8355396338af69d3bc5c4f84e6c2791b312c4 100644 (file)
@@ -3,22 +3,28 @@
 
 #include "nfs_mntent.h"
 
+#ifndef _PATH_FSTAB
+#define _PATH_FSTAB "/etc/fstab"
+#endif
+
 int mtab_is_writable(void);
 int mtab_does_not_exist(void);
 
 struct mntentchn {
        struct mntentchn *nxt, *prev;
-       nfs_mntent_t m;
+       struct mntent m;
 };
 
-struct mntentchn *mtab_head (void);
 struct mntentchn *getmntoptfile (const char *file);
 struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
 struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
 
+struct mntentchn *getfsfile (const char *file);
+struct mntentchn *getfsspec (const char *spec);
+
 void lock_mtab (void);
 void unlock_mtab (void);
-void update_mtab (const char *special, nfs_mntent_t *with);
+void update_mtab (const char *special, struct mntent *with);
 
 #endif /* _NFS_FSTAB_H */
 
index 27d42c1c88fbb695ce5fac627403a2f61af43d29..52289f5f4adf6f9db5f391b6cc6733d8f7744734 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -132,6 +132,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -191,6 +192,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index f0286b2ca07704a49c84502004333aefd8fceea5..fc26f4ec10a58500343455c59f5cbaaf27fde24b 100644 (file)
@@ -39,10 +39,6 @@ struct nfs_fh_old {
 #define NFSCTL_GETFD           7       /* get an fh by path (used by mountd) */
 #define NFSCTL_GETFS           8       /* get an fh by path with max size (used by mountd) */
 
-/* Above this is for lockd. */
-#define NFSCTL_LOCKD           0x10000
-#define LOCKDCTL_SVC           NFSCTL_LOCKD
-
 #define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
 #define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1))) 
 #define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1))) 
index 76f348ee45b1829d6bea18cb12782e299cddce92..010df2426516dd75a51072be1cbe625ae54cd9e9 100644 (file)
@@ -5,15 +5,7 @@
 
 #ifndef _NFS_MNTENT_H
 #define _NFS_MNTENT_H
-
-typedef struct nfs_mntent_s {
-       const char *mnt_fsname;
-       const char *mnt_dir;
-       const char *mnt_type;
-       const char *mnt_opts;
-       int mnt_freq;
-       int mnt_passno;
-} nfs_mntent_t;
+#include <mntent.h>
 
 #define ERR_MAX 5
 
@@ -27,8 +19,8 @@ typedef struct mntFILEstruct {
 
 mntFILE *nfs_setmntent (const char *file, char *mode);
 void nfs_endmntent (mntFILE *mfp);
-int nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt);
+int nfs_addmntent (mntFILE *mfp, struct mntent *mnt);
 struct nfs_mntent *my_getmntent (mntFILE *mfp);
-nfs_mntent_t *nfs_getmntent (mntFILE *mfp);
+struct mntent *nfs_getmntent (mntFILE *mfp);
 
 #endif /* _NFS_MNTENT_H */
index c0850291222fa64a45273cf83600aa05ad943bdd..d4f4150152de5390a737d463b27bccf077f52a57 100644 (file)
 #define        _PATH_PROC_EXPORTS_ALT  "/proc/fs/nfsd/exports"
 #endif
 
-enum cle_maptypes {
-       CLE_MAP_IDENT = 0,
-       CLE_MAP_FILE,
-       CLE_MAP_UGIDD,
-};
-
 /*
  * Data related to a single exports entry as returned by getexportent.
  * FIXME: export options should probably be parsed at a later time to
@@ -71,7 +65,6 @@ struct exportent {
           use it for anything else. */
        char            m_path[NFS_MAXPATHLEN+1];
        int             e_flags;
-       int             e_maptype;
        int             e_anonuid;
        int             e_anongid;
        int *           e_squids;
@@ -144,9 +137,6 @@ int check_new_cache(void);
 
 void closeall(int min);
 
-/* lockd. */
-int                    lockdsvc();
-
 int                    svctcp_socket (u_long __number, int __reuse);
 int                    svcudp_socket (u_long __number, int __reuse);
 
index 038caff5c80727db81149efad67250b0b38c6ff5..787af3226a50f35be4e70cbfcad8b4aca3e795f1 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -132,6 +132,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -191,6 +192,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 35df56c418c358e6f162bcbd24f6fe738a8b60df..0e1f1144b130a24b97f0b88de3384c5c327dcb81 100644 (file)
@@ -38,7 +38,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -139,6 +139,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -198,6 +199,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index a8019c7ec1458a3c6dae67d9b7790fa3adc37041..f21fcfa9c8b7b0cfc2fed910603b2853f7f46680 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -132,6 +132,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -191,6 +192,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index ba6f4ce29a47e31ca70b9dedc82560dcbb068cab..e5ffdad66f2357bbf3870d9dc6221772b61ba808 100644 (file)
@@ -39,7 +39,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -149,6 +149,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -208,6 +209,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index af8181da9e28d9c9dbf91ca6b533b39a0f3f8ab1..6006df63c5d7f36964a3f3daad01fb86b70b686f 100644 (file)
@@ -3,7 +3,7 @@
 noinst_LIBRARIES = libnfs.a
 libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
                   xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \
-                  nfsexport.c getfh.c nfsctl.c lockdsvc.c \
+                  nfsexport.c getfh.c nfsctl.c \
                   svc_socket.c cacheio.c closeall.c conn.c fstab.c nfs_mntent.c
 
 MAINTAINERCLEANFILES = Makefile.in
index b6bf3727fedc028022f79bd03c5ed46a81516a2c..d29596e42ef5a91a8382dcc9f5d2d8507267b804 100644 (file)
@@ -39,7 +39,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -53,9 +53,9 @@ am_libnfs_a_OBJECTS = exports.$(OBJEXT) rmtab.$(OBJEXT) xio.$(OBJEXT) \
        rpcmisc.$(OBJEXT) rpcdispatch.$(OBJEXT) xlog.$(OBJEXT) \
        xcommon.$(OBJEXT) wildmat.$(OBJEXT) nfssvc.$(OBJEXT) \
        nfsclient.$(OBJEXT) nfsexport.$(OBJEXT) getfh.$(OBJEXT) \
-       nfsctl.$(OBJEXT) lockdsvc.$(OBJEXT) svc_socket.$(OBJEXT) \
-       cacheio.$(OBJEXT) closeall.$(OBJEXT) conn.$(OBJEXT) \
-       fstab.$(OBJEXT) nfs_mntent.$(OBJEXT)
+       nfsctl.$(OBJEXT) svc_socket.$(OBJEXT) cacheio.$(OBJEXT) \
+       closeall.$(OBJEXT) conn.$(OBJEXT) fstab.$(OBJEXT) \
+       nfs_mntent.$(OBJEXT)
 libnfs_a_OBJECTS = $(am_libnfs_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -154,6 +154,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -213,6 +214,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
@@ -222,7 +224,7 @@ top_srcdir = @top_srcdir@
 noinst_LIBRARIES = libnfs.a
 libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
                   xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \
-                  nfsexport.c getfh.c nfsctl.c lockdsvc.c \
+                  nfsexport.c getfh.c nfsctl.c \
                   svc_socket.c cacheio.c closeall.c conn.c fstab.c nfs_mntent.c
 
 MAINTAINERCLEANFILES = Makefile.in
@@ -279,7 +281,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exports.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstab.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfh.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockdsvc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs_mntent.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsclient.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsctl.Po@am__quote@
index 89f767676b2aeb5f85d0b485c6865b6f5837c2bb..29dbb82c33dd102d3e90d0d0dcb223f7f7bc9c25 100644 (file)
@@ -49,7 +49,7 @@ u_long mntvers_to_nfs(const u_long vers)
  * RPC_ANYSOCK is returned which will cause 
  * the RPC code to create the socket instead. 
  */
-int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
+int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp, int conn)
 {
        int so, cc, type;
        struct sockaddr_in laddr;
@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
                        return RPC_ANYSOCK;
                }
        }
-       if (type == SOCK_STREAM || type == SOCK_DGRAM) {
+       if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
                cc = connect(so, (struct sockaddr *)saddr, namelen);
                if (cc < 0) {
                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
@@ -129,20 +129,37 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
        CLIENT *clnt=NULL;
        int sock, stat;
        static char clnt_res;
+       struct sockaddr dissolve;
 
        rpc_createerr.cf_stat = stat = errno = 0;
-       sock = get_socket(saddr, prot, FALSE);
-       if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
-               /*
-                * TCP timeout. Bubble up the error to see 
-                * how it should be handled.
-                */
-               rpc_createerr.cf_stat = RPC_TIMEDOUT;
-               goto out_bad;
+       sock = get_socket(saddr, prot, FALSE, TRUE);
+       if (sock == RPC_ANYSOCK) {
+               if (errno == ETIMEDOUT) {
+                       /*
+                        * TCP timeout. Bubble up the error to see 
+                        * how it should be handled.
+                        */
+                       rpc_createerr.cf_stat = RPC_TIMEDOUT;
+               }
+               return 0;
+       }
+
+       if (caddr) {
+               /* Get the address of our end of this connection */
+               socklen_t len = sizeof(*caddr);
+               if (getsockname(sock, caddr, &len) != 0)
+                       caddr->sin_family = 0;
        }
 
        switch(prot) {
        case IPPROTO_UDP:
+               /* The socket is connected (so we could getsockname successfully),
+                * but some servers on multi-homed hosts reply from
+                * the wrong address, so if we stay connected, we lose the reply.
+                */
+               dissolve.sa_family = AF_UNSPEC;
+               connect(sock, &dissolve, sizeof(dissolve));
+
                clnt = clntudp_bufcreate(saddr, prog, vers,
                                         RETRY_TIMEOUT, &sock,
                                         RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
@@ -151,11 +168,11 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
                clnt = clnttcp_create(saddr, prog, vers, &sock,
                                      RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
                break;
-       default:
-               goto out_bad;
        }
-       if (!clnt)
-               goto out_bad;
+       if (!clnt) {
+               close(sock);
+               return 0;
+       }
        memset(&clnt_res, 0, sizeof(clnt_res));
        stat = clnt_call(clnt, NULLPROC,
                         (xdrproc_t)xdr_void, (caddr_t)NULL,
@@ -166,21 +183,12 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
                rpc_createerr.cf_stat = stat;
        }
        clnt_destroy(clnt);
-       if (sock != -1) {
-               if (caddr) {
-                       /* Get the address of our end of this connection */
-                       socklen_t len = sizeof(*caddr);
-                       if (getsockname(sock, caddr, &len) != 0)
-                               caddr->sin_family = 0;
-               }
-               close(sock);
-       }
+       close(sock);
 
        if (stat == RPC_SUCCESS)
                return 1;
-
- out_bad:
-       return 0;
+       else
+               return 0;
 }
 
 CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
@@ -191,7 +199,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
 
        /* contact the mount daemon via TCP */
        mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
-       *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE);
+       *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);
 
        switch (mnt_pmap->pm_prot) {
        case IPPROTO_UDP:
index 294e1c90986e443f9e0dacf4d9e4b9e190cdb7b6..0baa5d05efd006a55233d2ca6fc486fd51a17d7e 100644 (file)
@@ -32,7 +32,7 @@
 #include "xio.h"
 
 #define EXPORT_DEFAULT_FLAGS   \
-  (NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES)
+  (NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES|NFSEXP_NOSUBTREECHECK)
 
 int export_errno;
 
@@ -48,7 +48,6 @@ static int    getpath(char *path, int len);
 static int     parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr);
 static int     parsesquash(char *list, int **idp, int *lenp, char **ep);
 static int     parsenum(char **cpp);
-static int     parsemaptype(char *type);
 static void    freesquash(void);
 static void    syntaxerr(char *msg);
 
@@ -94,7 +93,6 @@ getexportent(int fromkernel, int fromexports)
                        def_ee.e_flags &= ~NFSEXP_ASYNC;
                        def_ee.e_flags &= ~NFSEXP_GATHERED_WRITES;
                }
-               def_ee.e_maptype = CLE_MAP_IDENT;
                def_ee.e_anonuid = 65534;
                def_ee.e_anongid = 65534;
                def_ee.e_squids = NULL;
@@ -245,21 +243,6 @@ putexportent(struct exportent *ep)
                xlog(L_ERROR, "unknown fsloc method for %s:%s",
                     ep->e_hostname, ep->e_path);
        }
-       fprintf(fp, "mapping=");
-       switch (ep->e_maptype) {
-       case CLE_MAP_IDENT:
-               fprintf(fp, "identity,");
-               break;
-       case CLE_MAP_UGIDD:
-               fprintf(fp, "ugidd,");
-               break;
-       case CLE_MAP_FILE:
-               fprintf(fp, "file,");
-               break;
-       default:
-               xlog(L_ERROR, "unknown mapping type for %s:%s",
-                                       ep->e_hostname, ep->e_path);
-       }
        if ((id = ep->e_squids) != NULL) {
                fprintf(fp, "squash_uids=");
                for (i = 0; i < ep->e_nsquids; i += 2)
@@ -317,7 +300,6 @@ mkexportent(char *hname, char *path, char *options)
        static struct exportent ee;
 
        ee.e_flags = EXPORT_DEFAULT_FLAGS;
-       ee.e_maptype = CLE_MAP_IDENT;
        ee.e_anonuid = 65534;
        ee.e_anongid = 65534;
        ee.e_squids = NULL;
@@ -447,12 +429,6 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
                        ep->e_flags &= ~NFSEXP_NOACL;
                else if (strcmp(opt, "no_acl") == 0)
                        ep->e_flags |= NFSEXP_NOACL;
-               else if (strncmp(opt, "mapping=", 8) == 0)
-                       ep->e_maptype = parsemaptype(opt+8);
-               else if (strcmp(opt, "map_identity") == 0)      /* old style */
-                       ep->e_maptype = CLE_MAP_IDENT;
-               else if (strcmp(opt, "map_daemon") == 0)        /* old style */
-                       ep->e_maptype = CLE_MAP_UGIDD;
                else if (strncmp(opt, "anonuid=", 8) == 0) {
                        char *oe;
                        ep->e_anonuid = strtol(opt+8, &oe, 10);
@@ -541,8 +517,8 @@ bad_option:
 out:
        if (warn && !had_subtree_opt)
                xlog(L_WARNING, "%s [%d]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"%s:%s\".\n"
-                               "  Assuming default behaviour ('subtree_check').\n"
-                               "  NOTE: this default will change with nfs-utils version 1.1.0\n",
+                               "  Assuming default behaviour ('no_subtree_check').\n"
+                               "  NOTE: this default has changed since nfs-utils version 1.0.x\n",
 
                                flname, flline,
                                ep->e_hostname, ep->e_path);
@@ -624,19 +600,6 @@ parsenum(char **cpp)
        return num;
 }
 
-static int
-parsemaptype(char *type)
-{
-       if (!strcmp(type, "identity"))
-               return CLE_MAP_IDENT;
-       if (!strcmp(type, "ugidd"))
-               return CLE_MAP_UGIDD;
-       if (!strcmp(type, "file"))
-               return CLE_MAP_FILE;
-       syntaxerr("invalid map type");
-       return CLE_MAP_IDENT;   /* default */
-}
-
 static int
 getpath(char *path, int len)
 {
index 8dc7d66315376c4e51abbeeabfdb63a431ae7874..aee8e5395453f30f204ed847f23963cb3be8a633 100644 (file)
@@ -80,16 +80,28 @@ mtab_is_writable() {
 
 struct mntentchn mounttable;
 static int got_mtab = 0;
+struct mntentchn fstab;
+static int got_fstab = 0;
 
 static void read_mounttable(void);
+static void read_fstab(void);
 
-struct mntentchn *
+static struct mntentchn *
 mtab_head() {
        if (!got_mtab)
                read_mounttable();
        return &mounttable;
 }
 
+static struct mntentchn *
+fstab_head()
+{
+       if (!got_fstab)
+               read_fstab();
+       return &fstab;
+}
+
+#if 0
 static void
 my_free(const void *s) {
        if (s)
@@ -109,11 +121,12 @@ discard_mntentchn(struct mntentchn *mc0) {
                free(mc);
        }
 }
+#endif
 
 static void
 read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
        struct mntentchn *mc = mc0;
-       nfs_mntent_t *mnt;
+       struct mntent *mnt;
 
        while ((mnt = nfs_getmntent(mfp)) != NULL) {
                if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
@@ -167,6 +180,27 @@ read_mounttable() {
         read_mntentchn(mfp, fnam, mc);
 }
 
+static void
+read_fstab()
+{
+       mntFILE *mfp = NULL;
+       const char *fnam;
+       struct mntentchn *mc = &fstab;
+
+       got_fstab = 1;
+       mc->nxt = mc->prev = NULL;
+
+       fnam = _PATH_FSTAB;
+       mfp = nfs_setmntent (fnam, "r");
+       if (mfp == NULL || mfp->mntent_fp == NULL) {
+               int errsv = errno;
+               nfs_error(_("warning: can't open %s: %s"),
+                         _PATH_FSTAB, strerror (errsv));
+               return;
+       }
+       read_mntentchn(mfp, fnam, mc);
+}
+
 /*
  * Given the directory name NAME, and the place MCPREV we found it last time,
  * try to find more occurrences.
@@ -201,6 +235,32 @@ getmntdevbackward (const char *name, struct mntentchn *mcprev) {
        return NULL;
 }
 
+/* Find the dir FILE in fstab.  */
+struct mntentchn *
+getfsfile (const char *file)
+{
+       struct mntentchn *mc, *mc0;
+
+       mc0 = fstab_head();
+       for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
+               if (streq(mc->m.mnt_dir, file))
+                       return mc;
+       return NULL;
+}
+
+/* Find the device SPEC in fstab.  */
+struct mntentchn *
+getfsspec (const char *spec)
+{
+       struct mntentchn *mc, *mc0;
+
+       mc0 = fstab_head();
+       for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
+               if (streq(mc->m.mnt_fsname, spec))
+                       return mc;
+       return NULL;
+}
+
 /* Updating mtab ----------------------------------------------*/
 
 /* Flag for already existing lock file. */
@@ -386,7 +446,8 @@ lock_mtab (void) {
  */
 
 void
-update_mtab (const char *dir, nfs_mntent_t *instead) {
+update_mtab (const char *dir, struct mntent *instead)
+{
        mntFILE *mfp, *mftmp;
        const char *fnam = MOUNTED;
        struct mntentchn mtabhead;      /* dummy */
@@ -455,8 +516,14 @@ update_mtab (const char *dir, nfs_mntent_t *instead) {
                }
        }
 
+#if 0
+       /* the chain might have strings copied from 'instead',
+        * so we cannot safely free it.
+        * And there is no need anyway because we are going to exit
+        * shortly.  So just don't call discard_mntentchn....
+        */
        discard_mntentchn(mc0);
-
+#endif
        if (fchmod (fileno (mftmp->mntent_fp),
                    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
                int errsv = errno;
diff --git a/support/nfs/lockdsvc.c b/support/nfs/lockdsvc.c
deleted file mode 100644 (file)
index ca1e862..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * support/nfs/nfssvc.c
- *
- * Run an NFS daemon.
- *
- * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <nfslib.h>
-
-int
-lockdsvc()
-{
-       struct nfsctl_arg       arg;
-
-       arg.ca_version = NFSCTL_VERSION;
-       return nfsctl(LOCKDCTL_SVC, &arg, NULL);
-}
index d1d124bcac6efa8b68937dc1db2bf66a860fcadc..a3fecfc05d8604c9334300c9a1a48fe0102d0a2c 100644 (file)
@@ -124,7 +124,7 @@ nfs_endmntent (mntFILE *mfp) {
 }
 
 int
-nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt) {
+nfs_addmntent (mntFILE *mfp, struct mntent *mnt) {
        char *m1, *m2, *m3, *m4;
        int res;
 
@@ -147,10 +147,10 @@ nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt) {
 }
 
 /* Read the next entry from the file fp. Stop reading at an incorrect entry. */
-nfs_mntent_t *
+struct mntent *
 nfs_getmntent (mntFILE *mfp) {
        static char buf[4096];
-       static nfs_mntent_t me;
+       static struct mntent me;
        char *s;
 
  again:
index 5b0a88ff76745ea86c019718272bd3c10c66fa77..22ea62c1a88f5d8458968c4fe82cf88dc802025a 100644 (file)
@@ -184,8 +184,11 @@ int makesock(int port, int proto)
        sin.sin_port = htons(port);
 
        val = 1;
-       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
-               xlog(L_ERROR, "setsockopt failed: %s\n", strerror(errno));
+       if (proto == IPPROTO_TCP)
+               if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+                              &val, sizeof(val)) < 0)
+                       xlog(L_ERROR, "setsockopt failed: %s\n",
+                            strerror(errno));
 
 #if 0
        /* I was told it didn't work with gigabit ethernet.
index 33076009ac0538de8569fd3489282bbeb2d672ed..6799d16230e5278f74c2f404c39b14dd1f21c72b 100644 (file)
@@ -162,7 +162,7 @@ svctcp_socket (u_long number, int reuse)
 int
 svcudp_socket (u_long number, int reuse)
 {
-  return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, reuse);
+  return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, 0);
 }
 
 #ifdef TEST
index 515da1376e58042f761f0a0d247be3c56891d4d7..db153463c0a2d0d2b8b8a2cac8f7a4779d7d63c8 100644 (file)
@@ -1,5 +1,11 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = getiversion locktest rpcdebug rpcgen nlmtest
+OPTDIRS =
+
+if CONFIG_RPCGEN
+OPTDIRS += rpcgen
+endif
+
+SUBDIRS = locktest rpcdebug nlmtest $(OPTDIRS)
 
 MAINTAINERCLEANFILES = Makefile.in
index 4c3b03ba6769cd796b2369c6920d9cc9169e121d..977651c686366c4d1148645cad35b994b80c7698 100644 (file)
@@ -31,6 +31,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+@CONFIG_RPCGEN_TRUE@am__append_1 = rpcgen
 subdir = tools
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -38,7 +39,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -57,7 +58,7 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive       \
   distclean-recursive maintainer-clean-recursive
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = locktest rpcdebug nlmtest rpcgen
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
@@ -139,6 +140,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -198,13 +200,15 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-SUBDIRS = getiversion locktest rpcdebug rpcgen nlmtest
+OPTDIRS = $(am__append_1)
+SUBDIRS = locktest rpcdebug nlmtest $(OPTDIRS)
 MAINTAINERCLEANFILES = Makefile.in
 all: all-recursive
 
diff --git a/tools/getiversion/Makefile.am b/tools/getiversion/Makefile.am
deleted file mode 100644 (file)
index 7d7172e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-CC=$(CC_FOR_BUILD)
-LIBTOOL = @LIBTOOL@ --tag=CC
-
-noinst_PROGRAMS = getiversion
-getiversion_SOURCES = getiversion.c
-getiversion_CFLAGS=$(CFLAGS_FOR_BUILD)
-getiversion_CPPFLAGS=$(CPPFLAGS_FOR_BUILD) -I$(top_srcdir)/support/include
-getiversion_LDFLAGS=$(LDFLAGS_FOR_BUILD)
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/getiversion/getiversion.c b/tools/getiversion/getiversion.c
deleted file mode 100644 (file)
index fdaf102..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * getiversion
- *
- * Get version number for an inode on an ext2 file system.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#include <stdio.h>
-#include <sys/fs/ext2fs.h>
-
-int
-main(int argc, char **argv)
-{
-       int     i, fd;
-       u_int32_t       vers;
-
-       if (argc <= 1) {
-               fprintf(stderr, "usage: getiversion file ...\n");
-               return 1;
-       }
-
-       for (i = 1; i < argc; i++) {
-               if ((fd = open(argv[i], O_RDONLY)) < 0
-                || ioctl(fd, EXT2_IOC_GETVERSION, &vers) < 0) {
-                       perror(argv[i]);
-                       continue;
-               } else {
-                       printf("%-20s %d\n", argv[i], vers);
-               }
-               close(fd);
-       }
-       return 0;
-}
index 0a497c991285362ecd60648a1f34232a25413b0e..6c4cdb01c640ad68bde02cff97efffe7587fbd0b 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -150,6 +150,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -209,6 +210,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 0836e6e751d6ffa6bd1224e916f78406827827d6..d150c515a5e05a53023a4a6c2520c6b91eb9e2d5 100644 (file)
@@ -38,7 +38,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -127,6 +127,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -186,6 +187,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 663fff01323b889aac0c1f5eeaa591c527ce78d0..1745ae63bcc2de0a7b2fb3520a82e04a29aaa346 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -155,6 +155,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -214,6 +215,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index b322c8b12b71b5027bfcb6aeea10d73ca71283e7..27f2e2b7fffae3e8e13932ac3cdce25b31ebecf7 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -155,6 +155,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -214,6 +215,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 723657c7c69463d1fd047f9fd319a40064232e16..c1bc0599ecef4ac1a9fa9261002e393ecb6cdf9c 100644 (file)
@@ -20,7 +20,6 @@ endif
 
 SUBDIRS = \
        exportfs \
-       lockd \
        mountd \
        nfsd \
        nfsstat \
index ce06a2fe23b0059fa2e91f3435627ef88c5783c0..fb8336096a9b0e8dac9489a8c6b74f1121faef85 100644 (file)
@@ -42,7 +42,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -61,8 +61,8 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive       \
   distclean-recursive maintainer-clean-recursive
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = exportfs lockd mountd nfsd nfsstat showmount statd \
-       rquotad idmapd gssd mount
+DIST_SUBDIRS = exportfs mountd nfsd nfsstat showmount statd rquotad \
+       idmapd gssd mount
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
@@ -144,6 +144,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -203,6 +204,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
@@ -213,7 +215,6 @@ OPTDIRS = $(am__append_1) $(am__append_2) $(am__append_3) \
        $(am__append_4)
 SUBDIRS = \
        exportfs \
-       lockd \
        mountd \
        nfsd \
        nfsstat \
index 37211b178205a43f248b1b995c6d1dd5327ba116..7d5ef333e745f40f095b09ec26de374f34801728 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -158,6 +158,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -217,6 +218,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 22e13a35b9ac9675589fc62512a133d6d45fedc4..8c3f634de5984848de3ccc61037774ecbf89f791 100644 (file)
@@ -218,6 +218,7 @@ export_all(int verbose)
                        exp->m_xtabent = 1;
                        exp->m_mayexport = 1;
                        exp->m_changed = 1;
+                       exp->m_warned = 0;
                }
        }
 }
@@ -274,6 +275,7 @@ exportfs(char *arg, char *options, int verbose)
        exp->m_xtabent = 1;
        exp->m_mayexport = 1;
        exp->m_changed = 1;
+       exp->m_warned = 0;
        if (hp) free (hp);
 }
 
@@ -410,10 +412,6 @@ dump(int verbose)
                                c = dumpopt(c, "mountpoint%s%s", 
                                            ep->e_mountpoint[0]?"=":"", 
                                            ep->e_mountpoint);
-                       if (ep->e_maptype == CLE_MAP_UGIDD)
-                               c = dumpopt(c, "mapping=ugidd");
-                       else if (ep->e_maptype == CLE_MAP_FILE)
-                               c = dumpopt(c, "mapping=file");
                        if (ep->e_anonuid != 65534)
                                c = dumpopt(c, "anonuid=%d", ep->e_anonuid);
                        if (ep->e_anongid != 65534)
index ab63b03cfd6be56bdd56f8fda5ae5b1b53a55f39..41a5b16af64a1cd720e6ebaab79cfb88da756908 100644 (file)
@@ -400,43 +400,6 @@ options.
 Finally, you can map all user requests to the
 anonymous uid by specifying the
 .IR all_squash " option.
-'''.PP 
-'''For the benefit of installations where uids differ between different
-'''machines, 
-'''.I nfsd
-'''provides several mechanism to dynamically map server uids to client
-'''uids and vice versa: static mapping files, NIS-based mapping, and
-'''.IR ugidd -based
-'''mapping.
-'''.PP
-'''.IR ugidd -based
-'''mapping is enabled with the 
-'''.I map_daemon
-'''option, and uses the UGID RPC protocol. For this to work, you have to run
-'''the
-'''.IR ugidd (8)
-'''mapping daemon on the client host. It is the least secure of the three methods,
-'''because by running
-'''.IR ugidd ,
-'''everybody can query the client host for a list of valid user names. You
-'''can protect yourself by restricting access to
-'''.I ugidd
-'''to valid hosts only. This can be done by entering the list of valid
-'''hosts into the
-'''.I hosts.allow
-'''or 
-'''.I hosts.deny
-'''file. The service name is
-'''.IR ugidd .
-'''For a description of the file's syntax, please read
-'''.IR hosts_access (5).
-'''.PP
-'''Static mapping is enabled by using the
-'''.I map_static
-'''option, which takes a file name as an argument that describes the mapping.
-'''NIS-based mapping queries the client's NIS server to obtain a mapping from
-'''user and group names on the server host to user and group names on the
-'''client.
 .PP
 Here's the complete list of mapping options:
 .TP
@@ -450,14 +413,6 @@ or group
 .TP
 .IR no_root_squash
 Turn off root squashing. This option is mainly useful for diskless clients.
-'''.TP
-'''.IR squash_uids " and " squash_gids
-'''This option specifies a list of uids or gids that should be subject to
-'''anonymous mapping. A valid list of ids looks like this:
-'''.IP
-'''.IR squash_uids=0-15,20,25-50
-'''.IP
-'''Usually, your squash lists will look a lot simpler.
 .TP
 .IR all_squash
 Map all uids and gids to the anonymous user. Useful for NFS-exported
@@ -465,60 +420,6 @@ public FTP directories, news spool directories, etc. The opposite option
 is 
 .IR no_all_squash ,
 which is the default setting.
-'''.TP
-'''.IR map_daemon
-'''This option turns on dynamic uid/gid mapping. Each uid in an NFS request
-'''will be translated to the equivalent server uid, and each uid in an
-'''NFS reply will be mapped the other way round. This option requires that
-'''.IR rpc.ugidd (8)
-'''runs on the client host. The default setting is
-'''.IR map_identity ,
-'''which leaves all uids untouched. The normal squash options apply regardless
-'''of whether dynamic mapping is requested or not.
-'''.TP
-'''.IR map_static
-'''This option enables static mapping. It specifies the name of the file
-'''that describes the uid/gid mapping, e.g.
-'''.IP
-'''.IR map_static=/etc/nfs/foobar.map
-'''.IP
-'''The file's format looks like this
-'''.IP
-'''.nf
-'''.ta +3i
-'''# Mapping for client foobar:
-'''#    remote     local
-'''uid  0-99       -       # squash these
-'''uid  100-500    1000    # map 100-500 to 1000-1400
-'''gid  0-49       -       # squash these
-'''gid  50-100     700     # map 50-100 to 700-750
-'''.fi
-'''.TP
-'''.IR map_nis
-'''This option enables NIS-based uid/gid mapping. For instance, when
-'''the server encounters the uid 123 on the server, it will obtain the
-'''login name associated with it, and contact the NFS client's NIS server
-'''to obtain the uid the client associates with the name.
-'''.IP
-'''In order to do this, the NFS server must know the client's NIS domain.
-'''This is specified as an argument to the
-'''.I map_nis
-'''options, e.g.
-'''.IP
-'''.I map_nis=foo.com
-'''.IP
-'''Note that it may not be sufficient to simply specify the NIS domain
-'''here; you may have to take additional actions before
-'''.I nfsd
-'''is actually able to contact the server. If your distribution uses
-'''the NYS library, you can specify one or more NIS servers for the
-'''client's domain in
-'''.IR /etc/yp.conf .
-'''If you are using a different NIS library, you may have to obtain a
-'''special
-'''.IR ypbind (8)
-'''daemon that can be configured via
-'''.IR yp.conf .
 .TP
 .IR anonuid " and " anongid
 These options explicitly set the uid and gid of the anonymous account.
index 41503abb0b30ebb441ff83497f1ab4ecf2126e3a..1132bc4f776b1c51b84722e3883c572a7eafaac2 100644 (file)
@@ -41,7 +41,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -193,6 +193,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -252,6 +253,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 9988fe4ab6f85f04f93fdeda78fbd095f2fb595f..747637c636ef4234295780649924269916e6212e 100644 (file)
 #include "gss_util.h"
 #include "krb5_util.h"
 
-char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
+char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
+char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
 char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
 char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
 int  use_memcache = 0;
+int  root_uses_machine_creds = 1;
 
 void
 sig_die(int signal)
 {
        /* destroy krb5 machine creds */
-       gssd_destroy_krb5_machine_creds();
+       if (root_uses_machine_creds)
+               gssd_destroy_krb5_machine_creds();
        printerr(1, "exiting on signal %d\n", signal);
        exit(1);
 }
@@ -78,7 +81,7 @@ sig_hup(int signal)
 static void
 usage(char *progname)
 {
-       fprintf(stderr, "usage: %s [-f] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
+       fprintf(stderr, "usage: %s [-f] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
                progname);
        exit(1);
 }
@@ -93,7 +96,7 @@ main(int argc, char *argv[])
        extern char *optarg;
        char *progname;
 
-       while ((opt = getopt(argc, argv, "fvrmMp:k:d:")) != -1) {
+       while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
                switch (opt) {
                        case 'f':
                                fg = 1;
@@ -104,6 +107,9 @@ main(int argc, char *argv[])
                        case 'M':
                                use_memcache = 1;
                                break;
+                       case 'n':
+                               root_uses_machine_creds = 0;
+                               break;
                        case 'v':
                                verbosity++;
                                break;
@@ -111,8 +117,8 @@ main(int argc, char *argv[])
                                rpc_verbosity++;
                                break;
                        case 'p':
-                               strncpy(pipefsdir, optarg, sizeof(pipefsdir));
-                               if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
+                               strncpy(pipefs_dir, optarg, sizeof(pipefs_dir));
+                               if (pipefs_dir[sizeof(pipefs_dir)-1] != '\0')
                                        errx(1, "pipefs path name too long");
                                break;
                        case 'k':
@@ -130,10 +136,10 @@ main(int argc, char *argv[])
                                break;
                }
        }
-       strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME,
-               sizeof(pipefsdir)-strlen(pipefsdir));
-       if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
-               errx(1, "pipefs path name too long");
+       snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
+                pipefs_dir, GSSD_SERVICE_NAME);
+       if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
+               errx(1, "pipefs_nfsdir path name too long");
 
        if ((progname = strrchr(argv[0], '/')))
                progname++;
@@ -160,7 +166,8 @@ main(int argc, char *argv[])
        signal(SIGHUP, sig_hup);
 
        /* Process keytab file and get machine credentials */
-       gssd_refresh_krb5_machine_creds();
+       if (root_uses_machine_creds)
+               gssd_refresh_krb5_machine_creds();
 
        gssd_run();
        printerr(0, "gssd_run returned!\n");
index ec91e8980117391a7aa3b19b664212355cefa544..6b96ce17d6632997580be6755593d4218703af46 100644 (file)
@@ -58,10 +58,12 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUTHTYPE_LIPKEY};
 
 
 
-extern char                    pipefsdir[PATH_MAX];
+extern char                    pipefs_dir[PATH_MAX];
+extern char                    pipefs_nfsdir[PATH_MAX];
 extern char                    keytabfile[PATH_MAX];
 extern char                    ccachedir[PATH_MAX];
 extern int                     use_memcache;
+extern int                     root_uses_machine_creds;
 
 TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
 
index 250d26fe3e36af41b649ef77c620289d02858b8e..f2ecd69995f589832198066f78b90136bceba951 100644 (file)
@@ -2,11 +2,11 @@
 .\" rpc.gssd(8)
 .\"
 .\" Copyright (C) 2003 J. Bruce Fields <bfields@umich.edu>
-.TH rpc.gssd 8 "17 Mar 2003"
+.TH rpc.gssd 8 "14 Mar 2007"
 .SH NAME
 rpc.gssd \- rpcsec_gss daemon
 .SH SYNOPSIS
-.B "rpc.gssd [-f] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
+.B "rpc.gssd [-f] [-n] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
 .SH DESCRIPTION
 The rpcsec_gss protocol gives a means of using the gss-api generic security
 api to provide security for protocols using rpc (in particular, nfs).  Before
@@ -25,22 +25,34 @@ Runs
 .B rpc.gssd
 in the foreground and sends output to stderr (as opposed to syslogd)
 .TP
+.B -n
+By default,
+.B rpc.gssd
+treats accesses by the user with UID 0 specially, and uses
+"machine credentials" for all accesses by that user which
+require Kerberos authentication.
+With the \-n option, "machine credentials" will not be used
+for accesses by UID 0.  Instead, credentials must be obtained
+manually like all other users.  Use of this option means that
+"root" must manually obtain Kerberos credentials before
+attemtpting to mount an nfs filesystem requiring Kerberos
+authentication.
+.TP
 .B -k keytab
 Tells
 .B rpc.gssd
-to use the keys for principals nfs/hostname in
+to use the keys found in
 .I keytab
-to obtain machine credentials.
+to obtain "machine credentials".
 The default value is "/etc/krb5.keytab".
-.\".TP
-.\".B -m
-.\"Ordinarily,
-.\".B rpc.gssd
-.\"looks for a cached ticket for user $UID in /tmp/krb5cc_$UID.
-.\"With the -m option, the user with uid 0 will be treated specially, and will
-.\"be mapped instead to the credentials for the principal nfs/hostname found in
-.\"the keytab file.
-.\"(This option is now the default and is ignored if specified.)
+Previous versions of
+.B rpc.gssd
+used only "nfs/*" keys found within the keytab.
+Now, the first keytab entry for each distinct Kerberos realm
+within the keytab is used.  This means that an NFS client
+no longer needs an "nfs/hostname" principal and keytab entry,
+but can instead use a "host/hostname" (or any other) keytab
+entry that is available.
 .TP
 .B -p path
 Tells
index a086bb398ca1d2ecc6d866ca9d91456c1e7383e9..0559f7b7c7b9478dd223f2e76eb71818265eb332 100644 (file)
@@ -106,9 +106,9 @@ gssd_run()
        dn_act.sa_flags = SA_SIGINFO;
        sigaction(DNOTIFY_SIGNAL, &dn_act, NULL);
 
-       if ((fd = open(pipefsdir, O_RDONLY)) == -1) {
+       if ((fd = open(pipefs_nfsdir, O_RDONLY)) == -1) {
                printerr(0, "ERROR: failed to open %s: %s\n",
-                        pipefsdir, strerror(errno));
+                        pipefs_nfsdir, strerror(errno));
                exit(1);
        }
        fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL);
index 68d645ddc90a4b848448726979e7a2c3c53ee8a9..3b190f2995a97f54ebe3e76e6a93078d37c65374 100644 (file)
  *     with an index into pollarray[], and other basic data about that client.
  *
  * Directory structure: created by the kernel nfs client
- *      /pipefsdir/clntXX             : one per rpc_clnt struct in the kernel
- *      /pipefsdir/clntXX/krb5        : read uid for which kernel wants
- *                                      a context, write the resulting context
- *      /pipefsdir/clntXX/info        : stores info such as server name
+ *      {pipefs_nfsdir}/clntXX             : one per rpc_clnt struct in the kernel
+ *      {pipefs_nfsdir}/clntXX/krb5        : read uid for which kernel wants
+ *                                         a context, write the resulting context
+ *      {pipefs_nfsdir}/clntXX/info        : stores info such as server name
  *
  * Algorithm:
- *      Poll all /pipefsdir/clntXX/krb5 files.  When ready, data read
+ *      Poll all {pipefs_nfsdir}/clntXX/krb5 files.  When ready, data read
  *      is a uid; performs rpcsec_gss context initialization protocol to
  *      get a cred for that user.  Writes result to corresponding krb5 file
  *      in a form the kernel code will understand.
  *      In addition, we make sure we are notified whenever anything is
- *      created or destroyed in pipefsdir/ or in an of the clntXX directories,
- *      and rescan the whole pipefsdir when this happens.
+ *      created or destroyed in {pipefs_nfsdir} or in an of the clntXX directories,
+ *      and rescan the whole {pipefs_nfsdir} when this happens.
  */
 
 struct pollfd * pollarray;
@@ -389,16 +389,16 @@ update_client_list(void)
        struct dirent **namelist;
        int i, j;
 
-       if (chdir(pipefsdir) < 0) {
+       if (chdir(pipefs_nfsdir) < 0) {
                printerr(0, "ERROR: can't chdir to %s: %s\n",
-                        pipefsdir, strerror(errno));
+                        pipefs_nfsdir, strerror(errno));
                return -1;
        }
 
-       j = scandir(pipefsdir, &namelist, NULL, alphasort);
+       j = scandir(pipefs_nfsdir, &namelist, NULL, alphasort);
        if (j < 0) {
                printerr(0, "ERROR: can't scandir %s: %s\n",
-                        pipefsdir, strerror(errno));
+                        pipefs_nfsdir, strerror(errno));
                return -1;
        }
        update_old_clients(namelist, j);
@@ -675,6 +675,7 @@ handle_krb5_upcall(struct clnt_info *clp)
        gss_buffer_desc         token;
        char                    **credlist = NULL;
        char                    **ccname;
+       int                     create_resp = -1;
 
        printerr(1, "handling krb5 upcall\n");
 
@@ -688,49 +689,52 @@ handle_krb5_upcall(struct clnt_info *clp)
                goto out;
        }
 
-       if (uid == 0) {
-               int success = 0;
-
-               /*
-                * Get a list of credential cache names and try each
-                * of them until one works or we've tried them all
-                */
-               if (gssd_get_krb5_machine_cred_list(&credlist)) {
-                       printerr(0, "WARNING: Failed to obtain machine "
-                                   "credentials for connection to "
-                                   "server %s\n", clp->servername);
-                               goto out_return_error;
-               }
-               for (ccname = credlist; ccname && *ccname; ccname++) {
-                       gssd_setup_krb5_machine_gss_ccache(*ccname);
-                       if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
-                                                   AUTHTYPE_KRB5)) == 0) {
-                               /* Success! */
-                               success++;
-                               break;
-                       }
-                       printerr(2, "WARNING: Failed to create krb5 context "
-                                   "for user with uid %d with credentials "
-                                   "cache %s for server %s\n",
-                                uid, *ccname, clp->servername);
-               }
-               gssd_free_krb5_machine_cred_list(credlist);
-               if (!success) {
-                       printerr(0, "WARNING: Failed to create krb5 context "
-                                   "for user with uid %d with any "
-                                   "credentials cache for server %s\n",
-                                uid, clp->servername);
-                       goto out_return_error;
-               }
-       }
-       else {
+       if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) {
                /* Tell krb5 gss which credentials cache to use */
                gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
 
-               if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
-                                                       AUTHTYPE_KRB5)) != 0) {
+               create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
+                                                    AUTHTYPE_KRB5);
+       }
+       if (create_resp != 0) {
+               if (uid == 0 && root_uses_machine_creds == 1) {
+                       int success = 0;
+
+                       /*
+                        * Get a list of credential cache names and try each
+                        * of them until one works or we've tried them all
+                        */
+                       if (gssd_get_krb5_machine_cred_list(&credlist)) {
+                               printerr(0, "WARNING: Failed to obtain machine "
+                                        "credentials for connection to "
+                                        "server %s\n", clp->servername);
+                                       goto out_return_error;
+                       }
+                       for (ccname = credlist; ccname && *ccname; ccname++) {
+                               gssd_setup_krb5_machine_gss_ccache(*ccname);
+                               if ((create_auth_rpc_client(clp, &rpc_clnt,
+                                                           &auth, uid,
+                                                           AUTHTYPE_KRB5)) == 0) {
+                                       /* Success! */
+                                       success++;
+                                       break;
+                               }
+                               printerr(2, "WARNING: Failed to create krb5 context "
+                                        "for user with uid %d with credentials "
+                                        "cache %s for server %s\n",
+                                        uid, *ccname, clp->servername);
+                       }
+                       gssd_free_krb5_machine_cred_list(credlist);
+                       if (!success) {
+                               printerr(0, "WARNING: Failed to create krb5 context "
+                                        "for user with uid %d with any "
+                                        "credentials cache for server %s\n",
+                                        uid, clp->servername);
+                               goto out_return_error;
+                       }
+               } else {
                        printerr(0, "WARNING: Failed to create krb5 context "
-                                   "for user with uid %d for server %s\n",
+                                "for user with uid %d for server %s\n",
                                 uid, clp->servername);
                        goto out_return_error;
                }
index 096f6cf80812bf901c7c47db8ce45aa18218ab3c..f1682b8ec8701f5090577122869b76cf470c0eb9 100644 (file)
@@ -191,7 +191,7 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
                                 namelist[i]->d_name);
                        snprintf(statname, sizeof(statname),
                                 "%s/%s", ccachedir, namelist[i]->d_name);
-                       if (stat(statname, &tmp_stat)) {
+                       if (lstat(statname, &tmp_stat)) {
                                printerr(0, "Error doing stat on file '%s'\n",
                                         statname);
                                free(namelist[i]);
@@ -448,7 +448,7 @@ gssd_have_realm_ple(void *r)
 
 /*
  * Process the given keytab file and create a list of principals we
- * might use to perform mount operations.
+ * might use as machine credentials.
  *
  * Returns:
  *     0 => Sucess
@@ -465,9 +465,8 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
 
        /*
         * Look through each entry in the keytab file and determine
-        * if we might want to use it later to do a mount.  If so,
-        * save info in the global principal list
-        * (gssd_k5_kt_princ_list).
+        * if we might want to use it as machine credentials.  If so,
+        * save info in the global principal list (gssd_k5_kt_princ_list).
         * Note: (ple == principal list entry)
         */
        if ((code = krb5_kt_start_seq_get(context, kt, &cursor))) {
@@ -485,22 +484,14 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
                        printerr(0, "WARNING: Skipping keytab entry because "
                                    "we failed to unparse principal name: %s\n",
                                 error_message(code));
+                       krb5_kt_free_entry(context, &kte);
                        continue;
                }
                printerr(2, "Processing keytab entry for principal '%s'\n",
                         pname);
-#ifdef HAVE_KRB5
-               if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) &&
-                    (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME,
-                             GSSD_SERVICE_NAME_LEN) == 0) &&
-#else
-               if ( (strlen(kte.principal->name.name_string.val[0]) == GSSD_SERVICE_NAME_LEN) &&
-                    (strncmp(kte.principal->name.name_string.val[0], GSSD_SERVICE_NAME,
-                             GSSD_SERVICE_NAME_LEN) == 0) &&
-                             
-#endif
-                    (!gssd_have_realm_ple((void *)&kte.principal->realm)) ) {
-                       printerr(2, "We will use this entry (%s)\n", pname);
+               /* Just use the first keytab entry found for each realm */
+               if ((!gssd_have_realm_ple((void *)&kte.principal->realm)) ) {
+                       printerr(2, "We WILL use this entry (%s)\n", pname);
                        ple = malloc(sizeof(struct gssd_k5_kt_princ));
                        if (ple == NULL) {
                                printerr(0, "ERROR: could not allocate storage "
@@ -510,6 +501,7 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
 #else
                                free(pname);
 #endif
+                               krb5_kt_free_entry(context, &kte);
                                retval = ENOMEM;
                                goto out;
                        }
@@ -533,6 +525,7 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
 #else
                                free(pname);
 #endif
+                               krb5_kt_free_entry(context, &kte);
                                retval = ENOMEM;
                                goto out;
                        }
@@ -546,6 +539,7 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
 #else
                                free(pname);
 #endif
+                               krb5_kt_free_entry(context, &kte);
                                retval = code;
                                goto out;
                        }
@@ -565,6 +559,7 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name)
 #else
                free(pname);
 #endif
+               krb5_kt_free_entry(context, &kte);
        }
 
        if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) {
index a0054296385b8697984328b97537497477e60944..fc12c8e09d560060dfe5e66f56ca80527e17c174 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -155,6 +155,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -214,6 +215,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
diff --git a/utils/lockd/Makefile.am b/utils/lockd/Makefile.am
deleted file mode 100644 (file)
index e1546a4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-man8_MANS      = lockd.man
-EXTRA_DIST     = $(man8_MANS)
-
-RPCPREFIX      = rpc.
-KPREFIX                = @kprefix@
-sbin_PROGRAMS  = lockd
-lockd_SOURCES = lockd.c
-lockd_LDADD = ../../support/export/libexport.a \
-             ../../support/nfs/libnfs.a \
-             ../../support/misc/libmisc.a
-
-MAINTAINERCLEANFILES = Makefile.in
-
-#######################################################################
-# The following allows the current practice of having
-# daemons renamed during the install to include RPCPREFIX
-# and the KPREFIX
-# This could all be done much easier with program_transform_name
-# ( program_transform_name = s/^/$(RPCPREFIX)$(KPREFIX)/ )
-# but that also renames the man pages, which the current
-# practice does not do.
-install-exec-hook:
-       (cd $(DESTDIR)$(sbindir) && \
-         for p in $(sbin_PROGRAMS); do \
-           mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
-         done)
-uninstall-hook:
-       (cd $(DESTDIR)$(sbindir) && \
-         for p in $(sbin_PROGRAMS); do \
-           rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
-         done)
-
-
-# XXX This makes some assumptions about what automake does.
-# XXX But there is no install-man-hook or install-man-local.
-install-man: install-man8 install-man-links
-uninstall-man: uninstall-man8 uninstall-man-links
-
-install-man-links:
-       (cd $(DESTDIR)$(man8dir) && \
-         for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
-           inst=`echo $$m | sed -e 's/man$$/8/'`; \
-           rm -f $(RPCPREFIX)$$inst ; \
-           $(LN_S) $$inst $(RPCPREFIX)$$inst ; \
-         done)
-
-uninstall-man-links:
-       (cd $(DESTDIR)$(man8dir) && \
-         for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
-           inst=`echo $$m | sed -e 's/man$$/8/'`; \
-           rm -f $(RPCPREFIX)$$inst ; \
-         done)
-
diff --git a/utils/lockd/lockd.c b/utils/lockd/lockd.c
deleted file mode 100644 (file)
index 71b31b0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * lockd
- *
- * This is the user level part of lockd. This is very primitive, because
- * all the work is now done in the kernel module.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <nfslib.h>
-
-
-
-static void    usage(const char *);
-
-int
-main(int argc, char **argv)
-{
-       int error;
-
-       if (argc > 1)
-               usage (argv [0]);
-       
-       if (chdir(NFS_STATEDIR)) {
-               fprintf(stderr, "%s: chdir(%s) failed: %s\n",
-                       argv [0], NFS_STATEDIR, strerror(errno));
-               exit(1);
-       }
-
-       if ((error = lockdsvc()) < 0) {
-               if (errno == EINVAL)
-                       /* Ignore EINVAL since kernel may start
-                          lockd automatically. */
-                       error = 0;
-               else
-                       perror("lockdsvc");
-       }
-
-       return (error != 0);
-}
-
-static void
-usage(const char *prog)
-{
-       fprintf(stderr, "usage:\n%s\n", prog);
-       exit(2);
-}
diff --git a/utils/lockd/lockd.man b/utils/lockd/lockd.man
deleted file mode 100644 (file)
index aa76019..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.\"
-.\" lockd(8)
-.\"
-.\" Copyright (C) 2000 Chip Salzenberg <chip@debian.org>
-.\"
-.TH rpc.lockd 8 "25 Feb 2000"
-.SH NAME
-rpc.lockd \- start kernel lockd process
-.SH SYNOPSIS
-.B "rpc.lockd
-.SH DESCRIPTION
-The
-.B rpc.lockd
-program starts the NFS lock manager (NLM) on kernels that don't start
-it automatically.  However, since most kernels \fIdo\fR start it
-automatically,
-.BR rpc.lockd .
-is usually not required.  Even so, running it anyway is harmless.
-.SH SEE ALSO
-.BR rpc.statd (8),
-.BR  rpc.nfsd (8)
-.SH AUTHORS
-.br
-H.J. Lu <hjl@valinux.com>
index 4a2f43728de4317abe383e6ad12af97d494d6b08..07e86e4c5e4a1fd3ffe3c9a8470dc5da9824c8d4 100644 (file)
@@ -1,9 +1,14 @@
 ## Process this file with automake to produce Makefile.in
 
+# These binaries go in /sbin (not /usr/sbin), and that cannot be
+# overriden at config time.
+sbindir = /sbin
+
 man8_MANS      = mount.nfs.man umount.nfs.man
+man5_MANS      = nfs.man
 
 sbin_PROGRAMS  = mount.nfs
-EXTRA_DIST = nfsmount.x $(man8_MANS)
+EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
 mount_nfs_SOURCES = mount.c nfsmount.c nfs4mount.c nfsumount.c \
                  mount_constants.h nfs4_mount.h nfs_mount4.h
 
@@ -14,9 +19,10 @@ MAINTAINERCLEANFILES = Makefile.in
 
 install-exec-hook:
        (cd $(DESTDIR)$(sbindir) && \
-         ln -sf $(sbin_PROGRAMS) mount.nfs4 && \
-         ln -sf $(sbin_PROGRAMS) umount.nfs && \
-         ln -sf $(sbin_PROGRAMS) umount.nfs4)
+         ln -sf mount.nfs mount.nfs4 && \
+         ln -sf mount.nfs umount.nfs && \
+         ln -sf mount.nfs umount.nfs4 && \
+         chmod 4511 mount.nfs )
 uninstall-hook:
        (cd $(DESTDIR)$(sbindir) && \
            rm -f mount.nfs4 umount.nfs umount.nfs4)
@@ -28,6 +34,11 @@ install-man-links:
            inst=`echo $$m | sed -e 's/man$$/8/'`; \
            rm -f $$inst ; \
          done)
+       (cd $(DESTDIR)$(man5dir) && \
+         for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+           inst=`echo $$m | sed -e 's/man$$/5/'`; \
+           rm -f $$inst ; \
+         done)
 
 uninstall-man-links:
        (cd $(DESTDIR)$(man8dir) && \
@@ -35,4 +46,9 @@ uninstall-man-links:
            inst=`echo $$m | sed -e 's/man$$/8/'`; \
            rm -f $$inst ; \
          done)
+       (cd $(DESTDIR)$(man5dir) && \
+         for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+           inst=`echo $$m | sed -e 's/man$$/5/'`; \
+           rm -f $$inst ; \
+         done)
 
index faff61d9a753076df64ef6d986024cc0bda34799..55da8fa48e9f38e76f16b9eaa0df0965775d2ec3 100644 (file)
@@ -40,13 +40,14 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/support/include/config.h
 CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" \
+       "$(DESTDIR)$(man8dir)"
 sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(sbin_PROGRAMS)
 am_mount_nfs_OBJECTS = mount.$(OBJEXT) nfsmount.$(OBJEXT) \
@@ -68,9 +69,10 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        $(LDFLAGS) -o $@
 SOURCES = $(mount_nfs_SOURCES)
 DIST_SOURCES = $(mount_nfs_SOURCES)
+man5dir = $(mandir)/man5
 man8dir = $(mandir)/man8
 NROFF = nroff
-MANS = $(man8_MANS)
+MANS = $(man5_MANS) $(man8_MANS)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -154,6 +156,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -209,10 +212,14 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-sbindir = @sbindir@
+
+# These binaries go in /sbin (not /usr/sbin), and that cannot be
+# overriden at config time.
+sbindir = /sbin
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
@@ -220,7 +227,8 @@ target_alias = @target_alias@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 man8_MANS = mount.nfs.man umount.nfs.man
-EXTRA_DIST = nfsmount.x $(man8_MANS)
+man5_MANS = nfs.man
+EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
 mount_nfs_SOURCES = mount.c nfsmount.c nfs4mount.c nfsumount.c \
                  mount_constants.h nfs4_mount.h nfs_mount4.h
 
@@ -330,6 +338,51 @@ mostlyclean-libtool:
 
 clean-libtool:
        -rm -rf .libs _libs
+install-man5: $(man5_MANS) $(man_MANS)
+       @$(NORMAL_INSTALL)
+       test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
+       @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.5*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+         else file=$$i; fi; \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           5*) ;; \
+           *) ext='5' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+         $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+       done
+uninstall-man5:
+       @$(NORMAL_UNINSTALL)
+       @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.5*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           5*) ;; \
+           *) ext='5' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+         rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+       done
 install-man8: $(man8_MANS) $(man_MANS)
        @$(NORMAL_INSTALL)
        test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
@@ -454,7 +507,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(PROGRAMS) $(MANS)
 installdirs:
-       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -515,7 +568,7 @@ install-html: install-html-am
 
 install-info: install-info-am
 
-install-man: install-man8
+install-man: install-man5 install-man8
 
 install-pdf: install-pdf-am
 
@@ -545,7 +598,7 @@ uninstall-am: uninstall-man uninstall-sbinPROGRAMS
        @$(NORMAL_INSTALL)
        $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
 
-uninstall-man: uninstall-man8
+uninstall-man: uninstall-man5 uninstall-man8
 
 .MAKE: install-am install-exec-am install-strip uninstall-am
 
@@ -556,20 +609,22 @@ uninstall-man: uninstall-man8
        install install-am install-data install-data-am install-dvi \
        install-dvi-am install-exec install-exec-am install-exec-hook \
        install-html install-html-am install-info install-info-am \
-       install-man install-man8 install-pdf install-pdf-am install-ps \
-       install-ps-am install-sbinPROGRAMS install-strip installcheck \
-       installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags uninstall uninstall-am uninstall-hook uninstall-man \
-       uninstall-man8 uninstall-sbinPROGRAMS
+       install-man install-man5 install-man8 install-pdf \
+       install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags uninstall uninstall-am uninstall-hook \
+       uninstall-man uninstall-man5 uninstall-man8 \
+       uninstall-sbinPROGRAMS
 
 
 install-exec-hook:
        (cd $(DESTDIR)$(sbindir) && \
-         ln -sf $(sbin_PROGRAMS) mount.nfs4 && \
-         ln -sf $(sbin_PROGRAMS) umount.nfs && \
-         ln -sf $(sbin_PROGRAMS) umount.nfs4)
+         ln -sf mount.nfs mount.nfs4 && \
+         ln -sf mount.nfs umount.nfs && \
+         ln -sf mount.nfs umount.nfs4 && \
+         chmod 4511 mount.nfs )
 uninstall-hook:
        (cd $(DESTDIR)$(sbindir) && \
            rm -f mount.nfs4 umount.nfs umount.nfs4)
@@ -580,6 +635,11 @@ install-man-links:
            inst=`echo $$m | sed -e 's/man$$/8/'`; \
            rm -f $$inst ; \
          done)
+       (cd $(DESTDIR)$(man5dir) && \
+         for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+           inst=`echo $$m | sed -e 's/man$$/5/'`; \
+           rm -f $$inst ; \
+         done)
 
 uninstall-man-links:
        (cd $(DESTDIR)$(man8dir) && \
@@ -587,6 +647,11 @@ uninstall-man-links:
            inst=`echo $$m | sed -e 's/man$$/8/'`; \
            rm -f $$inst ; \
          done)
+       (cd $(DESTDIR)$(man5dir) && \
+         for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+           inst=`echo $$m | sed -e 's/man$$/5/'`; \
+           rm -f $$inst ; \
+         done)
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index 5e0e599578a9cad26ea12916e6c49e0c3bb99f0f..52b0d67d208281b5bbc75b3a1d55ef2a6854698e 100644 (file)
@@ -28,6 +28,7 @@
 #include <sys/mount.h>
 #include <getopt.h>
 #include <mntent.h>
+#include <pwd.h>
 
 #include "fstab.h"
 #include "xcommon.h"
@@ -43,6 +44,7 @@ char *progname;
 int nomtab;
 int verbose;
 int mounttype;
+int sloppy;
 
 static struct option longopts[] = {
   { "fake", 0, 0, 'f' },
@@ -74,6 +76,11 @@ struct opt_map {
   int  mask;                    /* flag mask value */
 };
 
+/* Custom mount options for our own purposes.  */
+#define MS_DUMMY       0x00000000
+#define MS_USERS       0x40000000
+#define MS_USER                0x80000000
+
 static const struct opt_map opt_map[] = {
   { "defaults", 0, 0, 0         },      /* default options */
   { "ro",       1, 0, MS_RDONLY },      /* read-only */
@@ -90,6 +97,18 @@ static const struct opt_map opt_map[] = {
   { "remount",  0, 0, MS_REMOUNT},      /* Alter flags of mounted FS */
   { "bind",     0, 0, MS_BIND   },      /* Remount part of tree elsewhere */
   { "rbind",    0, 0, MS_BIND|MS_REC }, /* Idem, plus mounted subtrees */
+  { "auto",     0, 0, MS_DUMMY },       /* Can be mounted using -a */
+  { "noauto",   0, 0, MS_DUMMY },       /* Can  only be mounted explicitly */
+  { "users",    1, 0, MS_USERS },      /* Allow ordinary user to mount */
+  { "nousers",  0, 1, MS_DUMMY  },      /* Forbid ordinary user to mount */
+  { "user",     1, 0, MS_USER  },      /* Allow ordinary user to mount */
+  { "nouser",   0, 1, MS_DUMMY   },     /* Forbid ordinary user to mount */
+  { "owner",    0, 0, MS_DUMMY  },      /* Let the owner of the device mount */
+  { "noowner",  0, 0, MS_DUMMY  },      /* Device owner has no special privs */
+  { "group",    0, 0, MS_DUMMY  },      /* Let the group of the device mount */
+  { "nogroup",  0, 0, MS_DUMMY  },      /* Device group has no special privs */
+  { "_netdev",  0, 0, MS_DUMMY},        /* Device requires network */
+  { "comment",  0, 0, MS_DUMMY},        /* fstab comment only (kudzu,_netdev)*/
 
   /* add new options here */
 #ifdef MS_NOSUB
@@ -104,6 +123,7 @@ static const struct opt_map opt_map[] = {
   { "mand",     0, 0, MS_MANDLOCK },    /* Allow mandatory locks on this FS */
   { "nomand",   0, 1, MS_MANDLOCK },    /* Forbid mandatory locks on this FS */
 #endif
+  { "loop",     1, 0, MS_DUMMY   },      /* use a loop device */
 #ifdef MS_NOATIME
   { "atime",    0, 1, MS_NOATIME },     /* Update access time */
   { "noatime",  0, 0, MS_NOATIME },     /* Do not update access time */
@@ -121,6 +141,15 @@ static char * fix_opts_string (int flags, const char *extra_opts) {
        char *new_opts;
 
        new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
+       if (flags & MS_USER) {
+               /* record who mounted this so they can unmount */
+               struct passwd *pw = getpwuid(getuid());
+               if(pw)
+                       new_opts = xstrconcat3(new_opts, ",user=", pw->pw_name);
+       }
+       if (flags & MS_USERS)
+               new_opts = xstrconcat3(new_opts, ",users", "");
+       
        for (om = opt_map; om->opt != NULL; om++) {
                if (om->skip)
                        continue;
@@ -139,7 +168,6 @@ static char * fix_opts_string (int flags, const char *extra_opts) {
 int add_mtab(char *fsname, char *mount_point, char *fstype, int flags, char *opts, int freq, int passno)
 {
        struct mntent ment;
-       int fd;
        FILE *mtab;
 
        ment.mnt_fsname = fsname;
@@ -149,6 +177,11 @@ int add_mtab(char *fsname, char *mount_point, char *fstype, int flags, char *opt
        ment.mnt_freq = 0;
        ment.mnt_passno= 0;
 
+       if(flags & MS_REMOUNT) {
+               update_mtab(ment.mnt_dir, &ment);
+               return 0;
+       }
+
        lock_mtab();
 
         if ((mtab = setmntent(MOUNTED, "a+")) == NULL) {
@@ -191,6 +224,7 @@ void mount_usage()
        printf("\t-w\t\tMount file system read-write\n");
        printf("\t-f\t\tFake mount, don't actually mount\n");
        printf("\t-n\t\tDo not update /etc/mtab\n");
+       printf("\t-s\t\tTolerate sloppy mount options rather than failing.\n");
        printf("\t-h\t\tPrint this help\n");
        printf("\tversion\t\tnfs4 - NFS version 4, nfs - older NFS version supported\n");
        printf("\tnfsoptions\tRefer mount.nfs(8) or nfs(5)\n\n");
@@ -225,66 +259,122 @@ static void parse_opts (const char *options, int *flags, char **extra_opts)
 {
        if (options != NULL) {
                char *opts = xstrdup(options);
-               char *opt;
-               int len = strlen(opts) + 20;
+               char *opt, *p;
+               int len = strlen(opts) + 1;             /* include room for a null */
+               int open_quote = 0;
 
                *extra_opts = xmalloc(len);
                **extra_opts = '\0';
 
-               for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ","))
-                       parse_opt(opt, flags, *extra_opts, len);
-
+               for (p=opts, opt=NULL; p && *p; p++) {
+                       if (!opt)
+                               opt = p;                /* begin of the option item */
+                       if (*p == '"')
+                               open_quote ^= 1;        /* reverse the status */
+                       if (open_quote)
+                               continue;               /* still in a quoted block */
+                       if (*p == ',')
+                               *p = '\0';              /* terminate the option item */
+                       /* end of option item or last item */
+                       if (*p == '\0' || *(p+1) == '\0') {
+                               parse_opt(opt, flags, *extra_opts, len);
+                               opt = NULL;
+                       }
+               }
                free(opts);
        }
-
 }
 
 static void mount_error(char *node)
 {
        switch(errno) {
                case ENOTDIR:
-                       printf("%s: mount point %s is not a directory\n", progname, node);
+                       fprintf(stderr, "%s: mount point %s is not a directory\n", progname, node);
                        break;
                case EBUSY:
-                       printf("%s: %s is already mounted or busy\n", progname, node);
+                       fprintf(stderr, "%s: %s is already mounted or busy\n", progname, node);
                        break;
                case ENOENT:
-                       printf("%s: mount point %s does not exist\n", progname, node);
+                       fprintf(stderr, "%s: mount point %s does not exist\n", progname, node);
                        break;
                default:
-                       printf("%s: %s\n", progname, strerror(errno));
+                       fprintf(stderr, "%s: %s\n", progname, strerror(errno));
        }
 }
 
+extern u_short getport(
+       struct sockaddr_in *saddr,
+       u_long prog,
+       u_long vers,
+       u_int prot);
+
+static int probe_statd()
+{
+       struct sockaddr_in addr;
+       u_short port;
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+       port = getport(&addr, 100024, 1, IPPROTO_UDP);
+
+       if (port == 0)
+               return 0;
+       addr.sin_port = htons(port);
+
+       if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0)
+               return 0;
+
+       return 1;
+}
+
+static int start_statd()
+{
+       /* If /var/run/rpc.statd.pid exists and is non-empty,
+        * assume statd already running.
+        * If START_STATD not defined, or defined to a non-existent file,
+        * don't bother,
+        * else run that file (typically a shell script)
+        */
+       struct stat stb;
+
+       if (probe_statd())
+               return 1;
+#ifdef START_STATD
+       if (stat(START_STATD, &stb) ==0 &&
+           S_ISREG(stb.st_mode) &&
+           (stb.st_mode & S_IXUSR)) {
+               system(START_STATD);
+               if (probe_statd())
+                       return 1;
+       }
+#endif
+       return 0;
+}
+
 int main(int argc, char *argv[])
 {
        int c, flags = 0, nfs_mount_vers = 0, mnt_err = 1, fake = 0;
        char *spec, *mount_point, *extra_opts = NULL;
        char *mount_opts = NULL, *p;
+       uid_t uid = getuid();
 
        progname = argv[0];
+       if (!progname)
+               exit(2);
+
        if ((p = strrchr(progname, '/')) != NULL)
                progname = p+1;
 
-       if (getuid() != 0) {
-               printf("%s: only root can do that.\n", progname);
-               exit(1);
-       }
-
        if(!strncmp(progname, "umount", strlen("umount"))) {
                if(argc < 2) {
                        umount_usage();
                        exit(1);
                }
-               return(nfsumount(argc, argv));
+               exit(nfsumount(argc, argv) ? 0 : 1);
        }
 
-       if ((argc < 2)) {
-               mount_usage();
-               exit(1);
-       }
-
-       if(argv[1][0] == '-') {
+       if(argv[1] && argv[1][0] == '-') {
                if(argv[1][1] == 'V')
                        printf("%s ("PACKAGE_STRING")\n", progname);
                else
@@ -292,14 +382,31 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:h",
+       if ((argc < 3)) {
+               mount_usage();
+               exit(1);
+       }
+
+       spec = argv[1];
+       mount_point = argv[2];
+
+       argv[2] = argv[0]; /* so that getopt error messages are correct */
+       while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:hs",
                                longopts, NULL)) != -1) {
                switch (c) {
                case 'r':
                        flags |= MS_RDONLY;
                        break;
                case 't':
-                       nfs_mount_vers = (strncmp(optarg, "nfs4", 4)) ? 0 : 4;
+                       if (strcmp(optarg, "nfs4") == 0)
+                               nfs_mount_vers = 4;
+                       else if (strcmp(optarg, "nfs") == 0)
+                               nfs_mount_vers = 0;
+                       else {
+                               fprintf(stderr, "%s: unknown filesystem type: %s\n",
+                                       progname, optarg);
+                               exit(1);
+                       }
                        break;
                case 'v':
                        ++verbose;
@@ -322,6 +429,9 @@ int main(int argc, char *argv[])
                        else
                                mount_opts = xstrdup(optarg);
                        break;
+               case 's':
+                       ++sloppy;
+                       break;
                case 128: /* bind */
                        mounttype = MS_BIND;
                        break;
@@ -349,36 +459,95 @@ int main(int argc, char *argv[])
                        exit(1);
                }
        }
+       if (optind != argc-2) {
+               /* Extra non-option words at the end... */
+               mount_usage();
+               exit(1);
+       }
 
-       spec = argv[1];
-       mount_point = canonicalize(argv[2]);
+       if (strcmp(progname, "mount.nfs4") == 0)
+               nfs_mount_vers = 4;
+
+       if (uid != 0) {
+               /* don't even think about it unless options exactly
+                * match fstab
+                */
+               struct mntentchn *mc;
+
+               if ((mc = getfsfile(mount_point)) == NULL ||
+                   strcmp(mc->m.mnt_fsname, spec) != 0 ||
+                   strcmp(mc->m.mnt_type, (nfs_mount_vers == 4 ? "nfs4":"nfs")) != 0
+                   ) {
+                       fprintf(stderr, "%s: permission died - no match for fstab\n",
+                               progname);
+                       exit(1);
+               }
+               /* 'mount' munges the options from fstab before passing them
+                * to us, so it is non-trivial to test that we have the correct
+                * set of options and we don't want to trust what the user
+                * gave us, so just take whatever is in fstab
+                */
+               mount_opts = strdup(mc->m.mnt_opts);
+               mounttype = 0;
+       }
+
+       mount_point = canonicalize(mount_point);
+       if (mount_point == NULL ||
+           mount_point[0] != '/') {
+               fprintf(stderr, "%s: unknown mount point %s\n",
+                       progname, mount_point ? : "");
+               exit(1);
+       }
        
        parse_opts(mount_opts, &flags, &extra_opts);
 
-       if (!strcmp(progname, "mount.nfs4") || nfs_mount_vers == 4) {
-               nfs_mount_vers = 4;
-               mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
+       if (uid != 0) {
+           if (! (flags & (MS_USERS | MS_USER))) {
+                   fprintf(stderr, "%s: permission denied\n", progname);
+                   exit(1);
+           }
        }
+
+       if (nfs_mount_vers == 4)
+               mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
        else {
-               if (!strcmp(progname, "mount.nfs")) {
-                       mnt_err = nfsmount(spec, mount_point, &flags,
-                                       &extra_opts, &mount_opts, &nfs_mount_vers, 0);
+               int need_statd = 0;
+               mnt_err = nfsmount(spec, mount_point, &flags,
+                                  &extra_opts, &mount_opts,
+                                  0, &need_statd);
+               if (!mnt_err && !fake && need_statd) {
+                       if (!start_statd()) {
+                               fprintf(stderr,
+                                       "%s: rpc.statd is not running but is "
+                                       "required for remote locking\n"
+                                       "   Either use \"-o nolocks\" to keep "
+                                       "locks local, or start statd.\n",
+                                       progname);
+                               exit(1);
+                       }
                }
        }
 
-       if (!mnt_err && !fake) {
-               mnt_err = do_mount_syscall(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs", flags, mount_opts);
-               
-               if(mnt_err) {
+       if (mnt_err)
+               exit(EX_FAIL);
+
+       if (!fake) {
+               mnt_err = do_mount_syscall(spec, mount_point,
+                                          nfs_mount_vers == 4 ? "nfs4" : "nfs",
+                                          flags & ~(MS_USER|MS_USERS) ,
+                                          mount_opts);
+
+               if (mnt_err) {
                        mount_error(mount_point);
-                       exit(-1);
+                       exit(EX_FAIL);
                }
-
-               if(!nomtab)
-                       add_mtab(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs",
-                                flags, extra_opts, 0, 0);
        }
 
+       if (!nomtab)
+               add_mtab(spec, mount_point,
+                        nfs_mount_vers == 4 ? "nfs4" : "nfs",
+                        flags, extra_opts, 0, 0);
+
        return 0;
 }
 
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
new file mode 100644 (file)
index 0000000..673556c
--- /dev/null
@@ -0,0 +1,464 @@
+.\" nfs.5 "Rick Sladkey" <jrs@world.std.com>
+.\" Wed Feb  8 12:52:42 1995, faith@cs.unc.edu: updates for Ross Biro's
+.\" patches. "
+.TH NFS 5 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
+.SH NAME
+nfs \- nfs and nfs4 fstab format and options
+.SH SYNOPSIS
+.B /etc/fstab
+.SH DESCRIPTION
+The
+.I fstab
+file contains information about which filesystems
+to mount where and with what options.
+For NFS mounts, it contains the server name and
+exported server directory to mount from,
+the local directory that is the mount point,
+and the NFS specific options that control
+the way the filesystem is mounted.
+.P
+Three different versions of the NFS protocol are
+supported by the Linux NFS client:
+NFS version 2, NFS version 3, and NFS version 4.
+To mount via NFS version 2, use the
+.BR nfs
+file system type and specify
+.BR nfsvers=2 .
+To mount via NFS version 3, use the
+.BR nfs
+file system type and specify
+.BR nfsvers=3 .
+Version 3 is the default protocol version for the
+.BR nfs
+file system type when
+.BR nfsvers=
+is not specified on the mount command and both client and server
+support it.
+To mount via NFS version 4, use the
+.BR nfs4
+file system type.
+The
+.BR nfsvers=
+keyword is not supported for the
+.BR nfs4
+file system type.
+.P
+These file system types share similar mount options;
+the differences are listed below.
+.P
+Here is an example from an \fI/etc/fstab\fP file for an NFSv3 mount
+over TCP.
+.sp
+.nf
+.ta 2.5i +0.75i +0.75i +1.0i
+server:/usr/local/pub  /pub    nfs     rsize=32768,wsize=32768,timeo=14,intr
+.fi
+.P
+Here is an example for an NFSv4 mount over TCP using Kerberos
+5 mutual authentication.
+.sp
+.nf
+.ta 2.5i +0.75i +0.75i +1.0i
+server:/usr/local/pub  /pub    nfs4    proto=tcp,sec=krb5,hard,intr
+.fi
+.DT
+.SS Options for the nfs file system type
+.TP 1.5i
+.I rsize=n
+The number of bytes NFS uses when reading files from an NFS server.
+The rsize is negotiated between the server and client to determine 
+the largest block size that both can support.
+The value specified by this option is the maximum size that could 
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I wsize=n
+The number of bytes NFS uses when writing files to an NFS server.
+The wsize is negotiated between the server and client to determine 
+the largest block size that both can support.
+The value specified by this option is the maximum size that could 
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I timeo=n
+The value in tenths of a second before sending the
+first retransmission after an RPC timeout.
+The default value is 7 tenths of a second.  After the first timeout,
+the timeout is doubled after each successive timeout until a maximum
+timeout of 60 seconds is reached or the enough retransmissions
+have occured to cause a major timeout.  Then, if the filesystem
+is hard mounted, each new timeout cascade restarts at twice the
+initial value of the previous cascade, again doubling at each
+retransmission.  The maximum timeout is always 60 seconds.
+Better overall performance may be achieved by increasing the
+timeout when mounting on a busy network, to a slow server, or through
+several routers or gateways.
+.TP 1.5i
+.I retrans=n
+The number of minor timeouts and retransmissions that must occur before
+a major timeout occurs.  The default is 3 timeouts.  When a major timeout
+occurs, the file operation is either aborted or a "server not responding"
+message is printed on the console.
+.TP 1.5i
+.I acregmin=n
+The minimum time in seconds that attributes of a regular file should
+be cached before requesting fresh information from a server.
+The default is 3 seconds.
+.TP 1.5i
+.I acregmax=n
+The maximum time in seconds that attributes of a regular file can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I acdirmin=n
+The minimum time in seconds that attributes of a directory should
+be cached before requesting fresh information from a server.
+The default is 30 seconds.
+.TP 1.5i
+.I acdirmax=n
+The maximum time in seconds that attributes of a directory can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I actimeo=n
+Using actimeo sets all of
+.I acregmin,
+.I acregmax,
+.I acdirmin,
+and
+.I acdirmax
+to the same value.
+There is no default value.
+.TP 1.5i
+.I retry=n
+The number of minutes to retry an NFS mount operation
+in the foreground or background before giving up.
+The default value for forground mounts is 2 minutes.  
+The default value for background mounts is 10000 minutes, 
+which is roughly one week.
+.TP 1.5i
+.I namlen=n
+When an NFS server does not support version two of the
+RPC mount protocol, this option can be used to specify
+the maximum length of a filename that is supported on
+the remote filesystem.  This is used to support the
+POSIX pathconf functions.  The default is 255 characters.
+.TP 1.5i
+.I port=n
+The numeric value of the port to connect to the NFS server on.
+If the port number is 0 (the default) then query the
+remote host's portmapper for the port number to use.
+If the remote host's NFS daemon is not registered with
+its portmapper, the standard NFS port number 2049 is
+used instead.
+.TP 1.5i
+.I mountport=n
+The numeric value of the
+.B mountd
+port.
+.TP 1.5i
+.I mounthost=name
+The name of the host running
+.B mountd .
+.TP 1.5i
+.I mountprog=n
+Use an alternate RPC program number to contact the
+mount daemon on the remote host.  This option is useful
+for hosts that can run multiple NFS servers.
+The default value is 100005 which is the standard RPC
+mount daemon program number.
+.TP 1.5i
+.I mountvers=n
+Use an alternate RPC version number to contact the
+mount daemon on the remote host.  This option is useful
+for hosts that can run multiple NFS servers.
+The default value depends on which kernel you are using.
+.TP 1.5i
+.I nfsprog=n
+Use an alternate RPC program number to contact the
+NFS daemon on the remote host.  This option is useful
+for hosts that can run multiple NFS servers.
+The default value is 100003 which is the standard RPC
+NFS daemon program number.
+.TP 1.5i
+.I nfsvers=n
+Use an alternate RPC version number to contact the
+NFS daemon on the remote host.  This option is useful
+for hosts that can run multiple NFS servers.
+The default value depends on which kernel you are using.
+.TP 1.5i
+.I vers=n
+vers is an alternative to nfsvers and is compatible with
+many other operating systems.
+.TP 1.5i
+.I nolock
+Disable NFS locking. Do not start lockd.
+This is appropriate for mounting the root filesystem or
+.B /usr
+or
+.BR /var .
+These filesystems are typically either read-only or not shared, and in
+those cases, remote locking is not needed.
+This also needs to be used with some old NFS servers
+that don't support locking.
+.br
+Note that applications can still get locks on files, but the locks
+only provide exclusion locally.  Other clients mounting the same
+filesystem will not be able to detect the locks.
+.TP 1.5i
+.I bg
+If the first NFS mount attempt times out, retry the mount
+in the background.
+After a mount operation is backgrounded, all subsequent mounts
+on the same NFS server will be backgrounded immediately, without
+first attempting the mount.
+A missing mount point is treated as a timeout,
+to allow for nested NFS mounts.
+.TP 1.5i
+.I fg
+If the first NFS mount attempt times out, retry the mount
+in the foreground.
+This is the complement of the
+.I bg
+option, and also the default behavior.
+.TP 1.5i
+.I soft
+If an NFS file operation has a major timeout then report an I/O error to
+the calling program.
+The default is to continue retrying NFS file operations indefinitely.
+.TP 1.5i
+.I hard
+If an NFS file operation has a major timeout then report
+"server not responding" on the console and continue retrying indefinitely.
+This is the default.
+.TP 1.5i
+.I intr
+If an NFS file operation has a major timeout and it is hard mounted,
+then allow signals to interupt the file operation and cause it to
+return EINTR to the calling program.  The default is to not
+allow file operations to be interrupted.
+.TP 1.5i
+.I posix
+Mount the NFS filesystem using POSIX semantics.  This allows
+an NFS filesystem to properly support the POSIX pathconf
+command by querying the mount server for the maximum length
+of a filename.  To do this, the remote host must support version
+two of the RPC mount protocol.  Many NFS servers support only
+version one.
+.TP 1.5i
+.I nocto
+Suppress the retrieval of new attributes when creating a file.
+.TP 1.5i
+.I noac
+Disable all forms of attribute caching entirely.  This extracts a
+significant performance penalty but it allows two different NFS clients
+to get reasonable results when both clients are actively
+writing to a common export on the server.
+.TP 1.5i
+.I noacl
+Disables Access Control List (ACL) processing.
+.TP 1.5i
+.I sec=mode
+Set the security flavor for this mount to "mode".
+The default setting is \f3sec=sys\f1, which uses local
+unix uids and gids to authenticate NFS operations (AUTH_SYS).
+Other currently supported settings are:
+\f3sec=krb5\f1, which uses Kerberos V5 instead of local unix uids
+and gids to authenticate users;
+\f3sec=krb5i\f1, which uses Kerberos V5 for user authentication
+and performs integrity checking of NFS operations using secure
+checksums to prevent data tampering; and
+\f3sec=krb5p\f1, which uses Kerberos V5 for user authentication
+and integrity checking, and encrypts NFS traffic to prevent
+traffic sniffing (this is the most secure setting).
+Note that there is a performance penalty when using integrity
+or privacy.
+.TP 1.5i
+.I tcp
+Mount the NFS filesystem using the TCP protocol.  This is the default
+if it is supported by both client and server.  Many NFS servers only
+support UDP.
+.TP 1.5i
+.I udp
+Mount the NFS filesystem using the UDP protocol.
+.TP 1.5i
+.I nordirplus
+Disables NFSv3 READDIRPLUS RPCs. Use this option when
+mounting servers that don't support or have broken
+READDIRPLUS implementations.
+.P
+All of the non-value options have corresponding nooption forms.
+For example, nointr means don't allow file operations to be
+interrupted.
+.SS Options for the nfs4 file system type
+.TP 1.5i
+.I rsize=n
+The number of bytes nfs4 uses when reading files from the server.
+The rsize is negotiated between the server and client to determine 
+the largest block size that both can support.
+The value specified by this option is the maximum size that could 
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I wsize=n
+The number of bytes nfs4 uses when writing files to the server.
+The wsize is negotiated between the server and client to determine 
+the largest block size that both can support.
+The value specified by this option is the maximum size that could 
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I timeo=n
+The value in tenths of a second before sending the
+first retransmission after an RPC timeout.
+The default value depends on whether
+.IR proto=udp
+or
+.IR proto=tcp
+is in effect (see below).
+The default value for UDP is 7 tenths of a second.
+The default value for TCP is 60 seconds.
+After the first timeout,
+the timeout is doubled after each successive timeout until a maximum
+timeout of 60 seconds is reached or the enough retransmissions
+have occured to cause a major timeout.  Then, if the filesystem
+is hard mounted, each new timeout cascade restarts at twice the
+initial value of the previous cascade, again doubling at each
+retransmission.  The maximum timeout is always 60 seconds.
+.TP 1.5i
+.I retrans=n
+The number of minor timeouts and retransmissions that must occur before
+a major timeout occurs.  The default is 5 timeouts for
+.IR proto=udp
+and 2 timeouts for
+.IR proto=tcp .
+When a major timeout
+occurs, the file operation is either aborted or a "server not responding"
+message is printed on the console.
+.TP 1.5i
+.I acregmin=n
+The minimum time in seconds that attributes of a regular file should
+be cached before requesting fresh information from a server.
+The default is 3 seconds.
+.TP 1.5i
+.I acregmax=n
+The maximum time in seconds that attributes of a regular file can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I acdirmin=n
+The minimum time in seconds that attributes of a directory should
+be cached before requesting fresh information from a server.
+The default is 30 seconds.
+.TP 1.5i
+.I acdirmax=n
+The maximum time in seconds that attributes of a directory can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I actimeo=n
+Using actimeo sets all of
+.I acregmin,
+.I acregmax,
+.I acdirmin,
+and
+.I acdirmax
+to the same value.
+There is no default value.
+.TP 1.5i
+.I retry=n
+The number of minutes to retry an NFS mount operation
+in the foreground or background before giving up.
+The default value for forground mounts is 2 minutes.  
+The default value for background mounts is 10000 minutes, 
+which is roughly one week.
+.TP 1.5i
+.I port=n
+The numeric value of the port to connect to the NFS server on.
+If the port number is 0 (the default) then query the
+remote host's portmapper for the port number to use.
+If the remote host's NFS daemon is not registered with
+its portmapper, the standard NFS port number 2049 is
+used instead.
+.TP 1.5i
+.I proto=n
+Mount the NFS filesystem using a specific network protocol
+instead of the default UDP protocol.
+Many NFS version 4 servers only support TCP.
+Valid protocol types are
+.IR udp
+and
+.IR tcp .
+.TP 1.5i
+.I clientaddr=n
+On a multi-homed client, this
+causes the client to use a specific callback address when
+communicating with an NFS version 4 server.
+This option is currently ignored.
+.TP 1.5i
+.I sec=mode
+Same as \f3sec=mode\f1 for the nfs filesystem type (see above).
+.TP 1.5i
+.I bg
+If an NFS mount attempt times out, retry the mount
+in the background.
+After a mount operation is backgrounded, all subsequent mounts
+on the same NFS server will be backgrounded immediately, without
+first attempting the mount.
+A missing mount point is treated as a timeout,
+to allow for nested NFS mounts.
+.TP 1.5i
+.I fg
+If the first NFS mount attempt times out, retry the mount
+in the foreground.
+This is the complement of the
+.I bg
+option, and also the default behavior.
+.TP 1.5i
+.I soft
+If an NFS file operation has a major timeout then report an I/O error to
+the calling program.
+The default is to continue retrying NFS file operations indefinitely.
+.TP 1.5i
+.I hard
+If an NFS file operation has a major timeout then report
+"server not responding" on the console and continue retrying indefinitely.
+This is the default.
+.TP 1.5i
+.I intr
+If an NFS file operation has a major timeout and it is hard mounted,
+then allow signals to interupt the file operation and cause it to
+return EINTR to the calling program.  The default is to not
+allow file operations to be interrupted.
+.TP 1.5i
+.I nocto
+Suppress the retrieval of new attributes when creating a file.
+.TP 1.5i
+.I noac
+Disable attribute caching, and force synchronous writes.
+This extracts a
+server performance penalty but it allows two different NFS clients
+to get reasonable good results when both clients are actively
+writing to common filesystem on the server.
+.P
+All of the non-value options have corresponding nooption forms.
+For example, nointr means don't allow file operations to be
+interrupted.
+.SH FILES
+.I /etc/fstab
+.SH "SEE ALSO"
+.BR fstab "(5), " mount "(8), " umount "(8), " exports (5)
+.SH AUTHOR
+"Rick Sladkey" <jrs@world.std.com>
+.SH BUGS
+.P
+Checking files on NFS filesystem referenced by file descriptors (i.e. the 
+.BR fcntl 
+and 
+.BR ioctl
+families of functions) may lead to inconsistent result due to the lack of
+consistency check in kernel even if noac is used.
index 717ad56756cad43f8445b73d4064ad65d2929afb..8aa13c6cf76f7655c158ec44b7762f79e257f868 100644 (file)
@@ -50,6 +50,7 @@
 #endif
 
 extern int verbose;
+extern int sloppy;
 
 char *IDMAPLCK = DEFAULT_DIR "/rpcidmapd";
 #define idmapd_check() do { \
@@ -308,7 +309,7 @@ int nfs4mount(const char *spec, const char *node, int *flags,
                                num_flavour = parse_sec(opteq+1, pseudoflavour);
                                if (!num_flavour)
                                        goto fail;
-                       } else if (!strcmp(opt, "addr")) {
+                       } else if (!strcmp(opt, "addr") || sloppy) {
                                /* ignore */;
                        } else {
                                printf(_("unknown nfs mount parameter: "
@@ -335,7 +336,7 @@ int nfs4mount(const char *spec, const char *node, int *flags,
                                nocto = !val;
                        else if (!strcmp(opt, "ac"))
                                noac = !val;
-                       else {
+                       else if (!sloppy) {
                                printf(_("unknown nfs mount option: "
                                         "%s%s\n"), val ? "" : "no", opt);
                                goto fail;
index 1fd74c870d75134c55fbb2b38c2d44091d675f46..4a061d834f4f20081bd7447d0948e22bcfcbe440 100644 (file)
@@ -63,6 +63,7 @@ struct nfs_mount_data {
 #define NFS_MOUNT_BROKEN_SUID  0x0400  /* 4 */
 #define NFS_MOUNT_NOACL     0x0800  /* 4 */
 #define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 */
+#define NFS_MOUNT_NORDIRPLUS   0x4000  /* 5 */
 
 /* security pseudoflavors */
 
@@ -78,7 +79,8 @@ struct nfs_mount_data {
 #define AUTH_GSS_SPKMP         390011
 #endif
 
-int nfsmount(const char *, const char *, int *, char **, char **, int *, int);
+int nfsmount(const char *, const char *, int *, char **, char **,
+            int, int *);
 void mount_errors(char *, int, int);
 
 #endif /* _NFS_MOUNT_H */
index 507ccdb39902b50dc080eab1b27fe2613e4a7399..815064a593e4ad917fe18a09124e6d0ee7e53c62 100644 (file)
@@ -104,6 +104,7 @@ typedef union {
 static char errbuf[BUFSIZ];
 static char *erreob = &errbuf[BUFSIZ];
 extern int verbose;
+extern int sloppy;
 
 /* Convert RPC errors into strings */
 int rpc_strerror(int);
@@ -292,21 +293,21 @@ int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
  * instead of reserve ports since reserve ports
  * are not needed for pmap requests.
  */
-static u_short
+u_short
 getport(
        struct sockaddr_in *saddr, 
        u_long prog, 
        u_long vers, 
        u_int prot)
 {
-       u_short port;
+       u_short port = 0;
        int    socket;
        CLIENT *clnt = NULL;
        struct pmap parms;
        enum clnt_stat stat;
 
        saddr->sin_port = htons (PMAPPORT);
-       socket = get_socket(saddr, prot, FALSE);
+       socket = get_socket(saddr, prot, FALSE, FALSE);
 
        switch (prot) {
        case IPPROTO_UDP:
@@ -547,15 +548,31 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
        struct pmap *mnt_pmap = &mnt_server->pmap;
        struct pmap *nfs_pmap = &nfs_server->pmap;
        int len;
-       char *opt, *opteq;
+       char *opt, *opteq, *p, *opt_b;
        char *mounthost = NULL;
        char cbuf[128];
+       int open_quote = 0;
 
        data->flags = 0;
        *bg = 0;
 
        len = strlen(new_opts);
-       for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
+       for (p=old_opts, opt_b=NULL; p && *p; p++) {
+               if (!opt_b)
+                       opt_b = p;              /* begin of the option item */
+               if (*p == '"')
+                       open_quote ^= 1;        /* reverse the status */
+               if (open_quote)
+                       continue;               /* still in a quoted block */
+               if (*p == ',')
+                       *p = '\0';              /* terminate the option item */
+               if (*p == '\0' || *(p+1) == '\0') {
+                       opt = opt_b;            /* opt is useful now */
+                       opt_b = NULL;
+               }
+               else
+                       continue;               /* still somewhere in the option item */
+
                if (strlen(opt) >= sizeof(cbuf))
                        goto bad_parameter;
                if ((opteq = strchr(opt, '=')) && isdigit(opteq[1])) {
@@ -606,13 +623,17 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "namlen")) {
                                if (nfs_mount_version >= 2)
                                        data->namlen = val;
+                               else if (sloppy)
+                                       continue;
                                else
                                        goto bad_parameter;
 #endif
                        } else if (!strcmp(opt, "addr")) {
                                /* ignore */;
                                continue;
-                       } else
+                       } else if (sloppy)
+                               continue;
+                       else
                                goto bad_parameter;
                        sprintf(cbuf, "%s=%s,", opt, opteq+1);
                } else if (opteq) {
@@ -629,7 +650,9 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
                                        data->flags |= NFS_MOUNT_TCP;
 #endif
-                               } else
+                               } else if (sloppy)
+                                       continue;
+                               else
                                        goto bad_parameter;
 #if NFS_MOUNT_VERSION >= 5
                        } else if (!strcmp(opt, "sec")) {
@@ -638,7 +661,9 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                if (nfs_mount_version < 5) {
                                        printf(_("Warning: ignoring sec=%s option\n"), secflavor);
                                        continue;
-                               } else if (!strcmp(secflavor, "sys"))
+                               } else if (!strcmp(secflavor, "none"))
+                                       data->pseudoflavor = AUTH_NONE;
+                               else if (!strcmp(secflavor, "sys"))
                                        data->pseudoflavor = AUTH_SYS;
                                else if (!strcmp(secflavor, "krb5"))
                                        data->pseudoflavor = AUTH_GSS_KRB5;
@@ -658,6 +683,8 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                        data->pseudoflavor = AUTH_GSS_SPKMI;
                                else if (!strcmp(secflavor, "spkm3p"))
                                        data->pseudoflavor = AUTH_GSS_SPKMP;
+                               else if (sloppy)
+                                       continue;
                                else {
                                        printf(_("Warning: Unrecognized security flavor %s.\n"),
                                                secflavor);
@@ -669,15 +696,27 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                mounthost=xstrndup(opteq+1,
                                                   strcspn(opteq+1," \t\n\r,"));
                         else if (!strcmp(opt, "context")) {
-                               char *context = opteq + 1;
-                               
-                               if (strlen(context) > NFS_MAX_CONTEXT_LEN) {
-                                       printf(_("context parameter exceeds limit of %d\n"),
-                                                NFS_MAX_CONTEXT_LEN);
+                               char *context = opteq + 1;
+                               int ctxlen = strlen(context);
+
+                               if (ctxlen > NFS_MAX_CONTEXT_LEN) {
+                                       printf(_("context parameter exceeds limit of %d\n"),
+                                                NFS_MAX_CONTEXT_LEN);
                                        goto bad_parameter;
-                               }
-                               strncpy(data->context, context, NFS_MAX_CONTEXT_LEN);
-                       } else
+                               }
+                               /* The context string is in the format of
+                                * "system_u:object_r:...".  We only want
+                                * the context str between the quotes.
+                                */
+                               if (*context == '"')
+                                       strncpy(data->context, context+1,
+                                                       ctxlen-2);
+                               else
+                                       strncpy(data->context, context,
+                                                       NFS_MAX_CONTEXT_LEN);
+                       } else if (sloppy)
+                               continue;
+                       else
                                goto bad_parameter;
                        sprintf(cbuf, "%s=%s,", opt, opteq+1);
                } else {
@@ -761,9 +800,15 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                data->flags &= ~NFS_MOUNT_NOACL;
                                if (!val)
                                        data->flags |= NFS_MOUNT_NOACL;
+                       } else if (!strcmp(opt, "rdirplus")) {
+                               data->flags &= ~NFS_MOUNT_NORDIRPLUS;
+                               if (!val)
+                                       data->flags |= NFS_MOUNT_NORDIRPLUS;
 #endif
                        } else {
                        bad_option:
+                               if (sloppy)
+                                       continue;
                                printf(_("Unsupported nfs mount option: "
                                         "%s%s\n"), val ? "" : "no", opt);
                                goto out_bad;
@@ -815,8 +860,8 @@ nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
 
 int
 nfsmount(const char *spec, const char *node, int *flags,
-        char **extra_opts, char **mount_opts, int *nfs_mount_vers,
-        int running_bg)
+        char **extra_opts, char **mount_opts,
+        int running_bg, int *need_statd)
 {
        static char *prev_bg_host;
        char hostdir[1024];
@@ -833,26 +878,20 @@ nfsmount(const char *spec, const char *node, int *flags,
                     *nfs_pmap = &nfs_server.pmap;
        struct pmap  save_mnt, save_nfs;
 
-       int fsock;
+       int fsock = -1;
 
        mntres_t mntres;
 
        struct stat statbuf;
        char *s;
        int bg, retry;
-       int retval;
+       int retval = EX_FAIL;
        time_t t;
        time_t prevt;
        time_t timeout;
 
-       /* The version to try is either specified or 0
-          In case it is 0 we tell the caller what we tried */
-       if (!*nfs_mount_vers)
-               *nfs_mount_vers = find_kernel_nfs_mount_version();
-       nfs_mount_version = *nfs_mount_vers;
+       nfs_mount_version = find_kernel_nfs_mount_version();
 
-       retval = EX_FAIL;
-       fsock = -1;
        if (strlen(spec) >= sizeof(hostdir)) {
                fprintf(stderr, _("mount: "
                                  "excessively long host:dir argument\n"));
@@ -902,7 +941,6 @@ nfsmount(const char *spec, const char *node, int *flags,
 #if NFS_MOUNT_VERSION >= 2
        data.namlen     = NAME_MAX;
 #endif
-       data.pseudoflavor = AUTH_SYS;
 
        bg = 0;
        retry = 10000;          /* 10000 minutes ~ 1 week */
@@ -949,6 +987,7 @@ nfsmount(const char *spec, const char *node, int *flags,
 #endif
 #if NFS_MOUNT_VERSION >= 5
        printf("sec = %u ", data.pseudoflavor);
+       printf("readdirplus = %d ", (data.flags & NFS_MOUNT_NORDIRPLUS) != 0);
 #endif
        printf("\n");
 #endif
@@ -1090,6 +1129,15 @@ nfsmount(const char *spec, const char *node, int *flags,
 
                flavor = mountres->auth_flavors.auth_flavors_val;
                while (--i >= 0) {
+                       /* If no flavour requested, use first simple
+                        * flavour that is offered.
+                        */
+                       if (! (data.flags & NFS_MOUNT_SECFLAVOUR) &&
+                           (flavor[i] == AUTH_SYS ||
+                            flavor[i] == AUTH_NONE)) {
+                               data.pseudoflavor = flavor[i];
+                               data.flags |= NFS_MOUNT_SECFLAVOUR;
+                       }
                        if (flavor[i] == data.pseudoflavor)
                                yum = 1;
 #ifdef NFS_MOUNT_DEBUG
@@ -1102,7 +1150,7 @@ nfsmount(const char *spec, const char *node, int *flags,
                                "mount: %s:%s failed, "
                                "security flavor not supported\n",
                                hostname, dirname);
-                       /* server has registered us in mtab, send umount */
+                       /* server has registered us in rmtab, send umount */
                        nfs_call_umount(&mnt_server, &dirname);
                        goto fail;
                }
@@ -1120,20 +1168,22 @@ noauth_flavors:
 #endif
        }
 
-       /* create nfs socket for kernel */
-
-       if (nfs_pmap->pm_prot == IPPROTO_TCP)
-               fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       else
-               fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       if (fsock < 0) {
-               perror(_("nfs socket"));
-               goto fail;
-       }
-       if (bindresvport(fsock, 0) < 0) {
-               perror(_("nfs bindresvport"));
-               goto fail;
+       if (nfs_mount_version == 1) {
+               /* create nfs socket for kernel */
+               if (nfs_pmap->pm_prot == IPPROTO_TCP)
+                       fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+               else
+                       fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+               if (fsock < 0) {
+                       perror(_("nfs socket"));
+                       goto fail;
+               }
+               if (bindresvport(fsock, 0) < 0) {
+                       perror(_("nfs bindresvport"));
+                       goto fail;
+               }
        }
+
 #ifdef NFS_MOUNT_DEBUG
        printf(_("using port %d for nfs deamon\n"), nfs_pmap->pm_port);
 #endif
@@ -1143,7 +1193,7 @@ noauth_flavors:
         * to avoid problems with multihomed hosts.
         * --Swen
         */
-       if (linux_version_code() <= 66314
+       if (linux_version_code() <= 0x01030a && fsock != -1
            && connect(fsock, (struct sockaddr *) nfs_saddr,
                       sizeof (*nfs_saddr)) < 0) {
                perror(_("nfs connect"));
@@ -1175,6 +1225,7 @@ noauth_flavors:
        strcat(new_opts, cbuf);
 
        *extra_opts = xstrdup(new_opts);
+       *need_statd = ! (data.flags & NFS_MOUNT_NONLM);
        return 0;
 
        /* abort */
index 28f42448105d20efcf18a00ab77e330ccc256851..b9737be23d355b86fd40a66d64adc22542755215 100644 (file)
  *
  */
 
+#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
 #include <getopt.h>
 #include <mntent.h>
 #include <sys/mount.h>
 #include <ctype.h>
+#include <pwd.h>
 
 #include "xcommon.h"
 #include "fstab.h"
@@ -55,24 +57,11 @@ extern int probe_mntport(clnt_addr_t *);
 extern int nfs_gethostbyname(const char *, struct sockaddr_in *);
 
 static inline enum clnt_stat
-nfs3_umount(dirpath *argp, CLIENT *clnt)
+nfs_umount(dirpath *argp, CLIENT *clnt)
 {
-       static char clnt_res;
-       memset (&clnt_res, 0, sizeof(clnt_res));
        return clnt_call(clnt, MOUNTPROC_UMNT,
                         (xdrproc_t) xdr_dirpath, (caddr_t)argp,
-                        (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
-                        TIMEOUT);
-}
-
-static inline enum clnt_stat
-nfs2_umount(dirpath *argp, CLIENT *clnt)
-{
-       static char clnt_res;
-       memset (&clnt_res, 0, sizeof(clnt_res));
-       return clnt_call(clnt, MOUNTPROC_UMNT,
-                        (xdrproc_t) xdr_dirpath, (caddr_t)argp,
-                        (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+                        (xdrproc_t) xdr_void, NULL,
                         TIMEOUT);
 }
 
@@ -82,54 +71,26 @@ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
        enum clnt_stat res = 0;
        int msock;
 
-       clnt = mnt_openclnt(mnt_server, &msock);
-       if (!clnt)
-               goto out_bad;
        switch (mnt_server->pmap.pm_vers) {
        case 3:
-               res = nfs3_umount(argp, clnt);
-               break;
        case 2:
        case 1:
-               res = nfs2_umount(argp, clnt);
+               if (!probe_mntport(mnt_server))
+                       goto out_bad;
+               clnt = mnt_openclnt(mnt_server, &msock);
+               if (!clnt)
+                       goto out_bad;
+               res = nfs_umount(argp, clnt);
+               mnt_closeclnt(clnt, msock);
+               if (res == RPC_SUCCESS)
+                       return 1;
                break;
        default:
+               res = 1;
                break;
        }
-       mnt_closeclnt(clnt, msock);
-       if (res == RPC_SUCCESS)
-               return 1;
  out_bad:
-       return 0;
-}
-
-u_int get_mntproto(const char *);
-u_int
-get_mntproto(const char *dirname)
-{
-       FILE *mtab;
-       struct mntent mntbuf;
-       char tmpbuf[BUFSIZ];
-       u_int proto = IPPROTO_TCP; /* assume tcp */
-
-        mtab = setmntent ("/proc/mounts", "r");
-        if (mtab == NULL)
-               mtab = setmntent (_PATH_MOUNTED, "r");
-       if (mtab == NULL)
-               return proto;
-
-       while(getmntent_r(mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) {
-               if (strcmp(mntbuf.mnt_type, "nfs"))
-                       continue;
-               if (strcmp(dirname,  mntbuf.mnt_fsname))
-                       continue;
-               if (hasmntopt(&mntbuf, "udp"))
-                       proto = IPPROTO_UDP;
-               break;
-       }
-       endmntent (mtab);
-
-       return proto;
+       return res;
 }
 
 /* complain about a failed umount */
@@ -156,12 +117,11 @@ static void complain(int err, const char *dev) {
   }
 }
 
-int add_mtab2(const char *spec, const char *node, const char *type,
-               const char *opts, struct mntentchn *mc)
+int del_mtab(const char *spec, const char *node)
 {
-       int umnt_err, umnt_err2, res;
+       int umnt_err, res;
 
-        umnt_err = umnt_err2 = 0;
+        umnt_err = 0;
         if (lazy) {
                 res = umount2 (node, MNT_DETACH);
                 if (res < 0)
@@ -184,32 +144,12 @@ int add_mtab2(const char *spec, const char *node, const char *type,
         } else
                 res = umount (node);
 
-        if (res < 0) {
-                umnt_err = errno;
-                /* A device might have been mounted on a node that has since
-                   been deleted or renamed, so if node fails, also try spec. */
-                /* Note that this is incorrect in case spec was mounted
-                   several times. */
-                /* if (umnt_err == ENOENT || umnt_err == EINVAL) */
-                if (umnt_err != EBUSY && strcmp(node, spec)) {
-                        if (verbose)
-                                printf (_("could not umount %s - trying %s instead\n"),
-                                        node, spec);
-                        res = umount (spec);
-                        if (res < 0)
-                                umnt_err2 = errno;
-                       /* Do not complain about remote NFS mount points */
-                        if (errno == ENOENT && index(spec, ':'))
-                                umnt_err2 = 0;
-                }
-        }
-
-        if (res < 0 && remount && (umnt_err == EBUSY || umnt_err2 == EBUSY)) {
+        if (res < 0 && remount && errno == EBUSY && spec) {
                 /* Umount failed - let us try a remount */
                 res = mount(spec, node, NULL,
                             MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
                 if (res == 0) {
-                        nfs_mntent_t remnt;
+                        struct mntent remnt;
                         fprintf(stderr,
                                 _("umount: %s busy - remounted read-only\n"),
                                 spec);
@@ -230,21 +170,19 @@ int add_mtab2(const char *spec, const char *node, const char *type,
         if (res >= 0) {
                 /* Umount succeeded */
                 if (verbose)
-                        printf (_("%s umounted\n"), spec);
+                        printf (_("%s umounted\n"), spec ? spec : node);
         }
 
  writemtab:
         if (!nomtab &&
             (umnt_err == 0 || umnt_err == EINVAL || umnt_err == ENOENT)) {
-               update_mtab (node, NULL);
+               update_mtab(node, NULL);
         }
 
         if (res >= 0)
                 return 0;
 
-        if (umnt_err2)
-                complain(umnt_err2, spec);
-        if (umnt_err && umnt_err != umnt_err2)
+        if (umnt_err)
                 complain(umnt_err, node);
         return 1;
 }
@@ -252,11 +190,12 @@ int add_mtab2(const char *spec, const char *node, const char *type,
 /*
  * Returns 1 if everything went well, else 0.
  */
-int _nfsumount(const char *spec, const char *opts)
+int _nfsumount(const char *spec, char *opts)
 {
        char *hostname;
        char *dirname;
        clnt_addr_t mnt_server = { &hostname, };
+       struct mntent mnt = { .mnt_opts = opts };
        struct pmap *pmap = &mnt_server.pmap;
        char *p;
 
@@ -290,24 +229,30 @@ int _nfsumount(const char *spec, const char *opts)
        }
 
        pmap->pm_prog = MOUNTPROG;
-       pmap->pm_vers = MOUNTVERS;
-       pmap->pm_prot = get_mntproto(spec);
+       pmap->pm_vers = MOUNTVERS_NFSV3;
+       pmap->pm_prot = IPPROTO_TCP;
        if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10)))
                pmap->pm_prog = atoi(p+10);
        if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
                pmap->pm_port = atoi(p+10);
-       if (opts && (p = strstr(opts, "nfsvers=")) && isdigit(*(p+8)))
-               pmap->pm_vers = nfsvers_to_mnt(atoi(p+8));
+       if (opts && hasmntopt(&mnt, "v2"))
+               pmap->pm_vers = nfsvers_to_mnt(2);
+       if (opts && hasmntopt(&mnt, "v3"))
+               pmap->pm_vers = nfsvers_to_mnt(3);
+       if (opts && hasmntopt(&mnt, "v4"))
+               pmap->pm_vers = nfsvers_to_mnt(4);
+       if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5)))
+               pmap->pm_vers = nfsvers_to_mnt(atoi(p+5));
        if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10)))
                pmap->pm_vers = atoi(p+10);
+       if (opts && (hasmntopt(&mnt, "udp") || hasmntopt(&mnt, "proto=udp")))
+               pmap->pm_prot = IPPROTO_UDP;
 
        if (!nfs_gethostbyname(hostname, &mnt_server.saddr))
                goto out_bad;
-       if (!probe_mntport(&mnt_server))
-               goto out_bad;
        return nfs_call_umount(&mnt_server, &dirname);
  out_bad:
-       printf("%s: %s: not found or not mounted\n", progname, spec);
+       fprintf(stderr, "%s: %s: not found or not mounted\n", progname, spec);
        return 0;
 }
 
@@ -343,6 +288,7 @@ int nfsumount(int argc, char *argv[])
        argv += 1;
        argc -= 1;
 
+       argv[0] = argv[-1]; /* So that getopt error messages are correct */
        while ((c = getopt_long (argc, argv, "fvnrlh",
                                umount_longopts, NULL)) != -1) {
 
@@ -368,25 +314,75 @@ int nfsumount(int argc, char *argv[])
                        return 0;
                }
        }
+       if (optind != argc) {
+               umount_usage();
+               return 0;
+       }
+       
+       if (spec == NULL || (*spec != '/' && strchr(spec,':') == NULL)) {
+               printf(_("umount: %s: not found\n"), spec);
+               return 0;
+       }
 
-       mc = getmntdirbackward(spec, NULL);
-       if (!mc)
+       if (*spec == '/')
+               mc = getmntdirbackward(spec, NULL);
+       else
                mc = getmntdevbackward(spec, NULL);
        if (!mc && verbose)
                printf(_("Could not find %s in mtab\n"), spec);
 
-       if(mc) {
-               ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
-               if(ret)
-                       ret = add_mtab2(mc->m.mnt_fsname, mc->m.mnt_dir,
-                               mc->m.mnt_type, mc->m.mnt_opts, mc);
+       if (mc && strcmp(mc->m.mnt_type, "nfs") != 0 &&
+           strcmp(mc->m.mnt_type, "nfs4") != 0) {
+               fprintf(stderr, "umount.nfs: %s on %s it not an nfs filesystem\n",
+                       mc->m.mnt_fsname, mc->m.mnt_dir);
+               exit(1);
        }
-       else {
-               ret = _nfsumount(spec, NULL);
-               if(ret)
-                       ret = add_mtab2(spec, spec, spec, spec, NULL);
+
+       if (getuid() != 0) {
+               /* only permitted if "user=" or "users" is in mount options */
+               if (!mc) {
+                       /* umount might call us twice.  The second time there will
+                        * be no entry in mtab and we should just exit quietly
+                        */
+                       return 0;
+
+               only_root:
+                       fprintf(stderr,"%s: You are not permitted to unmount %s\n",
+                               progname, spec);
+                       return 0;
+               }
+               if (hasmntopt(&mc->m, "users") == NULL) {
+                       char *opt = hasmntopt(&mc->m, "user");
+                       struct passwd *pw;
+                       char *comma;
+                       int len;
+                       if (!opt)
+                               goto only_root;
+                       if (opt[4] != '=')
+                               goto only_root;
+                       comma = strchr(opt, ',');
+                       if (comma)
+                               len = comma - (opt + 5);
+                       else
+                               len = strlen(opt+5);
+                       pw = getpwuid(getuid());
+                       if (pw == NULL || strlen(pw->pw_name) != len
+                           || strncmp(pw->pw_name, opt+5, len) != 0)
+                               goto only_root;
+               }
        }
 
+       ret = 0;
+       if (mc) {
+               if (!lazy)
+                       _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
+               ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
+       } else if (*spec != '/') {
+               if (!lazy)
+                       _nfsumount(spec, "tcp,v3");
+       } else
+               ret = del_mtab(NULL, spec);
+
        return(ret);
 }
 
index b6047ee44d58dfd38e3a74d87764d55106fd4913..29cd8c6c0c7a9b7db9756715a070cb039567b397 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -159,6 +159,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -218,6 +219,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index fbe829e2d3fc188fbe686fc78a820199b5951ac3..85e89753c760b81044a2b5b9d535ba3c7d467d6c 100644 (file)
@@ -23,6 +23,7 @@
 #include <ctype.h>
 #include <pwd.h>
 #include <grp.h>
+#include <mntent.h>
 #include "misc.h"
 #include "nfslib.h"
 #include "exportfs.h"
@@ -30,7 +31,9 @@
 #include "xmalloc.h"
 #include "fsloc.h"
 
+#ifdef USE_BLKID
 #include "blkid/blkid.h"
+#endif
 
 
 enum nfsd_fsid {
@@ -52,7 +55,7 @@ enum nfsd_fsid {
  * Record is terminated with newline.
  *
  */
-int cache_export_ent(char *domain, struct exportent *exp);
+int cache_export_ent(char *domain, struct exportent *exp, char *p);
 
 
 char *lbuf  = NULL;
@@ -151,6 +154,7 @@ void auth_unix_gid(FILE *f)
                free(groups);
 }
 
+#if USE_BLKID
 int get_uuid(char *path, char *uuid, int uuidlen, char *u)
 {
        /* extract hex digits from uuidstr and compose a uuid
@@ -215,7 +219,32 @@ int get_uuid(char *path, char *uuid, int uuidlen, char *u)
        }
        return 1;
 }
-       
+#endif
+
+/* Iterate through /etc/mtab, finding mountpoints
+ * at or below a given path
+ */
+static char *next_mnt(void **v, char *p)
+{
+       FILE *f;
+       struct mntent *me;
+       int l = strlen(p);
+       if (*v == NULL) {
+               f = setmntent("/etc/mtab", "r");
+               *v = f;
+       } else
+               f = *v;
+       while ((me = getmntent(f)) != NULL &&
+              (strncmp(me->mnt_dir, p, l) != 0 ||
+               me->mnt_dir[l] != '/'))
+               ;
+       if (me == NULL) {
+               endmntent(f);
+               *v = NULL;
+               return NULL;
+       }
+       return me->mnt_dir;
+}
 
 void nfsd_fh(FILE *f)
 {
@@ -234,6 +263,7 @@ void nfsd_fh(FILE *f)
        unsigned int fsidnum=0;
        char fsid[32];
        struct exportent *found = NULL;
+       char *found_path = NULL;
        nfs_export *exp;
        int i;
        int dev_missing = 0;
@@ -328,9 +358,35 @@ void nfsd_fh(FILE *f)
 
        /* Now determine export point for this fsid/domain */
        for (i=0 ; i < MCL_MAXTYPES; i++) {
-               for (exp = exportlist[i]; exp; exp = exp->m_next) {
+               nfs_export *next_exp;
+               for (exp = exportlist[i]; exp; exp = next_exp) {
                        struct stat stb;
-                       char u[16];                     
+                       char u[16];
+                       char *path;
+
+                       if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
+                               static nfs_export *prev = NULL;
+                               static void *mnt = NULL;
+                               
+                               if (prev == exp) {
+                                       /* try a submount */
+                                       path = next_mnt(&mnt, exp->m_export.e_path);
+                                       if (!path) {
+                                               next_exp = exp->m_next;
+                                               prev = NULL;
+                                               continue;
+                                       }
+                                       next_exp = exp;
+                               } else {
+                                       prev = exp;
+                                       mnt = NULL;
+                                       path = exp->m_export.e_path;
+                                       next_exp = exp;
+                               }
+                       } else {
+                               path = exp->m_export.e_path;
+                               next_exp = exp->m_next;
+                       }
 
                        if (!client_member(dom, exp->m_client->m_hostname))
                                continue;
@@ -339,7 +395,7 @@ void nfsd_fh(FILE *f)
                                           exp->m_export.e_mountpoint:
                                           exp->m_export.e_path))
                                dev_missing ++;
-                       if (stat(exp->m_export.e_path, &stb) != 0)
+                       if (stat(path, &stb) != 0)
                                continue;
                        switch(fsidtype){
                        case FSID_DEV:
@@ -363,27 +419,32 @@ void nfsd_fh(FILE *f)
                                goto check_uuid;
                        case FSID_UUID8:
                        case FSID_UUID16:
-                               if (!is_mountpoint(exp->m_export.e_path))
+                               if (!is_mountpoint(path))
                                        continue;
                        check_uuid:
+#if USE_BLKID
                                if (exp->m_export.e_uuid)
                                        get_uuid(NULL, exp->m_export.e_uuid,
                                                 uuidlen, u);
-                               else if (get_uuid(exp->m_export.e_path, NULL,
+                               else if (get_uuid(path, NULL,
                                                  uuidlen, u) == 0)
                                        continue;
 
                                if (memcmp(u, fhuuid, uuidlen) != 0)
                                        continue;
                                break;
+#else
+                               continue;
+#endif
                        }
                        /* It's a match !! */
-                       if (!found)
+                       if (!found) {
                                found = &exp->m_export;
-                       else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
+                               found_path = strdup(path);
+                       } else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
                        {
                                xlog(L_WARNING, "%s and %s have same filehandle for %s, using first",
-                                    found->e_path, exp->m_export.e_path, dom);
+                                    found_path, path, dom);
                        }
                }
        }
@@ -408,12 +469,21 @@ void nfsd_fh(FILE *f)
        }
 
        if (found)
-               cache_export_ent(dom, found);
+               if (cache_export_ent(dom, found, found_path) < 0)
+                       found = 0;
 
        qword_print(f, dom);
        qword_printint(f, fsidtype);
        qword_printhex(f, fsid, fsidlen);
-       qword_printint(f, time(0)+30*60);
+       /* The fsid -> path lookup can be quite expensive as it
+        * potentially stats and reads lots of devices, and some of those
+        * might have spun-down.  The Answer is not likely to
+        * change underneath us, and an 'exportfs -f' can always
+        * remove this from the kernel, so use a really log
+        * timeout.  Maybe this should be configurable on the command
+        * line.
+        */
+       qword_printint(f, 0x7fffffff);
        if (found)
                qword_print(f, found->e_path);
        qword_eol(f);
@@ -456,9 +526,10 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
                qword_printint(f, exp->e_anongid);
                qword_printint(f, exp->e_fsid);
                write_fsloc(f, exp, path);
+#if USE_BLKID
                if (exp->e_uuid == NULL) {
                        char u[16];
-                       if (get_uuid(exp->e_path, NULL, 16, u)) {
+                       if (get_uuid(path, NULL, 16, u)) {
                                qword_print(f, "uuid");
                                qword_printhex(f, u, 16);
                        }
@@ -466,6 +537,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
                        qword_print(f, "uuid");
                        qword_printhex(f, exp->e_uuid, 16);
                }
+#endif
        }
        return qword_eol(f);
 }
@@ -482,6 +554,7 @@ void nfsd_export(FILE *f)
        int i;
        char *dom, *path;
        nfs_export *exp, *found = NULL;
+       int found_type = 0;
 
 
        if (readline(fileno(f), &lbuf, &lbuflen) != 1)
@@ -506,21 +579,51 @@ void nfsd_export(FILE *f)
                for (exp = exportlist[i]; exp; exp = exp->m_next) {
                        if (!client_member(dom, exp->m_client->m_hostname))
                                continue;
-                       if (strcmp(path, exp->m_export.e_path))
+                       if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
+                               /* if path is a mountpoint below e_path, then OK */
+                               int l = strlen(exp->m_export.e_path);
+                               if (strcmp(path, exp->m_export.e_path) == 0 ||
+                                   (strncmp(path, exp->m_export.e_path, l) == 0 &&
+                                    path[l] == '/' &&
+                                    is_mountpoint(path)))
+                                       /* ok */;
+                               else
+                                       continue;
+                       } else if (strcmp(path, exp->m_export.e_path) != 0)
                                continue;
-                       if (!found)
+                       if (!found) {
                                found = exp;
-                       else {
-                               xlog(L_WARNING, "%s exported to both %s and %s in %s",
-                                    path, exp->m_client->m_hostname, found->m_client->m_hostname,
+                               found_type = i;
+                               continue;
+                       }
+                       /* If one is a CROSSMOUNT, then prefer the longest path */
+                       if (((found->m_export.e_flags & NFSEXP_CROSSMOUNT) ||
+                            (found->m_export.e_flags & NFSEXP_CROSSMOUNT)) &&
+                           strlen(found->m_export.e_path) !=
+                           strlen(found->m_export.e_path)) {
+
+                               if (strlen(exp->m_export.e_path) >
+                                   strlen(found->m_export.e_path)) {
+                                       found = exp;
+                                       found_type = i;
+                               }
+                               continue;
+
+                       } else if (found_type == i && found->m_warned == 0) {
+                               xlog(L_WARNING, "%s exported to both %s and %s, "
+                                    "arbitrarily choosing options from first",
+                                    path, found->m_client->m_hostname, exp->m_client->m_hostname,
                                     dom);
+                               found->m_warned = 1;
                        }
                }
        }
 
        if (found) {
-               dump_to_cache(f, dom, path, &found->m_export);
-               mountlist_add(dom, path);
+               if (dump_to_cache(f, dom, path, &found->m_export) < 0)
+                       dump_to_cache(f, dom, path, NULL);
+               else
+                       mountlist_add(dom, path);
        } else {
                dump_to_cache(f, dom, path, NULL);
        }
@@ -586,7 +689,7 @@ int cache_process_req(fd_set *readfds)
  * % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
  */
 
-int cache_export_ent(char *domain, struct exportent *exp)
+int cache_export_ent(char *domain, struct exportent *exp, char *path)
 {
        int err;
        FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
@@ -594,22 +697,56 @@ int cache_export_ent(char *domain, struct exportent *exp)
                return -1;
 
        err = dump_to_cache(f, domain, exp->e_path, exp);
-       fclose(f);
        mountlist_add(domain, exp->e_path);
+
+       while ((exp->e_flags & NFSEXP_CROSSMOUNT) && path) {
+               /* really an 'if', but we can break out of
+                * a 'while' more easily */
+               /* Look along 'path' for other filesystems
+                * and export them with the same options
+                */
+               struct stat stb;
+               int l = strlen(exp->e_path);
+               int dev;
+
+               if (strlen(path) <= l || path[l] != '/' ||
+                   strncmp(exp->e_path, path, l) != 0)
+                       break;
+               if (stat(exp->e_path, &stb) != 0)
+                       break;
+               dev = stb.st_dev;
+               while(path[l] == '/') {
+                       char c;
+                       int err;
+
+                       l++;
+                       while (path[l] != '/' && path[l])
+                               l++;
+                       c = path[l];
+                       path[l] = 0;
+                       err = lstat(path, &stb);
+                       path[l] = c;
+                       if (err < 0)
+                               break;
+                       if (stb.st_dev == dev)
+                               continue;
+                       dev = stb.st_dev;
+                       path[l] = 0;
+                       dump_to_cache(f, domain, path, exp);
+                       path[l] = c;
+               }
+               break;
+       }
+
+       fclose(f);
        return err;
 }
 
-int cache_export(nfs_export *exp)
+int cache_export(nfs_export *exp, char *path)
 {
        int err;
        FILE *f;
 
-       if (exp->m_export.e_maptype != CLE_MAP_IDENT) {
-               xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)",
-                   exp->m_export.m_path);
-               return -1;
-       }
-
        f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
        if (!f)
                return -1;
@@ -622,7 +759,7 @@ int cache_export(nfs_export *exp)
        
        fclose(f);
 
-       err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export)
+       err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path)
                || err;
        return err;
 }
index fc9a73cd07a4f8aaa44288900fb3e68f33fd2b71..04141d153a676b70e9e789f1a5369c93b7ab0625 100644 (file)
@@ -29,7 +29,7 @@
 
 extern void    cache_open(void);
 extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p);
-extern int cache_export(nfs_export *exp);
+extern int cache_export(nfs_export *exp, char *path);
 
 extern void my_svc_run(void);
 
@@ -399,7 +399,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3)
                     p, strerror(errno));
                *error = NFSERR_NOENT;
        } else if (estb.st_dev != stb.st_dev
-                  /* && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) */
+                  && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))
                ) {
                xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
                     p, exp->m_export.e_path);
@@ -418,7 +418,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3)
                 */
                struct nfs_fh_len  *fh;
 
-               if (cache_export(exp)) {
+               if (cache_export(exp, p)) {
                        *error = NFSERR_ACCES;
                        return NULL;
                }
index 7a8a595e2a60b7df657090fb0cd09918b736349e..422e839c171176638e66c32b53fa2af8a63f3886 100644 (file)
 void cache_set_fds(fd_set *fdset);
 int cache_process_req(fd_set *readfds);
 
+#if LONG_MAX != INT_MAX        
+/* bug in glibc 2.3.6 and earlier, we need
+ * our own svc_getreqset
+ */
+static void
+my_svc_getreqset (fd_set *readfds)
+{
+       fd_mask mask;
+       fd_mask *maskp;
+       int setsize;
+       int sock;
+       int bit;
+
+       setsize = _rpc_dtablesize ();
+       if (setsize > FD_SETSIZE)
+               setsize = FD_SETSIZE;
+       maskp = readfds->fds_bits;
+       for (sock = 0; sock < setsize; sock += NFDBITS)
+               for (mask = *maskp++;
+                    (bit = ffsl (mask));
+                    mask ^= (1L << (bit - 1)))
+                       svc_getreq_common (sock + bit - 1);
+}
+#define svc_getreqset my_svc_getreqset
+
+#endif
 
 /*
  * The heart of the server.  A crib from libc for the most part...
index eb9199607762524c6a02552093d7e1f9d719d065..0c234ff92f2a253921d4269b226f00d89c234c3f 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -153,6 +153,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -212,6 +213,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index c0227c9f70271135ff15d097e96075134a03958d..e5da82780e12b36e176801cc46822e4915cb59fc 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -153,6 +153,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -212,6 +213,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index dcc15ac9c4aad1c85d140b486ab8136cabb658c6..4bc036fca080d398e34ebb3863c353f58357c84f 100644 (file)
@@ -1,6 +1,5 @@
 ## Process this file with automake to produce Makefile.in
 
-RPCGEN         = $(top_builddir)/tools/rpcgen/rpcgen
 
 GENFILES_XDR   = rquota_xdr.c
 GENFILES_H     = rquota.h
@@ -27,9 +26,13 @@ rquotad_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
 
 MAINTAINERCLEANFILES = Makefile.in
 
-
+if CONFIG_RPCGEN
+RPCGEN         = $(top_builddir)/tools/rpcgen/rpcgen
 $(RPCGEN):
        make -C $(top_srcdir)/tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
 
 $(GENFILES_XDR): %_xdr.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
index 419f1818c38152a5a53ccc8be676402666812b2f..198aa151b9e4c47752c8a498f3dc44cb213df41d 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -158,6 +158,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -217,13 +218,13 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 GENFILES_XDR = rquota_xdr.c
 GENFILES_H = rquota.h
 BUILT_SOURCES = $(GENFILES_H)
@@ -244,6 +245,8 @@ rquotad_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
                    -I$(top_srcdir)/support/export
 
 MAINTAINERCLEANFILES = Makefile.in
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 CLEANFILES = $(GENFILES)
 all: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) all-am
@@ -653,9 +656,8 @@ uninstall-am: uninstall-man uninstall-sbinPROGRAMS
        tags uninstall uninstall-am uninstall-hook uninstall-man \
        uninstall-man8 uninstall-sbinPROGRAMS
 
-
-$(RPCGEN):
-       make -C $(top_srcdir)/tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@   make -C $(top_srcdir)/tools/rpcgen all
 
 $(GENFILES_XDR): %_xdr.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
index e123468840d455b48359bc19d4e0f493bab5287a..19b3338b1179ede2282391dc48ade5a3b27e3c1a 100644 (file)
@@ -40,7 +40,7 @@ am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -153,6 +153,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -212,6 +213,7 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
index 26800eae2d38153cc1f384760e5f28258721dfb5..8a3ba4ede06ced52f9ccddba35d52e79a2947f50 100644 (file)
@@ -1,8 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-man8_MANS = statd.man
-
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
+man8_MANS = statd.man sm-notify.man
 
 GENFILES_CLNT  = sm_inter_clnt.c
 GENFILES_SVC   = sm_inter_svc.c
@@ -13,21 +11,30 @@ GENFILES    = $(GENFILES_CLNT) $(GENFILES_SVC) $(GENFILES_XDR) $(GENFILES_H)
 
 RPCPREFIX      = rpc.
 KPREFIX                = @kprefix@
-sbin_PROGRAMS  = statd
-statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c notify.c \
-               simu.c stat.c statd.c state.c svc_run.c rmtcall.c \
+sbin_PROGRAMS  = statd sm-notify
+dist_sbin_SCRIPTS      = start-statd
+statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c \
+               simu.c stat.c statd.c svc_run.c rmtcall.c \
                sm_inter_clnt.c sm_inter_svc.c sm_inter_xdr.c log.h \
                notlist.h statd.h system.h version.h sm_inter.h
+sm_notify_SOURCES = sm-notify.c
+
 BUILT_SOURCES = $(GENFILES)
 statd_LDADD = ../../support/export/libexport.a \
              ../../support/nfs/libnfs.a \
              ../../support/misc/libmisc.a \
              $(LIBWRAP) $(LIBNSL)
+sm_notify_LDADD = $(LIBNSL)
 
 EXTRA_DIST = sim_sm_inter.x sm_inter.x $(man8_MANS) COPYRIGHT simulate.c
 
+if CONFIG_RPCGEN
+RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 $(RPCGEN):
        make -C ../../tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
 
 $(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
@@ -60,12 +67,12 @@ CLEANFILES = $(GENFILES)
 install-exec-hook:
        (cd $(DESTDIR)$(sbindir) && \
          for p in $(sbin_PROGRAMS); do \
-           mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+           [ $$p = sm-notify ] || mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
          done)
 uninstall-hook:
        (cd $(DESTDIR)$(sbindir) && \
          for p in $(sbin_PROGRAMS); do \
-           rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+           [ $$p = sm-notify ] || rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
          done)
 
 
index 2378ebd72fdb544edcd1c2f99f725a828ef0e7ab..0527c08742e4a881b36bb12fa2426acc1c4644ed 100644 (file)
@@ -14,6 +14,7 @@
 
 @SET_MAKE@
 
+
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -32,33 +33,40 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-sbin_PROGRAMS = statd$(EXEEXT)
+sbin_PROGRAMS = statd$(EXEEXT) sm-notify$(EXEEXT)
 subdir = utils/statd
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING TODO
+DIST_COMMON = $(dist_sbin_SCRIPTS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in COPYING TODO
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
        $(top_srcdir)/aclocal/kerberos5.m4 \
        $(top_srcdir)/aclocal/nfs-utils.m4 \
        $(top_srcdir)/aclocal/tcp-wrappers.m4 \
-       $(top_srcdir)/configure.in
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/support/include/config.h
 CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" \
+       "$(DESTDIR)$(man8dir)"
 sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(sbin_PROGRAMS)
+am_sm_notify_OBJECTS = sm-notify.$(OBJEXT)
+sm_notify_OBJECTS = $(am_sm_notify_OBJECTS)
+am__DEPENDENCIES_1 =
+sm_notify_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am_statd_OBJECTS = callback.$(OBJEXT) notlist.$(OBJEXT) log.$(OBJEXT) \
-       misc.$(OBJEXT) monitor.$(OBJEXT) notify.$(OBJEXT) \
-       simu.$(OBJEXT) stat.$(OBJEXT) statd.$(OBJEXT) state.$(OBJEXT) \
-       svc_run.$(OBJEXT) rmtcall.$(OBJEXT) sm_inter_clnt.$(OBJEXT) \
-       sm_inter_svc.$(OBJEXT) sm_inter_xdr.$(OBJEXT)
+       misc.$(OBJEXT) monitor.$(OBJEXT) simu.$(OBJEXT) stat.$(OBJEXT) \
+       statd.$(OBJEXT) svc_run.$(OBJEXT) rmtcall.$(OBJEXT) \
+       sm_inter_clnt.$(OBJEXT) sm_inter_svc.$(OBJEXT) \
+       sm_inter_xdr.$(OBJEXT)
 statd_OBJECTS = $(am_statd_OBJECTS)
-am__DEPENDENCIES_1 =
 statd_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+dist_sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(dist_sbin_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -71,8 +79,8 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
        $(LDFLAGS) -o $@
-SOURCES = $(statd_SOURCES)
-DIST_SOURCES = $(statd_SOURCES)
+SOURCES = $(sm_notify_SOURCES) $(statd_SOURCES)
+DIST_SOURCES = $(sm_notify_SOURCES) $(statd_SOURCES)
 man8dir = $(mandir)/man8
 NROFF = nroff
 MANS = $(man8_MANS)
@@ -159,6 +167,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
 RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
 RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
 RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
 SET_MAKE = @SET_MAKE@
@@ -218,14 +227,14 @@ sbindir = @sbindir@
 secure_statd = @secure_statd@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+startstatd = @startstatd@
 statduser = @statduser@
 statedir = @statedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-man8_MANS = statd.man
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
+man8_MANS = statd.man sm-notify.man
 GENFILES_CLNT = sm_inter_clnt.c
 GENFILES_SVC = sm_inter_svc.c
 GENFILES_XDR = sm_inter_xdr.c
@@ -233,18 +242,23 @@ GENFILES_H = sm_inter.h
 GENFILES = $(GENFILES_CLNT) $(GENFILES_SVC) $(GENFILES_XDR) $(GENFILES_H)
 RPCPREFIX = rpc.
 KPREFIX = @kprefix@
-statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c notify.c \
-               simu.c stat.c statd.c state.c svc_run.c rmtcall.c \
+dist_sbin_SCRIPTS = start-statd
+statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c \
+               simu.c stat.c statd.c svc_run.c rmtcall.c \
                sm_inter_clnt.c sm_inter_svc.c sm_inter_xdr.c log.h \
                notlist.h statd.h system.h version.h sm_inter.h
 
+sm_notify_SOURCES = sm-notify.c
 BUILT_SOURCES = $(GENFILES)
 statd_LDADD = ../../support/export/libexport.a \
              ../../support/nfs/libnfs.a \
              ../../support/misc/libmisc.a \
              $(LIBWRAP) $(LIBNSL)
 
+sm_notify_LDADD = $(LIBNSL)
 EXTRA_DIST = sim_sm_inter.x sm_inter.x $(man8_MANS) COPYRIGHT simulate.c
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
 MAINTAINERCLEANFILES = Makefile.in
 CLEANFILES = $(GENFILES)
 all: $(BUILT_SOURCES)
@@ -309,9 +323,31 @@ clean-sbinPROGRAMS:
          echo " rm -f $$p $$f"; \
          rm -f $$p $$f ; \
        done
+sm-notify$(EXEEXT): $(sm_notify_OBJECTS) $(sm_notify_DEPENDENCIES) 
+       @rm -f sm-notify$(EXEEXT)
+       $(LINK) $(sm_notify_OBJECTS) $(sm_notify_LDADD) $(LIBS)
 statd$(EXEEXT): $(statd_OBJECTS) $(statd_DEPENDENCIES) 
        @rm -f statd$(EXEEXT)
        $(LINK) $(statd_OBJECTS) $(statd_LDADD) $(LIBS)
+install-dist_sbinSCRIPTS: $(dist_sbin_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+       @list='$(dist_sbin_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(dist_sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+           $(dist_sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-dist_sbinSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(dist_sbin_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+       done
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -323,16 +359,15 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notify.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notlist.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmtcall.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm-notify.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_clnt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_svc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_xdr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/svc_run.Po@am__quote@
 
 .c.o:
@@ -484,9 +519,9 @@ distdir: $(DISTFILES)
 check-am: all-am
 check: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(PROGRAMS) $(MANS)
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS)
 installdirs:
-       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: $(BUILT_SOURCES)
@@ -542,7 +577,7 @@ install-data-am: install-man
 
 install-dvi: install-dvi-am
 
-install-exec-am: install-sbinPROGRAMS
+install-exec-am: install-dist_sbinSCRIPTS install-sbinPROGRAMS
        @$(NORMAL_INSTALL)
        $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
 
@@ -574,7 +609,8 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+uninstall-am: uninstall-dist_sbinSCRIPTS uninstall-man \
+       uninstall-sbinPROGRAMS
        @$(NORMAL_INSTALL)
        $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
 
@@ -584,20 +620,21 @@ uninstall-am: uninstall-man uninstall-sbinPROGRAMS
        clean-libtool clean-sbinPROGRAMS ctags distclean \
        distclean-compile distclean-generic distclean-libtool \
        distclean-tags distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-exec-hook \
-       install-html install-html-am install-info install-info-am \
-       install-man install-man8 install-pdf install-pdf-am install-ps \
+       install install-am install-data install-data-am \
+       install-dist_sbinSCRIPTS install-dvi install-dvi-am \
+       install-exec install-exec-am install-exec-hook install-html \
+       install-html-am install-info install-info-am install-man \
+       install-man8 install-pdf install-pdf-am install-ps \
        install-ps-am install-sbinPROGRAMS install-strip installcheck \
        installcheck-am installdirs maintainer-clean \
        maintainer-clean-generic mostlyclean mostlyclean-compile \
        mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags uninstall uninstall-am uninstall-hook uninstall-man \
-       uninstall-man8 uninstall-sbinPROGRAMS
-
+       tags uninstall uninstall-am uninstall-dist_sbinSCRIPTS \
+       uninstall-hook uninstall-man uninstall-man8 \
+       uninstall-sbinPROGRAMS
 
-$(RPCGEN):
-       make -C ../../tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@   make -C ../../tools/rpcgen all
 
 $(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
        test -f $@ && rm -rf $@ || true
@@ -626,12 +663,12 @@ $(GENFILES_H): %.h: %.x $(RPCGEN)
 install-exec-hook:
        (cd $(DESTDIR)$(sbindir) && \
          for p in $(sbin_PROGRAMS); do \
-           mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+           [ $$p = sm-notify ] || mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
          done)
 uninstall-hook:
        (cd $(DESTDIR)$(sbindir) && \
          for p in $(sbin_PROGRAMS); do \
-           rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+           [ $$p = sm-notify ] || rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
          done)
 
 # XXX This makes some assumptions about what automake does.
index 8a85ce90737c7de3aa8ce1db7b9f1bf214b83b90..b19bb901d8ee2305d38b7c30e0a00ac5fdb8ebbb 100644 (file)
@@ -27,6 +27,8 @@ sm_notify_1_svc(struct stat_chge *argp, struct svc_req *rqstp)
 {
        notify_list    *lp, *call;
        static char    *result = NULL;
+       char *ip_addr = xstrdup(inet_ntoa(svc_getcaller(rqstp->rq_xprt)
+                                         ->sin_addr));
 
        dprintf(N_DEBUG, "Received SM_NOTIFY from %s, state: %d",
                                argp->mon_name, argp->state);
@@ -45,15 +47,15 @@ sm_notify_1_svc(struct stat_chge *argp, struct svc_req *rqstp)
         * it. Lockd will want to continue monitoring the remote host
         * until it issues an SM_UNMON call.
         */
-       while ((lp = nlist_gethost(lp, argp->mon_name, 0)) != NULL) {
-               if (NL_STATE(lp) != argp->state) {
+       for (lp = rtnl ; lp ; lp = lp->next)
+               if (NL_STATE(lp) != argp->state &&
+                   (matchhostname(argp->mon_name, lp->dns_name) ||
+                    matchhostname(ip_addr, lp->dns_name))) {
                        NL_STATE(lp) = argp->state;
                        call = nlist_clone(lp);
-                       NL_TYPE(call) = NOTIFY_CALLBACK;
                        nlist_insert(&notify, call);
                }
-               lp = NL_NEXT(lp);
-       }
+
 
        return ((void *) &result);
 }
index 98cbf4a5940ba660bda50aa944f01769b0ee9ea4..b95b0ad51692e7b6708a2a94d289ad7484ccbbd1 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <arpa/inet.h>
+#include <dirent.h>
 #include "misc.h"
 #include "statd.h"
 #include "notlist.h"
@@ -26,6 +27,7 @@
 
 notify_list *          rtnl = NULL;    /* Run-time notify list. */
 
+#define LINELEN (4*(8+1)+SM_PRIV_SIZE*2+1)
 
 /*
  * Services SM_MON requests.
@@ -41,11 +43,11 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
        int             fd;
        notify_list     *clnt;
        struct in_addr  my_addr;
+       char            *dnsname;
 #ifdef RESTRICTED_STATD
-       struct in_addr  mon_addr, caller;
-#else
-       struct hostent  *hostinfo = NULL;
+       struct in_addr  caller;
 #endif
+       struct hostent  *hostinfo = NULL;
 
        /* Assume that we'll fail. */
        result.res_stat = STAT_FAIL;
@@ -87,6 +89,11 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
                goto failure;
        }
 
+#if 0
+       This is not usable anymore.  Linux-kernel can be configured to use
+       host names with NSM so that multi-homed hosts are handled properly.
+               NeilBrown 15mar2007
+
        /* 3.   mon_name must be an address in dotted quad.
         *      Again, specific to the linux kernel lockd.
         */
@@ -96,31 +103,46 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
                        mon_name);
                goto failure;
        }
+#endif
 #else
+       if (!(hostinfo = gethostbyname(my_name))) {
+               note(N_WARNING, "gethostbyname error for %s", my_name);
+               goto failure;
+       } else
+               my_addr = *(struct in_addr *) hostinfo->h_addr;
+#endif
        /*
         * Check hostnames.  If I can't look them up, I won't monitor.  This
         * might not be legal, but it adds a little bit of safety and sanity.
         */
 
        /* must check for /'s in hostname!  See CERT's CA-96.09 for details. */
-       if (strchr(mon_name, '/')) {
-               note(N_CRIT, "SM_MON request for hostname containing '/': %s",
-                       mon_name);
+       if (strchr(mon_name, '/') || mon_name[0] == '.') {
+               note(N_CRIT, "SM_MON request for hostname containing '/' "
+                    "or starting '.': %s", mon_name);
                note(N_CRIT, "POSSIBLE SPOOF/ATTACK ATTEMPT!");
                goto failure;
-       } else if (gethostbyname(mon_name) == NULL) {
+       } else if ((hostinfo = gethostbyname(mon_name)) == NULL) {
                note(N_WARNING, "gethostbyname error for %s", mon_name);
                goto failure;
-       } else if (!(hostinfo = gethostbyname(my_name))) {
-               note(N_WARNING, "gethostbyname error for %s", my_name);
-               goto failure;
-       } else
-               my_addr = *(struct in_addr *) hostinfo->h_addr;
-#endif
+       }
 
        /*
         * Hostnames checked OK.
-        * Now check to see if this is a duplicate, and warn if so.
+        * Now choose a hostname to use for matching.  We cannot
+        * really trust much in the incoming NOTIFY, so to make
+        * sure that multi-homed hosts work nicely, we get an
+        * FQDN now, and use that for matching
+        */
+       hostinfo = gethostbyaddr(hostinfo->h_addr,
+                                hostinfo->h_length,
+                                hostinfo->h_addrtype);
+       if (hostinfo)
+               dnsname = xstrdup(hostinfo->h_name);
+       else
+               dnsname = xstrdup(my_name);
+
+       /* Now check to see if this is a duplicate, and warn if so.
         * I will also return STAT_FAIL. (I *think* this is how I should
         * handle it.)
         *
@@ -129,27 +151,26 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
         * I'll just do a quickie success return and things should
         * be happy.
         */
-       if (rtnl) {
-               notify_list    *temp = rtnl;
-
-               while ((temp = nlist_gethost(temp, mon_name, 0))) {
-                       if (matchhostname(NL_MY_NAME(temp), my_name) &&
-                               NL_MY_PROC(temp) == id->my_proc &&
-                               NL_MY_PROG(temp) == id->my_prog &&
-                               NL_MY_VERS(temp) == id->my_vers) {
-                               /* Hey!  We already know you guys! */
-                               dprintf(N_DEBUG,
-                                       "Duplicate SM_MON request for %s "
-                                       "from procedure on %s",
-                                       mon_name, my_name);
+       clnt = rtnl;
 
-                               /* But we'll let you pass anyway. */
-                               result.res_stat = STAT_SUCC;
-                               result.state = MY_STATE;
-                               return (&result);
-                       }
-                       temp = NL_NEXT(temp);
+       while ((clnt = nlist_gethost(clnt, mon_name, 0))) {
+               if (matchhostname(NL_MY_NAME(clnt), my_name) &&
+                   NL_MY_PROC(clnt) == id->my_proc &&
+                   NL_MY_PROG(clnt) == id->my_prog &&
+                   NL_MY_VERS(clnt) == id->my_vers &&
+                   memcmp(NL_PRIV(clnt), argp->priv, SM_PRIV_SIZE) == 0) {
+                       /* Hey!  We already know you guys! */
+                       dprintf(N_DEBUG,
+                               "Duplicate SM_MON request for %s "
+                               "from procedure on %s",
+                               mon_name, my_name);
+
+                       /* But we'll let you pass anyway. */
+                       result.res_stat = STAT_SUCC;
+                       result.state = MY_STATE;
+                       return (&result);
                }
+               clnt = NL_NEXT(clnt);
        }
 
        /*
@@ -166,20 +187,36 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
        NL_MY_VERS(clnt) = id->my_vers;
        NL_MY_PROC(clnt) = id->my_proc;
        memcpy(NL_PRIV(clnt), argp->priv, SM_PRIV_SIZE);
+       clnt->dns_name = dnsname;
 
        /*
         * Now, Create file on stable storage for host.
         */
 
-       path=xmalloc(strlen(SM_DIR)+strlen(mon_name)+2);
-       sprintf(path, "%s/%s", SM_DIR, mon_name);
-       if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
+       path=xmalloc(strlen(SM_DIR)+strlen(dnsname)+2);
+       sprintf(path, "%s/%s", SM_DIR, dnsname);
+       if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT|O_APPEND,
+                      S_IRUSR|S_IWUSR)) < 0) {
                /* Didn't fly.  We won't monitor. */
                note(N_ERROR, "creat(%s) failed: %s", path, strerror (errno));
                nlist_free(NULL, clnt);
                free(path);
                goto failure;
        }
+       {
+               char buf[LINELEN + 1 + SM_MAXSTRLEN + 2];
+               char *e;
+               int i;
+               e = buf + sprintf(buf, "%08x %08x %08x %08x ",
+                                 my_addr.s_addr, id->my_prog,
+                                 id->my_vers, id->my_proc);
+               for (i=0; i<SM_PRIV_SIZE; i++)
+                       e += sprintf(e, "%02x", 0xff & (argp->priv[i]));
+               if (e+1-buf != LINELEN) abort();
+               e += sprintf(e, " %s\n", mon_name);
+               write(fd, buf, e-buf);
+       }
+
        free(path);
        /* PRC: do the HA callout: */
        ha_callout("add-client", mon_name, my_name, -1);
@@ -196,6 +233,65 @@ failure:
        return (&result);
 }
 
+void load_state(void)
+{
+       DIR *d;
+       struct dirent *de;
+       char buf[LINELEN + 1 + SM_MAXSTRLEN + 2];
+
+       d = opendir(SM_DIR);
+       if (!d)
+               return;
+       while ((de = readdir(d))) {
+               char *path;
+               FILE *f;
+               int p;
+
+               if (de->d_name[0] == '.')
+                       continue;
+               path = xmalloc(strlen(SM_DIR)+strlen(de->d_name)+2);
+               sprintf(path, "%s/%s", SM_DIR, de->d_name);
+               f = fopen(path, "r");
+               free(path);
+               if (f == NULL)
+                       continue;
+               while (fgets(buf, sizeof(buf), f) != NULL) {
+                       int addr, proc, prog, vers;
+                       char priv[SM_PRIV_SIZE];
+                       char *b;
+                       int i;
+                       notify_list     *clnt;
+
+                       buf[sizeof(buf)-1] = 0;
+                       b = strchr(buf, '\n');
+                       if (b) *b = 0;
+                       sscanf(buf, "%x %x %x %x ",
+                              &addr, &prog, &vers, &proc);
+                       b = buf+36;
+                       for (i=0; i<SM_PRIV_SIZE; i++) {
+                               sscanf(b, "%2x", &p);
+                               priv[i] = p;
+                               b += 2;
+                       }
+                       b++;
+                       clnt = nlist_new("127.0.0.1", b, 0);
+                       if (!clnt)
+                               break;
+                       NL_ADDR(clnt).s_addr = addr;
+                       NL_MY_PROG(clnt) = prog;
+                       NL_MY_VERS(clnt) = vers;
+                       NL_MY_PROC(clnt) = proc;
+                       clnt->dns_name = xstrdup(de->d_name);
+                       memcpy(NL_PRIV(clnt), priv, SM_PRIV_SIZE);
+                       nlist_insert(&rtnl, clnt);
+               }
+               fclose(f);
+       }
+       closedir(d);
+}
+
+
+
 
 /*
  * Services SM_UNMON requests.
diff --git a/utils/statd/notify.c b/utils/statd/notify.c
deleted file mode 100644 (file)
index d7aa1dd..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
- * Modified by Olaf Kirch, Oct. 1996.
- * Modified by H.J. Lu, 1998.
- *
- * NSM for Linux.
- */
-
-/*
- * NSM notify list handling.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <dirent.h>
-#include <errno.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include "misc.h"
-#include "statd.h"
-#include "notlist.h"
-
-/*
- * Initial (startup) notify list.
- */
-notify_list            *inl = NULL;
-
-
-/* 
- * Get list of hosts from stable storage, build list of hosts to
- * contact. These hosts are added to the global RPC notify list
- * which is processed as soon as statd enters svc_run.
- */
-void
-notify_hosts(void)
-{
-       DIR            *nld;
-       struct dirent  *de;
-       notify_list    *call;
-
-       if (!(nld = opendir(SM_BAK_DIR))) {
-               perror("opendir");
-               exit(errno);
-       }
-
-       while ((de = readdir(nld))) {
-               if (de->d_name[0] == '.')
-                       continue;
-
-               /* The following can happen for loopback NFS mounts
-                * (e.g. with cfsd) */
-               if (matchhostname(de->d_name, MY_NAME)
-                || matchhostname(de->d_name, "localhost")) {
-                       char *fname;
-                       fname=xmalloc(strlen(SM_BAK_DIR)+sizeof(de->d_name)+2);
-                       dprintf(N_DEBUG, "We're on our own notify list?!?");
-                       sprintf(fname, "%s/%s",  SM_BAK_DIR, de->d_name);
-                       if (unlink(fname)) 
-                               note(N_ERROR, "unlink(%s): %s", 
-                                       fname, strerror(errno));
-                       free(fname);
-                       continue;
-               }
-
-               call = nlist_new(MY_NAME, de->d_name, -1);
-               NL_TYPE(call) = NOTIFY_REBOOT;
-               nlist_insert(&notify, call);
-       }
-
-       if (closedir(nld) == -1) {
-               perror("closedir");
-               exit(1);
-       }
-}
index 911c092a7ebcb2da3429ecf97ce3dd2ac08b7c41..664c9d881bc84021b123ed75f3ed8463f08627ea 100644 (file)
@@ -16,18 +16,16 @@ struct notify_list {
   unsigned short       port;   /* port number for callback */
   short int            times;  /* Counter used for various things. */
   int                  state;  /* For storing notified state for callbacks. */
+  char                 *dns_name; /* used for matching incoming
+                                   * NOTIFY requests */
   struct notify_list   *next;  /* Linked list forward pointer. */
   struct notify_list   *prev;  /* Linked list backward pointer. */
   u_int32_t            xid;    /* XID of MS_NOTIFY RPC call */
   time_t               when;   /* notify: timeout for re-xmit */
-  int                  type;   /* type of notify (REBOOT/CALLBACK) */
 };
 
 typedef struct notify_list notify_list;
 
-#define NOTIFY_REBOOT  0       /* notify remote of our reboot */
-#define NOTIFY_CALLBACK        1       /* notify client of remote reboot */
-
 /*
  * Global Variables
  */
@@ -67,4 +65,3 @@ extern notify_list *  nlist_gethost(notify_list *, char *, int);
 #define NL_MY_PROG(L)  (NL_MY_ID((L)).my_prog)
 #define NL_MY_VERS(L)  (NL_MY_ID((L)).my_vers)
 #define NL_WHEN(L)     ((L)->when)
-#define NL_TYPE(L)     ((L)->type)
index 35cbccb54029fabdbb068a366c7d25000bbc4212..816a6f368fa208d12313de3f1721d297401cf42a 100644 (file)
@@ -59,7 +59,7 @@ static int            sockfd = -1;    /* notify socket */
  * Initialize callback socket
  */
 int
-statd_get_socket(int port)
+statd_get_socket(void)
 {
        struct sockaddr_in      sin;
 
@@ -76,139 +76,14 @@ statd_get_socket(int port)
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;
-       /*
-        * If a local hostname is given (-n option to statd), bind to the address
-        * specified. This is required to support clients that ignore the mon_name in
-        * the statd protocol but use the source address from the request packet.
-        */
-       if (MY_NAME) {
-               struct hostent *hp = gethostbyname(MY_NAME);
-               if (hp)
-                       sin.sin_addr = *(struct in_addr *) hp->h_addr;
-       }
-       if (port != 0) {
-               sin.sin_port = htons(port);
-               if (bind(sockfd, &sin, sizeof(sin)) == 0)
-                       goto out_success;
-               note(N_CRIT, "statd: failed to bind to outgoing port, %d\n"
-                               "       falling back on randomly chosen port\n", port);
-       }
+
        if (bindresvport(sockfd, &sin) < 0) {
                dprintf(N_WARNING,
                        "process_hosts: can't bind to reserved port\n");
        }
-out_success:
        return sockfd;
 }
 
-#ifdef HAVE_IFADDRS_H
-/*
- * Using the NL_ADDR(lp), reset (if needed) the hostname
- * that will be put in the SM_NOTIFY to the hostname
- * that is associated with the network interface 
- * that was monitored
- */
-static void
-reset_my_name(notify_list *lp)
-{
-       struct ifaddrs *ifa = NULL, *ifap;
-       struct in_addr netaddr, tmp;
-       struct sockaddr_in *sin, *nsin;
-       struct hostent *hp;
-
-       netaddr.s_addr = inet_netof(NL_ADDR(lp));
-       if (getifaddrs(&ifa) >= 0) {
-               for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
-                       if (!(ifap->ifa_flags & IFF_UP))
-                               continue;
-
-                       note(N_DEBUG, "ifa_name %s\n", ifap->ifa_name);
-                       if (ifap->ifa_addr == NULL)
-                               continue;
-                       if (ifap->ifa_addr->sa_family != AF_INET)
-                               continue;
-
-                       sin = (struct sockaddr_in *)ifap->ifa_addr;
-                       nsin = (struct sockaddr_in *)ifap->ifa_netmask;
-                       tmp.s_addr = sin->sin_addr.s_addr & nsin->sin_addr.s_addr;
-                       if (memcmp(&tmp.s_addr, &netaddr.s_addr, sizeof(netaddr.s_addr)))
-                               continue;
-                       hp = gethostbyaddr((char *)&sin->sin_addr, 
-                               sizeof(sin->sin_addr), AF_INET);
-                       if (hp == NULL)
-                               continue;
-                       if (strcmp(NL_MY_NAME(lp), hp->h_name)) {
-                               free(NL_MY_NAME(lp));
-                               NL_MY_NAME(lp)= strdup(hp->h_name);
-                               note(N_DEBUG, "NL_MY_NAME %s\n", NL_MY_NAME(lp));
-                       }
-               }
-       }
-       return;
-}
-#endif /* HAVE_IFADDRS_H */
-/*
- * Try to resolve host name for notify/callback request
- *
- * When compiled with RESTRICTED_STATD defined, we expect all
- * host names to be dotted quads. See monitor.c for details. --okir
- */
-#ifdef RESTRICTED_STATD
-static int
-try_to_resolve(notify_list *lp)
-{
-       char            *hname;
-
-       if (NL_TYPE(lp) == NOTIFY_REBOOT)
-               hname = NL_MON_NAME(lp);
-       else
-               hname = NL_MY_NAME(lp);
-       if (!inet_aton(hname, &(NL_ADDR(lp)))) {
-               note(N_ERROR, "%s is not an dotted-quad address", hname);
-               NL_TIMES(lp) = 0;
-               return 0;
-       }
-
-       /* XXX: In order to handle multi-homed hosts, we could do
-        * a reverse lookup, a forward lookup, and cycle through
-        * all the addresses.
-        */
-       return 1;
-}
-#else
-static int
-try_to_resolve(notify_list *lp)
-{
-       struct hostent  *hp;
-       char            *hname;
-
-       if (NL_TYPE(lp) == NOTIFY_REBOOT)
-               hname = NL_MON_NAME(lp);
-       else
-               hname = NL_MY_NAME(lp);
-
-       dprintf(N_DEBUG, "Trying to resolve %s.", hname);
-       if (!(hp = gethostbyname(hname))) {
-               herror("gethostbyname");
-               NL_TIMES(lp) -= 1;
-               return 0;
-       }
-
-       if (hp->h_addrtype != AF_INET) {
-               note(N_ERROR, "%s is not an AF_INET address", hname);
-               NL_TIMES(lp) = 0;
-               return 0;
-       }
-
-       /* FIXME: should try all addresses for multi-homed hosts in
-        * alternation because one interface might be down/unreachable. */
-       NL_ADDR(lp) = *(struct in_addr *) hp->h_addr;
-
-       dprintf(N_DEBUG, "address of %s is %s", hname, inet_ntoa(NL_ADDR(lp)));
-       return 1;
-}
-#endif
-
 static unsigned long
 xmit_call(int sockfd, struct sockaddr_in *sin,
          u_int32_t prog, u_int32_t vers, u_int32_t proc,
@@ -356,14 +231,11 @@ process_entry(int sockfd, notify_list *lp)
 {
        struct sockaddr_in      sin;
        struct status           new_status;
-       stat_chge               new_stat;
        xdrproc_t               func;
        void                    *objp;
        u_int32_t               proc, vers, prog;
 /*     __u32                   proc, vers, prog; */
 
-       if (lp->addr.s_addr == INADDR_ANY && !try_to_resolve(lp))
-               return NL_TIMES(lp);
        if (NL_TIMES(lp) == 0) {
                note(N_DEBUG, "Cannot notify %s, giving up.\n",
                                        inet_ntoa(NL_ADDR(lp)));
@@ -375,54 +247,24 @@ process_entry(int sockfd, notify_list *lp)
        sin.sin_port   = lp->port;
        /* LH - moved address into switch */
 
-       switch (NL_TYPE(lp)) {
-       case NOTIFY_REBOOT:
-               prog = SM_PROG;
-               vers = SM_VERS;
-               proc = SM_NOTIFY;
-
-               /* Use source address for notify replies */
-               sin.sin_addr   = lp->addr;
-               /* 
-                * Unless a static hostname has been defined
-                * set the NL_MY_NAME(lp) hostname to the 
-                * one associated with the network interface
-                */
-#ifdef HAVE_IFADDRS_H
-               if (!(run_mode & STATIC_HOSTNAME))
-                       reset_my_name(lp);
-#endif /* HAVE_IFADDRS_H */
-               func = (xdrproc_t) xdr_stat_chge;
-               new_stat.state = MY_STATE;
-               new_stat.mon_name = NL_MY_NAME(lp);
+       prog = NL_MY_PROG(lp);
+       vers = NL_MY_VERS(lp);
+       proc = NL_MY_PROC(lp);
 
-               objp = &new_stat;
-               break;
-       case NOTIFY_CALLBACK:
-               prog = NL_MY_PROG(lp);
-               vers = NL_MY_VERS(lp);
-               proc = NL_MY_PROC(lp);
-
-               /* __FORCE__ loopback for callbacks to lockd ... */
-               /* Just in case we somehow ignored it thus far */
-               sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-               func = (xdrproc_t) xdr_status;
-               objp = &new_status;
-               new_status.mon_name = NL_MON_NAME(lp);
-               new_status.state    = NL_STATE(lp);
-               memcpy(new_status.priv, NL_PRIV(lp), SM_PRIV_SIZE);
-               break;
-       default:
-               note(N_ERROR, "notify_host: unknown notify type %d",
-                               NL_TYPE(lp));
-               return 0;
-       }
+       /* __FORCE__ loopback for callbacks to lockd ... */
+       /* Just in case we somehow ignored it thus far */
+       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+       func = (xdrproc_t) xdr_status;
+       objp = &new_status;
+       new_status.mon_name = NL_MON_NAME(lp);
+       new_status.state    = NL_STATE(lp);
+       memcpy(new_status.priv, NL_PRIV(lp), SM_PRIV_SIZE);
 
        lp->xid = xmit_call(sockfd, &sin, prog, vers, proc, func, objp);
        if (!lp->xid) {
-               note(N_WARNING, "notify_host: failed to notify %s\n",
-                               inet_ntoa(lp->addr));
+               note(N_WARNING, "notify_host: failed to notify port %d\n",
+                               ntohs(lp->port));
        }
        NL_TIMES(lp) -= 1;
 
@@ -455,12 +297,7 @@ process_reply(FD_SET_TYPE *rfds)
                        return 1;
                }
                note(N_WARNING, "recv_rply: [%s] service %d not registered",
-                       inet_ntoa(lp->addr),
-                       NL_TYPE(lp) == NOTIFY_REBOOT? SM_PROG : NL_MY_PROG(lp));
-       } else if (NL_TYPE(lp) == NOTIFY_REBOOT) {
-               dprintf(N_DEBUG, "Notification of %s succeeded.",
-                       NL_MON_NAME(lp));
-               xunlink(SM_BAK_DIR, NL_MON_NAME(lp), 0);
+                       inet_ntoa(lp->addr), NL_MY_PROG(lp));
        } else {
                dprintf(N_DEBUG, "Callback to %s (for %d) succeeded.",
                        NL_MY_NAME(lp), NL_MON_NAME(lp));
@@ -481,7 +318,7 @@ process_notify_list(void)
        time_t          now;
        int             fd;
 
-       if ((fd = statd_get_socket(0)) < 0)
+       if ((fd = statd_get_socket()) < 0)
                return 0;
 
        while ((entry = notify) != NULL && NL_WHEN(entry) < time(&now)) {
@@ -489,21 +326,13 @@ process_notify_list(void)
                        NL_WHEN(entry) = time(NULL) + NOTIFY_TIMEOUT;
                        nlist_remove(&notify, entry);
                        nlist_insert_timer(&notify, entry);
-               } else if (NL_TYPE(entry) == NOTIFY_CALLBACK) {
+               } else {
                        note(N_ERROR,
                                "Can't callback %s (%d,%d), giving up.",
                                        NL_MY_NAME(entry),
                                        NL_MY_PROG(entry),
                                        NL_MY_VERS(entry));
                        nlist_free(&notify, entry);
-               } else {
-                       note(N_ERROR,
-                               "Can't notify %s, giving up.",
-                                       NL_MON_NAME(entry));
-                       /* PRC: do the HA callout */
-                       ha_callout("del-client", NL_MON_NAME(entry), NL_MY_NAME(entry), -1);
-                       xunlink(SM_BAK_DIR, NL_MON_NAME(entry), 0);
-                       nlist_free(&notify, entry);
                }
        }
 
index 9d685adc3da3b268408954451e4298e9b2fec25b..82d794e1c2667a20198f0cb24a89bcf5e95f75ca 100644 (file)
@@ -7,6 +7,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <arpa/inet.h>
 
 #include "statd.h"
 #include "notlist.h"
@@ -22,11 +23,34 @@ sm_simu_crash_1_svc (void *argp, struct svc_req *rqstp)
 {
   static char *result = NULL;
 
+#ifdef RESTRICTED_STATD
+       struct in_addr  caller;
+
+       /* 1.   Reject anyone not calling from 127.0.0.1.
+        *      Ignore the my_name specified by the caller, and
+        *      use "127.0.0.1" instead.
+        */
+       caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
+       if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
+               note(N_WARNING,
+                       "Call to statd from non-local host %s",
+                       inet_ntoa(caller));
+               goto failure;
+       }
+       if (ntohs(svc_getcaller(rqstp->rq_xprt)->sin_port) >= 1024) {
+               note(N_WARNING,
+                    "Call to statd-simu-crash from unprivileged port\n");
+               goto failure;
+       }
+#endif
   note (N_WARNING, "*** SIMULATING CRASH! ***");
   my_svc_exit ();
 
   if (rtnl)
     nlist_kill (&rtnl);
 
+#ifdef RESTRICTED_STATD
+ failure:
+#endif
   return ((void *)&result);
 }
diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c
new file mode 100644 (file)
index 0000000..a94876d
--- /dev/null
@@ -0,0 +1,760 @@
+/*
+ * Send NSM notify calls to all hosts listed in /var/lib/sm
+ *
+ * Copyright (C) 2004-2006 Olaf Kirch <okir@suse.de>
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <sys/syslog.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <time.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <errno.h>
+#include <grp.h>
+
+#ifndef BASEDIR
+# ifdef NFS_STATEDIR
+#  define BASEDIR              NFS_STATEDIR
+# else
+#  define BASEDIR              "/var/lib/nfs"
+# endif
+#endif
+
+#define DEFAULT_SM_STATE_PATH  BASEDIR "/state"
+#define        DEFAULT_SM_DIR_PATH     BASEDIR "/sm"
+#define        DEFAULT_SM_BAK_PATH     DEFAULT_SM_DIR_PATH ".bak"
+
+char *_SM_BASE_PATH = BASEDIR;
+char *_SM_STATE_PATH = DEFAULT_SM_STATE_PATH;
+char *_SM_DIR_PATH = DEFAULT_SM_DIR_PATH;
+char *_SM_BAK_PATH = DEFAULT_SM_BAK_PATH;
+
+#define NSM_PROG       100024
+#define NSM_PROGRAM    100024
+#define NSM_VERSION    1
+#define NSM_TIMEOUT    2
+#define NSM_NOTIFY     6
+#define NSM_MAX_TIMEOUT        120     /* don't make this too big */
+#define MAXMSGSIZE     256
+
+typedef struct sockaddr_storage nsm_address;
+
+struct nsm_host {
+       struct nsm_host *       next;
+       char *                  name;
+       char *                  path;
+       nsm_address             addr;
+       struct addrinfo         *ai;
+       time_t                  last_used;
+       time_t                  send_next;
+       unsigned int            timeout;
+       unsigned int            retries;
+       unsigned int            xid;
+};
+
+static char            nsm_hostname[256];
+static uint32_t                nsm_state;
+static int             opt_debug = 0;
+static int             opt_quiet = 0;
+static int             opt_update_state = 1;
+static unsigned int    opt_max_retry = 15 * 60;
+static char *          opt_srcaddr = 0;
+static uint16_t                opt_srcport = 0;
+static int             log_syslog = 0;
+
+static unsigned int    nsm_get_state(int);
+static void            notify(void);
+static void            notify_host(int, struct nsm_host *);
+static void            recv_reply(int);
+static void            backup_hosts(const char *, const char *);
+static void            get_hosts(const char *);
+static void            insert_host(struct nsm_host *);
+struct nsm_host *      find_host(uint32_t);
+static int             addr_get_port(nsm_address *);
+static void            addr_set_port(nsm_address *, int);
+static struct addrinfo *host_lookup(int, const char *);
+void                   nsm_log(int fac, const char *fmt, ...);
+static int             record_pid();
+static void            drop_privs(void);
+
+static struct nsm_host *       hosts = NULL;
+
+int
+main(int argc, char **argv)
+{
+       int     c;
+       int     force = 0;
+
+       while ((c = getopt(argc, argv, "dm:np:v:qP:f")) != -1) {
+               switch (c) {
+               case 'f':
+                       force = 1;
+                       break;
+               case 'd':
+                       opt_debug++;
+                       break;
+               case 'm':
+                       opt_max_retry = atoi(optarg) * 60;
+                       break;
+               case 'n':
+                       opt_update_state = 0;
+                       break;
+               case 'p':
+                       opt_srcport = atoi(optarg);
+                       break;
+               case 'v':
+                       opt_srcaddr = optarg;
+                       break;
+               case 'q':
+                       opt_quiet = 1;
+                       break;
+               case 'P':
+                       _SM_BASE_PATH = strdup(optarg);
+                       _SM_STATE_PATH = malloc(strlen(optarg)+1+sizeof("state"));
+                       _SM_DIR_PATH = malloc(strlen(optarg)+1+sizeof("sm"));
+                       _SM_BAK_PATH = malloc(strlen(optarg)+1+sizeof("sm.bak"));
+                       if (_SM_BASE_PATH == NULL ||
+                           _SM_STATE_PATH == NULL ||
+                           _SM_DIR_PATH == NULL ||
+                           _SM_BAK_PATH == NULL) {
+                               nsm_log(LOG_WARNING, "unable to allocate memory");
+                               exit(1);
+                       }
+                       strcat(strcpy(_SM_STATE_PATH, _SM_BASE_PATH), "/state");
+                       strcat(strcpy(_SM_DIR_PATH, _SM_BASE_PATH), "/sm");
+                       strcat(strcpy(_SM_BAK_PATH, _SM_BASE_PATH), "/sm.bak");
+                       break;
+
+               default:
+                       goto usage;
+               }
+       }
+
+       if (optind < argc) {
+usage:         fprintf(stderr,
+                       "Usage: sm-notify [-dfq] [-m max-retry-minutes] [-p srcport]\n"
+                       "            [-P /path/to/state/directory] [-v my_host_name]\n");
+               return 1;
+       }
+
+       if (strcmp(_SM_BASE_PATH, BASEDIR) == 0) {
+               if (record_pid() == 0 && force == 0 && opt_update_state == 1)
+                       /* already run, don't try again */
+                       exit(0);
+       }
+
+       if (opt_srcaddr) {
+               strncpy(nsm_hostname, opt_srcaddr, sizeof(nsm_hostname)-1);
+       } else
+       if (gethostname(nsm_hostname, sizeof(nsm_hostname)) < 0) {
+               perror("gethostname");
+               return 1;
+       }
+
+       backup_hosts(_SM_DIR_PATH, _SM_BAK_PATH);
+       get_hosts(_SM_BAK_PATH);
+
+       if (!opt_debug) {
+               if (!opt_quiet)
+                       printf("Backgrounding to notify hosts...\n");
+
+               openlog("sm-notify", LOG_PID, LOG_DAEMON);
+               log_syslog = 1;
+
+               if (daemon(0, 0) < 0) {
+                       nsm_log(LOG_WARNING, "unable to background: %s",
+                                       strerror(errno));
+                       return 1;
+               }
+
+               close(0);
+               close(1);
+               close(2);
+       }
+
+       /* Get and update the NSM state. This will call sync() */
+       nsm_state = nsm_get_state(opt_update_state);
+
+       notify();
+
+       if (hosts) {
+               struct nsm_host *hp;
+
+               while ((hp = hosts) != 0) {
+                       hosts = hp->next;
+                       nsm_log(LOG_NOTICE,
+                               "Unable to notify %s, giving up",
+                               hp->name);
+               }
+               return 1;
+       }
+
+       return 0;
+}
+
+/*
+ * Notify hosts
+ */
+void
+notify(void)
+{
+       nsm_address local_addr;
+       time_t  failtime = 0;
+       int     sock = -1;
+
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0) {
+               perror("socket");
+               exit(1);
+       }
+       fcntl(sock, F_SETFL, O_NONBLOCK);
+
+       memset(&local_addr, 0, sizeof(local_addr));
+       local_addr.ss_family = AF_INET; /* Default to IPv4 */
+
+       /* Bind source IP if provided on command line */
+       if (opt_srcaddr) {
+               struct addrinfo *ai = host_lookup(AF_INET, opt_srcaddr);
+               if (!ai) {
+                       nsm_log(LOG_WARNING,
+                               "Not a valid hostname or address: \"%s\"\n",
+                               opt_srcaddr);
+                       exit(1);
+               }
+               memcpy(&local_addr, ai->ai_addr, ai->ai_addrlen);
+               /* We know it's IPv4 at this point */
+       }
+
+       /* Use source port if provided on the command line,
+        * otherwise use bindresvport */
+       if (opt_srcport) {
+               addr_set_port(&local_addr, opt_srcport);
+               if (bind(sock, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) {
+                       perror("bind");
+                       exit(1);
+               }
+       } else {
+               (void) bindresvport(sock, (struct sockaddr_in *) &local_addr);
+       }
+
+       if (opt_max_retry)
+               failtime = time(NULL) + opt_max_retry;
+
+       drop_privs();
+
+       while (hosts) {
+               struct pollfd   pfd;
+               time_t          now = time(NULL);
+               unsigned int    sent = 0;
+               struct nsm_host *hp;
+               long            wait;
+
+               if (failtime && now >= failtime)
+                       break;
+
+               while ((wait = hosts->send_next - now) <= 0) {
+                       /* Never send more than 10 packets at once */
+                       if (sent++ >= 10)
+                               break;
+
+                       /* Remove queue head */
+                       hp = hosts;
+                       hosts = hp->next;
+
+                       notify_host(sock, hp);
+
+                       /* Set the timeout for this call, using an
+                          exponential timeout strategy */
+                       wait = hp->timeout;
+                       if ((hp->timeout <<= 1) > NSM_MAX_TIMEOUT)
+                               hp->timeout = NSM_MAX_TIMEOUT;
+                       hp->send_next = now + wait;
+                       hp->retries++;
+
+                       insert_host(hp);
+               }
+
+               nsm_log(LOG_DEBUG, "Host %s due in %ld seconds",
+                               hosts->name, wait);
+
+               pfd.fd = sock;
+               pfd.events = POLLIN;
+
+               wait *= 1000;
+               if (wait < 100)
+                       wait = 100;
+               if (poll(&pfd, 1, wait) != 1)
+                       continue;
+
+               recv_reply(sock);
+       }
+}
+
+/*
+ * Send notification to a single host
+ */
+void
+notify_host(int sock, struct nsm_host *host)
+{
+       static unsigned int     xid = 0;
+       nsm_address             dest;
+       uint32_t                msgbuf[MAXMSGSIZE], *p;
+       unsigned int            len;
+
+       if (!xid)
+               xid = getpid() + time(NULL);
+       if (!host->xid)
+               host->xid = xid++;
+
+       memset(msgbuf, 0, sizeof(msgbuf));
+       p = msgbuf;
+       *p++ = htonl(host->xid);
+       *p++ = 0;
+       *p++ = htonl(2);
+
+       /* If we retransmitted 4 times, reset the port to force
+        * a new portmap lookup (in case statd was restarted).
+        * We also rotate through multiple IP addresses at this
+        * point.
+        */
+       if (host->retries >= 4) {
+               struct addrinfo *hold = host->ai;
+               struct addrinfo **next = &host->ai;
+               *next = hold->ai_next;
+               while ( *next )
+                       next = & (*next)->ai_next;
+               *next = hold;
+               hold->ai_next = NULL;
+               memcpy(&host->addr, hold->ai_addr, hold->ai_addrlen);
+               addr_set_port(&host->addr, 0);
+               host->retries = 0;
+       }
+
+       dest = host->addr;
+       if (addr_get_port(&dest) == 0) {
+               /* Build a PMAP packet */
+               nsm_log(LOG_DEBUG, "Sending portmap query to %s", host->name);
+
+               addr_set_port(&dest, 111);
+               *p++ = htonl(100000);
+               *p++ = htonl(2);
+               *p++ = htonl(3);
+
+               /* Auth and verf */
+               *p++ = 0; *p++ = 0;
+               *p++ = 0; *p++ = 0;
+
+               *p++ = htonl(NSM_PROGRAM);
+               *p++ = htonl(NSM_VERSION);
+               *p++ = htonl(IPPROTO_UDP);
+               *p++ = 0;
+       } else {
+               /* Build an SM_NOTIFY packet */
+               nsm_log(LOG_DEBUG, "Sending SM_NOTIFY to %s", host->name);
+
+               *p++ = htonl(NSM_PROGRAM);
+               *p++ = htonl(NSM_VERSION);
+               *p++ = htonl(NSM_NOTIFY);
+
+               /* Auth and verf */
+               *p++ = 0; *p++ = 0;
+               *p++ = 0; *p++ = 0;
+
+               /* state change */
+               len = strlen(nsm_hostname);
+               *p++ = htonl(len);
+               memcpy(p, nsm_hostname, len);
+               p += (len + 3) >> 2;
+               *p++ = htonl(nsm_state);
+       }
+       len = (p - msgbuf) << 2;
+
+       sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest));
+}
+
+/*
+ * Receive reply from remote host
+ */
+void
+recv_reply(int sock)
+{
+       struct nsm_host *hp;
+       uint32_t        msgbuf[MAXMSGSIZE], *p, *end;
+       uint32_t        xid;
+       int             res;
+
+       res = recv(sock, msgbuf, sizeof(msgbuf), 0);
+       if (res < 0)
+               return;
+
+       nsm_log(LOG_DEBUG, "Received packet...");
+
+       p = msgbuf;
+       end = p + (res >> 2);
+
+       xid = ntohl(*p++);
+       if (*p++ != htonl(1)    /* must be REPLY */
+        || *p++ != htonl(0)    /* must be ACCEPTED */
+        || *p++ != htonl(0)    /* must be NULL verifier */
+        || *p++ != htonl(0)
+        || *p++ != htonl(0))   /* must be SUCCESS */
+               return;
+
+       /* Before we look at the data, find the host struct for
+          this reply */
+       if ((hp = find_host(xid)) == NULL)
+               return;
+
+       if (addr_get_port(&hp->addr) == 0) {
+               /* This was a portmap request */
+               unsigned int    port;
+
+               port = ntohl(*p++);
+               if (p > end)
+                       goto fail;
+
+               hp->send_next = time(NULL);
+               if (port == 0) {
+                       /* No binding for statd. Delay the next
+                        * portmap query for max timeout */
+                       nsm_log(LOG_DEBUG, "No statd on %s", hp->name);
+                       hp->timeout = NSM_MAX_TIMEOUT;
+                       hp->send_next += NSM_MAX_TIMEOUT;
+               } else {
+                       addr_set_port(&hp->addr, port);
+                       if (hp->timeout >= NSM_MAX_TIMEOUT / 4)
+                               hp->timeout = NSM_MAX_TIMEOUT / 4;
+               }
+               hp->xid = 0;
+       } else {
+               /* Successful NOTIFY call. Server returns void,
+                * so nothing we need to do here (except
+                * check that we didn't read past the end of the
+                * packet)
+                */
+               if (p <= end) {
+                       nsm_log(LOG_DEBUG, "Host %s notified successfully", hp->name);
+                       unlink(hp->path);
+                       free(hp->name);
+                       free(hp->path);
+                       free(hp);
+                       freeaddrinfo(hp->ai);
+                       return;
+               }
+       }
+
+fail:  /* Re-insert the host */
+       insert_host(hp);
+}
+
+/*
+ * Back up all hosts from the sm directory to sm.bak
+ */
+static void
+backup_hosts(const char *dirname, const char *bakname)
+{
+       struct dirent   *de;
+       DIR             *dir;
+
+       if (!(dir = opendir(dirname))) {
+               perror(dirname);
+               return;
+       }
+
+       while ((de = readdir(dir)) != NULL) {
+               char    src[1024], dst[1024];
+
+               if (de->d_name[0] == '.')
+                       continue;
+
+               snprintf(src, sizeof(src), "%s/%s", dirname, de->d_name);
+               snprintf(dst, sizeof(dst), "%s/%s", bakname, de->d_name);
+               if (rename(src, dst) < 0) {
+                       nsm_log(LOG_WARNING,
+                               "Failed to rename %s -> %s: %m",
+                               src, dst);
+               }
+       }
+       closedir(dir);
+}
+
+/*
+ * Get all entries from sm.bak and convert them to host names
+ */
+static void
+get_hosts(const char *dirname)
+{
+       struct nsm_host *host;
+       struct dirent   *de;
+       DIR             *dir;
+
+       if (!(dir = opendir(dirname))) {
+               perror(dirname);
+               return;
+       }
+
+       host = NULL;
+       while ((de = readdir(dir)) != NULL) {
+               struct stat     stb;
+               char            path[1024];
+
+               if (de->d_name[0] == '.')
+                       continue;
+               if (host == NULL)
+                       host = calloc(1, sizeof(*host));
+
+               snprintf(path, sizeof(path), "%s/%s", dirname, de->d_name);
+               if (stat(path, &stb) < 0)
+                       continue;
+
+               host->ai = host_lookup(AF_UNSPEC, de->d_name);
+               if (! host->ai) {
+                       nsm_log(LOG_WARNING,
+                               "%s doesn't seem to be a valid address, skipped",
+                               de->d_name);
+                       unlink(path);
+                       continue;
+               }
+
+               host->last_used = stb.st_mtime;
+               host->timeout = NSM_TIMEOUT;
+               host->path = strdup(path);
+               host->name = strdup(de->d_name);
+               host->retries = 100; /* force address retry */
+
+               insert_host(host);
+               host = NULL;
+       }
+       closedir(dir);
+
+       if (host)
+               free(host);
+}
+
+/*
+ * Insert host into sorted list
+ */
+void
+insert_host(struct nsm_host *host)
+{
+       struct nsm_host **where, *p;
+
+       where = &hosts;
+       while ((p = *where) != 0) {
+               /* Sort in ascending order of timeout */
+               if (host->send_next < p->send_next)
+                       break;
+               /* If we have the same timeout, put the
+                * most recently used host first.
+                * This makes sure that "recent" hosts
+                * get notified first.
+                */
+               if (host->send_next == p->send_next
+                && host->last_used > p->last_used)
+                       break;
+               where = &p->next;
+       }
+
+       host->next = *where;
+       *where = host;
+}
+
+/*
+ * Find host given the XID
+ */
+struct nsm_host *
+find_host(uint32_t xid)
+{
+       struct nsm_host **where, *p;
+
+       where = &hosts;
+       while ((p = *where) != 0) {
+               if (p->xid == xid) {
+                       *where = p->next;
+                       return p;
+               }
+               where = &p->next;
+       }
+       return NULL;
+}
+
+
+/*
+ * Retrieve the current NSM state
+ */
+unsigned int
+nsm_get_state(int update)
+{
+       char            newfile[PATH_MAX];
+       int             fd, state;
+
+       if ((fd = open(_SM_STATE_PATH, O_RDONLY)) < 0) {
+               if (!opt_quiet) {
+                       nsm_log(LOG_WARNING, "%s: %m", _SM_STATE_PATH);
+                       nsm_log(LOG_WARNING, "Creating %s, set initial state 1",
+                               _SM_STATE_PATH);
+               }
+               state = 1;
+               update = 1;
+       } else {
+               if (read(fd, &state, sizeof(state)) != sizeof(state)) {
+                       nsm_log(LOG_WARNING,
+                               "%s: bad file size, setting state = 1",
+                               _SM_STATE_PATH);
+                       state = 1;
+                       update = 1;
+               } else {
+                       if (!(state & 1))
+                               state += 1;
+               }
+               close(fd);
+       }
+
+       if (update) {
+               state += 2;
+               snprintf(newfile, sizeof(newfile),
+                               "%s.new", _SM_STATE_PATH);
+               if ((fd = open(newfile, O_CREAT|O_WRONLY, 0644)) < 0) {
+                       nsm_log(LOG_WARNING, "Cannot create %s: %m", newfile);
+                       exit(1);
+               }
+               if (write(fd, &state, sizeof(state)) != sizeof(state)) {
+                       nsm_log(LOG_WARNING,
+                               "Failed to write state to %s", newfile);
+                       exit(1);
+               }
+               close(fd);
+               if (rename(newfile, _SM_STATE_PATH) < 0) {
+                       nsm_log(LOG_WARNING,
+                               "Cannot create %s: %m", _SM_STATE_PATH);
+                       exit(1);
+               }
+               sync();
+       }
+
+       return state;
+}
+
+/*
+ * Address handling utilities
+ */
+
+int
+addr_get_port(nsm_address *addr)
+{
+       switch (((struct sockaddr *) addr)->sa_family) {
+       case AF_INET:
+               return ntohs(((struct sockaddr_in *) addr)->sin_port);
+       case AF_INET6:
+               return ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
+       }
+       return 0;
+}
+
+static void
+addr_set_port(nsm_address *addr, int port)
+{
+       switch (((struct sockaddr *) addr)->sa_family) {
+       case AF_INET:
+               ((struct sockaddr_in *) addr)->sin_port = htons(port);
+               break;
+       case AF_INET6:
+               ((struct sockaddr_in6 *) addr)->sin6_port = htons(port);
+       }
+}
+
+static struct addrinfo *
+host_lookup(int af, const char *name)
+{
+       struct addrinfo hints, *ai;
+
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = af;
+       hints.ai_protocol = IPPROTO_UDP;
+
+       if (getaddrinfo(name, NULL, &hints, &ai) != 0)
+               return NULL;
+
+       return ai;
+}
+
+/*
+ * Log a message
+ */
+void
+nsm_log(int fac, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (fac == LOG_DEBUG && !opt_debug)
+               return;
+
+       va_start(ap, fmt);
+       if (log_syslog)
+               vsyslog(fac, fmt, ap);
+       else {
+               vfprintf(stderr, fmt, ap);
+               fputs("\n", stderr);
+       }
+       va_end(ap);
+}
+
+/*
+ * Record pid in /var/run/sm-notify.pid
+ * This file should remain until a reboot, even if the
+ * program exits.
+ * If file already exists, fail.
+ */
+static int record_pid()
+{
+       char pid[20];
+       int fd;
+
+       snprintf(pid, 20, "%d\n", getpid());
+       fd = open("/var/run/sm-notify.pid", O_CREAT|O_EXCL|O_WRONLY, 0600);
+       if (fd < 0)
+               return 0;
+       write(fd, pid, strlen(pid));
+       close(fd);
+       return 1;
+}
+
+/* Drop privileges to match owner of state-directory
+ * (in case a reply triggers some unknown bug).
+ */
+static void drop_privs(void)
+{
+       struct stat st;
+
+       if (stat(_SM_DIR_PATH, &st) == -1 &&
+           stat(_SM_BASE_PATH, &st) == -1) {
+               st.st_uid = 0;
+               st.st_gid = 0;
+       }
+
+       if (st.st_uid == 0) {
+               nsm_log(LOG_WARNING,
+                       "sm-notify running as root. chown %s to choose different user\n",
+                   _SM_DIR_PATH);
+               return;
+       }
+
+       setgroups(0, NULL);
+       if (setgid(st.st_gid) == -1
+           || setuid(st.st_uid) == -1) {
+               nsm_log(LOG_ERR, "Fail to drop privileges");
+               exit(1);
+       }
+}
diff --git a/utils/statd/sm-notify.man b/utils/statd/sm-notify.man
new file mode 100644 (file)
index 0000000..dd03b8d
--- /dev/null
@@ -0,0 +1,166 @@
+.\"
+.\" sm-notify(8)
+.\"
+.\" Copyright (C) 2004 Olaf Kirch <okir@suse.de>
+.TH sm-notify 8 "19 Mar 2007
+.SH NAME
+sm-notify \- Send out NSM reboot notifications
+.SH SYNOPSIS
+.BI "/sbin/sm-notify [-dfq] [-m " time "] [-p " port "] [-P " path "] [-v " my_name " ]
+.SH DESCRIPTION
+File locking over NFS (v2 and v3) requires a facility to notify peers in
+case of a reboot, so that clients can reclaim locks after
+a server crash, and/or
+servers can release locks held by the rebooted client.
+.PP
+This is a two-step process: during normal
+operations, a mechanism is required to keep track of which
+hosts need to be informed of a reboot. And of course,
+notifications need to be sent out during reboot.
+The protocol used for this is called NSM, for
+.IR "Network Status Monitor" .
+.PP
+This implementation separates these into separate program.
+.B rpc.statd
+tracks hosts which need to be notified and this
+.B sm-notify
+performs the notification.  When
+.B rpc.statd
+is started it will typically started
+.B sm-notify
+but this is configurable.
+.SS Operation
+For each NFS client or server machine to be monitored,
+.B rpc.statd
+creates a file in
+.BR /var/lib/nfs/sm ", "
+and removes the file if monitoring is no longer required.
+.PP
+When the machine is rebooted,
+.B sm-notify
+iterates through these files and notifies the peer
+.B statd
+server on those machines.
+.PP
+Each machine has an
+.I "NSM state" ,
+which is basically an integer counter that is incremented
+each time the machine reboots. This counter is stored
+in
+.BR /var/lib/nfs/state ,
+and updated by
+.BR sm-notify .
+.SS Security
+.B sm-notify
+has little need for root privileges and so drops them as soon as
+possible.
+It continues to need to make changes to the
+.B sm
+and
+.B sm.bak
+directories so to be able to drop privileges, these must be writable
+by a non-privileged user.  If these directories are owned by a
+non-root user,
+.B sm-notify
+will drop privilege to match that user once it has created sockets for
+sending out request (for which it needs privileged) but before it
+processes any reply (which is the most likely source of possible
+privilege abuse).
+.SH OPTIONS
+.TP
+.BI -m " failtime
+When notifying hosts,
+.B sm-notify
+will try to contact each host for up to 15 minutes,
+and will give up if unable to reach it within this time
+frame.
+.IP
+Using the
+.B -m
+option, you can override this. A value of 0 tells
+sm-notify to retry indefinitely; any other value is
+interpreted as the maximum retry time in minutes.
+.TP
+.BI -v " ipaddr-or-hostname
+This option tells
+.B sm-notify
+to bind to the specified
+.IR ipaddr ,
+(or the ipaddr of the given
+.IR hostname )
+so that all notification packets originate from this address.
+This is useful for NFS failover.  The given name is also used as the
+.I name
+of this host in the NSM request.
+.TP
+.BI -p " port
+instructs
+.B sm-notify
+to bind to the indicated IP
+.IR port
+number. If this option is not given, it will try to bind to
+a randomly chosen privileged port below 1024.
+.TP
+.B -q
+Be quiet. This suppresses all messages except error
+messages while collecting the list of hosts.
+.TP
+.BI -P " /path/to/state/directory
+If
+.B sm-notify
+should look in a no-standard place of state file, the path can be
+given here.  The directories
+.B sm
+and
+.B sm.bak
+and the file
+.B state
+must exist in that directory with the standard names.
+.TP
+.B -f
+If the state path has not been reset with
+.BR -P ,
+.B sm-notify
+will normally create a file in
+.B /var/run
+to indicate that it has been
+run.  If this file is found when
+.B sm-notify
+starts, it will not run again (as it is normally only needed once per
+reboot).
+If
+.B -f
+(for
+.BR force )
+is given,
+.B sm-notify
+will run even if the file in
+.B /var/run
+is present.
+.TP
+.B -n
+Do not update the NSM state. This is for testing only.  Setting this
+flag implies
+.BR -f .
+.TP
+.B -d
+Enables debugging.
+By default,
+.B sm-notify
+forks and puts itself in the background after obtaining the
+list of hosts from
+.BR /var/lib/nfs/sm .
+.SH FILES
+.BR /var/lib/nfs/state
+.br
+.BR /var/lib/nfs/sm/*
+.br
+.BR /var/lib/nfs/sm.bak/*
+.br
+.BR /var/run/sm-notify.pid
+.SH SEE ALSO
+.BR rpc.nfsd(8),
+.BR portmap(8)
+.SH AUTHORS
+.br
+Olaf Kirch <okir@suse.de>
diff --git a/utils/statd/start-statd b/utils/statd/start-statd
new file mode 100644 (file)
index 0000000..6e7ea04
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+# nfsmount calls this script when mounting a filesystem with locking
+# enabled, but when statd does not seem to be running (based on
+# /var/run/rpc.statd.pid).
+# It should run run statd with whatever flags are apropriate for this
+# site.
+PATH=/sbin:/usr/sbin
+exec rpc.statd --no-notify
+
index c92e12f29c3a72d1c4bb84a9f51b3c8f5e344e61..091ced9316e9220408fb7799004c297b8c0fd9ec 100644 (file)
@@ -23,6 +23,7 @@
 #include <rpc/pmap_clnt.h>
 #include <rpcmisc.h>
 #include <sys/resource.h>
+#include <sys/wait.h>
 #include <grp.h>
 #include "statd.h"
 #include "version.h"
@@ -44,7 +45,6 @@ char *  SM_STAT_PATH = DEFAULT_SM_STAT_PATH;
 
 /* ----- end of state directory path stuff ------- */
 
-short int restart = 0;
 int    run_mode = 0;           /* foreground logging mode */
 
 /* LH - I had these local to main, but it seemed silly to have 
@@ -70,11 +70,12 @@ static struct option longopts[] =
        { "state-directory-path", 1, 0, 'P' },
        { "notify-mode", 0, 0, 'N' },
        { "ha-callout", 1, 0, 'H' },
+       { "no-notify", 0, 0, 'L' },
        { NULL, 0, 0, 0 }
 };
 
 extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
-extern int statd_get_socket(int port);
+extern int statd_get_socket(void);
 
 #ifdef SIMULATIONS
 extern void simulator (int, char **);
@@ -107,8 +108,7 @@ static void
 killer (int sig)
 {
        note (N_FATAL, "Caught signal %d, un-registering and exiting.", sig);
-       if (!(run_mode & MODE_NOTIFY_ONLY))
-               pmap_unset (SM_PROG, SM_VERS);
+       pmap_unset (SM_PROG, SM_VERS);
 
        exit (0);
 }
@@ -116,9 +116,10 @@ killer (int sig)
 static void
 sigusr (int sig)
 {
+       extern void my_svc_exit (void);
        dprintf (N_DEBUG, "Caught signal %d, re-notifying (state %d).", sig,
                                                                MY_STATE);
-       re_notify = 1;
+       my_svc_exit();
 }
 
 /*
@@ -138,16 +139,7 @@ static void log_modes(void)
        if (run_mode & MODE_LOG_STDERR)
                strcat(buf,"Log-STDERR ");
 
-       if (run_mode & MODE_NOTIFY_ONLY)
-       {
-               strcat(buf,"Notify-Only ");
-       }
        note(N_WARNING,buf);
-       /* future: IP aliasing
-       if (run_mode & MODE_NOTIFY_ONLY)
-       {
-               dprintf(N_DEBUG,"Notify IP: %s",svr_addr);
-       } */
 }
 
 /*
@@ -167,6 +159,7 @@ usage()
        fprintf(stderr,"      -n, --name           Specify a local hostname.\n");
        fprintf(stderr,"      -P                   State directory path.\n");
        fprintf(stderr,"      -N                   Run in notify only mode.\n");
+       fprintf(stderr,"      -L, --no-notify      Do not perform any notification.\n");
        fprintf(stderr,"      -H                   Specify a high-availability callout program.\n");
 }
 
@@ -223,6 +216,29 @@ static void drop_privs(void)
        }
 }
 
+static void run_sm_notify(int outport)
+{
+       char op[20];
+       char *av[6];
+       int ac = 0;
+
+       av[ac++] = "/usr/sbin/sm-notify";
+       if (run_mode & MODE_NODAEMON)
+               av[ac++] = "-d";
+       if (outport) {
+               sprintf(op, "-p%d", outport);
+               av[ac++] = op;
+       }
+       if (run_mode & STATIC_HOSTNAME) {
+               av[ac++] = "-v";
+               av[ac++] = MY_NAME;
+       }
+       av[ac] = NULL;
+       execv(av[0], av);
+       fprintf(stderr, "%s: failed to run %s\n", name_p, av[0]);
+       exit(2);
+
+}
 /* 
  * Entry routine/main loop.
  */
@@ -258,7 +274,7 @@ int main (int argc, char **argv)
        MY_NAME = NULL;
 
        /* Process command line switches */
-       while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:", longopts, NULL)) != EOF) {
+       while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:L", longopts, NULL)) != EOF) {
                switch (arg) {
                case 'V':       /* Version */
                case 'v':
@@ -270,6 +286,9 @@ int main (int argc, char **argv)
                case 'N':
                        run_mode |= MODE_NOTIFY_ONLY;
                        break;
+               case 'L': /* Listen only */
+                       run_mode |= MODE_NO_NOTIFY;
+                       break;
                case 'd':       /* No daemon only - log to stderr */
                        run_mode |= MODE_LOG_STDERR;
                        break;
@@ -347,6 +366,13 @@ int main (int argc, char **argv)
                exit(-1);
        }
 
+       if (run_mode & MODE_NOTIFY_ONLY) {
+               fprintf(stderr, "%s: -N deprecated, consider using /usr/sbin/sm-notify directly\n",
+                       name_p);
+               run_sm_notify(out_port);
+       }
+
+
        if (!(run_mode & MODE_NODAEMON)) {
                run_mode &= ~MODE_LOG_STDERR;   /* Never log to console in
                                                   daemon mode. */
@@ -435,49 +461,68 @@ int main (int argc, char **argv)
         */
        signal(SIGPIPE, SIG_IGN);
 
-       /* initialize out_port */
-       statd_get_socket(out_port);
-
        create_pidfile();
        atexit(truncate_pidfile);
-       drop_privs();
 
-       for (;;) {
-               if (!(run_mode & MODE_NOTIFY_ONLY)) {
-                       /* Do not do pmap_unset() when running in notify mode.
-                        * We may clear the portmapper record for a statd not
-                        * running in notify mode disabling it.
-                        * Juan C. Gomez j_carlos_gomez@yahoo.com
-                        */
-                       pmap_unset (SM_PROG, SM_VERS);
+       if (! (run_mode & MODE_NO_NOTIFY))
+               switch (pid = fork()) {
+               case 0:
+                       run_sm_notify(out_port);
+                       break;
+               case -1:
+                       break;
+               default:
+                       waitpid(pid, NULL, 0);
                }
-               change_state ();
-               shuffle_dirs ();        /* Move directory names around */
 
-               /* If we got this far, we have successfully started, so notify parent */
-               if (pipefds[1] > 0) {
-                       status = 0;
-                       write(pipefds[1], &status, 1);
-                       close(pipefds[1]);
-                       pipefds[1] = -1;
-               }
+       /* Make sure we have a privilege port for calling into the kernel */
+       statd_get_socket();
+
+       /* If sm-notify didn't take all the state files, load
+        * state information into our notify-list so we can
+        * pass on any SM_NOTIFY that arrives
+        */
+       load_state();
 
-               notify_hosts ();        /* Send out notify requests */
-               ++restart;
+       pmap_unset (SM_PROG, SM_VERS);
 
-               /* this registers both UDP and TCP services */
-               if (!(run_mode & MODE_NOTIFY_ONLY)) {
-                       rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
-               } 
+       /* this registers both UDP and TCP services */
+       rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
 
+       /* If we got this far, we have successfully started, so notify parent */
+       if (pipefds[1] > 0) {
+               status = 0;
+               write(pipefds[1], &status, 1);
+               close(pipefds[1]);
+               pipefds[1] = -1;
+       }
+
+       drop_privs();
+
+       for (;;) {
                /*
                 * Handle incoming requests:  SM_NOTIFY socket requests, as
                 * well as callbacks from lockd.
                 */
                my_svc_run();   /* I rolled my own, Olaf made it better... */
 
-               if ((run_mode & MODE_NOTIFY_ONLY))
-                       break;                  
+               /* Only get here when simulating a crash so we should probably
+                * start sm-notify running again.  As we have already dropped
+                * privileges, this might not work, but I don't think
+                * responding to SM_SIMU_CRASH is an important use cases to
+                * get perfect.
+                */
+               if (! (run_mode & MODE_NO_NOTIFY))
+                       switch (pid = fork()) {
+                       case 0:
+                               run_sm_notify(out_port);
+                               break;
+                       case -1:
+                               break;
+                       default:
+                               waitpid(pid, NULL, 0);
+                       }
+
        }
        return 0;
 }
index ace2ce507043e113ec8c771098ded3c1f107252a..b7ea40b54d6fe5e769de933571daa4cc71e5b411 100644 (file)
@@ -54,6 +54,7 @@ extern int    process_reply(FD_SET_TYPE *);
 extern char *  xstrdup(const char *);
 extern void *  xmalloc(size_t);
 extern void    xunlink (char *, char *, short int);
+extern void    load_state(void);
 
 /*
  * Host status structure and macros.
@@ -82,7 +83,7 @@ extern int run_mode;
  * that just came back up, for ex, when failing over a HA service to
  * another host.... */
 #define STATIC_HOSTNAME 8      /* Always use the hostname set by -n */
-
+#define        MODE_NO_NOTIFY  16      /* Don't notify peers of a reboot */
 /*
  * Program name and version pointers -- See statd.c for the reasoning
  * as to why they're global.
@@ -90,4 +91,3 @@ extern int run_mode;
 extern char *name_p;           /* program basename */
 extern const char *version_p;  /* program version */
 
-extern int             re_notify; /* time to re-read notify list */
index ce29dfdfba200a7540fd5448d8e963b28e6d5dc9..e8be9f3b4fb12d1035f3898050eb7710c321617b 100644 (file)
@@ -9,7 +9,7 @@
 .SH NAME
 rpc.statd \- NSM status monitor
 .SH SYNOPSIS
-.B "rpc.statd [-F] [-d] [-?] [-n " name "] [-o " port "] [-p " port "] [-H " prog "] [-V]"
+.B "rpc.statd [-FNL] [-d] [-?] [-n " name "] [-o " port "] [-p " port "] [-H " prog "] [-V]"
 .SH DESCRIPTION
 The
 .B rpc.statd
@@ -25,7 +25,9 @@ For each NFS client or server machine to be monitored,
 .B rpc.statd
 creates a file in
 .BR /var/lib/nfs/sm .
-When starting, it iterates through these files and notifies the
+When starting, it normally runs
+.B sm-notify
+to iterate through these files and notify the
 peer
 .B rpc.statd
 on those machines.
@@ -101,6 +103,21 @@ Causes statd to run in the notify-only mode. When started in this mode, the
 statd program will check its state directory, send notifications to any
 monitored nodes, and exit once the notifications have been sent. This mode is
 used to enable Highly Available NFS implementations (i.e. HA-NFS).
+This mode is deprecated \-
+.B sm-notify
+should be used directly instead.
+.TP
+.BR -L , " --no-notify
+Inhibits the running of
+.BR sm-notify .
+If
+.B sm-notify
+is run by some other script at boot time, there is no need for
+.B statd
+to start sm-notify itself.  This can be appropriate if starting of
+statd needs to be delayed until it is actually need.  In such cases
+.B sm-notify
+should still be run at boot time.
 .TP
 .BI "\-H, " "" " \-\-ha-callout " prog
 Specify a high availability callout program, which will receive callouts
diff --git a/utils/statd/state.c b/utils/statd/state.c
deleted file mode 100644 (file)
index f46dae5..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 1995-1997, 1999 Jeffrey A. Uphoff
- * Modified by Olaf Kirch, 1996.
- * Modified by H.J. Lu, 1998.
- *
- * NSM for Linux.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "statd.h"
-
-
-/* 
- * Most NSM's keep the status number in an ASCII file.  I'm keeping it
- * as an int (4-byte binary) for now...
- */
-void
-change_state (void)
-{
-  int fd, size;
-  
-  if ((fd = open (SM_STAT_PATH, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) == -1)
-    die ("open (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if ((size = read (fd, &MY_STATE, sizeof MY_STATE)) == -1)
-    die ("read (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if (size != 0 && size != sizeof MY_STATE) {
-    note (N_ERROR, "Error in status file format...correcting.");
-
-    if (close (fd) == -1)
-      die ("close (%s): %s", SM_STAT_PATH, strerror (errno));
-
-    if ((fd = creat (SM_STAT_PATH, S_IRUSR | S_IWUSR)) == -1)
-      die ("creat (%s): %s", SM_STAT_PATH, strerror (errno));
-  }
-  note (N_DEBUG, "New state: %u", (++MY_STATE % 2) ? MY_STATE : ++MY_STATE);
-
-  if (lseek (fd, 0, SEEK_SET) == -1)
-    die ("lseek (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if (write (fd, &MY_STATE, sizeof MY_STATE) != sizeof MY_STATE)
-    die ("write (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if (fsync (fd) == -1)
-    note (N_ERROR, "fsync (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if (close (fd) == -1)
-    note (N_ERROR, "close (%s): %s", SM_STAT_PATH, strerror (errno));
-
-  if (MY_NAME == NULL) {
-    char fullhost[SM_MAXSTRLEN + 1];
-    struct hostent *hostinfo;
-
-    if (gethostname (fullhost, SM_MAXSTRLEN) == -1)
-      die ("gethostname: %s", strerror (errno));
-
-    if ((hostinfo = gethostbyname (fullhost)) == NULL)
-      note (N_ERROR, "gethostbyname error for %s", fullhost);
-    else {
-      strncpy (fullhost, hostinfo->h_name, sizeof (fullhost) - 1);
-      fullhost[sizeof (fullhost) - 1] = '\0';
-    }
-
-    MY_NAME = xstrdup (fullhost);
-  }
-}
-
-
-/* 
- * Fairly traditional use of two directories for this.
- */
-void 
-shuffle_dirs (void)
-{
-  DIR *nld;
-  struct dirent *de;
-  struct stat st;
-  char *src, *dst;
-  int len1, len2, len;
-  
-  if (stat (SM_DIR, &st) == -1 && errno != ENOENT)
-    die ("stat (%s): %s", SM_DIR, strerror (errno));
-
-  if (!S_ISDIR (st.st_mode))
-    if (mkdir (SM_DIR, S_IRWXU) == -1)
-      die ("mkdir (%s): %s", SM_DIR, strerror (errno));
-
-  memset (&st, 0, sizeof st);
-
-  if (stat (SM_BAK_DIR, &st) == -1 && errno != ENOENT)
-    die ("stat (%s): %s", SM_BAK_DIR, strerror (errno));
-
-  if (!S_ISDIR (st.st_mode))
-    if (mkdir (SM_BAK_DIR, S_IRWXU) == -1)
-      die ("mkdir (%s): %s", SM_BAK_DIR, strerror (errno));
-
-  if (!(nld = opendir (SM_DIR)))
-    die ("opendir (%s): %s", SM_DIR, strerror (errno));
-
-  len1=strlen(SM_DIR);
-  len2=strlen(SM_BAK_DIR);
-  while ((de = readdir (nld))) {
-    if (de->d_name[0] == '.')
-      continue;
-    len=strlen(de->d_name);
-    src=xmalloc(len1+len+2);
-    dst=xmalloc(len2+len+2);
-    sprintf (src, "%s/%s", SM_DIR, de->d_name);
-    sprintf (dst, "%s/%s", SM_BAK_DIR, de->d_name);
-    if (rename (src, dst) == -1)
-      die ("rename (%s to %s): %s", SM_DIR, SM_BAK_DIR, strerror (errno));
-    free(src);
-    free(dst);
-  }
-  if (closedir (nld) == -1)
-    note (N_ERROR, "closedir (%s): %s", SM_DIR, strerror (errno));
-}
index 67bb05cccfed5a486f8e294a5f575a3c961b2b43..a33da0d634289ae979500b778b1fc79568d41472 100644 (file)
@@ -64,7 +64,6 @@ static int    svc_stop = 0;
  * requests are put.
  */
 notify_list *  notify = NULL;
-int    re_notify = 0;
 
 /*
  * Jump-off function.
@@ -91,13 +90,6 @@ my_svc_run(void)
        for (;;) {
                if (svc_stop)
                        return;
-               if (re_notify) {
-                       change_state();
-                       dprintf(N_DEBUG, "Notifying...(new state %d)",
-                                                               MY_STATE);
-                       notify_hosts();
-                       re_notify = 0;
-               }
 
                /* Ah, there are some notifications to be processed */
                while (notify && NL_WHEN(notify) <= time(&now)) {
@@ -114,9 +106,7 @@ my_svc_run(void)
                                                        tv.tv_sec);
                        selret = select(FD_SETSIZE, &readfds,
                                (void *) 0, (void *) 0, &tv);
-               } else if (run_mode & MODE_NOTIFY_ONLY)
-                       return;
-               else {
+               } else {
                        dprintf(N_DEBUG, "Waiting for client connections.");
                        selret = select(FD_SETSIZE, &readfds,
                                (void *) 0, (void *) 0, (struct timeval *) 0);