summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--Makefile4
-rw-r--r--config.mk.in1
-rwxr-xr-xconfigure120
-rw-r--r--configure.in9
-rw-r--r--utils/statd/log.c2
-rw-r--r--utils/statd/statd.c111
7 files changed, 200 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 6eda83a..f1890c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,22 @@
This is a 'pre-release' for 1.1.0 Hopefully 1.1.0 will be the
baseline for 2.6 and 2.8. I.e. it should continue to work right
through the 2.8 (or 3.0) kernel series. Previous releases wont.
+
+2003-07-04 NeilBrown <neilb@cse.unsw.edu.au>
+ Steve Dickson <SteveD@redhat.com>
+
+ statd cleanup:
+ * utils/statd/statd.c: create a pidfile with pid of statd, and
+ truncate it when statd exists.
+ * utils/statd/statd.c: drop privs by setuid to owner of SM_DIR,
+ and warn if this is root.
+ * utils/statd/statd.c: when statd forks, connect child to parent
+ with a pipe, and send a byte down the pipe once the child is
+ working properly.
+ * Makefile: create and chown sm, sm.bak, state when "make install"
+ * configure.in: add --with-statduser= option which defaults to
+ "rpcuser" or "nobody"
+ * config.mk.in: pass "statduser" through to Makefile
2003-07-03 NeilBrown <neilb@cse.unsw.edu.au>
diff --git a/Makefile b/Makefile
index 2789f00..dcc6b36 100644
--- a/Makefile
+++ b/Makefile
@@ -20,3 +20,7 @@ install:: installman
touch $(STATEDIR)/xtab; chmod 644 $(STATEDIR)/xtab
touch $(STATEDIR)/etab; chmod 644 $(STATEDIR)/etab
touch $(STATEDIR)/rmtab; chmod 644 $(STATEDIR)/rmtab
+ mkdir -p $(STATEDIR)/sm $(STATEDIR)/sm.bak
+ touch $(STATEDIR)/state
+ chmod go-rwx $(STATEDIR)/sm $(STATEDIR)/sm.bak $(STATEDIR)/state
+ chown $(STATDUSER) $(STATEDIR)/sm $(STATEDIR)/sm.bak $(STATEDIR)/state
diff --git a/config.mk.in b/config.mk.in
index d2cbea0..67f3d01 100644
--- a/config.mk.in
+++ b/config.mk.in
@@ -10,6 +10,7 @@ BINDIR = @bindir@
SBINDIR = @sbindir@
MANDIR = @mandir@
STATEDIR = $(install_prefix)@statedir@
+STATDUSER = @statduser@
##################################################################
# This is the prefix that will be used for nfsd and mountd. Leave this
diff --git a/configure b/configure
index 8038764..0922048 100755
--- a/configure
+++ b/configure
@@ -17,6 +17,8 @@ ac_help="$ac_help
ac_help="$ac_help
--with-statedir=/foo use state dir /foo [/var/lib/nfs]"
ac_help="$ac_help
+ --with-statduser=rpcuser user for statd to run under [rpcuser or nobody]"
+ac_help="$ac_help
--enable-nfsv3 enable support for NFSv3"
ac_help="$ac_help
--enable-kprefix install progs as rpc.knfsd etc"
@@ -558,6 +560,19 @@ else
fi
+# Check whether --with-statduser or --without-statduser was given.
+if test "${with_statduser+set}" = set; then
+ withval="$with_statduser"
+ statduser=$withval
+else
+ if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
+ statduser=rpcuser
+ else
+ statduser=nobody
+ fi
+fi
+
+
# Check whether --enable-nfsv3 or --disable-nfsv3 was given.
if test "${enable_nfsv3+set}" = set; then
enableval="$enable_nfsv3"
@@ -618,7 +633,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:622: checking for $ac_word" >&5
+echo "configure:637: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -648,7 +663,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:652: checking for $ac_word" >&5
+echo "configure:667: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -699,7 +714,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:703: checking for $ac_word" >&5
+echo "configure:718: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -731,7 +746,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:735: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:750: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -742,12 +757,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 746 "configure"
+#line 761 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -773,12 +788,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:777: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:792: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:782: checking whether we are using GNU C" >&5
+echo "configure:797: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -787,7 +802,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -806,7 +821,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:810: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:825: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -838,7 +853,7 @@ else
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:842: checking how to run the C preprocessor" >&5
+echo "configure:857: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -853,13 +868,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 857 "configure"
+#line 872 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:878: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -870,13 +885,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 874 "configure"
+#line 889 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:880: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -887,13 +902,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 891 "configure"
+#line 906 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:912: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -948,7 +963,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:952: checking for a BSD compatible install" >&5
+echo "configure:967: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1011,7 +1026,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1015: checking host system type" >&5
+echo "configure:1030: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -1032,7 +1047,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1036: checking build system type" >&5
+echo "configure:1051: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -1058,7 +1073,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1062: checking for $ac_word" >&5
+echo "configure:1077: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1090,7 +1105,7 @@ if test -n "$ac_tool_prefix"; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1094: checking for $ac_word" >&5
+echo "configure:1109: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1125,7 +1140,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1129: checking for $ac_word" >&5
+echo "configure:1144: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1157,7 +1172,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args.
set dummy ${ac_tool_prefix}ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1161: checking for $ac_word" >&5
+echo "configure:1176: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1188,12 +1203,12 @@ fi
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1192: checking for ANSI C header files" >&5
+echo "configure:1207: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1197 "configure"
+#line 1212 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1201,7 +1216,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1220: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1218,7 +1233,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1222 "configure"
+#line 1237 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1236,7 +1251,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1240 "configure"
+#line 1255 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1257,7 +1272,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1261 "configure"
+#line 1276 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1268,7 +1283,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1292,12 +1307,12 @@ EOF
fi
echo $ac_n "checking for GNU libc2""... $ac_c" 1>&6
-echo "configure:1296: checking for GNU libc2" >&5
+echo "configure:1311: checking for GNU libc2" >&5
if eval "test \"`echo '$''{'knfsd_cv_glibc2'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1301 "configure"
+#line 1316 "configure"
#include "confdefs.h"
#include <features.h>
@@ -1306,7 +1321,7 @@ else
#endif
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1310: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1325: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1329,7 +1344,7 @@ fi
echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
-echo "configure:1333: checking for main in -lsocket" >&5
+echo "configure:1348: checking for main in -lsocket" >&5
ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1337,14 +1352,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1341 "configure"
+#line 1356 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1365,7 +1380,7 @@ else
fi
echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:1369: checking for main in -lnsl" >&5
+echo "configure:1384: checking for main in -lnsl" >&5
ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1373,14 +1388,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1377 "configure"
+#line 1392 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1401,7 +1416,7 @@ else
fi
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:1405: checking for crypt in -lcrypt" >&5
+echo "configure:1420: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1409,7 +1424,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1413 "configure"
+#line 1428 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1420,7 +1435,7 @@ int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:1424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1442,7 +1457,7 @@ fi
if test "$knfsd_cv_glibc2" = no; then
echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6
-echo "configure:1446: checking for daemon in -lbsd" >&5
+echo "configure:1461: checking for daemon in -lbsd" >&5
ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1450,7 +1465,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lbsd $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1454 "configure"
+#line 1469 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1461,7 +1476,7 @@ int main() {
daemon()
; return 0; }
EOF
-if { (eval echo configure:1465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1488,14 +1503,14 @@ fi
echo $ac_n "checking for the tcp wrapper library""... $ac_c" 1>&6
-echo "configure:1492: checking for the tcp wrapper library" >&5
+echo "configure:1507: checking for the tcp wrapper library" >&5
if eval "test \"`echo '$''{'knfsd_cv_tcp_wrapper'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
old_LIBS="$LIBS"
LIBS="$LIBS -lwrap $LIBNSL"
cat > conftest.$ac_ext <<EOF
-#line 1499 "configure"
+#line 1514 "configure"
#include "confdefs.h"
int deny_severity = 0;
@@ -1504,7 +1519,7 @@ int main() {
return hosts_ctl ("nfsd", "", "")
; return 0; }
EOF
-if { (eval echo configure:1508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
knfsd_cv_tcp_wrapper=yes
else
@@ -1530,12 +1545,12 @@ fi
for ac_func in innetgr
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1534: checking for $ac_func" >&5
+echo "configure:1549: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1539 "configure"
+#line 1554 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1558,7 +1573,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1727,6 +1742,7 @@ s%@mandir@%$mandir%g
s%@VERSION@%$VERSION%g
s%@RELEASE@%$RELEASE%g
s%@statedir@%$statedir%g
+s%@statduser@%$statduser%g
s%@enable_nfsv3@%$enable_nfsv3%g
s%@kprefix@%$kprefix%g
s%@secure_statd@%$secure_statd%g
diff --git a/configure.in b/configure.in
index d96a5da..017e795 100644
--- a/configure.in
+++ b/configure.in
@@ -20,6 +20,15 @@ AC_ARG_WITH(statedir,
statedir=$withval,
statedir=/var/lib/nfs)
AC_SUBST(statedir)
+AC_ARG_WITH(statduser,
+ [ --with-statduser=rpcuser user for statd to run under [rpcuser or nobody]],
+ statduser=$withval,
+ if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
+ statduser=rpcuser
+ else
+ statduser=nobody
+ fi)
+ AC_SUBST(statduser)
AC_ARG_ENABLE(nfsv3,
[ --enable-nfsv3 enable support for NFSv3],
enable_nfsv3=$enableval,
diff --git a/utils/statd/log.c b/utils/statd/log.c
index 104dee9..a8414b7 100644
--- a/utils/statd/log.c
+++ b/utils/statd/log.c
@@ -32,7 +32,7 @@ static int opt_debug = 0; /* Will be command-line option, eventually */
void log_init()
{
if (!(run_mode & MODE_LOG_STDERR))
- openlog(name_p, LOG_PID, LOG_DAEMON);
+ openlog(name_p, LOG_PID | LOG_NDELAY, LOG_DAEMON);
mypid = getpid();
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index 127e258..dbd73b3 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -12,11 +12,13 @@
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
+#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <rpcmisc.h>
+#include <grp.h>
#include "statd.h"
#include "version.h"
@@ -147,6 +149,57 @@ usage()
fprintf(stderr," -N Run in notify only mode.\n");
}
+static const char *pidfile = "/var/run/rpc.statd.pid";
+
+int pidfd = -1;
+static void create_pidfile(void)
+{
+ FILE *fp;
+
+ unlink(pidfile);
+ fp = fopen(pidfile, "w");
+ if (!fp)
+ die("Opening %s failed: %s\n",
+ pidfile, strerror(errno));
+ fprintf(fp, "%d\n", getpid());
+ pidfd = dup(fileno(fp));
+ if (fclose(fp) < 0)
+ log(L_WARNING, "Flushing pid file failed.\n");
+}
+
+static void truncate_pidfile(void)
+{
+ if (pidfd >= 0)
+ ftruncate(pidfd, 0);
+}
+
+static void drop_privs(void)
+{
+ struct stat st;
+
+ if (stat(SM_DIR, &st) == -1 &&
+ stat(DIR_BASE, &st) == -1)
+ st.st_uid = 0;
+
+ if (st.st_uid == 0) {
+ log(L_WARNING, "statd running as root. chown %s to choose different user\n",
+ SM_DIR);
+ return;
+ }
+ /* better chown the pid file before dropping, as if it
+ * if over nfs we might loose access
+ */
+ if (pidfd >= 0)
+ fchown(pidfd, st.st_uid, st.st_gid);
+
+ setgroups(0, NULL);
+ if (setgid(st.st_gid) == -1
+ || setuid(st.st_uid) == -1) {
+ log(L_ERROR, "Fail to drop privileges");
+ exit(1);
+ }
+}
+
/*
* Entry routine/main loop.
*/
@@ -157,6 +210,9 @@ int main (int argc, char **argv)
int arg;
int port = 0, out_port = 0;
+ int pipefds[2] = { -1, -1};
+ char status;
+
/* Default: daemon mode, no other options */
run_mode = 0;
@@ -264,10 +320,6 @@ int main (int argc, char **argv)
daemon mode. */
}
- log_init (name_p,version_p);
-
- log_modes();
-
#ifdef SIMULATIONS
if (argc > 1)
/* LH - I _really_ need to update simulator... */
@@ -277,28 +329,54 @@ int main (int argc, char **argv)
if (!(run_mode & MODE_NODAEMON)) {
int filedes, fdmax, tempfd;
+ if (pipe(pipefds)<0) {
+ perror("statd: unable to create pipe");
+ exit(1);
+ }
if ((pid = fork ()) < 0) {
- perror ("Could not fork");
+ perror ("statd: Could not fork");
exit (1);
} else if (pid != 0) {
- /* Parent. */
+ /* Parent.
+ * Wait for status from child.
+ */
+ close(pipefds[1]);
+ if (read(pipefds[0], &status, 1) != 1)
+ exit(1);
exit (0);
}
/* Child. */
+ close(pipefds[0]);
setsid ();
- chdir (DIR_BASE);
+ if (chdir (DIR_BASE) == -1) {
+ perror("statd: Could not chdir");
+ exit(1);
+ }
+ while (pipefds[1] <= 2) {
+ pipefds[1] = dup(pipefds[1]);
+ if (pipefds[1]<0) {
+ perror("statd: dup");
+ exit(1);
+ }
+ }
tempfd = open("/dev/null", O_RDWR);
close(0); dup2(tempfd, 0);
close(1); dup2(tempfd, 1);
close(2); dup2(tempfd, 2);
fdmax = sysconf (_SC_OPEN_MAX);
- for (filedes = 3; filedes < fdmax; filedes++) {
- close (filedes);
- }
+ for (filedes = 3; filedes < fdmax; filedes++)
+ if (filedes != pipefds[1])
+ close (filedes);
+
}
/* Child. */
+
+ log_init (name_p,version_p);
+
+ log_modes();
+
signal (SIGHUP, killer);
signal (SIGINT, killer);
signal (SIGTERM, killer);
@@ -308,6 +386,10 @@ int main (int argc, char **argv)
/* 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.
@@ -319,6 +401,15 @@ int main (int argc, char **argv)
}
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;
+ }
+
notify_hosts (); /* Send out notify requests */
++restart;