From: Ben Hutchings Date: Wed, 14 Jul 2010 01:49:26 +0000 (+0100) Subject: Merge branch 'upstream' X-Git-Tag: debian/1%1.1.0_rc1-1~1 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=4f7fc41f6324daad94c37e9327567d27a0d50afe;hp=54354b74c2597f58901bf4824fc233fdcfe1add1 Merge branch 'upstream' 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 --- diff --git a/Makefile.am b/Makefile.am index c04e9de..ec8e832 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.in b/Makefile.in index aa32357..41514d5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 adb9e66..fe3571a 100644 --- 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. diff --git a/aclocal.m4 b/aclocal.m4 index 31a9f5d..e90a163 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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 diff --git a/aclocal/kerberos5.m4 b/aclocal/kerberos5.m4 index 1dac9f0..b83e122 100644 --- a/aclocal/kerberos5.m4 +++ b/aclocal/kerberos5.m4 @@ -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 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 . +# +# 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 or send patches to +# . + +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 . +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: diff --git a/configure b/configure index bcf3b6b..0f561ff 100755 --- 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 . # @@ -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 + /* 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 + /* 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 + /* 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 + /* 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 + /* 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 < conftest.$ac_ext <&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 ." _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 index 0000000..65a2d02 --- /dev/null +++ b/configure.ac @@ -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 index 61e5be2..0000000 --- a/configure.in +++ /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 - diff --git a/linux-nfs/Makefile.in b/linux-nfs/Makefile.in index 8bb936c..a0e0b7d 100644 --- a/linux-nfs/Makefile.in +++ b/linux-nfs/Makefile.in @@ -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@ diff --git a/support/Makefile.in b/support/Makefile.in index 49d346d..2759d3d 100644 --- a/support/Makefile.in +++ b/support/Makefile.in @@ -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@ diff --git a/support/export/Makefile.am b/support/export/Makefile.am index 7a6a441..1ea1539 100644 --- a/support/export/Makefile.am +++ b/support/export/Makefile.am @@ -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 diff --git a/support/export/Makefile.in b/support/export/Makefile.in index 8d1c342..8effbc7 100644 --- a/support/export/Makefile.in +++ b/support/export/Makefile.in @@ -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 diff --git a/support/export/client.c b/support/export/client.c index 33dfdb0..686c744 100644 --- a/support/export/client.c +++ b/support/export/client.c @@ -329,6 +329,7 @@ add_name(char *old, char *add) strcat(new, ","); strcat(new, cp); } + free(old); return new; } diff --git a/support/export/export.c b/support/export/export.c index a4b0788..74e1d1b 100644 --- a/support/export/export.c +++ b/support/export/export.c @@ -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; diff --git a/support/export/nfsctl.c b/support/export/nfsctl.c index b74334c..32d92bd 100644 --- a/support/export/nfsctl.c +++ b/support/export/nfsctl.c @@ -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); diff --git a/support/include/Makefile.in b/support/include/Makefile.in index 72ced48..f5f9204 100644 --- a/support/include/Makefile.in +++ b/support/include/Makefile.in @@ -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@ diff --git a/support/include/config.h.in b/support/include/config.h.in index f288aa0..19ff77c 100644 --- a/support/include/config.h.in +++ b/support/include/config.h.in @@ -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 @@ -319,6 +319,9 @@ 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 @@ -376,6 +379,9 @@ 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 @@ -385,6 +391,9 @@ /* Define to 1 if your 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 */ @@ -393,6 +402,12 @@ /* 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 diff --git a/support/include/conn.h b/support/include/conn.h index 1761dc4..11f16ab 100644 --- a/support/include/conn.h +++ b/support/include/conn.h @@ -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); diff --git a/support/include/exportfs.h b/support/include/exportfs.h index 458611b..431b5ce 100644 --- a/support/include/exportfs.h +++ b/support/include/exportfs.h @@ -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]; diff --git a/support/include/fstab.h b/support/include/fstab.h index 52af743..64c8355 100644 --- a/support/include/fstab.h +++ b/support/include/fstab.h @@ -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 */ diff --git a/support/include/nfs/Makefile.in b/support/include/nfs/Makefile.in index 27d42c1..52289f5 100644 --- a/support/include/nfs/Makefile.in +++ b/support/include/nfs/Makefile.in @@ -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@ diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h index f0286b2..fc26f4e 100644 --- a/support/include/nfs/nfs.h +++ b/support/include/nfs/nfs.h @@ -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))) diff --git a/support/include/nfs_mntent.h b/support/include/nfs_mntent.h index 76f348e..010df24 100644 --- a/support/include/nfs_mntent.h +++ b/support/include/nfs_mntent.h @@ -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 #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 */ diff --git a/support/include/nfslib.h b/support/include/nfslib.h index c085029..d4f4150 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -51,12 +51,6 @@ #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); diff --git a/support/include/rpcsvc/Makefile.in b/support/include/rpcsvc/Makefile.in index 038caff..787af32 100644 --- a/support/include/rpcsvc/Makefile.in +++ b/support/include/rpcsvc/Makefile.in @@ -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@ diff --git a/support/include/sys/Makefile.in b/support/include/sys/Makefile.in index 35df56c..0e1f114 100644 --- a/support/include/sys/Makefile.in +++ b/support/include/sys/Makefile.in @@ -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@ diff --git a/support/include/sys/fs/Makefile.in b/support/include/sys/fs/Makefile.in index a8019c7..f21fcfa 100644 --- a/support/include/sys/fs/Makefile.in +++ b/support/include/sys/fs/Makefile.in @@ -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@ diff --git a/support/misc/Makefile.in b/support/misc/Makefile.in index ba6f4ce..e5ffdad 100644 --- a/support/misc/Makefile.in +++ b/support/misc/Makefile.in @@ -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@ diff --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am index af8181d..6006df6 100644 --- a/support/nfs/Makefile.am +++ b/support/nfs/Makefile.am @@ -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 diff --git a/support/nfs/Makefile.in b/support/nfs/Makefile.in index b6bf372..d29596e 100644 --- a/support/nfs/Makefile.in +++ b/support/nfs/Makefile.in @@ -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@ diff --git a/support/nfs/conn.c b/support/nfs/conn.c index 89f7676..29dbb82 100644 --- a/support/nfs/conn.c +++ b/support/nfs/conn.c @@ -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: diff --git a/support/nfs/exports.c b/support/nfs/exports.c index 294e1c9..0baa5d0 100644 --- a/support/nfs/exports.c +++ b/support/nfs/exports.c @@ -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) { diff --git a/support/nfs/fstab.c b/support/nfs/fstab.c index 8dc7d66..aee8e53 100644 --- a/support/nfs/fstab.c +++ b/support/nfs/fstab.c @@ -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 index ca1e862..0000000 --- a/support/nfs/lockdsvc.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * support/nfs/nfssvc.c - * - * Run an NFS daemon. - * - * Copyright (C) 1995, 1996 Olaf Kirch - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -int -lockdsvc() -{ - struct nfsctl_arg arg; - - arg.ca_version = NFSCTL_VERSION; - return nfsctl(LOCKDCTL_SVC, &arg, NULL); -} diff --git a/support/nfs/nfs_mntent.c b/support/nfs/nfs_mntent.c index d1d124b..a3fecfc 100644 --- a/support/nfs/nfs_mntent.c +++ b/support/nfs/nfs_mntent.c @@ -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: diff --git a/support/nfs/rpcmisc.c b/support/nfs/rpcmisc.c index 5b0a88f..22ea62c 100644 --- a/support/nfs/rpcmisc.c +++ b/support/nfs/rpcmisc.c @@ -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. diff --git a/support/nfs/svc_socket.c b/support/nfs/svc_socket.c index 3307600..6799d16 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -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 diff --git a/tools/Makefile.am b/tools/Makefile.am index 515da13..db15346 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -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 diff --git a/tools/Makefile.in b/tools/Makefile.in index 4c3b03b..977651c 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -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 index 7d7172e..0000000 --- a/tools/getiversion/Makefile.am +++ /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 index fdaf102..0000000 --- a/tools/getiversion/getiversion.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * getiversion - * - * Get version number for an inode on an ext2 file system. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif - -#include -#include - -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; -} diff --git a/tools/locktest/Makefile.in b/tools/locktest/Makefile.in index 0a497c9..6c4cdb0 100644 --- a/tools/locktest/Makefile.in +++ b/tools/locktest/Makefile.in @@ -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@ diff --git a/tools/nlmtest/Makefile.in b/tools/nlmtest/Makefile.in index 0836e6e..d150c51 100644 --- a/tools/nlmtest/Makefile.in +++ b/tools/nlmtest/Makefile.in @@ -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@ diff --git a/tools/rpcdebug/Makefile.in b/tools/rpcdebug/Makefile.in index 663fff0..1745ae6 100644 --- a/tools/rpcdebug/Makefile.in +++ b/tools/rpcdebug/Makefile.in @@ -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/tools/rpcgen/Makefile.in b/tools/rpcgen/Makefile.in index b322c8b..27f2e2b 100644 --- a/tools/rpcgen/Makefile.in +++ b/tools/rpcgen/Makefile.in @@ -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/Makefile.am b/utils/Makefile.am index 723657c..c1bc059 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -20,7 +20,6 @@ endif SUBDIRS = \ exportfs \ - lockd \ mountd \ nfsd \ nfsstat \ diff --git a/utils/Makefile.in b/utils/Makefile.in index ce06a2f..fb83360 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -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 \ diff --git a/utils/exportfs/Makefile.in b/utils/exportfs/Makefile.in index 37211b1..7d5ef33 100644 --- a/utils/exportfs/Makefile.in +++ b/utils/exportfs/Makefile.in @@ -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@ diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 22e13a3..8c3f634 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -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) diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man index ab63b03..41a5b16 100644 --- a/utils/exportfs/exports.man +++ b/utils/exportfs/exports.man @@ -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. diff --git a/utils/gssd/Makefile.in b/utils/gssd/Makefile.in index 41503ab..1132bc4 100644 --- a/utils/gssd/Makefile.in +++ b/utils/gssd/Makefile.in @@ -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@ diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c index 9988fe4..747637c 100644 --- a/utils/gssd/gssd.c +++ b/utils/gssd/gssd.c @@ -53,16 +53,19 @@ #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"); diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h index ec91e89..6b96ce1 100644 --- a/utils/gssd/gssd.h +++ b/utils/gssd/gssd.h @@ -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; diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man index 250d26f..f2ecd69 100644 --- a/utils/gssd/gssd.man +++ b/utils/gssd/gssd.man @@ -2,11 +2,11 @@ .\" rpc.gssd(8) .\" .\" Copyright (C) 2003 J. Bruce Fields -.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 diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c index a086bb3..0559f7b 100644 --- a/utils/gssd/gssd_main_loop.c +++ b/utils/gssd/gssd_main_loop.c @@ -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); diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c index 68d645d..3b190f2 100644 --- a/utils/gssd/gssd_proc.c +++ b/utils/gssd/gssd_proc.c @@ -80,19 +80,19 @@ * 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; } diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 096f6cf..f1682b8 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -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))) { diff --git a/utils/idmapd/Makefile.in b/utils/idmapd/Makefile.in index a005429..fc12c8e 100644 --- a/utils/idmapd/Makefile.in +++ b/utils/idmapd/Makefile.in @@ -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 index e1546a4..0000000 --- a/utils/lockd/Makefile.am +++ /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 index 71b31b0..0000000 --- a/utils/lockd/lockd.c +++ /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 -#endif - -#include -#include -#include -#include -#include - - - -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 index aa76019..0000000 --- a/utils/lockd/lockd.man +++ /dev/null @@ -1,24 +0,0 @@ -.\" -.\" lockd(8) -.\" -.\" Copyright (C) 2000 Chip Salzenberg -.\" -.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 diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am index 4a2f437..07e86e4 100644 --- a/utils/mount/Makefile.am +++ b/utils/mount/Makefile.am @@ -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) diff --git a/utils/mount/Makefile.in b/utils/mount/Makefile.in index faff61d..55da8fa 100644 --- a/utils/mount/Makefile.in +++ b/utils/mount/Makefile.in @@ -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: diff --git a/utils/mount/mount.c b/utils/mount/mount.c index 5e0e599..52b0d67 100644 --- a/utils/mount/mount.c +++ b/utils/mount/mount.c @@ -28,6 +28,7 @@ #include #include #include +#include #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 index 0000000..673556c --- /dev/null +++ b/utils/mount/nfs.man @@ -0,0 +1,464 @@ +.\" nfs.5 "Rick Sladkey" +.\" 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" +.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. diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c index 717ad56..8aa13c6 100644 --- a/utils/mount/nfs4mount.c +++ b/utils/mount/nfs4mount.c @@ -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; diff --git a/utils/mount/nfs_mount.h b/utils/mount/nfs_mount.h index 1fd74c8..4a061d8 100644 --- a/utils/mount/nfs_mount.h +++ b/utils/mount/nfs_mount.h @@ -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 */ diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c index 507ccdb..815064a 100644 --- a/utils/mount/nfsmount.c +++ b/utils/mount/nfsmount.c @@ -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 */ diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index 28f4244..b9737be 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -17,12 +17,14 @@ * */ +#include #include #include #include #include #include #include +#include #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); } diff --git a/utils/mountd/Makefile.in b/utils/mountd/Makefile.in index b6047ee..29cd8c6 100644 --- a/utils/mountd/Makefile.in +++ b/utils/mountd/Makefile.in @@ -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@ diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index fbe829e..85e8975 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -23,6 +23,7 @@ #include #include #include +#include #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; } diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index fc9a73c..04141d1 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -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; } diff --git a/utils/mountd/svc_run.c b/utils/mountd/svc_run.c index 7a8a595..422e839 100644 --- a/utils/mountd/svc_run.c +++ b/utils/mountd/svc_run.c @@ -57,6 +57,32 @@ 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... diff --git a/utils/nfsd/Makefile.in b/utils/nfsd/Makefile.in index eb91996..0c234ff 100644 --- a/utils/nfsd/Makefile.in +++ b/utils/nfsd/Makefile.in @@ -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@ diff --git a/utils/nfsstat/Makefile.in b/utils/nfsstat/Makefile.in index c0227c9..e5da827 100644 --- a/utils/nfsstat/Makefile.in +++ b/utils/nfsstat/Makefile.in @@ -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@ diff --git a/utils/rquotad/Makefile.am b/utils/rquotad/Makefile.am index dcc15ac..4bc036f 100644 --- a/utils/rquotad/Makefile.am +++ b/utils/rquotad/Makefile.am @@ -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 diff --git a/utils/rquotad/Makefile.in b/utils/rquotad/Makefile.in index 419f181..198aa15 100644 --- a/utils/rquotad/Makefile.in +++ b/utils/rquotad/Makefile.in @@ -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 diff --git a/utils/showmount/Makefile.in b/utils/showmount/Makefile.in index e123468..19b3338 100644 --- a/utils/showmount/Makefile.in +++ b/utils/showmount/Makefile.in @@ -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@ diff --git a/utils/statd/Makefile.am b/utils/statd/Makefile.am index 26800ea..8a3ba4e 100644 --- a/utils/statd/Makefile.am +++ b/utils/statd/Makefile.am @@ -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) diff --git a/utils/statd/Makefile.in b/utils/statd/Makefile.in index 2378ebd..0527c08 100644 --- a/utils/statd/Makefile.in +++ b/utils/statd/Makefile.in @@ -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. diff --git a/utils/statd/callback.c b/utils/statd/callback.c index 8a85ce9..b19bb90 100644 --- a/utils/statd/callback.c +++ b/utils/statd/callback.c @@ -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(¬ify, call); } - lp = NL_NEXT(lp); - } + return ((void *) &result); } diff --git a/utils/statd/monitor.c b/utils/statd/monitor.c index 98cbf4a..b95b0ad 100644 --- a/utils/statd/monitor.c +++ b/utils/statd/monitor.c @@ -19,6 +19,7 @@ #include #include #include +#include #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; ipriv[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; idns_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 index d7aa1dd..0000000 --- a/utils/statd/notify.c +++ /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 -#endif - -#include -#include -#include -#include -#include -#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(¬ify, call); - } - - if (closedir(nld) == -1) { - perror("closedir"); - exit(1); - } -} diff --git a/utils/statd/notlist.h b/utils/statd/notlist.h index 911c092..664c9d8 100644 --- a/utils/statd/notlist.h +++ b/utils/statd/notlist.h @@ -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) diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c index 35cbccb..816a6f3 100644 --- a/utils/statd/rmtcall.c +++ b/utils/statd/rmtcall.c @@ -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(¬ify, entry); nlist_insert_timer(¬ify, 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(¬ify, 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(¬ify, entry); } } diff --git a/utils/statd/simu.c b/utils/statd/simu.c index 9d685ad..82d794e 100644 --- a/utils/statd/simu.c +++ b/utils/statd/simu.c @@ -7,6 +7,7 @@ #ifdef HAVE_CONFIG_H #include #endif +#include #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 index 0000000..a94876d --- /dev/null +++ b/utils/statd/sm-notify.c @@ -0,0 +1,760 @@ +/* + * Send NSM notify calls to all hosts listed in /var/lib/sm + * + * Copyright (C) 2004-2006 Olaf Kirch + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..dd03b8d --- /dev/null +++ b/utils/statd/sm-notify.man @@ -0,0 +1,166 @@ +.\" +.\" sm-notify(8) +.\" +.\" Copyright (C) 2004 Olaf Kirch +.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 diff --git a/utils/statd/start-statd b/utils/statd/start-statd new file mode 100644 index 0000000..6e7ea04 --- /dev/null +++ b/utils/statd/start-statd @@ -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 + diff --git a/utils/statd/statd.c b/utils/statd/statd.c index c92e12f..091ced9 100644 --- a/utils/statd/statd.c +++ b/utils/statd/statd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #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; } diff --git a/utils/statd/statd.h b/utils/statd/statd.h index ace2ce5..b7ea40b 100644 --- a/utils/statd/statd.h +++ b/utils/statd/statd.h @@ -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 */ diff --git a/utils/statd/statd.man b/utils/statd/statd.man index ce29dfd..e8be9f3 100644 --- a/utils/statd/statd.man +++ b/utils/statd/statd.man @@ -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 index f46dae5..0000000 --- a/utils/statd/state.c +++ /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 -#endif - -#include -#include -#include -#include -#include -#include -#include -#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)); -} diff --git a/utils/statd/svc_run.c b/utils/statd/svc_run.c index 67bb05c..a33da0d 100644 --- a/utils/statd/svc_run.c +++ b/utils/statd/svc_run.c @@ -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);