2345 lines
62 KiB
Diff
2345 lines
62 KiB
Diff
# 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";
|