diff options
Diffstat (limited to 'meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch')
-rw-r--r-- | meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch | 2344 |
1 files changed, 0 insertions, 2344 deletions
diff --git a/meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch b/meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch deleted file mode 100644 index 886ce92b3..000000000 --- a/meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch +++ /dev/null @@ -1,2344 +0,0 @@ -# Patch origin: nfs-server source RPM from openSUSE 10.3 - -diff -urN nfs-server-2.2beta47/.version nfs-server-2.2beta51/.version ---- nfs-server-2.2beta47/.version Tue Sep 7 09:47:27 1999 -+++ nfs-server-2.2beta51/.version Fri Nov 8 14:45:36 2002 -@@ -1 +1 @@ --2.2beta46 -+2.2beta51 -diff -urN nfs-server-2.2beta47/ChangeLog nfs-server-2.2beta51/ChangeLog ---- nfs-server-2.2beta47/ChangeLog Wed Nov 10 10:17:51 1999 -+++ nfs-server-2.2beta51/ChangeLog Fri Nov 8 14:45:36 2002 -@@ -1,8 +1,59 @@ -+Thu Nov 9 17:03:05 2000 -+ -+ * No longer use OPEN_MAX -+ -+ * Reworked configure.in, BUILD script no longer needed -+ (nor functioning) -+ -+ * Be more anal about matching cached fh's and real files. -+ In addition to the psi, we also store dev/ino/type now -+ and match that in fh_find. -+ -+ * Write pidfiles -+ -+ * Support nosetuid -+ -+Wed Feb 9 14:52:34 2000 -+ -+ * auth_init.c didn't properly parse options--rot_squash -+ which is obviously a typo was parsed as ro. -+ Thanks to Jan Steffan for complaining about this :-) -+ -+Mon Jan 31 11:48:34 2000 -+ -+ * Fixed Y2K bug in logging.c. -+ Thanks to Jonathan Hankins <jhankins@homewood.k12.al.us>. -+ -+Thu Dec 9 11:14:21 1999 -+ -+ * Fix handling of NFS-mounted and /proc directories. -+ They weren't properly hidden. -+ Thanks to Dick Streefland <dick_streefland@tasking.com> -+ for the report and a first patch. -+ - Wed Nov 10 10:17:16 1999 - - * Security fix for buffer overflow in fh_buildpath - No thanks to Mariusz who reported it to bugtraq - rather than me. -+ -+Wed Nov 09 17:10:00 1999 -+ -+ * Workaround for broken Solaris clients that can't handle -+ atime/mtime/ctime of 0. -+ Thanks to Frank Wuebbelin for his problem report and -+ testing the fix. -+ -+ * Fixed typo in exports.man -+ -+Tue Nov 2 10:31:14 1999 -+ -+ * Patch for mode 0100 and 0100 executables by -+ Michael Deutschmann <michael@talamasca.wkpowerlink.com> -+ -+ * Common startup stuff for all daemons. -+ Inspired by code sent to me by someone (sorry, I forgot -+ your name, and the mail's gone!) - - Wed Sep 8 09:07:38 1999 - -diff -urN nfs-server-2.2beta47/Makefile.in nfs-server-2.2beta51/Makefile.in ---- nfs-server-2.2beta47/Makefile.in Tue Jun 22 14:53:10 1999 -+++ nfs-server-2.2beta51/Makefile.in Fri Nov 8 14:45:36 2002 -@@ -17,23 +17,30 @@ - - #### Start of system configuration section. #### - --srcdir = @srcdir@ --VPATH = @srcdir@ -+srcdir = @srcdir@ -+VPATH = @srcdir@ - --CC = @CC@ --AR = ar --RANLIB = @RANLIB@ -- --INSTALL = @INSTALL@ --INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755 --INSTALL_DATA = @INSTALL_DATA@ --MAKEINFO = makeinfo --TEXI2DVI = texi2dvi --RPCGEN = @RPCGEN@ @RPCGEN_C@ -+CC = @CC@ -+AR = ar -+RANLIB = @RANLIB@ -+ -+INSTALL = @INSTALL@ -+INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755 -+INSTALL_DATA = @INSTALL_DATA@ -+MAKEINFO = makeinfo -+TEXI2DVI = texi2dvi -+RPCGEN = @RPCGEN@ @RPCGEN_C@ - - # General compile options and libs: --DEFS = @DEFS@ $(NFSD_DEFS) --LIBS = libnfs.a @LIBS@ -+DEFS = @DEFS@ $(NFSD_DEFS) -+LIBS = libnfs.a @LIBS@ -+ -+# Ugidd support -+UGIDD_PROG = @UGIDD_PROG@ -+UGIDD_MAN = @UGIDD_MAN@ -+ -+# New inode mapping scheme -+DEVTAB_FILE = $(install_prefix)@PATH_DEVTAB@ - - # Compile options for nfsd: - # CALL_PROFILING -@@ -80,9 +87,6 @@ - - #### End of system configuration section. #### - --# include site-specific defintions generated by BUILD. --include site.mk -- - SHELL = /bin/sh - - SRCS = version.c logging.c fh.c devtab.c \ -@@ -96,19 +100,19 @@ - utimes.c mkdir.c rename.c getopt.c getopt_long.c \ - alloca.c mountlist.c xmalloc.c \ - xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \ -- haccess.c failsafe.c signals.c -+ haccess.c daemon.c signals.c - XDRFILES = mount.x nfs_prot.x - GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \ - ugid.h ugid_xdr.c ugid_clnt.c - HDRS = system.h nfsd.h auth.h fh.h logging.h fakefsuid.h \ - rpcmisc.h faccess.h rquotad.h rquota.h haccess.h --LIBHDRS = fsusage.h getopt.h mountlist.h failsafe.h signals.h -+LIBHDRS = fsusage.h getopt.h mountlist.h daemon.h signals.h - MANPAGES5 = exports - MANPAGES8p = mountd nfsd $(UGIDD_MAN) - MANPAGES8 = showmount - MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8) - LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \ -- nfsmounted.o faccess.o haccess.o failsafe.o \ -+ nfsmounted.o faccess.o haccess.o daemon.o \ - signals.o @LIBOBJS@ @ALLOCA@ - OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o - NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \ -@@ -174,15 +178,13 @@ - ${srcdir}/mkinstalldirs $(bindir) $(man5dir) $(man8dir) - - $(rpcprefix)mountd: $(MOUNTD_OBJS) libnfs.a -- $(CC) $(LDFLAGS) -o $@ $(MOUNTD_OBJS) $(LIBS) \ -- $(LIBWRAP_DIR) $(LIBWRAP_LIB) -+ $(CC) $(LDFLAGS) -o $@ $(MOUNTD_OBJS) $(LIBS) - - $(rpcprefix)nfsd: $(NFSD_OBJS) libnfs.a - $(CC) $(LDFLAGS) -o $@ $(NFSD_OBJS) $(LIBS) - - $(rpcprefix)ugidd: $(UGIDD_OBJS) libnfs.a -- $(CC) $(LDFLAGS) -o $@ $(UGIDD_OBJS) $(LIBS) \ -- $(LIBWRAP_DIR) $(LIBWRAP_LIB) -+ $(CC) $(LDFLAGS) -o $@ $(UGIDD_OBJS) $(LIBS) - - showmount: $(SHOWMOUNT_OBJS) libnfs.a - $(CC) $(LDFLAGS) -o $@ $(SHOWMOUNT_OBJS) $(LIBS) -diff -urN nfs-server-2.2beta47/aclocal.m4 nfs-server-2.2beta51/aclocal.m4 ---- nfs-server-2.2beta47/aclocal.m4 Fri Jun 11 12:04:22 1999 -+++ nfs-server-2.2beta51/aclocal.m4 Fri Nov 8 14:45:36 2002 -@@ -221,20 +221,14 @@ - ])dnl - dnl *********** libwrap bug ************** - define(AC_LIBWRAP_BUG, -- [if test -f site.mk; then -- . ./site.mk -- fi -- if test ! -z "$LIBWRAP_DIR"; then -+ [if test "$ac_cv_lib_wrap_main" = yes; then - AC_MSG_CHECKING(for link problem with libwrap.a) - AC_CACHE_VAL(nfsd_cv_lib_wrap_bug, -- [ac_save_LIBS=$LIBS -- LIBS="$LIBS $LIBWRAP_DIR $LIBWRAP_LIB" -- AC_TRY_LINK([ -+ [AC_TRY_LINK([ - extern int deny_severity; - ],[ - deny_severity=1; - ], nfsd_cv_lib_wrap_bug=no, nfsd_cv_lib_wrap_bug=yes) -- LIBS=$ac_save_LIBS - ]) dnl - AC_MSG_RESULT($nfsd_cv_lib_wrap_bug) - test $nfsd_cv_lib_wrap_bug = yes && AC_DEFINE(HAVE_LIBWRAP_BUG) -diff -urN nfs-server-2.2beta47/auth.c nfs-server-2.2beta51/auth.c ---- nfs-server-2.2beta47/auth.c Mon Sep 13 16:56:03 1999 -+++ nfs-server-2.2beta51/auth.c Fri Nov 8 14:45:36 2002 -@@ -84,8 +84,9 @@ - 0, /* relative links */ - 0, /* noaccess */ - 1, /* cross_mounts */ -- (uid_t)-2, /* default uid */ -- (gid_t)-2, /* default gid */ -+ 1, /* allow setuid */ -+ 65534, /* default uid */ -+ 65534, /* default gid */ - 0, /* no NIS domain */ - }; - -@@ -99,8 +100,9 @@ - 0, /* relative links */ - 0, /* noaccess */ - 1, /* cross_mounts */ -- (uid_t)-2, /* default uid */ -- (gid_t)-2, /* default gid */ -+ 0, /* allow setuid */ -+ 65534, /* default uid */ -+ 65534, /* default gid */ - 0, /* no NIS domain */ - }; - -@@ -673,6 +675,7 @@ - cpp = &unknown_clients; - } else { - cpp = &known_clients; -+ cp->clnt_addr = *(struct in_addr *) hp->h_addr; - auth_hash_host(cp, hp); - } - cp->next = *cpp; -diff -urN nfs-server-2.2beta47/auth.h nfs-server-2.2beta51/auth.h ---- nfs-server-2.2beta47/auth.h Thu Apr 8 14:47:56 1999 -+++ nfs-server-2.2beta51/auth.h Fri Nov 8 14:45:36 2002 -@@ -23,14 +23,6 @@ - extern char * public_root_path; - extern struct nfs_fh public_root; - --#if defined(linux) && defined(i386) && !defined(HAVE_SETFSUID) --# define MAYBE_HAVE_SETFSUID --#endif -- --#ifdef MAYBE_HAVE_SETFSUID --extern int have_setfsuid; --#endif -- - /* - * These externs are set in the dispatcher (dispatch.c) and auth_fh - * (nfsd.c) so that we can determine access rights, export options, -@@ -59,6 +51,7 @@ - int link_relative; - int noaccess; - int cross_mounts; -+ int allow_setuid; - uid_t nobody_uid; - gid_t nobody_gid; - char * clnt_nisdomain; -@@ -112,7 +105,7 @@ - extern void auth_free_lists(void); - extern nfs_client *auth_clnt(struct svc_req *rqstp); - extern nfs_mount *auth_path(nfs_client *, struct svc_req *, char *); --extern void auth_user(nfs_mount *, struct svc_req *); -+extern int auth_user(nfs_mount *, struct svc_req *); - - extern nfs_client *auth_get_client(char *); - extern nfs_mount *auth_match_mount(nfs_client *, char *); -diff -urN nfs-server-2.2beta47/auth_clnt.c nfs-server-2.2beta51/auth_clnt.c ---- nfs-server-2.2beta47/auth_clnt.c Wed Nov 10 10:18:06 1999 -+++ nfs-server-2.2beta51/auth_clnt.c Fri Nov 8 14:45:36 2002 -@@ -12,20 +12,17 @@ - */ - - -+#include <sys/fsuid.h> - #include "system.h" - #include "nfsd.h" --#include "fakefsuid.h" -- --#ifndef svc_getcaller --#define svc_getcaller(x) ((struct sockaddr_in *) &(x)->xp_rtaddr.buf) --#endif -+#include "rpcmisc.h" - - --#if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID) --static void setfsids(uid_t, gid_t, gid_t *, int); -+#if defined(HAVE_SETFSUID) -+static int setfsids(uid_t, gid_t, gid_t *, int); - #endif - #ifndef HAVE_SETFSUID --static void seteids(uid_t, gid_t, gid_t *, int); -+static int seteids(uid_t, gid_t, gid_t *, int); - #endif - - uid_t auth_uid = 0; /* Current effective user ids */ -@@ -43,6 +40,17 @@ - short *gid, short *nrgids, int *groups); - #endif - -+/* -+ * The following crap is required for glibc 2.1 which has 32bit uids -+ * in user land mapped to 16bit uids in the Linux kernel -+ */ -+#if defined(HAVE_BROKEN_SETFSUID) -+# define native_uid(u) ((unsigned short)(u)) -+# define native_gid(g) ((unsigned short)(g)) -+#else -+# define native_uid(u) (u) -+# define native_gid(g) (g) -+#endif - - /* - * For an RPC request, look up the NFS client info along with the -@@ -92,8 +100,9 @@ - } - - if (logging_enabled(D_AUTH)) { -- Dprintf(D_AUTH, "auth_path(%s): mount point %s, (%s%s%s%s%s)\n", -- path, mp->path, -+ Dprintf(D_AUTH, "auth_path(%s, %s): " -+ "mount point %s, (%s%s%s%s%s)\n", -+ inet_ntoa(cp->clnt_addr), path, mp->path, - mp->o.all_squash? "all_squash " : ( - mp->o.root_squash? "root_squash " : ""), - (mp->o.uidmap == map_daemon)? "uidmap " : "", -@@ -105,7 +114,8 @@ - return mp; - } - --void auth_user(nfs_mount *mp, struct svc_req *rqstp) -+int -+auth_user(nfs_mount *mp, struct svc_req *rqstp) - { - uid_t cuid; - gid_t cgid; -@@ -160,23 +170,18 @@ - else if (cred_len > NGRPS) - cred_len = NGRPS; - -- cuid = luid(cred_uid, mp, rqstp); -- cgid = lgid(cred_gid, mp, rqstp); -+ cuid = luid(native_uid(cred_uid), mp, rqstp); -+ cgid = lgid(native_gid(cred_gid), mp, rqstp); - clen = cred_len; - for (i = 0; i < cred_len; i++) -- cgids[i] = lgid(cred_gids[i], mp, rqstp); -+ cgids[i] = lgid(native_gid(cred_gids[i]), mp, rqstp); - } else { - /* On systems that have 32bit uid_t in user space but - * 16bit in the kernel, we need to truncate the - * nobody ID (default -2). - */ --#if !defined(HAVE_BROKEN_SETFSUID) -- cuid = mp->o.nobody_uid; -- cgid = mp->o.nobody_gid; --#else -- cuid = (unsigned short) mp->o.nobody_uid; -- cgid = (unsigned short) mp->o.nobody_gid; --#endif -+ cuid = native_uid(mp->o.nobody_uid); -+ cgid = native_gid(mp->o.nobody_gid); - /* Construct a list of one gid. */ - cgids[0] = cgid; - clen = 1; -@@ -193,14 +198,9 @@ - * upper 16 bits set (including our default nobody uid -2). - */ - #if defined(HAVE_SETFSUID) -- setfsids(cuid, cgid, cgids, clen); -+ return setfsids(cuid, cgid, cgids, clen); - #else --#if defined(MAYBE_HAVE_SETFSUID) -- if (have_setfsuid) -- setfsids(cuid, cgid, cgids, clen); -- else --#endif -- seteids(cuid, cgid, cgids, clen); -+ return seteids(cuid, cgid, cgids, clen); - #endif - } - -@@ -210,6 +210,8 @@ - void - auth_override_uid(uid_t uid) - { -+ int res; -+ - /* extension hooks: */ - efs_setfsuid(uid); - -@@ -217,19 +219,18 @@ - uid = (unsigned short) uid; - #endif - #if defined(HAVE_SETFSUID) -- setfsuid(uid); -+ res = setfsuid(uid); - #else --#if defined(MAYBE_HAVE_SETFSUID) -- if (have_setfsuid) -- setfsuid(uid); -- else --#endif -- seteuid(uid); -+ res = seteuid(uid); - #endif -+ /* should never happen */ -+ if (res < 0) -+ Dprintf(L_FATAL, "auth_override_uid(%d) failed: %s", -+ uid, strerror(errno)); - } - --#if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID) --static void -+#if defined(HAVE_SETFSUID) -+static int - setfsids(uid_t cred_uid, gid_t cred_gid, gid_t *cred_gids, int cred_len) - { - /* extension hooks: */ -@@ -238,43 +239,47 @@ - - /* First, set the user ID. */ - if (auth_uid != cred_uid) { -- if (setfsuid(cred_uid) < 0) -+ if (setfsuid(cred_uid) < 0) { - Dprintf(L_ERROR, "Unable to setfsuid %d: %s\n", - cred_uid, strerror(errno)); -- else -- auth_uid = cred_uid; -+ return 0; -+ } -+ auth_uid = cred_uid; - } - - /* Next, the group ID. */ - if (auth_gid != cred_gid) { -- if (setfsgid(cred_gid) < 0) -+ if (setfsgid(cred_gid) < 0) { - Dprintf(L_ERROR, "Unable to setfsgid %d: %s\n", - cred_gid, strerror(errno)); -- else -- auth_gid = cred_gid; -+ return 0; -+ } -+ auth_gid = cred_gid; - } - - #ifdef HAVE_SETGROUPS - /* Finally, set the supplementary group IDs if possible. */ -- if (cred_len < 0 || cred_len > NGRPS) -+ if (cred_len < 0 || cred_len > NGRPS) { - Dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len); -- else if (cred_len != auth_gidlen -- || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) { -- if (setgroups(cred_len, cred_gids) < 0) -+ return 0; -+ } -+ if (cred_len != auth_gidlen -+ || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) { -+ if (setgroups(cred_len, cred_gids) < 0) { - Dprintf(L_ERROR, "Unable to setgroups: %s\n", - strerror(errno)); -- else { -- memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t)); -- auth_gidlen = cred_len; -+ return 0; - } -+ memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t)); -+ auth_gidlen = cred_len; - } - #endif /* HAVE_SETGROUPS */ -- -+ return 1; - } - #endif - - #if !defined(HAVE_SETFSUID) --static void -+static int - seteids(uid_t cred_uid, gid_t cred_gid, gid_t *cred_gids, int cred_len) - { - /* extension hooks: */ -@@ -286,52 +291,62 @@ - /* First set the group ID. */ - if (auth_gid != cred_gid) { - if (auth_uid != ROOT_UID) { -- if (seteuid(ROOT_UID) < 0) -+ if (seteuid(ROOT_UID) < 0) { - Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n", - ROOT_UID, strerror(errno)); -- else -- auth_uid = ROOT_UID; -+ return 0; -+ } -+ auth_uid = ROOT_UID; - } -- if (setegid(cred_gid) < 0) -+ if (setegid(cred_gid) < 0) { - Dprintf(L_ERROR, "Unable to setegid(%d): %s\n", - cred_gid, strerror(errno)); -- else -- auth_gid = cred_gid; -+ return 0; -+ } -+ auth_gid = cred_gid; - } - - #ifdef HAVE_SETGROUPS - /* Next set the supplementary group IDs if possible. */ -- if (cred_len < 0 || cred_len > NGRPS) -+ if (cred_len < 0 || cred_len > NGRPS) { - Dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len); -- else if (cred_len != auth_gidlen -- || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) { -+ return 0; -+ } -+ if (cred_len != auth_gidlen -+ || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) { - if (auth_uid != ROOT_UID) { -- if (seteuid(ROOT_UID) < 0) -+ if (seteuid(ROOT_UID) < 0) { - Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n", - ROOT_UID, strerror(errno)); -- else -- auth_uid = ROOT_UID; -+ return 0; -+ } -+ auth_uid = ROOT_UID; - } -- if (setgroups(cred_len, cred_gids) < 0) -+ if (setgroups(cred_len, cred_gids) < 0) { - Dprintf(L_ERROR, "Unable to setgroups: %s\n", - strerror(errno)); -- else { -- memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t)); -- auth_gidlen = cred_len; -+ return 0; - } -+ memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t)); -+ auth_gidlen = cred_len; - } - #endif /* HAVE_SETGROUPS */ - - /* Finally, set the user ID. */ - if (auth_uid != cred_uid) { -- if (auth_uid != ROOT_UID && seteuid(ROOT_UID) < 0) -+ if (auth_uid != ROOT_UID && seteuid(ROOT_UID) < 0) { - Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n", - ROOT_UID, strerror(errno)); -- if (seteuid(cred_uid) < 0) -+ return 0; -+ } -+ if (seteuid(cred_uid) < 0) { - Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n", - cred_uid, strerror(errno)); -- else -- auth_uid = cred_uid; -+ return 0; -+ } -+ auth_uid = cred_uid; - } -+ -+ return 1; - } - #endif -diff -urN nfs-server-2.2beta47/auth_init.c nfs-server-2.2beta51/auth_init.c ---- nfs-server-2.2beta47/auth_init.c Mon Apr 19 14:01:21 1999 -+++ nfs-server-2.2beta51/auth_init.c Fri Nov 8 14:45:36 2002 -@@ -13,7 +13,6 @@ - */ - - #include "nfsd.h" --#include "fakefsuid.h" - #include <pwd.h> - - #define LINE_SIZE 1024 -@@ -263,55 +262,63 @@ - cp++; - while (*cp != terminator) { - kwd = cp; -- while (isalpha(*cp) || *cp == '_' || *cp == '=') { -- /* break out of loop after = sign */ -- if (*cp++ == '=') -- break; -- } -+ /* Gobble up keyword and "=" if there is one */ -+ while (isalpha(*cp) || *cp == '_') -+ ++cp; -+ if (*cp == '=') -+ ++cp; -+ - klen = cp - kwd; - - /* process keyword */ -- if (strncmp(kwd, "secure", 6) == 0) -+#define ifkwd(n, string) \ -+ if (klen == (n) && !strncmp(kwd, string, (n))) -+ -+ ifkwd(2, "ro") -+ mp->o.read_only = 1; -+ else ifkwd(2, "rw") -+ mp->o.read_only = 0; -+ else ifkwd(6, "secure") - mp->o.secure_port = 1; -- else if (strncmp(kwd, "insecure", 8) == 0) -+ else ifkwd(8, "insecure") - mp->o.secure_port = 0; -- else if (strncmp(kwd, "root_squash", 11) == 0) -+ else ifkwd(11, "root_squash") - mp->o.root_squash = 1; -- else if (strncmp(kwd, "no_root_squash", 14) == 0) -+ else ifkwd(14, "no_root_squash") - mp->o.root_squash = 0; -- else if (strncmp(kwd, "ro", 2) == 0) -- mp->o.read_only = 1; -- else if (strncmp(kwd, "rw", 2) == 0) -- mp->o.read_only = 0; -- else if (strncmp(kwd, "link_relative", 13) == 0) -+ else ifkwd(13, "link_relative") - mp->o.link_relative = 1; -- else if (strncmp(kwd, "link_absolute", 13) == 0) -+ else ifkwd(13, "link_absolute") - mp->o.link_relative = 0; -- else if (strncmp(kwd, "map_daemon", 10) == 0) -+ else ifkwd(10, "map_daemon") - mp->o.uidmap = map_daemon; -- else if (strncmp(kwd, "map_nis=", 8) == 0) -+ else ifkwd(8, "map_nis=") - parse_nis_uidmap(mp, &cp); -- else if (strncmp(kwd, "map_static=", 11) == 0) -+ else ifkwd(11, "map_static=") - parse_static_uidmap(mp, &cp); -- else if (strncmp(kwd, "map_identity", 12) == 0) -+ else ifkwd(12, "map_identity") - mp->o.uidmap = identity; -- else if (strncmp(kwd, "all_squash", 10) == 0) -+ else ifkwd(10, "all_squash") - mp->o.all_squash = 1; -- else if (strncmp(kwd, "no_all_squash", 13) == 0) -+ else ifkwd(13, "no_all_squash") - mp->o.all_squash = 0; -- else if (strncmp(kwd, "noaccess", 8) == 0) -+ else ifkwd(8, "noaccess") - mp->o.noaccess = 1; -- else if (strncmp(kwd, "squash_uids=", 12) == 0) -+ else ifkwd(12, "squash_uids=") - parse_squash(mp, 1, &cp); -- else if (strncmp(kwd, "squash_gids=", 12) == 0) -+ else ifkwd(12, "squash_gids=") - parse_squash(mp, 0, &cp); -- else if (strncmp(kwd, "anonuid=", 8) == 0) -+ else ifkwd(8, "anonuid=") - mp->o.nobody_uid = parse_num(&cp); -- else if (strncmp(kwd, "anongid=", 8) == 0) -+ else ifkwd(8, "anongid=") - mp->o.nobody_gid = parse_num(&cp); -- else if (strncmp(kwd, "async", 5) == 0) -+ else ifkwd(6, "setuid") -+ mp->o.allow_setuid = 1; -+ else ifkwd(8, "nosetuid") -+ mp->o.allow_setuid = 0; -+ else ifkwd(5, "async") - /* knfsd compatibility, ignore */; -- else if (strncmp(kwd, "sync", 4) == 0) -+ else ifkwd(4, "sync") - /* knfsd compatibility, ignore */; - else { - Dprintf(L_ERROR, -@@ -566,11 +573,6 @@ - auth_check_all_wildcards(); - auth_sort_all_mountlists(); - auth_log_all(); -- --#if defined(MAYBE_HAVE_SETFSUID) && !defined(HAVE_SETFSUID) -- /* check if the a.out setfsuid syscall works on this machine */ -- have_setfsuid = (setfsuid(0) >= 0); --#endif - - auth_initialized = 1; - } -diff -urN nfs-server-2.2beta47/config.h.in nfs-server-2.2beta51/config.h.in ---- nfs-server-2.2beta47/config.h.in Fri Jun 11 12:01:22 1999 -+++ nfs-server-2.2beta51/config.h.in Fri Nov 8 14:45:36 2002 -@@ -3,7 +3,7 @@ - /* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ --#ifndef _ALL_SOURCE -+#ifdef _ALL_SOURCE - #undef _ALL_SOURCE - #endif - -diff -urN nfs-server-2.2beta47/configure.in nfs-server-2.2beta51/configure.in ---- nfs-server-2.2beta47/configure.in Fri Jun 11 11:58:10 1999 -+++ nfs-server-2.2beta51/configure.in Fri Nov 8 14:45:36 2002 -@@ -2,7 +2,36 @@ - dnl Updated for autoconf 2. - dnl - AC_INIT(nfsd.c) --AC_CONFIG_HEADER(config.h) -+AC_CONFIG_HEADER(config.h site.h) -+ -+dnl ************************************************************** -+dnl * handle --enable options -+dnl ************************************************************** -+AC_ARG_ENABLE(new-inodes, -+ [ --enable-new-inodes Enable new-style inode inodes]) -+AC_ARG_WITH(devtab, -+ [ --with-devtab=file Specify location for devtab [/var/lib/nfs/devtab]], -+ PATH_DEVTAB=$withval, -+ PATH_DEVTAB=/var/lib/nfs/devtab) -+AC_ARG_ENABLE(ugid-dynamic, -+ [ --enable-ugid-dynamic Enable uid mapping using rpc.ugidd (not recommended)]) -+AC_ARG_ENABLE(ugid-nis, -+ [ --enable-ugid-nis Enable NIS-based uid mapping]) -+AC_ARG_ENABLE(host-access, -+ [ --enable-host-access Enable host access checking]) -+AC_ARG_ENABLE(mount-logging, -+ [ --disable-mount-logging Do not log mount operations to syslog],, -+ enable_mount_logging=yes) -+AC_ARG_WITH(exports-uid, -+ [ --with-exports-uid=N Make sure that /etc/exports is owned by uid N],, -+ with_exports_uid=0) -+AC_ARG_WITH(exports-gid, -+ [ --with-exports-gid=N Make sure that /etc/exports is owned by gid N],, -+ with_exports_gid=0) -+ -+dnl ************************************************************** -+dnl * Check for all kinds of stuff -+dnl ************************************************************** - AC_PROG_CC - # If we're using gcc, we want warning flags - test -n "$GCC" && -@@ -19,7 +48,7 @@ - AC_MINIX - AC_ISC_POSIX - AC_PROG_INSTALL --AC_CROSS_CHECK -+dnl AC_CROSS_CHECK - AC_STDC_HEADERS - AC_GNULIBC - AC_CONST -@@ -52,14 +81,45 @@ - AC_CHECK_LIB(rpc, main) - AC_CHECK_LIB(crypt, main) - AC_CHECK_LIB(nys, main) --AC_REPLACE_FUNCS(strerror realpath mkdir rename utimes strdup strstr getopt getopt_long) - AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred) - AC_AUTHDES_GETUCRED - AC_BROKEN_SETFSUID - AC_MOUNTLIST - AC_FSUSAGE -+AC_CHECK_LIB(wrap, main) - AC_LIBWRAP_BUG - AC_BSD_SIGNALS -+ -+dnl ************************************************************** -+dnl * Munge user specified options -+dnl ************************************************************** -+if test "$enable_new_inodes" = yes; then -+ AC_DEFINE(ENABLE_DEVTAB) -+fi -+if test "$enable_ugid_dynamic" = yes; then -+ AC_DEFINE(ENABLE_UGID_DAEMON) -+ UGIDD_PROG=\${rpcprefix}.ugidd -+ UGIDD_MAN=ugidd -+fi -+if test "$enable_ugid_nis" = yes; then -+ AC_DEFINE(ENABLE_UGID_NIS) -+fi -+if test "$enable_host_access" = yes; then -+ AC_DEFINE(HOSTS_ACCESS) -+fi -+if test "$enable_mount_logging" = yes; then -+ AC_DEFINE(WANT_LOG_MOUNTS) -+fi -+AC_DEFINE_UNQUOTED(EXPORTSOWNERUID, $with_exports_uid) -+AC_DEFINE_UNQUOTED(EXPORTSOWNERGID, $with_exports_gid) -+AC_SUBST(PATH_DEVTAB) -+AC_SUBST(UGIDD_PROG) -+AC_SUBST(UGIDD_MAN) -+ -+dnl ************************************************************** -+dnl * Output CFLAGS and LDFLAGS -+dnl ************************************************************** - AC_SUBST(LDFLAGS) - AC_SUBST(CFLAGS) -+ - AC_OUTPUT(Makefile) -diff -urN nfs-server-2.2beta47/daemon.c nfs-server-2.2beta51/daemon.c ---- nfs-server-2.2beta47/daemon.c Thu Jan 1 01:00:00 1970 -+++ nfs-server-2.2beta51/daemon.c Fri Nov 8 14:45:52 2002 -@@ -0,0 +1,270 @@ -+/* -+ * daemon.c -+ * -+ * Copyright (C) 1998, <okir@monad.swb.de> -+ * -+ * Implements common daemon stuff and -+ * fail-safe mode for nfsd/mountd. -+ */ -+ -+#include "system.h" -+#include "logging.h" -+#include "signals.h" -+#include <sys/wait.h> -+ -+static const char * pidfilename = 0; -+static const char * get_signame(int signo); -+ -+/* -+ * Do the Crawley Thing -+ */ -+void -+daemonize(void) -+{ -+ int c; -+ -+ /* Ignore SIGHUP so the parent can exit while we're still -+ * in limbo */ -+ ignore_signal(SIGHUP); -+ -+ /* Now fork */ -+ c = fork(); -+ if (c < 0) -+ Dprintf(L_FATAL, "unable to fork: %s", strerror(errno)); -+ -+ /* Parent process: exit */ -+ if (c > 0) -+ exit(0); -+ -+ /* Do the session stuff */ -+ close(0); -+ close(1); -+ close(2); -+#ifdef HAVE_SETSID -+ setsid(); -+#else -+ if ((c = open("/dev/tty", O_RDWR)) >= 0) { -+ ioctl(c, TIOCNOTTY, (char *) NULL); -+ close(c); -+ } -+#endif -+ -+ /* Stop stderr logging */ -+ background_logging(); -+} -+ -+void -+setpidpath(const char *filename) -+{ -+ pidfilename = filename; -+} -+ -+void -+writepid(pid_t pid, int clear) -+{ -+ FILE *fp; -+ -+ fp = fopen(pidfilename, clear? "w" : "a"); -+ if (fp == NULL) -+ Dprintf(L_FATAL, "Unable to open %s: %m", pidfilename); -+ fprintf(fp, "%d\n", pid); -+ fclose(fp); -+ return; -+} -+ -+void -+failsafe(int level, int ncopies) -+{ -+ int *servers, running, child, i; -+ int pid, signo, status; -+ time_t last_restart = 0, now; -+ int restarts = 0, backoff = 60; -+ -+ servers = (int *) xmalloc(ncopies * sizeof(int)); -+ memset(servers, 0, ncopies * sizeof(int)); -+ -+ /* Loop forever, until we get SIGTERM */ -+ running = 0; -+ while (1) { -+ /* Rewrite the pidfile */ -+ writepid(getpid(), 1); -+ for (i = 0; i < ncopies; i++) { -+ if (servers[i] != 0) -+ writepid(servers[i], 0); -+ } -+ -+ while (running < ncopies) { -+ if ((now = time(NULL)) == last_restart) { -+ if (++restarts > 2 * ncopies) { -+ Dprintf(L_ERROR, -+ "Servers restarting too " -+ "quickly, backing off."); -+ if (backoff < 60 * 60) -+ backoff <<= 1; -+ sleep(backoff); -+ } -+ } else { -+ last_restart = now; -+ restarts = 0; -+ backoff = 60; -+ } -+ -+ /* Locate a free pid slot */ -+ for (i = 0, child = -1; i < ncopies; i++) { -+ if (servers[i] == 0) { -+ child = i; -+ break; -+ } -+ } -+ -+ if (child < 0) -+ Dprintf(L_FATAL, "failsafe: no pid slot?!"); -+ -+ Dprintf(D_GENERAL, -+ "starting server thread %d...\n", child + 1); -+ -+ pid = fork(); -+ if (pid < 0) -+ Dprintf(L_FATAL, -+ "Unable to fork for failsafe: %s", -+ strerror(errno)); -+ -+ if (pid == 0) { -+ /* Child process: continue with execution. */ -+ return; -+ } -+ -+ writepid(pid, 0); -+ servers[child] = pid; -+ running++; -+ } -+ -+ /* Ignore some signals */ -+ ignore_signal(SIGTERM); -+ ignore_signal(SIGHUP); -+ ignore_signal(SIGINT); -+ ignore_signal(SIGCHLD); -+ -+ if ((pid = wait(&status)) < 0) { -+ Dprintf((errno == ECHILD)? L_FATAL : L_WARNING, -+ "failsafe: wait(): %s", strerror(errno)); -+ continue; -+ } -+ -+ /* Locate the child */ -+ for (i = 0, child = -1; i < ncopies; i++) { -+ if (servers[i] == pid) { -+ child = i; -+ break; -+ } -+ } -+ -+ if (child < 0) { -+ Dprintf(L_WARNING, -+ "failsafe: unknown child (pid %d) terminated", -+ pid); -+ continue; -+ } -+ -+ /* Book-keeping */ -+ servers[child] = 0; -+ running--; -+ -+ if (WIFSIGNALED(status)) { -+ signo = WTERMSIG(status); -+ if (signo == SIGTERM) { -+ Dprintf(L_NOTICE, "failsafe: " -+ "child %d terminated by SIGTERM. %s.", -+ pid, running? "Continue" : "Exit"); -+ } else { -+ Dprintf(L_WARNING, "failsafe: " -+ "child %d terminated by %s. " -+ "Restarting.", -+ pid, get_signame(signo)); -+ child = -1; /* Restart */ -+ } -+ } else if (WIFEXITED(status)) { -+ Dprintf(L_NOTICE, "failsafe: " -+ "child %d exited, status %d.", -+ pid, WEXITSTATUS(status)); -+ } else { -+ Dprintf(L_ERROR, "failsafe: " -+ "abnormal child termination, " -+ "pid=%d status=%d. Restarting.", -+ pid, status); -+ child = -1; /* Restart */ -+ } -+ -+ /* If child >= 0, we should not restart */ -+ if (child >= 0) { -+ if (!running) { -+ Dprintf(D_GENERAL, -+ "No more children, exiting."); -+ exit(0); -+ } -+ for (i = child; i < ncopies-1; i++) -+ servers[i] = servers[i+1]; -+ ncopies--; /* Make sure we start no new servers */ -+ } -+ } -+} -+ -+/* -+ * Failsafe session, catch core file. -+ * -+ * Not yet implemented. -+ * General outline: we need to fork first, because nfsd changes -+ * uids frequently, and the kernel won't write out a core file after -+ * that. The forked proc starts out with a clean dumpable flag though. -+ * -+ * After the fork, we might want to make sure we end up in some common -+ * directory that the failsafe loop knows about. -+ */ -+void -+failsafe_loop(int level, void (*function)(void)) -+{ -+ /* NOP */ -+} -+ -+static const char * -+get_signame(int signo) -+{ -+ static char namebuf[30]; -+ -+ switch (signo) { -+ case SIGHUP: return "SIGHUP"; -+ case SIGINT: return "SIGINT"; -+ case SIGQUIT: return "SIGQUIT"; -+ case SIGILL: return "SIGILL"; -+ case SIGTRAP: return "SIGTRAP"; -+ case SIGIOT: return "SIGIOT"; -+ case SIGBUS: return "SIGBUS"; -+ case SIGFPE: return "SIGFPE"; -+ case SIGKILL: return "SIGKILL"; -+ case SIGUSR1: return "SIGUSR1"; -+ case SIGSEGV: return "SIGSEGV"; -+ case SIGUSR2: return "SIGUSR2"; -+ case SIGPIPE: return "SIGPIPE"; -+ case SIGALRM: return "SIGALRM"; -+ case SIGTERM: return "SIGTERM"; -+ case SIGCHLD: return "SIGCHLD"; -+ case SIGCONT: return "SIGCONT"; -+ case SIGSTOP: return "SIGSTOP"; -+ case SIGTSTP: return "SIGTSTP"; -+ case SIGTTIN: return "SIGTTIN"; -+ case SIGTTOU: return "SIGTTOU"; -+ case SIGURG: return "SIGURG"; -+ case SIGXCPU: return "SIGXCPU"; -+ case SIGXFSZ: return "SIGXFSZ"; -+ case SIGVTALRM: return "SIGVTALRM"; -+ case SIGPROF: return "SIGPROF"; -+ case SIGWINCH: return "SIGWINCH"; -+ case SIGIO: return "SIGIO"; -+#ifdef SIGPWR -+ case SIGPWR: return "SIGPWR"; -+#endif -+ } -+ -+ sprintf(namebuf, "signal #%d", signo); -+ return namebuf; -+} -diff -urN nfs-server-2.2beta47/daemon.h nfs-server-2.2beta51/daemon.h ---- nfs-server-2.2beta47/daemon.h Thu Jan 1 01:00:00 1970 -+++ nfs-server-2.2beta51/daemon.h Fri Nov 8 14:45:52 2002 -@@ -0,0 +1,18 @@ -+/* -+ * daemon.h -+ * -+ * Daemon support -+ */ -+ -+#ifndef CRAWLEY_H -+#define CRAWLEY_H -+ -+#define _PATH_NFSD_PIDFILE "/var/run/nfsd.pid" -+#define _PATH_MOUNTD_PIDFILE "/var/run/mountd.pid" -+ -+extern void daemonize(void); -+extern void setpidpath(const char *); -+extern void writepid(pid_t, int); -+extern void failsafe(int level, int ncopies); -+ -+#endif /* CRAWLEY_H */ -diff -urN nfs-server-2.2beta47/exports.man nfs-server-2.2beta51/exports.man ---- nfs-server-2.2beta47/exports.man Wed Nov 10 10:18:49 1999 -+++ nfs-server-2.2beta51/exports.man Fri Nov 8 14:45:36 2002 -@@ -45,6 +45,12 @@ - simultaneously. This is done by specifying an IP address and netmask pair - as - .IR address/netmask . -+.IP "world -+You can export a directory to the world (i.e. to all computers that -+are able to reach your NFS server network-wise) by using the empty -+hostname. When exporting to the world, the -+.BR root_squash ", " all_squash ", " ro " and " nosetuid -+options are turned on by default. - .TP - .B =public - This is a special ``hostname'' that identifies the given directory name -@@ -81,6 +87,12 @@ - by using the - .IR ro " option. - .TP -+.I setuid -+This allows clients to assert the setuid and setgid bits on regular -+files. For non-anonymous exports, this option is on by default. -+For anonymous exports, the default is -+.IR nosetuid . -+.TP - .I noaccess - This makes everything below the directory inaccessible for the named - client. This is useful when you want to export a directory hierarchy to -@@ -296,6 +308,22 @@ - .I /usr/X11R6 - entry apply. This is also true when the latter is a wildcard or netgroup - entry. -+.PP -+You should also be careful about where you place spaces in the -+exports file. For instance, the following may appear as if you've -+exported -+.BR /pub " readonly to host " foozle , -+but what this does in fact is export the directory to -+.B foozle -+with the default options, -+.I and -+export it to the world with the readonly option: -+.PP -+.nf -+.ta +3i -+# bad: export to the world -+/pub foozle (ro) -+.fi - .SH FILES - /etc/exports - .SH DIAGNOSTICS -diff -urN nfs-server-2.2beta47/fh.c nfs-server-2.2beta51/fh.c ---- nfs-server-2.2beta47/fh.c Wed Nov 10 10:41:14 1999 -+++ nfs-server-2.2beta51/fh.c Fri Nov 8 14:45:36 2002 -@@ -95,17 +95,14 @@ - static int fh_list_size; - static time_t curtime; - --#ifndef FOPEN_MAX --#define FOPEN_MAX 256 --#endif -- - #ifndef FHTRACE - #undef D_FHTRACE - #define D_FHTRACE D_FHCACHE - #endif - --static fhcache * fd_cache[FOPEN_MAX] = { NULL }; -+static fhcache ** fd_cache = NULL; - static int fd_cache_size = 0; -+static int fd_cache_max = 0; - - #ifndef NFSERR_INVAL /* that Sun forgot */ - #define NFSERR_INVAL 22 -@@ -141,10 +138,13 @@ - - /* Forward declared local functions */ - static psi_t path_psi(char *, nfsstat *, struct stat *, int); -+static psi_t path_psi_m(char *, nfsstat *, struct stat *, -+ struct stat *, int); - static int fh_flush_fds(void); - static char * fh_dump(svc_fh *); - static void fh_insert_fdcache(fhcache *fhc); - static void fh_unlink_fdcache(fhcache *fhc); -+static void fh_complain(const char *msg, fhcache *fhc); - - static void - fh_move_to_front(fhcache *fhc) -@@ -192,6 +192,13 @@ - static void - fh_insert_fdcache(fhcache *fhc) - { -+#ifdef FHTRACE -+ Dprintf(D_FHTRACE, "insert fh %x into fdcache @%d\n", fhc->h.psi, fhc->fd); -+ if (fhc->fd < 0) { -+ fh_complain("fd cache bug: bad fd", fhc); -+ return; -+ } -+#endif - if (fhc == fd_lru_head) - return; - if (fhc->fd_next || fhc->fd_prev) -@@ -203,9 +210,20 @@ - fhc->fd_next = fd_lru_head; - fd_lru_head = fhc; - -+ if (fhc->fd >= fd_cache_max) { -+ int oldmax = fd_cache_max, newmax; -+ -+ newmax = (fhc->fd + 8) & ~7; -+ fd_cache = (fhcache **) xrealloc(fd_cache, newmax * sizeof(fhcache *)); -+ memset(fd_cache + oldmax, 0, (newmax - oldmax) * sizeof(fhcache *)); -+ fd_cache_max = newmax; -+ } -+ - #ifdef FHTRACE - if (fd_cache[fhc->fd] != NULL) { -- Dprintf(L_ERROR, "fd cache inconsistency!\n"); -+ Dprintf(L_ERROR, "fd cache inconsistency (two fh's for same fd)"); -+ fh_complain("new fh", fhc); -+ fh_complain("old fh", fd_cache[fhc->fd]); - return; - } - #endif -@@ -225,7 +243,7 @@ - } else if (fd_lru_tail == fhc) { - fd_lru_tail = prev; - } else { -- Dprintf(L_ERROR, "fd cache inconsistency\n"); -+ fh_complain("fd cache inconsistency (no next and not at tail)", fhc); - return; - } - if (prev) { -@@ -233,13 +251,13 @@ - } else if (fd_lru_head == fhc) { - fd_lru_head = next; - } else { -- Dprintf(L_ERROR, "fd cache inconsistency\n"); -+ fh_complain("fd cache inconsistency (no prev and not at head)", fhc); - return; - } - - #ifdef FHTRACE - if (fd_cache[fhc->fd] != fhc) { -- Dprintf(L_ERROR, "fd cache inconsistency!\n"); -+ fh_complain("fd cache inconsistency (fd cache ptr mismatch)", fhc); - return; - } - #endif -@@ -285,7 +303,7 @@ - hash_slot = &((*hash_slot)->hash_next); - if (*hash_slot == NULL) - Dprintf(L_ERROR, -- "internal inconsistency -- fhc(%x) not in hash table\n", -+ "internal inconsistency -- fhc(%x) not in hash table!\n", - fhc); - else - *hash_slot = fhc->hash_next; -@@ -572,7 +590,7 @@ - efs_seekdir(dir, cookie_stack[i]); - while ((dp = efs_readdir(dir))) { - char *name = dp->d_name; -- int n = strlen(name); -+ int n = strlen(name); /* or: dp->d_reclen */ - - if (pathlen + n + 1 >= NFS_MAXPATHLEN - || (name[0] == '.' -@@ -738,7 +756,16 @@ - static psi_t - path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid) - { -- struct stat sbuf; -+ struct stat smounted; -+ -+ return path_psi_m(path, status, sbp, &smounted, svalid); -+} -+ -+static psi_t -+path_psi_m(char *path, nfsstat *status, -+ struct stat *sbp, struct stat *mbp, int svalid) -+{ -+ struct stat sbuf, ddbuf; - - if (sbp == NULL) - sbp = &sbuf; -@@ -746,10 +773,10 @@ - *status = nfs_errno(); - return (0); - } -+ *mbp = *sbp; - if (S_ISDIR(sbp->st_mode) && strcmp(path, "/") != 0) { - /* Special case for directories--test for mount point. */ -- struct stat ddbuf; -- char *fname; -+ char *fname; - - /* Find start of last component of path. */ - #if 1 -@@ -819,6 +846,19 @@ - return (pseudo_inode(sbp->st_ino, sbp->st_dev)); - } - -+/* -+ * Match attributes to make sure we're still referring to the original file -+ */ -+static inline int -+fh_attrmatch(struct fhcache *fhc, struct stat *attr) -+{ -+ if (fhc->dev == attr->st_dev -+ && fhc->ino == attr->st_ino -+ && fhc->type == (attr->st_mode & S_IFMT)) -+ return 1; -+ return 0; -+} -+ - fhcache * - fh_find(svc_fh *h, int mode) - { -@@ -838,6 +878,9 @@ - ex_state = active; - time(&curtime); - while ((fhc = fh_lookup(h->psi)) != NULL) { -+ struct stat sbuf, *s = NULL; -+ nfsstat dummy; -+ - Dprintf(D_FHCACHE, "fh_find: psi=%lx... found '%s', fd=%d\n", - (unsigned long) h->psi, - fhc->path ? fhc->path : "<unnamed>", -@@ -857,33 +900,27 @@ - * If it doesn't try to rebuild the path. - */ - if (check) { -- struct stat *s = &fhc->attrs; -- psi_t psi; -- nfsstat dummy; -- -+ s = &sbuf; - if (efs_lstat(fhc->path, s) < 0) { - Dprintf(D_FHTRACE, - "fh_find: stale fh: lstat: %m\n"); - } else { -- fhc->flags |= FHC_ATTRVALID; -- /* If pseudo-inos don't match, we fhc->path -- * may be a mount point (hence lstat() returns -+ /* If device/ino don't match, fhc->path may -+ * be a mount point (hence lstat() returns - * a different inode number than the readdir() - * stuff used in path_psi) - */ -- psi = pseudo_inode(s->st_ino, s->st_dev); -- if (h->psi == psi) -+ if (fh_attrmatch(fhc, s)) - goto fh_return; - -- /* Try again by computing the path psi */ -- psi = path_psi(fhc->path, &dummy, s, 1); -- if (h->psi == psi) -+ /* Get the dev/ino of the underlying -+ * mount point. */ -+ path_psi(fhc->path, &dummy, s, 1); -+ if (fh_attrmatch(fhc, s)) - goto fh_return; - -- Dprintf(D_FHTRACE, "fh_find: stale fh: " -- "dev/ino %x/%lx psi %lx", -- s->st_dev, s->st_ino, -- (unsigned long) psi); -+ Dprintf(D_FHTRACE, "fh_find: stale fh: %lx", -+ (unsigned long) h->psi); - } - - fh_discard: -@@ -896,6 +933,12 @@ - } - - fh_return: -+ /* Valid attributes; cache them */ -+ if (s != NULL) { -+ memcpy(&fhc->attrs, s, sizeof(*s)); -+ fhc->flags |= FHC_ATTRVALID; -+ } -+ - /* The cached fh seems valid */ - if (fhc != fh_head.next) - fh_move_to_front(fhc); -@@ -905,7 +948,8 @@ - } - - Dprintf(D_FHCACHE, "fh_find: psi=%lx... not found\n", -- (unsigned long) h->psi); -+ (unsigned long) h->psi); -+ - if (mode == FHFIND_FCACHED) { - ex_state = inactive; - return NULL; -@@ -918,6 +962,7 @@ - fhc = flush->prev; - fh_delete(flush); - } -+ - fhc = (fhcache *) xmalloc(sizeof *fhc); - if (mode == FHFIND_FCREATE) { - /* File will be created */ -@@ -937,11 +982,31 @@ - } - fhc->path = path; - } -+ - fhc->flags = 0; - if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) { -- if (re_export && nfsmounted(fhc->path, &fhc->attrs)) -+ if (nfsmounted(fhc->path, &fhc->attrs)) { - fhc->flags |= FHC_NFSMOUNTED; -+#if 0 -+ /* We must allow the client to send us the -+ * file handle for the NFS mount point itself, -+ * but not for entries within an NFS mount. -+ * XXX: needs fixing. -+ */ -+ if (!re_export) { -+ Dprintf(D_FHTRACE, -+ "Attempt to use %s (non-exportable)\n", -+ fhc->path); -+ free(fhc); -+ ex_state = inactive; -+ return NULL; -+ } -+#endif -+ } - fhc->flags |= FHC_ATTRVALID; -+ fhc->dev = fhc->attrs.st_dev; -+ fhc->ino = fhc->attrs.st_ino; -+ fhc->type = fhc->attrs.st_mode & S_IFMT; - } - fhc->fd = -1; - fhc->last_used = curtime; -@@ -993,6 +1058,14 @@ - return buf; - } - -+static void -+fh_complain(const char *msg, fhcache *fhc) -+{ -+ Dprintf(L_ERROR, "%s: ptr=%p fd=%d path=%s\n", msg, -+ fhc, fhc->fd, -+ fhc->path? fhc->path : "<unnamed>"); -+} -+ - /* - * This routine is only used by the mount daemon. - * It creates the initial file handle. -@@ -1000,23 +1073,25 @@ - int - fh_create(nfs_fh *fh, char *path) - { -- svc_fh key; -- fhcache *h; -- psi_t psi; -- nfsstat status; -- char *s; -+ struct stat stb; -+ svc_fh key; -+ fhcache *h; -+ psi_t psi; -+ nfsstat status; -+ char *s; - - memset(&key, 0, sizeof(key)); - status = NFS_OK; -- if ((psi = path_psi("/", &status, NULL, 0)) == 0) -+ if ((psi = path_psi("/", &status, &stb, 0)) == 0) - return ((int) status); -+ - s = path; - while ((s = strchr(s + 1, '/')) != NULL) { - if (++(key.hash_path[0]) >= HP_LEN) - return ((int) NFSERR_NAMETOOLONG); - key.hash_path[key.hash_path[0]] = hash_psi(psi); - *s = '\0'; -- if ((psi = path_psi(path, &status, NULL, 0)) == 0) -+ if ((psi = path_psi(path, &status, &stb, 0)) == 0) - return ((int) status); - *s = '/'; - } -@@ -1024,7 +1099,7 @@ - if (++(key.hash_path[0]) >= HP_LEN) - return ((int) NFSERR_NAMETOOLONG); - key.hash_path[key.hash_path[0]] = hash_psi(psi); -- if ((psi = path_psi(path, &status, NULL, 0)) == 0) -+ if ((psi = path_psi(path, &status, &stb, 0)) == 0) - return ((int) status); - } - key.psi = psi; -@@ -1037,9 +1112,12 @@ - - /* assert(h != NULL); */ - if (h->path == NULL) { -- h->fd = -1; -- h->path = xstrdup(path); -+ h->fd = -1; -+ h->path = xstrdup(path); - h->flags = 0; -+ h->dev = stb.st_dev; -+ h->ino = stb.st_ino; -+ h->type = stb.st_mode & S_IFMT; - } - memcpy(fh, &key, sizeof(key)); - return ((int) status); -@@ -1064,6 +1142,44 @@ - return ((nfs_fh*)&(h->h)); - } - -+ -+static inline int -+access_override(int omode, int perm, struct stat *buf) -+{ -+ /* Be suspicous of flags, particularly O_CREAT/O_TRUNC. A previous -+ * comment said: -+ * -+ * "[Not checking this] would truncate read-only files on creat() -+ * calls. Of course, ftruncate(fd, 0) should still be legal for -+ * the user when the file was chmoded *after* opening it, but we -+ * have no way to tell, and a semi-succeding `cp foo readonly-file' -+ * is much more unintuitive and destructive than a failing -+ * ftruncate()." -+ */ -+ if (omode & ~O_ACCMODE) -+ return 0; -+ -+ /* Users can do anything to their own files. Harmless (since they -+ * could chown anyway), and helps to mask NFSes statelessness. -+ * -+ * (in passing, this also handles mode 0100 execution) -+ */ -+ if (buf->st_uid == auth_uid) -+ return 1; -+ -+ /* Henceforth, we are considering granting read access to facilitate -+ * exec access. This is read only */ -+ if (omode != O_RDONLY) -+ return 0; -+ -+ /* Mode 0110 execution */ -+ if (buf->st_gid == auth_gid) -+ return (buf->st_mode & S_IXGRP) != 0; -+ -+ /* Mode 0111 execution */ -+ return (buf->st_mode & S_IXOTH) != 0; -+} -+ - int - path_open(char *path, int omode, int perm) - { -@@ -1113,30 +1229,15 @@ - * lishes two things: first, it gives the file owner r/w access to - * the file whatever the permissions are, so that files are still - * accessible after an fchown(fd, 0). The second part of the -- * condition allows read access to mode 0111 executables. -- * -- * The old conditon read like this: -- * if (fd < 0 && oerrno == EACCES) { -- * if (oerrno == EACCES && (buf.st_uid == auth_uid -- * || (omode == O_RDONLY && (buf.st_mode & S_IXOTH)))) { -- * override uid; etc... -- * } -- * } -- * This would truncate read-only files on creat() calls. Now -- * ftruncate(fd, 0) should still be legal for the user when the -- * file was chmoded *after* opening it, but we have no way to tell, -- * and a semi-succeding `cp foo readonly-file' is much more -- * unintuitive and destructive than a failing ftruncate(). -+ * condition allows read access to `execute-only' files. - */ -- if (fd < 0 && oerrno == EACCES && !(omode & (O_CREAT|O_TRUNC))) { -- if ((buf.st_uid == auth_uid && (omode & O_ACCMODE) == omode) -- || ((buf.st_mode & S_IXOTH) && omode == O_RDONLY)) { -- auth_override_uid(ROOT_UID); -- fd = efs_open(path, omode, perm); -- oerrno = errno; -- auth_override_uid(auth_uid); -- } -+ if (fd < 0 && oerrno == EACCES && access_override(omode, perm, &buf)) { -+ auth_override_uid(ROOT_UID); -+ fd = efs_open(path, omode, perm); -+ oerrno = errno; -+ auth_override_uid(auth_uid); - } -+ - - if (fd < 0) { - Dprintf(D_FHCACHE, -@@ -1241,7 +1342,7 @@ - char *sindx; - int is_dd; - nfsstat ret; -- struct stat sbuf; -+ struct stat sbuf, smount; - char pathbuf[PATH_MAX + NAME_MAX + 1], *fname; - - /* should not happen */ -@@ -1318,7 +1419,7 @@ - - *new_fh = dopa->dir; - key = (svc_fh *) new_fh; -- if ((key->psi = path_psi(pathbuf, &ret, sbp, 0)) == 0) -+ if ((key->psi = path_psi_m(pathbuf, &ret, sbp, &smount, 0)) == 0) - return (ret); - - if (is_dd) { -@@ -1344,6 +1445,10 @@ - h->h.hash_path[0]); - return NFSERR_STALE; - } -+ if (sbp->st_dev != smount.st_dev) { -+ Dprintf(D_FHTRACE, "fh_compose: %s hit%s mount point\n", -+ pathbuf, nfsmounted(pathbuf, &smount)? " NFS" : ""); -+ } - #endif - - /* New code added by Don Becker */ -@@ -1356,7 +1461,8 @@ - if (!h) return NFSERR_STALE; - #endif - if (h->path) -- Dprintf(L_ERROR, "Internal inconsistency: double entry (path '%s', now '%s').\n", -+ Dprintf(L_ERROR, -+ "internal inconsistency: double entry (path '%s', now '%s').\n", - h->path, pathbuf); - } - Dprintf(D_FHCACHE, "fh_compose: using handle %x ('%s', fd=%d)\n", -@@ -1365,9 +1471,18 @@ - - /* assert(h != NULL); */ - if (h->path == 0) { -- h->path = xstrdup(pathbuf); -+ h->path = xstrdup(pathbuf); - h->flags = 0; -- if (!re_export && nfsmounted(pathbuf, sbp)) -+ h->dev = sbp->st_dev; -+ h->ino = sbp->st_ino; -+ h->type = sbp->st_mode & S_IFMT; -+ -+ /* Note: in the case of a mount point, -+ * sbp contains the stats of the mount point, while -+ * ddbuf has the dev/ino of the underlying directory -+ */ -+ if (sbp->st_dev != smount.st_dev -+ && nfsmounted(pathbuf, &smount)) - h->flags |= FHC_NFSMOUNTED; - #ifdef FHTRACE - Dprintf(D_FHTRACE, "fh_compose: created handle %s\n", h->path); -diff -urN nfs-server-2.2beta47/fh.h nfs-server-2.2beta51/fh.h ---- nfs-server-2.2beta47/fh.h Mon Nov 23 12:15:43 1998 -+++ nfs-server-2.2beta51/fh.h Fri Nov 8 14:45:36 2002 -@@ -97,7 +97,13 @@ - struct fhcache * hash_next; - struct fhcache * fd_next; - struct fhcache * fd_prev; -+ -+ /* These are fixed during the lifetime of this object */ - svc_fh h; -+ dev_t dev; -+ ino_t ino; -+ mode_t type; /* st_mode & S_IFMT */ -+ - int fd; - int omode; - char * path; -diff -urN nfs-server-2.2beta47/getattr.c nfs-server-2.2beta51/getattr.c ---- nfs-server-2.2beta47/getattr.c Fri Oct 30 18:10:11 1998 -+++ nfs-server-2.2beta51/getattr.c Fri Nov 8 14:45:36 2002 -@@ -115,6 +115,16 @@ - attr->fsid = 1; - attr->fileid = fh_psi((nfs_fh *)&(fhc->h)); - #endif -+ -+ /* This may be needed by some Suns... testing */ -+#define MINTIME (24 * 2600) -+ if (s->st_atime < MINTIME) -+ s->st_atime = MINTIME; -+ if (s->st_mtime < MINTIME) -+ s->st_mtime = MINTIME; -+ if (s->st_ctime < MINTIME) -+ s->st_ctime = MINTIME; -+ - attr->atime.seconds = s->st_atime; - attr->atime.useconds = 0; - attr->mtime.seconds = s->st_mtime; -diff -urN nfs-server-2.2beta47/logging.c nfs-server-2.2beta51/logging.c ---- nfs-server-2.2beta47/logging.c Fri Oct 30 17:11:22 1998 -+++ nfs-server-2.2beta51/logging.c Fri Nov 8 14:45:36 2002 -@@ -147,8 +147,9 @@ - (void) time(&now); - tm = localtime(&now); - fprintf(log_fp, "%s %02d/%02d/%02d %02d:%02d %s", -- log_name, tm->tm_mon + 1, tm->tm_mday, tm->tm_year, -- tm->tm_hour, tm->tm_min, buff); -+ log_name, tm->tm_mon + 1, tm->tm_mday, -+ tm->tm_year % 100, -+ tm->tm_hour, tm->tm_min, buff); - if (strchr(buff, '\n') == NULL) - fputc('\n', log_fp); - } -@@ -182,7 +183,8 @@ - tm = localtime(&unix_cred->aup_time); - snprintf(buffer + len, total - len, - "%d/%d/%d %02d:%02d:%02d %s %d.%d", -- tm->tm_year, tm->tm_mon + 1, tm->tm_mday, -+ tm->tm_year %100, -+ tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - unix_cred->aup_machname, - unix_cred->aup_uid, -diff -urN nfs-server-2.2beta47/mountd.c nfs-server-2.2beta51/mountd.c ---- nfs-server-2.2beta47/mountd.c Wed Jun 2 14:10:33 1999 -+++ nfs-server-2.2beta51/mountd.c Fri Nov 8 14:45:36 2002 -@@ -32,7 +32,7 @@ - #include "rpcmisc.h" - #include "rmtab.h" - #include "haccess.h" --#include "failsafe.h" -+#include "daemon.h" - #include "signals.h" - #include <rpc/pmap_clnt.h> - -@@ -44,6 +44,8 @@ - /* - * Option table for mountd - */ -+#define OPT_NOTCP 300 -+#define OPT_LOOPBACK 301 - static struct option longopts[] = - { - { "debug", required_argument, 0, 'd' }, -@@ -56,6 +58,8 @@ - { "no-spoof-trace", 0, 0, 't' }, - { "version", 0, 0, 'v' }, - { "fail-safe", optional_argument, 0, 'z' }, -+ { "no-tcp", 0, 0, OPT_NOTCP }, -+ { "loopback-only", 0, 0, OPT_LOOPBACK }, - - { NULL, 0, 0, 0 } - }; -@@ -358,6 +362,12 @@ - break; - case 0: - break; -+ case OPT_NOTCP: -+ udp_only = 1; -+ break; -+ case OPT_LOOPBACK: -+ loopback_only = 1; -+ break; - case '?': - default: - usage(stderr, 1); -@@ -384,38 +394,27 @@ - /* Create services and register with portmapper */ - rpc_init("mountd", MOUNTPROG, mountd_versions, mount_dispatch, port, 0); - -- if (!foreground && !_rpcpmstart) { --#ifndef RPC_SVC_FG -- /* We first fork off a child. */ -- if ((c = fork()) > 0) -- exit(0); -- if (c < 0) { -- Dprintf(L_FATAL, "mountd: cannot fork: %s\n", -- strerror(errno)); -- } -- /* No more logging to stderr */ -- background_logging(); -+ if (_rpcpmstart) { -+ /* Always foreground mode */ -+ foreground = 1; - -- /* Now we remove ourselves from the foreground. */ -- (void) close(0); -- (void) close(1); -- (void) close(2); --#ifdef TIOCNOTTY -- if ((c = open("/dev/tty", O_RDWR)) >= 0) { -- (void) ioctl(c, TIOCNOTTY, (char *) NULL); -- (void) close(c); -- } --#else -- setsid(); --#endif --#endif /* not RPC_SVC_FG */ -+ /* ... but no logging */ -+ background_logging(); - } - -+ /* Become a daemon */ -+ if (!foreground) -+ daemonize(); -+ - /* Initialize the FH module. */ - fh_init(); - - /* Initialize the AUTH module. */ - auth_init(auth_file); -+ -+ /* Write pidfile */ -+ setpidpath(_PATH_MOUNTD_PIDFILE); -+ writepid(getpid(), 1); - - /* Failsafe mode */ - if (failsafe_level) -diff -urN nfs-server-2.2beta47/mountd.man nfs-server-2.2beta51/mountd.man ---- nfs-server-2.2beta47/mountd.man Wed Jun 2 14:12:21 1999 -+++ nfs-server-2.2beta51/mountd.man Fri Nov 8 14:45:36 2002 -@@ -14,6 +14,8 @@ - .B "[\ \-\-allow\-non\-root\ ]" - .B "[\ \-\-re\-export\ ]" - .B "[\ \-\-no\-spoof\-trace\ ]" -+.B "[\ \-\-no\-tcp ]" -+.B "[\ \-\-loopback\-only ]" - .B "[\ \-\-version\ ]" - .ad b - .SH DESCRIPTION -@@ -123,6 +125,18 @@ - .TP - .BR \-v " or " \-\-version - Report the current version number of the program. -+.TP -+.BR \-\-no\-tcp -+Force -+.I mountd -+to register only the UDP transport, but no TCP. -+This is an experimental option. -+.TP -+.BR \-\-loopback\-only -+Force -+.I mountd -+to bind to the loopback interface. -+This is an experimental option. - .SS Access Control - For enhanced security, access to - .I mountd -diff -urN nfs-server-2.2beta47/nfsd.c nfs-server-2.2beta51/nfsd.c ---- nfs-server-2.2beta47/nfsd.c Wed Nov 10 10:33:28 1999 -+++ nfs-server-2.2beta51/nfsd.c Fri Nov 8 14:45:36 2002 -@@ -21,7 +21,7 @@ - #include "getopt.h" - #include "fsusage.h" - #include "rpcmisc.h" --#include "failsafe.h" -+#include "daemon.h" - #include "signals.h" - #ifdef __linux__ /* XXX - MvS: for UNIX sockets. */ - # include <sys/un.h> -@@ -30,7 +30,6 @@ - # include <syslog.h> - #endif - --#define MULTIPLE_SERVERS - - /* Flags for auth_fh */ - #define CHK_READ 0 -@@ -51,6 +50,8 @@ - /* - * Option table - */ -+#define OPT_NOTCP 300 -+#define OPT_LOOPBACK 301 - static struct option longopts[] = { - { "auth-deamon", required_argument, 0, 'a' }, - { "debug", required_argument, 0, 'd' }, -@@ -68,6 +69,9 @@ - { "version", 0, 0, 'v' }, - { "no-cross-mounts", 0, 0, 'x' }, - { "fail-safe", optional_argument, 0, 'z' }, -+ { "no-tcp", 0, 0, OPT_NOTCP }, -+ { "udp-only", 0, 0, OPT_NOTCP }, -+ { "loopback-only", 0, 0, OPT_LOOPBACK }, - - { NULL, 0, 0, 0 } - }; -@@ -173,7 +177,10 @@ - return NULL; - } - -- auth_user(nfsmount, rqstp); -+ if (!auth_user(nfsmount, rqstp)) { -+ *statp = NFSERR_ACCES; -+ return NULL; -+ } - - *statp = NFS_OK; - return fhc; -@@ -211,7 +218,11 @@ - - if ((nfsmount = auth_path(nfsclient, rqstp, path)) == NULL) - return NFSERR_ACCES; -- auth_user(nfsmount, rqstp); -+ -+ /* XXX: really need to call it again here? -+ * Already invoked in auth_fh */ -+ if (!auth_user(nfsmount, rqstp)) -+ return NFSERR_ACCES; - - return (NFS_OK); - } -@@ -575,7 +586,8 @@ - #endif - - /* MvS: Some clients use chardev 0xFFFF for a FIFO. */ -- if (S_ISCHR(argp->attributes.mode) && dev == 0xFFFF) { -+ if (S_ISCHR(argp->attributes.mode) -+ && (dev == 0xFFFF || dev == (dev_t) -1)) { - is_borc = 0; - dev = 0; - argp->attributes.mode &= ~S_IFMT; -@@ -623,7 +635,7 @@ - flags = (argp->attributes.size == 0 ? - CREATE_OMODE | O_TRUNC : CREATE_OMODE); - if (!exists) -- flags |= O_CREAT; -+ flags |= O_CREAT|O_EXCL; - tmpfd = path_open(pathbuf, flags, - argp->attributes.mode & ~S_IFMT); - if (tmpfd < 0) -@@ -965,9 +977,7 @@ - int nfsport = 0; - int failsafe_level = 0; - int c; --#ifdef MULTIPLE_SERVERS - int i, ncopies = 1; --#endif - - program_name = argv[0]; - chdir("/"); -@@ -1031,12 +1041,17 @@ - break; - case 0: - break; -+ case OPT_NOTCP: -+ udp_only = 1; -+ break; -+ case OPT_LOOPBACK: -+ loopback_only = 1; -+ break; - case '?': - default: - usage(stderr, 1); - } - --#ifdef MULTIPLE_SERVERS - if (optind == argc-1 && isdigit(argv[optind][0])) { - ncopies = atoi(argv[optind++]); - if (ncopies <= 0) { -@@ -1051,7 +1066,6 @@ - ncopies = 1; - } - } --#endif - - /* No more arguments allowed. */ - if (optind != argc) -@@ -1075,72 +1089,54 @@ - rpc_init("nfsd", NFS_PROGRAM, nfsd_versions, nfs_dispatch, - nfsport, NFS_MAXDATA); - -- /* No more than 1 copy when run from inetd */ -- if (_rpcpmstart && ncopies > 1) { -- Dprintf(L_WARNING, -- "nfsd: warning: can run only " -- "one server in inetd mode\n"); -- ncopies = 1; -+ if (_rpcpmstart) { -+ /* Always do foreground mode */ -+ foreground = 1; -+ -+ /* ... but don't log to stderr */ -+ background_logging(); -+ -+ /* No more than 1 copy when run from inetd */ -+ if (ncopies > 1) { -+ Dprintf(L_WARNING, -+ "nfsd: warning: can run only " -+ "one server in inetd mode\n"); -+ ncopies = 1; -+ } - } - --#ifndef MULTIPLE_SERVERS_READWRITE - if (ncopies > 1) - read_only = 1; --#endif - -- /* We first fork off a child. */ -- if (!foreground) { -- if ((c = fork()) > 0) -- exit(0); -- if (c < 0) { -- Dprintf(L_FATAL, "nfsd: cannot fork: %s\n", -- strerror(errno)); -- } -- } -+ /* -+ * We first fork off a child and detach from tty -+ */ -+ if (!foreground) -+ daemonize(); - - /* Initialize the AUTH module. */ - auth_init(auth_file); - -+ setpidpath(_PATH_NFSD_PIDFILE); - if (failsafe_level == 0) { - /* Start multiple copies of the server */ -+ writepid(getpid(), 1); - for (i = 1; i < ncopies; i++) { -+ pid_t pid; -+ - Dprintf(D_GENERAL, "Forking server thread...\n"); -- if ((c = fork()) < 0) { -+ if ((pid = fork()) < 0) { - Dprintf(L_ERROR, "Unable to fork: %s", - strerror(errno)); -- } else if (c == 0) { -- /* Child process */ -- break; -+ } else if (pid != 0) { -+ writepid(pid, 0); -+ } else { -+ break; /* Child process */ - } - } - } else { - /* Init for failsafe mode */ - failsafe(failsafe_level, ncopies); -- } -- -- /* Now that we've done all the required forks, we make do all the -- * session magic. -- */ -- if (!foreground) { -- /* No more logging to stderr */ -- background_logging(); -- -- /* Now we remove ourselves from the foreground. */ -- close(0); -- close(1); -- close(2); --#ifdef HAVE_SETSID -- setsid(); --#else -- { -- int fd; -- -- if ((fd = open("/dev/tty", O_RDWR)) >= 0) { -- ioctl(fd, TIOCNOTTY, (char *) NULL); -- close(fd); -- } -- } --#endif - } - - /* -diff -urN nfs-server-2.2beta47/nfsd.man nfs-server-2.2beta51/nfsd.man ---- nfs-server-2.2beta47/nfsd.man Wed Jun 2 14:13:37 1999 -+++ nfs-server-2.2beta51/nfsd.man Fri Nov 8 14:45:36 2002 -@@ -8,7 +8,7 @@ - .B "[\ \-d\ facility\ ]" - .B "[\ \-P\ port\ ]" - .B "[\ \-R\ dirname\ ]" --.B "[\ \-Fhlnprstv\ ]" -+.B "[\ \-Fhlnprstuv\ ]" - .B "[\ \-\-debug\ facility\ ]" - .B "[\ \-\-exports\-file=file\ ]" - .B "[\ \-\-foreground\ ]" -@@ -18,6 +18,8 @@ - .B "[\ \-\-public\-root\ dirname\ ]" - .\".B "[\ \-\-synchronous\-writes\ ]" - .B "[\ \-\-no\-spoof\-trace\ ]" -+.B "[\ \-\-no\-tcp ]" -+.B "[\ \-\-loopback-only ]" - .B "[\ \-\-port\ port\ ]" - .B "[\ \-\-log-transfers\ ]" - .B "[\ \-\-version\ ]" -@@ -56,7 +58,7 @@ - .PP - When run from - .IR inetd , --.i nfsd -+.I nfsd - will terminate after a certain period of inactivity. - .SH OPTIONS - .TP -@@ -167,6 +169,14 @@ - .BR \-v " or " \-\-version - Report the current version number of the program. - .TP -+.BR \-\-no\-tcp -+Force nfsd to only register a UDP transport, but not TCP. -+This is an experimental option. -+.TP -+.BR \-\-loopback\-only -+Force nfsd to bind to the loopback interface. -+This is an experimental option. -+.TP - .BR numcopies - This is an experimental feature that lets you run several instances of - .I nfsd -@@ -174,15 +184,8 @@ - .B numcopies - greater than one, - .I nfsd --will fork as many times as specified by this value. --However, the servers do not share a common file handle --cache, which makes certain file operations impossible. --.IP --For this reason, --.I nfsd --will disallow all write operations when invoked with this option. Although --this is very limiting, this feature may still prove useful for exporting --public FTP areas or Usenet News spools. -+will fork as many times as specified by this value so it is able to -+handle that many NFS requests in parallel. - .SS WebNFS Support - WebNFS is an extension to the normal NFS protocol developed by Sun - that is particularly well-suited for file retrieval over the -@@ -268,6 +271,19 @@ - .I nfsd - writes out a transfer record whenever it encounters a READ or WRITE - request at offset zero. -+.SS Generating a debug trace -+When suspecting a bug in nfsd, it is helpful to look at a debug trace -+of what's going on. You can create such a trace by first killing nfsd, -+and then restarting it as -+.PP -+.nf -+.ta +3i -+/usr/sbin/rpc.nfsd -F -d all -+.fi -+.PP -+Instead of -+.BR all , -+you can use less verbose debug facilities as described above. - .SH "SEE ALSO" - exports(5), mountd(8), ugidd(8C) - .SH AUTHORS -diff -urN nfs-server-2.2beta47/rmtab.c nfs-server-2.2beta51/rmtab.c ---- nfs-server-2.2beta47/rmtab.c Fri Feb 6 09:43:25 1998 -+++ nfs-server-2.2beta51/rmtab.c Fri Nov 8 14:45:36 2002 -@@ -8,6 +8,7 @@ - - #include "nfsd.h" - #include "rmtab.h" -+#include "rpcmisc.h" - - static char * rmtab_gethost(struct svc_req *); - static int rmtab_insert(char *, char *); -diff -urN nfs-server-2.2beta47/rpcmisc.c nfs-server-2.2beta51/rpcmisc.c ---- nfs-server-2.2beta47/rpcmisc.c Tue Sep 7 10:42:58 1999 -+++ nfs-server-2.2beta51/rpcmisc.c Fri Nov 8 14:45:36 2002 -@@ -39,6 +39,8 @@ - int _rpcfdtype = 0; - int _rpcsvcdirty = 0; - const char * auth_daemon = 0; -+int udp_only = 0; -+int loopback_only = 0; - - #ifdef AUTH_DAEMON - static bool_t (*tcp_rendevouser)(SVCXPRT *, struct rpc_msg *); -@@ -96,7 +98,7 @@ - } - } - -- if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { -+ if ((_rpcfdtype == 0 && !udp_only) || (_rpcfdtype == SOCK_STREAM)) { - if (_rpcfdtype == 0 && defport != 0) - sock = makesock(defport, IPPROTO_TCP, bufsiz); - transp = svctcp_create(sock, 0, 0); -@@ -199,6 +201,9 @@ - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(port); -+ -+ if (loopback_only) -+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - #ifdef DEBUG - { -diff -urN nfs-server-2.2beta47/rpcmisc.h nfs-server-2.2beta51/rpcmisc.h ---- nfs-server-2.2beta47/rpcmisc.h Tue Sep 7 10:37:38 1999 -+++ nfs-server-2.2beta51/rpcmisc.h Fri Nov 8 14:45:36 2002 -@@ -9,6 +9,8 @@ - extern int _rpcpmstart; - extern int _rpcfdtype; - extern int _rpcsvcdirty; -+extern int udp_only; -+extern int loopback_only; - extern const char * auth_daemon; - - extern void rpc_init(const char *name, int prog, int *verstbl, -@@ -16,5 +18,13 @@ - int defport, int bufsize); - extern void rpc_exit(int prog, int *verstbl); - extern void rpc_closedown(void); -+ -+/* -+ * Some older systems don't have svc_getcaller. -+ * Some, like glibc 2.2, have it but it returns some type that's -+ * not a sockaddr_in anymore. -+ */ -+#undef svc_getcaller -+#define svc_getcaller(xprt) ((struct sockaddr_in *) (&(xprt)->xp_raddr)) - - #endif /* RPCMISC_H */ -diff -urN nfs-server-2.2beta47/setattr.c nfs-server-2.2beta51/setattr.c ---- nfs-server-2.2beta47/setattr.c Fri Oct 30 18:29:42 1998 -+++ nfs-server-2.2beta51/setattr.c Fri Nov 8 14:45:36 2002 -@@ -103,6 +103,10 @@ - if (flags & SATTR_CHMOD) { - unsigned int mode = attr->mode; - -+ /* If setuid is not allowed, silently squash them */ -+ if (!nfsmount->o.allow_setuid && S_ISREG(s->st_mode)) -+ mode &= ~(S_ISUID|S_ISGID) | s->st_mode; -+ - if (mode != -1 && mode != 0xFFFF /* ultrix bug */ - && (mode & 07777) != (s->st_mode & 07777)) { - if (efs_chmod(path, mode) < 0) -diff -urN nfs-server-2.2beta47/showmount.c nfs-server-2.2beta51/showmount.c ---- nfs-server-2.2beta47/showmount.c Wed Jun 12 22:31:04 1996 -+++ nfs-server-2.2beta51/showmount.c Fri Nov 8 14:45:36 2002 -@@ -162,17 +162,13 @@ - break; - } - -- if (hostname[0] >= '0' && hostname[0] <= '9') { -- server_addr.sin_family = AF_INET; -- server_addr.sin_addr.s_addr = inet_addr(hostname); -- } -- else { -+ server_addr.sin_family = AF_INET; -+ if (!inet_aton(hostname, &server_addr.sin_addr)) { - if ((hp = gethostbyname(hostname)) == NULL) { - fprintf(stderr, "%s: can't get address for %s\n", - program_name, hostname); - exit(1); - } -- server_addr.sin_family = AF_INET; - memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); - } - -diff -urN nfs-server-2.2beta47/site.h.in nfs-server-2.2beta51/site.h.in ---- nfs-server-2.2beta47/site.h.in Thu Jan 1 01:00:00 1970 -+++ nfs-server-2.2beta51/site.h.in Fri Nov 8 14:45:57 2002 -@@ -0,0 +1,50 @@ -+/* -+ * Site-specific configuration options generated by BUILD. -+ * Please do not edit. -+ */ -+ -+/* -+ * If ENABLE_DEVTAB is defined, nfsd will use the new inode -+ * number generation scheme for avoiding inode number clashes -+ * on big hard disks. -+ */ -+#undef ENABLE_DEVTAB -+ -+/* -+ * If MULTIPLE_SERVER_READWRITE is defined, you will be able -+ * to run several nfsd process in parallel servicing all NFS -+ * requests. -+ */ -+#define MULTIPLE_SERVERS_READWRITE -+ -+/* -+ * If ENABLE_UGID_DAEMON is defined, the real rpc.ugidd is built, -+ * nfsd is built to support ugidd queries. -+ * Otherwise, a dummy program is created -+ */ -+#undef ENABLE_UGID_DAEMON -+ -+/* -+ * If ENABLE_UGID_NIS is defined, nfsd will support user mapping -+ * vie the client's NIS server. -+ */ -+#undef ENABLE_UGID_NIS -+ -+/* -+ * if HOSTS_ACCESS is defined, ugidd uses host access control -+ * provided by libwrap.a from tcp_wrappers -+ */ -+#define HOSTS_ACCESS -+ -+/* -+ * Define correct ownership of export control file -+ */ -+#define EXPORTSOWNERUID 0 -+#define EXPORTSOWNERGID 0 -+ -+/* -+ * If WANT_LOG_MOUNTS is defined, every mount request will be logged -+ * to syslogd with the name of source site and a path that was -+ * it requested -+ */ -+#define WANT_LOG_MOUNTS -diff -urN nfs-server-2.2beta47/ugidd.c nfs-server-2.2beta51/ugidd.c ---- nfs-server-2.2beta47/ugidd.c Wed Dec 10 12:34:16 1997 -+++ nfs-server-2.2beta51/ugidd.c Fri Nov 8 14:45:36 2002 -@@ -43,9 +43,7 @@ - }; - - int --main(argc, argv) --int argc; --char **argv; -+main(int argc, char **argv) - { - SVCXPRT *transp; - int c, longind; -@@ -92,32 +90,11 @@ - exit(1); - } - -- if (!foreground) { -- if ((c = fork()) > 0) -- exit(0); -- if (c < 0) { -- fprintf(stderr, "ugidd: cannot fork: %s\n", -- strerror(errno)); -- exit(-1); -- } -- close(0); -- close(1); -- close(2); --#ifdef HAVE_SETSID -- setsid(); --#else -- { -- int fd; -- -- if ((fd = open("/dev/tty", O_RDWR)) >= 0) { -- ioctl(fd, TIOCNOTTY, (char *) NULL); -- close(fd); -- } -- } --#endif -- } -- - log_open("ugidd", foreground); -+ -+ /* Become a daemon */ -+ if (!foreground) -+ daemonize(); - - svc_run(); - Dprintf(L_ERROR, "svc_run returned\n"); -diff -urN nfs-server-2.2beta47/version.c nfs-server-2.2beta51/version.c ---- nfs-server-2.2beta47/version.c Wed Nov 10 10:33:33 1999 -+++ nfs-server-2.2beta51/version.c Fri Nov 8 14:45:36 2002 -@@ -1 +1 @@ --char version[] = "Universal NFS Server 2.2beta47"; -+char version[] = "Universal NFS Server 2.2beta51"; |