summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch')
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch2344
1 files changed, 2344 insertions, 0 deletions
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch
new file mode 100644
index 0000000000..886ce92b34
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch
@@ -0,0 +1,2344 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3diff -urN nfs-server-2.2beta47/.version nfs-server-2.2beta51/.version
4--- nfs-server-2.2beta47/.version Tue Sep 7 09:47:27 1999
5+++ nfs-server-2.2beta51/.version Fri Nov 8 14:45:36 2002
6@@ -1 +1 @@
7-2.2beta46
8+2.2beta51
9diff -urN nfs-server-2.2beta47/ChangeLog nfs-server-2.2beta51/ChangeLog
10--- nfs-server-2.2beta47/ChangeLog Wed Nov 10 10:17:51 1999
11+++ nfs-server-2.2beta51/ChangeLog Fri Nov 8 14:45:36 2002
12@@ -1,8 +1,59 @@
13+Thu Nov 9 17:03:05 2000
14+
15+ * No longer use OPEN_MAX
16+
17+ * Reworked configure.in, BUILD script no longer needed
18+ (nor functioning)
19+
20+ * Be more anal about matching cached fh's and real files.
21+ In addition to the psi, we also store dev/ino/type now
22+ and match that in fh_find.
23+
24+ * Write pidfiles
25+
26+ * Support nosetuid
27+
28+Wed Feb 9 14:52:34 2000
29+
30+ * auth_init.c didn't properly parse options--rot_squash
31+ which is obviously a typo was parsed as ro.
32+ Thanks to Jan Steffan for complaining about this :-)
33+
34+Mon Jan 31 11:48:34 2000
35+
36+ * Fixed Y2K bug in logging.c.
37+ Thanks to Jonathan Hankins <jhankins@homewood.k12.al.us>.
38+
39+Thu Dec 9 11:14:21 1999
40+
41+ * Fix handling of NFS-mounted and /proc directories.
42+ They weren't properly hidden.
43+ Thanks to Dick Streefland <dick_streefland@tasking.com>
44+ for the report and a first patch.
45+
46 Wed Nov 10 10:17:16 1999
47
48 * Security fix for buffer overflow in fh_buildpath
49 No thanks to Mariusz who reported it to bugtraq
50 rather than me.
51+
52+Wed Nov 09 17:10:00 1999
53+
54+ * Workaround for broken Solaris clients that can't handle
55+ atime/mtime/ctime of 0.
56+ Thanks to Frank Wuebbelin for his problem report and
57+ testing the fix.
58+
59+ * Fixed typo in exports.man
60+
61+Tue Nov 2 10:31:14 1999
62+
63+ * Patch for mode 0100 and 0100 executables by
64+ Michael Deutschmann <michael@talamasca.wkpowerlink.com>
65+
66+ * Common startup stuff for all daemons.
67+ Inspired by code sent to me by someone (sorry, I forgot
68+ your name, and the mail's gone!)
69
70 Wed Sep 8 09:07:38 1999
71
72diff -urN nfs-server-2.2beta47/Makefile.in nfs-server-2.2beta51/Makefile.in
73--- nfs-server-2.2beta47/Makefile.in Tue Jun 22 14:53:10 1999
74+++ nfs-server-2.2beta51/Makefile.in Fri Nov 8 14:45:36 2002
75@@ -17,23 +17,30 @@
76
77 #### Start of system configuration section. ####
78
79-srcdir = @srcdir@
80-VPATH = @srcdir@
81+srcdir = @srcdir@
82+VPATH = @srcdir@
83
84-CC = @CC@
85-AR = ar
86-RANLIB = @RANLIB@
87-
88-INSTALL = @INSTALL@
89-INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755
90-INSTALL_DATA = @INSTALL_DATA@
91-MAKEINFO = makeinfo
92-TEXI2DVI = texi2dvi
93-RPCGEN = @RPCGEN@ @RPCGEN_C@
94+CC = @CC@
95+AR = ar
96+RANLIB = @RANLIB@
97+
98+INSTALL = @INSTALL@
99+INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755
100+INSTALL_DATA = @INSTALL_DATA@
101+MAKEINFO = makeinfo
102+TEXI2DVI = texi2dvi
103+RPCGEN = @RPCGEN@ @RPCGEN_C@
104
105 # General compile options and libs:
106-DEFS = @DEFS@ $(NFSD_DEFS)
107-LIBS = libnfs.a @LIBS@
108+DEFS = @DEFS@ $(NFSD_DEFS)
109+LIBS = libnfs.a @LIBS@
110+
111+# Ugidd support
112+UGIDD_PROG = @UGIDD_PROG@
113+UGIDD_MAN = @UGIDD_MAN@
114+
115+# New inode mapping scheme
116+DEVTAB_FILE = $(install_prefix)@PATH_DEVTAB@
117
118 # Compile options for nfsd:
119 # CALL_PROFILING
120@@ -80,9 +87,6 @@
121
122 #### End of system configuration section. ####
123
124-# include site-specific defintions generated by BUILD.
125-include site.mk
126-
127 SHELL = /bin/sh
128
129 SRCS = version.c logging.c fh.c devtab.c \
130@@ -96,19 +100,19 @@
131 utimes.c mkdir.c rename.c getopt.c getopt_long.c \
132 alloca.c mountlist.c xmalloc.c \
133 xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \
134- haccess.c failsafe.c signals.c
135+ haccess.c daemon.c signals.c
136 XDRFILES = mount.x nfs_prot.x
137 GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \
138 ugid.h ugid_xdr.c ugid_clnt.c
139 HDRS = system.h nfsd.h auth.h fh.h logging.h fakefsuid.h \
140 rpcmisc.h faccess.h rquotad.h rquota.h haccess.h
141-LIBHDRS = fsusage.h getopt.h mountlist.h failsafe.h signals.h
142+LIBHDRS = fsusage.h getopt.h mountlist.h daemon.h signals.h
143 MANPAGES5 = exports
144 MANPAGES8p = mountd nfsd $(UGIDD_MAN)
145 MANPAGES8 = showmount
146 MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8)
147 LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \
148- nfsmounted.o faccess.o haccess.o failsafe.o \
149+ nfsmounted.o faccess.o haccess.o daemon.o \
150 signals.o @LIBOBJS@ @ALLOCA@
151 OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o
152 NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \
153@@ -174,15 +178,13 @@
154 ${srcdir}/mkinstalldirs $(bindir) $(man5dir) $(man8dir)
155
156 $(rpcprefix)mountd: $(MOUNTD_OBJS) libnfs.a
157- $(CC) $(LDFLAGS) -o $@ $(MOUNTD_OBJS) $(LIBS) \
158- $(LIBWRAP_DIR) $(LIBWRAP_LIB)
159+ $(CC) $(LDFLAGS) -o $@ $(MOUNTD_OBJS) $(LIBS)
160
161 $(rpcprefix)nfsd: $(NFSD_OBJS) libnfs.a
162 $(CC) $(LDFLAGS) -o $@ $(NFSD_OBJS) $(LIBS)
163
164 $(rpcprefix)ugidd: $(UGIDD_OBJS) libnfs.a
165- $(CC) $(LDFLAGS) -o $@ $(UGIDD_OBJS) $(LIBS) \
166- $(LIBWRAP_DIR) $(LIBWRAP_LIB)
167+ $(CC) $(LDFLAGS) -o $@ $(UGIDD_OBJS) $(LIBS)
168
169 showmount: $(SHOWMOUNT_OBJS) libnfs.a
170 $(CC) $(LDFLAGS) -o $@ $(SHOWMOUNT_OBJS) $(LIBS)
171diff -urN nfs-server-2.2beta47/aclocal.m4 nfs-server-2.2beta51/aclocal.m4
172--- nfs-server-2.2beta47/aclocal.m4 Fri Jun 11 12:04:22 1999
173+++ nfs-server-2.2beta51/aclocal.m4 Fri Nov 8 14:45:36 2002
174@@ -221,20 +221,14 @@
175 ])dnl
176 dnl *********** libwrap bug **************
177 define(AC_LIBWRAP_BUG,
178- [if test -f site.mk; then
179- . ./site.mk
180- fi
181- if test ! -z "$LIBWRAP_DIR"; then
182+ [if test "$ac_cv_lib_wrap_main" = yes; then
183 AC_MSG_CHECKING(for link problem with libwrap.a)
184 AC_CACHE_VAL(nfsd_cv_lib_wrap_bug,
185- [ac_save_LIBS=$LIBS
186- LIBS="$LIBS $LIBWRAP_DIR $LIBWRAP_LIB"
187- AC_TRY_LINK([
188+ [AC_TRY_LINK([
189 extern int deny_severity;
190 ],[
191 deny_severity=1;
192 ], nfsd_cv_lib_wrap_bug=no, nfsd_cv_lib_wrap_bug=yes)
193- LIBS=$ac_save_LIBS
194 ]) dnl
195 AC_MSG_RESULT($nfsd_cv_lib_wrap_bug)
196 test $nfsd_cv_lib_wrap_bug = yes && AC_DEFINE(HAVE_LIBWRAP_BUG)
197diff -urN nfs-server-2.2beta47/auth.c nfs-server-2.2beta51/auth.c
198--- nfs-server-2.2beta47/auth.c Mon Sep 13 16:56:03 1999
199+++ nfs-server-2.2beta51/auth.c Fri Nov 8 14:45:36 2002
200@@ -84,8 +84,9 @@
201 0, /* relative links */
202 0, /* noaccess */
203 1, /* cross_mounts */
204- (uid_t)-2, /* default uid */
205- (gid_t)-2, /* default gid */
206+ 1, /* allow setuid */
207+ 65534, /* default uid */
208+ 65534, /* default gid */
209 0, /* no NIS domain */
210 };
211
212@@ -99,8 +100,9 @@
213 0, /* relative links */
214 0, /* noaccess */
215 1, /* cross_mounts */
216- (uid_t)-2, /* default uid */
217- (gid_t)-2, /* default gid */
218+ 0, /* allow setuid */
219+ 65534, /* default uid */
220+ 65534, /* default gid */
221 0, /* no NIS domain */
222 };
223
224@@ -673,6 +675,7 @@
225 cpp = &unknown_clients;
226 } else {
227 cpp = &known_clients;
228+ cp->clnt_addr = *(struct in_addr *) hp->h_addr;
229 auth_hash_host(cp, hp);
230 }
231 cp->next = *cpp;
232diff -urN nfs-server-2.2beta47/auth.h nfs-server-2.2beta51/auth.h
233--- nfs-server-2.2beta47/auth.h Thu Apr 8 14:47:56 1999
234+++ nfs-server-2.2beta51/auth.h Fri Nov 8 14:45:36 2002
235@@ -23,14 +23,6 @@
236 extern char * public_root_path;
237 extern struct nfs_fh public_root;
238
239-#if defined(linux) && defined(i386) && !defined(HAVE_SETFSUID)
240-# define MAYBE_HAVE_SETFSUID
241-#endif
242-
243-#ifdef MAYBE_HAVE_SETFSUID
244-extern int have_setfsuid;
245-#endif
246-
247 /*
248 * These externs are set in the dispatcher (dispatch.c) and auth_fh
249 * (nfsd.c) so that we can determine access rights, export options,
250@@ -59,6 +51,7 @@
251 int link_relative;
252 int noaccess;
253 int cross_mounts;
254+ int allow_setuid;
255 uid_t nobody_uid;
256 gid_t nobody_gid;
257 char * clnt_nisdomain;
258@@ -112,7 +105,7 @@
259 extern void auth_free_lists(void);
260 extern nfs_client *auth_clnt(struct svc_req *rqstp);
261 extern nfs_mount *auth_path(nfs_client *, struct svc_req *, char *);
262-extern void auth_user(nfs_mount *, struct svc_req *);
263+extern int auth_user(nfs_mount *, struct svc_req *);
264
265 extern nfs_client *auth_get_client(char *);
266 extern nfs_mount *auth_match_mount(nfs_client *, char *);
267diff -urN nfs-server-2.2beta47/auth_clnt.c nfs-server-2.2beta51/auth_clnt.c
268--- nfs-server-2.2beta47/auth_clnt.c Wed Nov 10 10:18:06 1999
269+++ nfs-server-2.2beta51/auth_clnt.c Fri Nov 8 14:45:36 2002
270@@ -12,20 +12,17 @@
271 */
272
273
274+#include <sys/fsuid.h>
275 #include "system.h"
276 #include "nfsd.h"
277-#include "fakefsuid.h"
278-
279-#ifndef svc_getcaller
280-#define svc_getcaller(x) ((struct sockaddr_in *) &(x)->xp_rtaddr.buf)
281-#endif
282+#include "rpcmisc.h"
283
284
285-#if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID)
286-static void setfsids(uid_t, gid_t, gid_t *, int);
287+#if defined(HAVE_SETFSUID)
288+static int setfsids(uid_t, gid_t, gid_t *, int);
289 #endif
290 #ifndef HAVE_SETFSUID
291-static void seteids(uid_t, gid_t, gid_t *, int);
292+static int seteids(uid_t, gid_t, gid_t *, int);
293 #endif
294
295 uid_t auth_uid = 0; /* Current effective user ids */
296@@ -43,6 +40,17 @@
297 short *gid, short *nrgids, int *groups);
298 #endif
299
300+/*
301+ * The following crap is required for glibc 2.1 which has 32bit uids
302+ * in user land mapped to 16bit uids in the Linux kernel
303+ */
304+#if defined(HAVE_BROKEN_SETFSUID)
305+# define native_uid(u) ((unsigned short)(u))
306+# define native_gid(g) ((unsigned short)(g))
307+#else
308+# define native_uid(u) (u)
309+# define native_gid(g) (g)
310+#endif
311
312 /*
313 * For an RPC request, look up the NFS client info along with the
314@@ -92,8 +100,9 @@
315 }
316
317 if (logging_enabled(D_AUTH)) {
318- Dprintf(D_AUTH, "auth_path(%s): mount point %s, (%s%s%s%s%s)\n",
319- path, mp->path,
320+ Dprintf(D_AUTH, "auth_path(%s, %s): "
321+ "mount point %s, (%s%s%s%s%s)\n",
322+ inet_ntoa(cp->clnt_addr), path, mp->path,
323 mp->o.all_squash? "all_squash " : (
324 mp->o.root_squash? "root_squash " : ""),
325 (mp->o.uidmap == map_daemon)? "uidmap " : "",
326@@ -105,7 +114,8 @@
327 return mp;
328 }
329
330-void auth_user(nfs_mount *mp, struct svc_req *rqstp)
331+int
332+auth_user(nfs_mount *mp, struct svc_req *rqstp)
333 {
334 uid_t cuid;
335 gid_t cgid;
336@@ -160,23 +170,18 @@
337 else if (cred_len > NGRPS)
338 cred_len = NGRPS;
339
340- cuid = luid(cred_uid, mp, rqstp);
341- cgid = lgid(cred_gid, mp, rqstp);
342+ cuid = luid(native_uid(cred_uid), mp, rqstp);
343+ cgid = lgid(native_gid(cred_gid), mp, rqstp);
344 clen = cred_len;
345 for (i = 0; i < cred_len; i++)
346- cgids[i] = lgid(cred_gids[i], mp, rqstp);
347+ cgids[i] = lgid(native_gid(cred_gids[i]), mp, rqstp);
348 } else {
349 /* On systems that have 32bit uid_t in user space but
350 * 16bit in the kernel, we need to truncate the
351 * nobody ID (default -2).
352 */
353-#if !defined(HAVE_BROKEN_SETFSUID)
354- cuid = mp->o.nobody_uid;
355- cgid = mp->o.nobody_gid;
356-#else
357- cuid = (unsigned short) mp->o.nobody_uid;
358- cgid = (unsigned short) mp->o.nobody_gid;
359-#endif
360+ cuid = native_uid(mp->o.nobody_uid);
361+ cgid = native_gid(mp->o.nobody_gid);
362 /* Construct a list of one gid. */
363 cgids[0] = cgid;
364 clen = 1;
365@@ -193,14 +198,9 @@
366 * upper 16 bits set (including our default nobody uid -2).
367 */
368 #if defined(HAVE_SETFSUID)
369- setfsids(cuid, cgid, cgids, clen);
370+ return setfsids(cuid, cgid, cgids, clen);
371 #else
372-#if defined(MAYBE_HAVE_SETFSUID)
373- if (have_setfsuid)
374- setfsids(cuid, cgid, cgids, clen);
375- else
376-#endif
377- seteids(cuid, cgid, cgids, clen);
378+ return seteids(cuid, cgid, cgids, clen);
379 #endif
380 }
381
382@@ -210,6 +210,8 @@
383 void
384 auth_override_uid(uid_t uid)
385 {
386+ int res;
387+
388 /* extension hooks: */
389 efs_setfsuid(uid);
390
391@@ -217,19 +219,18 @@
392 uid = (unsigned short) uid;
393 #endif
394 #if defined(HAVE_SETFSUID)
395- setfsuid(uid);
396+ res = setfsuid(uid);
397 #else
398-#if defined(MAYBE_HAVE_SETFSUID)
399- if (have_setfsuid)
400- setfsuid(uid);
401- else
402-#endif
403- seteuid(uid);
404+ res = seteuid(uid);
405 #endif
406+ /* should never happen */
407+ if (res < 0)
408+ Dprintf(L_FATAL, "auth_override_uid(%d) failed: %s",
409+ uid, strerror(errno));
410 }
411
412-#if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID)
413-static void
414+#if defined(HAVE_SETFSUID)
415+static int
416 setfsids(uid_t cred_uid, gid_t cred_gid, gid_t *cred_gids, int cred_len)
417 {
418 /* extension hooks: */
419@@ -238,43 +239,47 @@
420
421 /* First, set the user ID. */
422 if (auth_uid != cred_uid) {
423- if (setfsuid(cred_uid) < 0)
424+ if (setfsuid(cred_uid) < 0) {
425 Dprintf(L_ERROR, "Unable to setfsuid %d: %s\n",
426 cred_uid, strerror(errno));
427- else
428- auth_uid = cred_uid;
429+ return 0;
430+ }
431+ auth_uid = cred_uid;
432 }
433
434 /* Next, the group ID. */
435 if (auth_gid != cred_gid) {
436- if (setfsgid(cred_gid) < 0)
437+ if (setfsgid(cred_gid) < 0) {
438 Dprintf(L_ERROR, "Unable to setfsgid %d: %s\n",
439 cred_gid, strerror(errno));
440- else
441- auth_gid = cred_gid;
442+ return 0;
443+ }
444+ auth_gid = cred_gid;
445 }
446
447 #ifdef HAVE_SETGROUPS
448 /* Finally, set the supplementary group IDs if possible. */
449- if (cred_len < 0 || cred_len > NGRPS)
450+ if (cred_len < 0 || cred_len > NGRPS) {
451 Dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len);
452- else if (cred_len != auth_gidlen
453- || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
454- if (setgroups(cred_len, cred_gids) < 0)
455+ return 0;
456+ }
457+ if (cred_len != auth_gidlen
458+ || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
459+ if (setgroups(cred_len, cred_gids) < 0) {
460 Dprintf(L_ERROR, "Unable to setgroups: %s\n",
461 strerror(errno));
462- else {
463- memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
464- auth_gidlen = cred_len;
465+ return 0;
466 }
467+ memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
468+ auth_gidlen = cred_len;
469 }
470 #endif /* HAVE_SETGROUPS */
471-
472+ return 1;
473 }
474 #endif
475
476 #if !defined(HAVE_SETFSUID)
477-static void
478+static int
479 seteids(uid_t cred_uid, gid_t cred_gid, gid_t *cred_gids, int cred_len)
480 {
481 /* extension hooks: */
482@@ -286,52 +291,62 @@
483 /* First set the group ID. */
484 if (auth_gid != cred_gid) {
485 if (auth_uid != ROOT_UID) {
486- if (seteuid(ROOT_UID) < 0)
487+ if (seteuid(ROOT_UID) < 0) {
488 Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
489 ROOT_UID, strerror(errno));
490- else
491- auth_uid = ROOT_UID;
492+ return 0;
493+ }
494+ auth_uid = ROOT_UID;
495 }
496- if (setegid(cred_gid) < 0)
497+ if (setegid(cred_gid) < 0) {
498 Dprintf(L_ERROR, "Unable to setegid(%d): %s\n",
499 cred_gid, strerror(errno));
500- else
501- auth_gid = cred_gid;
502+ return 0;
503+ }
504+ auth_gid = cred_gid;
505 }
506
507 #ifdef HAVE_SETGROUPS
508 /* Next set the supplementary group IDs if possible. */
509- if (cred_len < 0 || cred_len > NGRPS)
510+ if (cred_len < 0 || cred_len > NGRPS) {
511 Dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len);
512- else if (cred_len != auth_gidlen
513- || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
514+ return 0;
515+ }
516+ if (cred_len != auth_gidlen
517+ || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
518 if (auth_uid != ROOT_UID) {
519- if (seteuid(ROOT_UID) < 0)
520+ if (seteuid(ROOT_UID) < 0) {
521 Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
522 ROOT_UID, strerror(errno));
523- else
524- auth_uid = ROOT_UID;
525+ return 0;
526+ }
527+ auth_uid = ROOT_UID;
528 }
529- if (setgroups(cred_len, cred_gids) < 0)
530+ if (setgroups(cred_len, cred_gids) < 0) {
531 Dprintf(L_ERROR, "Unable to setgroups: %s\n",
532 strerror(errno));
533- else {
534- memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
535- auth_gidlen = cred_len;
536+ return 0;
537 }
538+ memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
539+ auth_gidlen = cred_len;
540 }
541 #endif /* HAVE_SETGROUPS */
542
543 /* Finally, set the user ID. */
544 if (auth_uid != cred_uid) {
545- if (auth_uid != ROOT_UID && seteuid(ROOT_UID) < 0)
546+ if (auth_uid != ROOT_UID && seteuid(ROOT_UID) < 0) {
547 Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
548 ROOT_UID, strerror(errno));
549- if (seteuid(cred_uid) < 0)
550+ return 0;
551+ }
552+ if (seteuid(cred_uid) < 0) {
553 Dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
554 cred_uid, strerror(errno));
555- else
556- auth_uid = cred_uid;
557+ return 0;
558+ }
559+ auth_uid = cred_uid;
560 }
561+
562+ return 1;
563 }
564 #endif
565diff -urN nfs-server-2.2beta47/auth_init.c nfs-server-2.2beta51/auth_init.c
566--- nfs-server-2.2beta47/auth_init.c Mon Apr 19 14:01:21 1999
567+++ nfs-server-2.2beta51/auth_init.c Fri Nov 8 14:45:36 2002
568@@ -13,7 +13,6 @@
569 */
570
571 #include "nfsd.h"
572-#include "fakefsuid.h"
573 #include <pwd.h>
574
575 #define LINE_SIZE 1024
576@@ -263,55 +262,63 @@
577 cp++;
578 while (*cp != terminator) {
579 kwd = cp;
580- while (isalpha(*cp) || *cp == '_' || *cp == '=') {
581- /* break out of loop after = sign */
582- if (*cp++ == '=')
583- break;
584- }
585+ /* Gobble up keyword and "=" if there is one */
586+ while (isalpha(*cp) || *cp == '_')
587+ ++cp;
588+ if (*cp == '=')
589+ ++cp;
590+
591 klen = cp - kwd;
592
593 /* process keyword */
594- if (strncmp(kwd, "secure", 6) == 0)
595+#define ifkwd(n, string) \
596+ if (klen == (n) && !strncmp(kwd, string, (n)))
597+
598+ ifkwd(2, "ro")
599+ mp->o.read_only = 1;
600+ else ifkwd(2, "rw")
601+ mp->o.read_only = 0;
602+ else ifkwd(6, "secure")
603 mp->o.secure_port = 1;
604- else if (strncmp(kwd, "insecure", 8) == 0)
605+ else ifkwd(8, "insecure")
606 mp->o.secure_port = 0;
607- else if (strncmp(kwd, "root_squash", 11) == 0)
608+ else ifkwd(11, "root_squash")
609 mp->o.root_squash = 1;
610- else if (strncmp(kwd, "no_root_squash", 14) == 0)
611+ else ifkwd(14, "no_root_squash")
612 mp->o.root_squash = 0;
613- else if (strncmp(kwd, "ro", 2) == 0)
614- mp->o.read_only = 1;
615- else if (strncmp(kwd, "rw", 2) == 0)
616- mp->o.read_only = 0;
617- else if (strncmp(kwd, "link_relative", 13) == 0)
618+ else ifkwd(13, "link_relative")
619 mp->o.link_relative = 1;
620- else if (strncmp(kwd, "link_absolute", 13) == 0)
621+ else ifkwd(13, "link_absolute")
622 mp->o.link_relative = 0;
623- else if (strncmp(kwd, "map_daemon", 10) == 0)
624+ else ifkwd(10, "map_daemon")
625 mp->o.uidmap = map_daemon;
626- else if (strncmp(kwd, "map_nis=", 8) == 0)
627+ else ifkwd(8, "map_nis=")
628 parse_nis_uidmap(mp, &cp);
629- else if (strncmp(kwd, "map_static=", 11) == 0)
630+ else ifkwd(11, "map_static=")
631 parse_static_uidmap(mp, &cp);
632- else if (strncmp(kwd, "map_identity", 12) == 0)
633+ else ifkwd(12, "map_identity")
634 mp->o.uidmap = identity;
635- else if (strncmp(kwd, "all_squash", 10) == 0)
636+ else ifkwd(10, "all_squash")
637 mp->o.all_squash = 1;
638- else if (strncmp(kwd, "no_all_squash", 13) == 0)
639+ else ifkwd(13, "no_all_squash")
640 mp->o.all_squash = 0;
641- else if (strncmp(kwd, "noaccess", 8) == 0)
642+ else ifkwd(8, "noaccess")
643 mp->o.noaccess = 1;
644- else if (strncmp(kwd, "squash_uids=", 12) == 0)
645+ else ifkwd(12, "squash_uids=")
646 parse_squash(mp, 1, &cp);
647- else if (strncmp(kwd, "squash_gids=", 12) == 0)
648+ else ifkwd(12, "squash_gids=")
649 parse_squash(mp, 0, &cp);
650- else if (strncmp(kwd, "anonuid=", 8) == 0)
651+ else ifkwd(8, "anonuid=")
652 mp->o.nobody_uid = parse_num(&cp);
653- else if (strncmp(kwd, "anongid=", 8) == 0)
654+ else ifkwd(8, "anongid=")
655 mp->o.nobody_gid = parse_num(&cp);
656- else if (strncmp(kwd, "async", 5) == 0)
657+ else ifkwd(6, "setuid")
658+ mp->o.allow_setuid = 1;
659+ else ifkwd(8, "nosetuid")
660+ mp->o.allow_setuid = 0;
661+ else ifkwd(5, "async")
662 /* knfsd compatibility, ignore */;
663- else if (strncmp(kwd, "sync", 4) == 0)
664+ else ifkwd(4, "sync")
665 /* knfsd compatibility, ignore */;
666 else {
667 Dprintf(L_ERROR,
668@@ -566,11 +573,6 @@
669 auth_check_all_wildcards();
670 auth_sort_all_mountlists();
671 auth_log_all();
672-
673-#if defined(MAYBE_HAVE_SETFSUID) && !defined(HAVE_SETFSUID)
674- /* check if the a.out setfsuid syscall works on this machine */
675- have_setfsuid = (setfsuid(0) >= 0);
676-#endif
677
678 auth_initialized = 1;
679 }
680diff -urN nfs-server-2.2beta47/config.h.in nfs-server-2.2beta51/config.h.in
681--- nfs-server-2.2beta47/config.h.in Fri Jun 11 12:01:22 1999
682+++ nfs-server-2.2beta51/config.h.in Fri Nov 8 14:45:36 2002
683@@ -3,7 +3,7 @@
684 /* Define if on AIX 3.
685 System headers sometimes define this.
686 We just want to avoid a redefinition error message. */
687-#ifndef _ALL_SOURCE
688+#ifdef _ALL_SOURCE
689 #undef _ALL_SOURCE
690 #endif
691
692diff -urN nfs-server-2.2beta47/configure.in nfs-server-2.2beta51/configure.in
693--- nfs-server-2.2beta47/configure.in Fri Jun 11 11:58:10 1999
694+++ nfs-server-2.2beta51/configure.in Fri Nov 8 14:45:36 2002
695@@ -2,7 +2,36 @@
696 dnl Updated for autoconf 2.
697 dnl
698 AC_INIT(nfsd.c)
699-AC_CONFIG_HEADER(config.h)
700+AC_CONFIG_HEADER(config.h site.h)
701+
702+dnl **************************************************************
703+dnl * handle --enable options
704+dnl **************************************************************
705+AC_ARG_ENABLE(new-inodes,
706+ [ --enable-new-inodes Enable new-style inode inodes])
707+AC_ARG_WITH(devtab,
708+ [ --with-devtab=file Specify location for devtab [/var/lib/nfs/devtab]],
709+ PATH_DEVTAB=$withval,
710+ PATH_DEVTAB=/var/lib/nfs/devtab)
711+AC_ARG_ENABLE(ugid-dynamic,
712+ [ --enable-ugid-dynamic Enable uid mapping using rpc.ugidd (not recommended)])
713+AC_ARG_ENABLE(ugid-nis,
714+ [ --enable-ugid-nis Enable NIS-based uid mapping])
715+AC_ARG_ENABLE(host-access,
716+ [ --enable-host-access Enable host access checking])
717+AC_ARG_ENABLE(mount-logging,
718+ [ --disable-mount-logging Do not log mount operations to syslog],,
719+ enable_mount_logging=yes)
720+AC_ARG_WITH(exports-uid,
721+ [ --with-exports-uid=N Make sure that /etc/exports is owned by uid N],,
722+ with_exports_uid=0)
723+AC_ARG_WITH(exports-gid,
724+ [ --with-exports-gid=N Make sure that /etc/exports is owned by gid N],,
725+ with_exports_gid=0)
726+
727+dnl **************************************************************
728+dnl * Check for all kinds of stuff
729+dnl **************************************************************
730 AC_PROG_CC
731 # If we're using gcc, we want warning flags
732 test -n "$GCC" &&
733@@ -19,7 +48,7 @@
734 AC_MINIX
735 AC_ISC_POSIX
736 AC_PROG_INSTALL
737-AC_CROSS_CHECK
738+dnl AC_CROSS_CHECK
739 AC_STDC_HEADERS
740 AC_GNULIBC
741 AC_CONST
742@@ -52,14 +81,45 @@
743 AC_CHECK_LIB(rpc, main)
744 AC_CHECK_LIB(crypt, main)
745 AC_CHECK_LIB(nys, main)
746-AC_REPLACE_FUNCS(strerror realpath mkdir rename utimes strdup strstr getopt getopt_long)
747 AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred)
748 AC_AUTHDES_GETUCRED
749 AC_BROKEN_SETFSUID
750 AC_MOUNTLIST
751 AC_FSUSAGE
752+AC_CHECK_LIB(wrap, main)
753 AC_LIBWRAP_BUG
754 AC_BSD_SIGNALS
755+
756+dnl **************************************************************
757+dnl * Munge user specified options
758+dnl **************************************************************
759+if test "$enable_new_inodes" = yes; then
760+ AC_DEFINE(ENABLE_DEVTAB)
761+fi
762+if test "$enable_ugid_dynamic" = yes; then
763+ AC_DEFINE(ENABLE_UGID_DAEMON)
764+ UGIDD_PROG=\${rpcprefix}.ugidd
765+ UGIDD_MAN=ugidd
766+fi
767+if test "$enable_ugid_nis" = yes; then
768+ AC_DEFINE(ENABLE_UGID_NIS)
769+fi
770+if test "$enable_host_access" = yes; then
771+ AC_DEFINE(HOSTS_ACCESS)
772+fi
773+if test "$enable_mount_logging" = yes; then
774+ AC_DEFINE(WANT_LOG_MOUNTS)
775+fi
776+AC_DEFINE_UNQUOTED(EXPORTSOWNERUID, $with_exports_uid)
777+AC_DEFINE_UNQUOTED(EXPORTSOWNERGID, $with_exports_gid)
778+AC_SUBST(PATH_DEVTAB)
779+AC_SUBST(UGIDD_PROG)
780+AC_SUBST(UGIDD_MAN)
781+
782+dnl **************************************************************
783+dnl * Output CFLAGS and LDFLAGS
784+dnl **************************************************************
785 AC_SUBST(LDFLAGS)
786 AC_SUBST(CFLAGS)
787+
788 AC_OUTPUT(Makefile)
789diff -urN nfs-server-2.2beta47/daemon.c nfs-server-2.2beta51/daemon.c
790--- nfs-server-2.2beta47/daemon.c Thu Jan 1 01:00:00 1970
791+++ nfs-server-2.2beta51/daemon.c Fri Nov 8 14:45:52 2002
792@@ -0,0 +1,270 @@
793+/*
794+ * daemon.c
795+ *
796+ * Copyright (C) 1998, <okir@monad.swb.de>
797+ *
798+ * Implements common daemon stuff and
799+ * fail-safe mode for nfsd/mountd.
800+ */
801+
802+#include "system.h"
803+#include "logging.h"
804+#include "signals.h"
805+#include <sys/wait.h>
806+
807+static const char * pidfilename = 0;
808+static const char * get_signame(int signo);
809+
810+/*
811+ * Do the Crawley Thing
812+ */
813+void
814+daemonize(void)
815+{
816+ int c;
817+
818+ /* Ignore SIGHUP so the parent can exit while we're still
819+ * in limbo */
820+ ignore_signal(SIGHUP);
821+
822+ /* Now fork */
823+ c = fork();
824+ if (c < 0)
825+ Dprintf(L_FATAL, "unable to fork: %s", strerror(errno));
826+
827+ /* Parent process: exit */
828+ if (c > 0)
829+ exit(0);
830+
831+ /* Do the session stuff */
832+ close(0);
833+ close(1);
834+ close(2);
835+#ifdef HAVE_SETSID
836+ setsid();
837+#else
838+ if ((c = open("/dev/tty", O_RDWR)) >= 0) {
839+ ioctl(c, TIOCNOTTY, (char *) NULL);
840+ close(c);
841+ }
842+#endif
843+
844+ /* Stop stderr logging */
845+ background_logging();
846+}
847+
848+void
849+setpidpath(const char *filename)
850+{
851+ pidfilename = filename;
852+}
853+
854+void
855+writepid(pid_t pid, int clear)
856+{
857+ FILE *fp;
858+
859+ fp = fopen(pidfilename, clear? "w" : "a");
860+ if (fp == NULL)
861+ Dprintf(L_FATAL, "Unable to open %s: %m", pidfilename);
862+ fprintf(fp, "%d\n", pid);
863+ fclose(fp);
864+ return;
865+}
866+
867+void
868+failsafe(int level, int ncopies)
869+{
870+ int *servers, running, child, i;
871+ int pid, signo, status;
872+ time_t last_restart = 0, now;
873+ int restarts = 0, backoff = 60;
874+
875+ servers = (int *) xmalloc(ncopies * sizeof(int));
876+ memset(servers, 0, ncopies * sizeof(int));
877+
878+ /* Loop forever, until we get SIGTERM */
879+ running = 0;
880+ while (1) {
881+ /* Rewrite the pidfile */
882+ writepid(getpid(), 1);
883+ for (i = 0; i < ncopies; i++) {
884+ if (servers[i] != 0)
885+ writepid(servers[i], 0);
886+ }
887+
888+ while (running < ncopies) {
889+ if ((now = time(NULL)) == last_restart) {
890+ if (++restarts > 2 * ncopies) {
891+ Dprintf(L_ERROR,
892+ "Servers restarting too "
893+ "quickly, backing off.");
894+ if (backoff < 60 * 60)
895+ backoff <<= 1;
896+ sleep(backoff);
897+ }
898+ } else {
899+ last_restart = now;
900+ restarts = 0;
901+ backoff = 60;
902+ }
903+
904+ /* Locate a free pid slot */
905+ for (i = 0, child = -1; i < ncopies; i++) {
906+ if (servers[i] == 0) {
907+ child = i;
908+ break;
909+ }
910+ }
911+
912+ if (child < 0)
913+ Dprintf(L_FATAL, "failsafe: no pid slot?!");
914+
915+ Dprintf(D_GENERAL,
916+ "starting server thread %d...\n", child + 1);
917+
918+ pid = fork();
919+ if (pid < 0)
920+ Dprintf(L_FATAL,
921+ "Unable to fork for failsafe: %s",
922+ strerror(errno));
923+
924+ if (pid == 0) {
925+ /* Child process: continue with execution. */
926+ return;
927+ }
928+
929+ writepid(pid, 0);
930+ servers[child] = pid;
931+ running++;
932+ }
933+
934+ /* Ignore some signals */
935+ ignore_signal(SIGTERM);
936+ ignore_signal(SIGHUP);
937+ ignore_signal(SIGINT);
938+ ignore_signal(SIGCHLD);
939+
940+ if ((pid = wait(&status)) < 0) {
941+ Dprintf((errno == ECHILD)? L_FATAL : L_WARNING,
942+ "failsafe: wait(): %s", strerror(errno));
943+ continue;
944+ }
945+
946+ /* Locate the child */
947+ for (i = 0, child = -1; i < ncopies; i++) {
948+ if (servers[i] == pid) {
949+ child = i;
950+ break;
951+ }
952+ }
953+
954+ if (child < 0) {
955+ Dprintf(L_WARNING,
956+ "failsafe: unknown child (pid %d) terminated",
957+ pid);
958+ continue;
959+ }
960+
961+ /* Book-keeping */
962+ servers[child] = 0;
963+ running--;
964+
965+ if (WIFSIGNALED(status)) {
966+ signo = WTERMSIG(status);
967+ if (signo == SIGTERM) {
968+ Dprintf(L_NOTICE, "failsafe: "
969+ "child %d terminated by SIGTERM. %s.",
970+ pid, running? "Continue" : "Exit");
971+ } else {
972+ Dprintf(L_WARNING, "failsafe: "
973+ "child %d terminated by %s. "
974+ "Restarting.",
975+ pid, get_signame(signo));
976+ child = -1; /* Restart */
977+ }
978+ } else if (WIFEXITED(status)) {
979+ Dprintf(L_NOTICE, "failsafe: "
980+ "child %d exited, status %d.",
981+ pid, WEXITSTATUS(status));
982+ } else {
983+ Dprintf(L_ERROR, "failsafe: "
984+ "abnormal child termination, "
985+ "pid=%d status=%d. Restarting.",
986+ pid, status);
987+ child = -1; /* Restart */
988+ }
989+
990+ /* If child >= 0, we should not restart */
991+ if (child >= 0) {
992+ if (!running) {
993+ Dprintf(D_GENERAL,
994+ "No more children, exiting.");
995+ exit(0);
996+ }
997+ for (i = child; i < ncopies-1; i++)
998+ servers[i] = servers[i+1];
999+ ncopies--; /* Make sure we start no new servers */
1000+ }
1001+ }
1002+}
1003+
1004+/*
1005+ * Failsafe session, catch core file.
1006+ *
1007+ * Not yet implemented.
1008+ * General outline: we need to fork first, because nfsd changes
1009+ * uids frequently, and the kernel won't write out a core file after
1010+ * that. The forked proc starts out with a clean dumpable flag though.
1011+ *
1012+ * After the fork, we might want to make sure we end up in some common
1013+ * directory that the failsafe loop knows about.
1014+ */
1015+void
1016+failsafe_loop(int level, void (*function)(void))
1017+{
1018+ /* NOP */
1019+}
1020+
1021+static const char *
1022+get_signame(int signo)
1023+{
1024+ static char namebuf[30];
1025+
1026+ switch (signo) {
1027+ case SIGHUP: return "SIGHUP";
1028+ case SIGINT: return "SIGINT";
1029+ case SIGQUIT: return "SIGQUIT";
1030+ case SIGILL: return "SIGILL";
1031+ case SIGTRAP: return "SIGTRAP";
1032+ case SIGIOT: return "SIGIOT";
1033+ case SIGBUS: return "SIGBUS";
1034+ case SIGFPE: return "SIGFPE";
1035+ case SIGKILL: return "SIGKILL";
1036+ case SIGUSR1: return "SIGUSR1";
1037+ case SIGSEGV: return "SIGSEGV";
1038+ case SIGUSR2: return "SIGUSR2";
1039+ case SIGPIPE: return "SIGPIPE";
1040+ case SIGALRM: return "SIGALRM";
1041+ case SIGTERM: return "SIGTERM";
1042+ case SIGCHLD: return "SIGCHLD";
1043+ case SIGCONT: return "SIGCONT";
1044+ case SIGSTOP: return "SIGSTOP";
1045+ case SIGTSTP: return "SIGTSTP";
1046+ case SIGTTIN: return "SIGTTIN";
1047+ case SIGTTOU: return "SIGTTOU";
1048+ case SIGURG: return "SIGURG";
1049+ case SIGXCPU: return "SIGXCPU";
1050+ case SIGXFSZ: return "SIGXFSZ";
1051+ case SIGVTALRM: return "SIGVTALRM";
1052+ case SIGPROF: return "SIGPROF";
1053+ case SIGWINCH: return "SIGWINCH";
1054+ case SIGIO: return "SIGIO";
1055+#ifdef SIGPWR
1056+ case SIGPWR: return "SIGPWR";
1057+#endif
1058+ }
1059+
1060+ sprintf(namebuf, "signal #%d", signo);
1061+ return namebuf;
1062+}
1063diff -urN nfs-server-2.2beta47/daemon.h nfs-server-2.2beta51/daemon.h
1064--- nfs-server-2.2beta47/daemon.h Thu Jan 1 01:00:00 1970
1065+++ nfs-server-2.2beta51/daemon.h Fri Nov 8 14:45:52 2002
1066@@ -0,0 +1,18 @@
1067+/*
1068+ * daemon.h
1069+ *
1070+ * Daemon support
1071+ */
1072+
1073+#ifndef CRAWLEY_H
1074+#define CRAWLEY_H
1075+
1076+#define _PATH_NFSD_PIDFILE "/var/run/nfsd.pid"
1077+#define _PATH_MOUNTD_PIDFILE "/var/run/mountd.pid"
1078+
1079+extern void daemonize(void);
1080+extern void setpidpath(const char *);
1081+extern void writepid(pid_t, int);
1082+extern void failsafe(int level, int ncopies);
1083+
1084+#endif /* CRAWLEY_H */
1085diff -urN nfs-server-2.2beta47/exports.man nfs-server-2.2beta51/exports.man
1086--- nfs-server-2.2beta47/exports.man Wed Nov 10 10:18:49 1999
1087+++ nfs-server-2.2beta51/exports.man Fri Nov 8 14:45:36 2002
1088@@ -45,6 +45,12 @@
1089 simultaneously. This is done by specifying an IP address and netmask pair
1090 as
1091 .IR address/netmask .
1092+.IP "world
1093+You can export a directory to the world (i.e. to all computers that
1094+are able to reach your NFS server network-wise) by using the empty
1095+hostname. When exporting to the world, the
1096+.BR root_squash ", " all_squash ", " ro " and " nosetuid
1097+options are turned on by default.
1098 .TP
1099 .B =public
1100 This is a special ``hostname'' that identifies the given directory name
1101@@ -81,6 +87,12 @@
1102 by using the
1103 .IR ro " option.
1104 .TP
1105+.I setuid
1106+This allows clients to assert the setuid and setgid bits on regular
1107+files. For non-anonymous exports, this option is on by default.
1108+For anonymous exports, the default is
1109+.IR nosetuid .
1110+.TP
1111 .I noaccess
1112 This makes everything below the directory inaccessible for the named
1113 client. This is useful when you want to export a directory hierarchy to
1114@@ -296,6 +308,22 @@
1115 .I /usr/X11R6
1116 entry apply. This is also true when the latter is a wildcard or netgroup
1117 entry.
1118+.PP
1119+You should also be careful about where you place spaces in the
1120+exports file. For instance, the following may appear as if you've
1121+exported
1122+.BR /pub " readonly to host " foozle ,
1123+but what this does in fact is export the directory to
1124+.B foozle
1125+with the default options,
1126+.I and
1127+export it to the world with the readonly option:
1128+.PP
1129+.nf
1130+.ta +3i
1131+# bad: export to the world
1132+/pub foozle (ro)
1133+.fi
1134 .SH FILES
1135 /etc/exports
1136 .SH DIAGNOSTICS
1137diff -urN nfs-server-2.2beta47/fh.c nfs-server-2.2beta51/fh.c
1138--- nfs-server-2.2beta47/fh.c Wed Nov 10 10:41:14 1999
1139+++ nfs-server-2.2beta51/fh.c Fri Nov 8 14:45:36 2002
1140@@ -95,17 +95,14 @@
1141 static int fh_list_size;
1142 static time_t curtime;
1143
1144-#ifndef FOPEN_MAX
1145-#define FOPEN_MAX 256
1146-#endif
1147-
1148 #ifndef FHTRACE
1149 #undef D_FHTRACE
1150 #define D_FHTRACE D_FHCACHE
1151 #endif
1152
1153-static fhcache * fd_cache[FOPEN_MAX] = { NULL };
1154+static fhcache ** fd_cache = NULL;
1155 static int fd_cache_size = 0;
1156+static int fd_cache_max = 0;
1157
1158 #ifndef NFSERR_INVAL /* that Sun forgot */
1159 #define NFSERR_INVAL 22
1160@@ -141,10 +138,13 @@
1161
1162 /* Forward declared local functions */
1163 static psi_t path_psi(char *, nfsstat *, struct stat *, int);
1164+static psi_t path_psi_m(char *, nfsstat *, struct stat *,
1165+ struct stat *, int);
1166 static int fh_flush_fds(void);
1167 static char * fh_dump(svc_fh *);
1168 static void fh_insert_fdcache(fhcache *fhc);
1169 static void fh_unlink_fdcache(fhcache *fhc);
1170+static void fh_complain(const char *msg, fhcache *fhc);
1171
1172 static void
1173 fh_move_to_front(fhcache *fhc)
1174@@ -192,6 +192,13 @@
1175 static void
1176 fh_insert_fdcache(fhcache *fhc)
1177 {
1178+#ifdef FHTRACE
1179+ Dprintf(D_FHTRACE, "insert fh %x into fdcache @%d\n", fhc->h.psi, fhc->fd);
1180+ if (fhc->fd < 0) {
1181+ fh_complain("fd cache bug: bad fd", fhc);
1182+ return;
1183+ }
1184+#endif
1185 if (fhc == fd_lru_head)
1186 return;
1187 if (fhc->fd_next || fhc->fd_prev)
1188@@ -203,9 +210,20 @@
1189 fhc->fd_next = fd_lru_head;
1190 fd_lru_head = fhc;
1191
1192+ if (fhc->fd >= fd_cache_max) {
1193+ int oldmax = fd_cache_max, newmax;
1194+
1195+ newmax = (fhc->fd + 8) & ~7;
1196+ fd_cache = (fhcache **) xrealloc(fd_cache, newmax * sizeof(fhcache *));
1197+ memset(fd_cache + oldmax, 0, (newmax - oldmax) * sizeof(fhcache *));
1198+ fd_cache_max = newmax;
1199+ }
1200+
1201 #ifdef FHTRACE
1202 if (fd_cache[fhc->fd] != NULL) {
1203- Dprintf(L_ERROR, "fd cache inconsistency!\n");
1204+ Dprintf(L_ERROR, "fd cache inconsistency (two fh's for same fd)");
1205+ fh_complain("new fh", fhc);
1206+ fh_complain("old fh", fd_cache[fhc->fd]);
1207 return;
1208 }
1209 #endif
1210@@ -225,7 +243,7 @@
1211 } else if (fd_lru_tail == fhc) {
1212 fd_lru_tail = prev;
1213 } else {
1214- Dprintf(L_ERROR, "fd cache inconsistency\n");
1215+ fh_complain("fd cache inconsistency (no next and not at tail)", fhc);
1216 return;
1217 }
1218 if (prev) {
1219@@ -233,13 +251,13 @@
1220 } else if (fd_lru_head == fhc) {
1221 fd_lru_head = next;
1222 } else {
1223- Dprintf(L_ERROR, "fd cache inconsistency\n");
1224+ fh_complain("fd cache inconsistency (no prev and not at head)", fhc);
1225 return;
1226 }
1227
1228 #ifdef FHTRACE
1229 if (fd_cache[fhc->fd] != fhc) {
1230- Dprintf(L_ERROR, "fd cache inconsistency!\n");
1231+ fh_complain("fd cache inconsistency (fd cache ptr mismatch)", fhc);
1232 return;
1233 }
1234 #endif
1235@@ -285,7 +303,7 @@
1236 hash_slot = &((*hash_slot)->hash_next);
1237 if (*hash_slot == NULL)
1238 Dprintf(L_ERROR,
1239- "internal inconsistency -- fhc(%x) not in hash table\n",
1240+ "internal inconsistency -- fhc(%x) not in hash table!\n",
1241 fhc);
1242 else
1243 *hash_slot = fhc->hash_next;
1244@@ -572,7 +590,7 @@
1245 efs_seekdir(dir, cookie_stack[i]);
1246 while ((dp = efs_readdir(dir))) {
1247 char *name = dp->d_name;
1248- int n = strlen(name);
1249+ int n = strlen(name); /* or: dp->d_reclen */
1250
1251 if (pathlen + n + 1 >= NFS_MAXPATHLEN
1252 || (name[0] == '.'
1253@@ -738,7 +756,16 @@
1254 static psi_t
1255 path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid)
1256 {
1257- struct stat sbuf;
1258+ struct stat smounted;
1259+
1260+ return path_psi_m(path, status, sbp, &smounted, svalid);
1261+}
1262+
1263+static psi_t
1264+path_psi_m(char *path, nfsstat *status,
1265+ struct stat *sbp, struct stat *mbp, int svalid)
1266+{
1267+ struct stat sbuf, ddbuf;
1268
1269 if (sbp == NULL)
1270 sbp = &sbuf;
1271@@ -746,10 +773,10 @@
1272 *status = nfs_errno();
1273 return (0);
1274 }
1275+ *mbp = *sbp;
1276 if (S_ISDIR(sbp->st_mode) && strcmp(path, "/") != 0) {
1277 /* Special case for directories--test for mount point. */
1278- struct stat ddbuf;
1279- char *fname;
1280+ char *fname;
1281
1282 /* Find start of last component of path. */
1283 #if 1
1284@@ -819,6 +846,19 @@
1285 return (pseudo_inode(sbp->st_ino, sbp->st_dev));
1286 }
1287
1288+/*
1289+ * Match attributes to make sure we're still referring to the original file
1290+ */
1291+static inline int
1292+fh_attrmatch(struct fhcache *fhc, struct stat *attr)
1293+{
1294+ if (fhc->dev == attr->st_dev
1295+ && fhc->ino == attr->st_ino
1296+ && fhc->type == (attr->st_mode & S_IFMT))
1297+ return 1;
1298+ return 0;
1299+}
1300+
1301 fhcache *
1302 fh_find(svc_fh *h, int mode)
1303 {
1304@@ -838,6 +878,9 @@
1305 ex_state = active;
1306 time(&curtime);
1307 while ((fhc = fh_lookup(h->psi)) != NULL) {
1308+ struct stat sbuf, *s = NULL;
1309+ nfsstat dummy;
1310+
1311 Dprintf(D_FHCACHE, "fh_find: psi=%lx... found '%s', fd=%d\n",
1312 (unsigned long) h->psi,
1313 fhc->path ? fhc->path : "<unnamed>",
1314@@ -857,33 +900,27 @@
1315 * If it doesn't try to rebuild the path.
1316 */
1317 if (check) {
1318- struct stat *s = &fhc->attrs;
1319- psi_t psi;
1320- nfsstat dummy;
1321-
1322+ s = &sbuf;
1323 if (efs_lstat(fhc->path, s) < 0) {
1324 Dprintf(D_FHTRACE,
1325 "fh_find: stale fh: lstat: %m\n");
1326 } else {
1327- fhc->flags |= FHC_ATTRVALID;
1328- /* If pseudo-inos don't match, we fhc->path
1329- * may be a mount point (hence lstat() returns
1330+ /* If device/ino don't match, fhc->path may
1331+ * be a mount point (hence lstat() returns
1332 * a different inode number than the readdir()
1333 * stuff used in path_psi)
1334 */
1335- psi = pseudo_inode(s->st_ino, s->st_dev);
1336- if (h->psi == psi)
1337+ if (fh_attrmatch(fhc, s))
1338 goto fh_return;
1339
1340- /* Try again by computing the path psi */
1341- psi = path_psi(fhc->path, &dummy, s, 1);
1342- if (h->psi == psi)
1343+ /* Get the dev/ino of the underlying
1344+ * mount point. */
1345+ path_psi(fhc->path, &dummy, s, 1);
1346+ if (fh_attrmatch(fhc, s))
1347 goto fh_return;
1348
1349- Dprintf(D_FHTRACE, "fh_find: stale fh: "
1350- "dev/ino %x/%lx psi %lx",
1351- s->st_dev, s->st_ino,
1352- (unsigned long) psi);
1353+ Dprintf(D_FHTRACE, "fh_find: stale fh: %lx",
1354+ (unsigned long) h->psi);
1355 }
1356
1357 fh_discard:
1358@@ -896,6 +933,12 @@
1359 }
1360
1361 fh_return:
1362+ /* Valid attributes; cache them */
1363+ if (s != NULL) {
1364+ memcpy(&fhc->attrs, s, sizeof(*s));
1365+ fhc->flags |= FHC_ATTRVALID;
1366+ }
1367+
1368 /* The cached fh seems valid */
1369 if (fhc != fh_head.next)
1370 fh_move_to_front(fhc);
1371@@ -905,7 +948,8 @@
1372 }
1373
1374 Dprintf(D_FHCACHE, "fh_find: psi=%lx... not found\n",
1375- (unsigned long) h->psi);
1376+ (unsigned long) h->psi);
1377+
1378 if (mode == FHFIND_FCACHED) {
1379 ex_state = inactive;
1380 return NULL;
1381@@ -918,6 +962,7 @@
1382 fhc = flush->prev;
1383 fh_delete(flush);
1384 }
1385+
1386 fhc = (fhcache *) xmalloc(sizeof *fhc);
1387 if (mode == FHFIND_FCREATE) {
1388 /* File will be created */
1389@@ -937,11 +982,31 @@
1390 }
1391 fhc->path = path;
1392 }
1393+
1394 fhc->flags = 0;
1395 if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) {
1396- if (re_export && nfsmounted(fhc->path, &fhc->attrs))
1397+ if (nfsmounted(fhc->path, &fhc->attrs)) {
1398 fhc->flags |= FHC_NFSMOUNTED;
1399+#if 0
1400+ /* We must allow the client to send us the
1401+ * file handle for the NFS mount point itself,
1402+ * but not for entries within an NFS mount.
1403+ * XXX: needs fixing.
1404+ */
1405+ if (!re_export) {
1406+ Dprintf(D_FHTRACE,
1407+ "Attempt to use %s (non-exportable)\n",
1408+ fhc->path);
1409+ free(fhc);
1410+ ex_state = inactive;
1411+ return NULL;
1412+ }
1413+#endif
1414+ }
1415 fhc->flags |= FHC_ATTRVALID;
1416+ fhc->dev = fhc->attrs.st_dev;
1417+ fhc->ino = fhc->attrs.st_ino;
1418+ fhc->type = fhc->attrs.st_mode & S_IFMT;
1419 }
1420 fhc->fd = -1;
1421 fhc->last_used = curtime;
1422@@ -993,6 +1058,14 @@
1423 return buf;
1424 }
1425
1426+static void
1427+fh_complain(const char *msg, fhcache *fhc)
1428+{
1429+ Dprintf(L_ERROR, "%s: ptr=%p fd=%d path=%s\n", msg,
1430+ fhc, fhc->fd,
1431+ fhc->path? fhc->path : "<unnamed>");
1432+}
1433+
1434 /*
1435 * This routine is only used by the mount daemon.
1436 * It creates the initial file handle.
1437@@ -1000,23 +1073,25 @@
1438 int
1439 fh_create(nfs_fh *fh, char *path)
1440 {
1441- svc_fh key;
1442- fhcache *h;
1443- psi_t psi;
1444- nfsstat status;
1445- char *s;
1446+ struct stat stb;
1447+ svc_fh key;
1448+ fhcache *h;
1449+ psi_t psi;
1450+ nfsstat status;
1451+ char *s;
1452
1453 memset(&key, 0, sizeof(key));
1454 status = NFS_OK;
1455- if ((psi = path_psi("/", &status, NULL, 0)) == 0)
1456+ if ((psi = path_psi("/", &status, &stb, 0)) == 0)
1457 return ((int) status);
1458+
1459 s = path;
1460 while ((s = strchr(s + 1, '/')) != NULL) {
1461 if (++(key.hash_path[0]) >= HP_LEN)
1462 return ((int) NFSERR_NAMETOOLONG);
1463 key.hash_path[key.hash_path[0]] = hash_psi(psi);
1464 *s = '\0';
1465- if ((psi = path_psi(path, &status, NULL, 0)) == 0)
1466+ if ((psi = path_psi(path, &status, &stb, 0)) == 0)
1467 return ((int) status);
1468 *s = '/';
1469 }
1470@@ -1024,7 +1099,7 @@
1471 if (++(key.hash_path[0]) >= HP_LEN)
1472 return ((int) NFSERR_NAMETOOLONG);
1473 key.hash_path[key.hash_path[0]] = hash_psi(psi);
1474- if ((psi = path_psi(path, &status, NULL, 0)) == 0)
1475+ if ((psi = path_psi(path, &status, &stb, 0)) == 0)
1476 return ((int) status);
1477 }
1478 key.psi = psi;
1479@@ -1037,9 +1112,12 @@
1480
1481 /* assert(h != NULL); */
1482 if (h->path == NULL) {
1483- h->fd = -1;
1484- h->path = xstrdup(path);
1485+ h->fd = -1;
1486+ h->path = xstrdup(path);
1487 h->flags = 0;
1488+ h->dev = stb.st_dev;
1489+ h->ino = stb.st_ino;
1490+ h->type = stb.st_mode & S_IFMT;
1491 }
1492 memcpy(fh, &key, sizeof(key));
1493 return ((int) status);
1494@@ -1064,6 +1142,44 @@
1495 return ((nfs_fh*)&(h->h));
1496 }
1497
1498+
1499+static inline int
1500+access_override(int omode, int perm, struct stat *buf)
1501+{
1502+ /* Be suspicous of flags, particularly O_CREAT/O_TRUNC. A previous
1503+ * comment said:
1504+ *
1505+ * "[Not checking this] would truncate read-only files on creat()
1506+ * calls. Of course, ftruncate(fd, 0) should still be legal for
1507+ * the user when the file was chmoded *after* opening it, but we
1508+ * have no way to tell, and a semi-succeding `cp foo readonly-file'
1509+ * is much more unintuitive and destructive than a failing
1510+ * ftruncate()."
1511+ */
1512+ if (omode & ~O_ACCMODE)
1513+ return 0;
1514+
1515+ /* Users can do anything to their own files. Harmless (since they
1516+ * could chown anyway), and helps to mask NFSes statelessness.
1517+ *
1518+ * (in passing, this also handles mode 0100 execution)
1519+ */
1520+ if (buf->st_uid == auth_uid)
1521+ return 1;
1522+
1523+ /* Henceforth, we are considering granting read access to facilitate
1524+ * exec access. This is read only */
1525+ if (omode != O_RDONLY)
1526+ return 0;
1527+
1528+ /* Mode 0110 execution */
1529+ if (buf->st_gid == auth_gid)
1530+ return (buf->st_mode & S_IXGRP) != 0;
1531+
1532+ /* Mode 0111 execution */
1533+ return (buf->st_mode & S_IXOTH) != 0;
1534+}
1535+
1536 int
1537 path_open(char *path, int omode, int perm)
1538 {
1539@@ -1113,30 +1229,15 @@
1540 * lishes two things: first, it gives the file owner r/w access to
1541 * the file whatever the permissions are, so that files are still
1542 * accessible after an fchown(fd, 0). The second part of the
1543- * condition allows read access to mode 0111 executables.
1544- *
1545- * The old conditon read like this:
1546- * if (fd < 0 && oerrno == EACCES) {
1547- * if (oerrno == EACCES && (buf.st_uid == auth_uid
1548- * || (omode == O_RDONLY && (buf.st_mode & S_IXOTH)))) {
1549- * override uid; etc...
1550- * }
1551- * }
1552- * This would truncate read-only files on creat() calls. Now
1553- * ftruncate(fd, 0) should still be legal for the user when the
1554- * file was chmoded *after* opening it, but we have no way to tell,
1555- * and a semi-succeding `cp foo readonly-file' is much more
1556- * unintuitive and destructive than a failing ftruncate().
1557+ * condition allows read access to `execute-only' files.
1558 */
1559- if (fd < 0 && oerrno == EACCES && !(omode & (O_CREAT|O_TRUNC))) {
1560- if ((buf.st_uid == auth_uid && (omode & O_ACCMODE) == omode)
1561- || ((buf.st_mode & S_IXOTH) && omode == O_RDONLY)) {
1562- auth_override_uid(ROOT_UID);
1563- fd = efs_open(path, omode, perm);
1564- oerrno = errno;
1565- auth_override_uid(auth_uid);
1566- }
1567+ if (fd < 0 && oerrno == EACCES && access_override(omode, perm, &buf)) {
1568+ auth_override_uid(ROOT_UID);
1569+ fd = efs_open(path, omode, perm);
1570+ oerrno = errno;
1571+ auth_override_uid(auth_uid);
1572 }
1573+
1574
1575 if (fd < 0) {
1576 Dprintf(D_FHCACHE,
1577@@ -1241,7 +1342,7 @@
1578 char *sindx;
1579 int is_dd;
1580 nfsstat ret;
1581- struct stat sbuf;
1582+ struct stat sbuf, smount;
1583 char pathbuf[PATH_MAX + NAME_MAX + 1], *fname;
1584
1585 /* should not happen */
1586@@ -1318,7 +1419,7 @@
1587
1588 *new_fh = dopa->dir;
1589 key = (svc_fh *) new_fh;
1590- if ((key->psi = path_psi(pathbuf, &ret, sbp, 0)) == 0)
1591+ if ((key->psi = path_psi_m(pathbuf, &ret, sbp, &smount, 0)) == 0)
1592 return (ret);
1593
1594 if (is_dd) {
1595@@ -1344,6 +1445,10 @@
1596 h->h.hash_path[0]);
1597 return NFSERR_STALE;
1598 }
1599+ if (sbp->st_dev != smount.st_dev) {
1600+ Dprintf(D_FHTRACE, "fh_compose: %s hit%s mount point\n",
1601+ pathbuf, nfsmounted(pathbuf, &smount)? " NFS" : "");
1602+ }
1603 #endif
1604
1605 /* New code added by Don Becker */
1606@@ -1356,7 +1461,8 @@
1607 if (!h) return NFSERR_STALE;
1608 #endif
1609 if (h->path)
1610- Dprintf(L_ERROR, "Internal inconsistency: double entry (path '%s', now '%s').\n",
1611+ Dprintf(L_ERROR,
1612+ "internal inconsistency: double entry (path '%s', now '%s').\n",
1613 h->path, pathbuf);
1614 }
1615 Dprintf(D_FHCACHE, "fh_compose: using handle %x ('%s', fd=%d)\n",
1616@@ -1365,9 +1471,18 @@
1617
1618 /* assert(h != NULL); */
1619 if (h->path == 0) {
1620- h->path = xstrdup(pathbuf);
1621+ h->path = xstrdup(pathbuf);
1622 h->flags = 0;
1623- if (!re_export && nfsmounted(pathbuf, sbp))
1624+ h->dev = sbp->st_dev;
1625+ h->ino = sbp->st_ino;
1626+ h->type = sbp->st_mode & S_IFMT;
1627+
1628+ /* Note: in the case of a mount point,
1629+ * sbp contains the stats of the mount point, while
1630+ * ddbuf has the dev/ino of the underlying directory
1631+ */
1632+ if (sbp->st_dev != smount.st_dev
1633+ && nfsmounted(pathbuf, &smount))
1634 h->flags |= FHC_NFSMOUNTED;
1635 #ifdef FHTRACE
1636 Dprintf(D_FHTRACE, "fh_compose: created handle %s\n", h->path);
1637diff -urN nfs-server-2.2beta47/fh.h nfs-server-2.2beta51/fh.h
1638--- nfs-server-2.2beta47/fh.h Mon Nov 23 12:15:43 1998
1639+++ nfs-server-2.2beta51/fh.h Fri Nov 8 14:45:36 2002
1640@@ -97,7 +97,13 @@
1641 struct fhcache * hash_next;
1642 struct fhcache * fd_next;
1643 struct fhcache * fd_prev;
1644+
1645+ /* These are fixed during the lifetime of this object */
1646 svc_fh h;
1647+ dev_t dev;
1648+ ino_t ino;
1649+ mode_t type; /* st_mode & S_IFMT */
1650+
1651 int fd;
1652 int omode;
1653 char * path;
1654diff -urN nfs-server-2.2beta47/getattr.c nfs-server-2.2beta51/getattr.c
1655--- nfs-server-2.2beta47/getattr.c Fri Oct 30 18:10:11 1998
1656+++ nfs-server-2.2beta51/getattr.c Fri Nov 8 14:45:36 2002
1657@@ -115,6 +115,16 @@
1658 attr->fsid = 1;
1659 attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
1660 #endif
1661+
1662+ /* This may be needed by some Suns... testing */
1663+#define MINTIME (24 * 2600)
1664+ if (s->st_atime < MINTIME)
1665+ s->st_atime = MINTIME;
1666+ if (s->st_mtime < MINTIME)
1667+ s->st_mtime = MINTIME;
1668+ if (s->st_ctime < MINTIME)
1669+ s->st_ctime = MINTIME;
1670+
1671 attr->atime.seconds = s->st_atime;
1672 attr->atime.useconds = 0;
1673 attr->mtime.seconds = s->st_mtime;
1674diff -urN nfs-server-2.2beta47/logging.c nfs-server-2.2beta51/logging.c
1675--- nfs-server-2.2beta47/logging.c Fri Oct 30 17:11:22 1998
1676+++ nfs-server-2.2beta51/logging.c Fri Nov 8 14:45:36 2002
1677@@ -147,8 +147,9 @@
1678 (void) time(&now);
1679 tm = localtime(&now);
1680 fprintf(log_fp, "%s %02d/%02d/%02d %02d:%02d %s",
1681- log_name, tm->tm_mon + 1, tm->tm_mday, tm->tm_year,
1682- tm->tm_hour, tm->tm_min, buff);
1683+ log_name, tm->tm_mon + 1, tm->tm_mday,
1684+ tm->tm_year % 100,
1685+ tm->tm_hour, tm->tm_min, buff);
1686 if (strchr(buff, '\n') == NULL)
1687 fputc('\n', log_fp);
1688 }
1689@@ -182,7 +183,8 @@
1690 tm = localtime(&unix_cred->aup_time);
1691 snprintf(buffer + len, total - len,
1692 "%d/%d/%d %02d:%02d:%02d %s %d.%d",
1693- tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
1694+ tm->tm_year %100,
1695+ tm->tm_mon + 1, tm->tm_mday,
1696 tm->tm_hour, tm->tm_min, tm->tm_sec,
1697 unix_cred->aup_machname,
1698 unix_cred->aup_uid,
1699diff -urN nfs-server-2.2beta47/mountd.c nfs-server-2.2beta51/mountd.c
1700--- nfs-server-2.2beta47/mountd.c Wed Jun 2 14:10:33 1999
1701+++ nfs-server-2.2beta51/mountd.c Fri Nov 8 14:45:36 2002
1702@@ -32,7 +32,7 @@
1703 #include "rpcmisc.h"
1704 #include "rmtab.h"
1705 #include "haccess.h"
1706-#include "failsafe.h"
1707+#include "daemon.h"
1708 #include "signals.h"
1709 #include <rpc/pmap_clnt.h>
1710
1711@@ -44,6 +44,8 @@
1712 /*
1713 * Option table for mountd
1714 */
1715+#define OPT_NOTCP 300
1716+#define OPT_LOOPBACK 301
1717 static struct option longopts[] =
1718 {
1719 { "debug", required_argument, 0, 'd' },
1720@@ -56,6 +58,8 @@
1721 { "no-spoof-trace", 0, 0, 't' },
1722 { "version", 0, 0, 'v' },
1723 { "fail-safe", optional_argument, 0, 'z' },
1724+ { "no-tcp", 0, 0, OPT_NOTCP },
1725+ { "loopback-only", 0, 0, OPT_LOOPBACK },
1726
1727 { NULL, 0, 0, 0 }
1728 };
1729@@ -358,6 +362,12 @@
1730 break;
1731 case 0:
1732 break;
1733+ case OPT_NOTCP:
1734+ udp_only = 1;
1735+ break;
1736+ case OPT_LOOPBACK:
1737+ loopback_only = 1;
1738+ break;
1739 case '?':
1740 default:
1741 usage(stderr, 1);
1742@@ -384,38 +394,27 @@
1743 /* Create services and register with portmapper */
1744 rpc_init("mountd", MOUNTPROG, mountd_versions, mount_dispatch, port, 0);
1745
1746- if (!foreground && !_rpcpmstart) {
1747-#ifndef RPC_SVC_FG
1748- /* We first fork off a child. */
1749- if ((c = fork()) > 0)
1750- exit(0);
1751- if (c < 0) {
1752- Dprintf(L_FATAL, "mountd: cannot fork: %s\n",
1753- strerror(errno));
1754- }
1755- /* No more logging to stderr */
1756- background_logging();
1757+ if (_rpcpmstart) {
1758+ /* Always foreground mode */
1759+ foreground = 1;
1760
1761- /* Now we remove ourselves from the foreground. */
1762- (void) close(0);
1763- (void) close(1);
1764- (void) close(2);
1765-#ifdef TIOCNOTTY
1766- if ((c = open("/dev/tty", O_RDWR)) >= 0) {
1767- (void) ioctl(c, TIOCNOTTY, (char *) NULL);
1768- (void) close(c);
1769- }
1770-#else
1771- setsid();
1772-#endif
1773-#endif /* not RPC_SVC_FG */
1774+ /* ... but no logging */
1775+ background_logging();
1776 }
1777
1778+ /* Become a daemon */
1779+ if (!foreground)
1780+ daemonize();
1781+
1782 /* Initialize the FH module. */
1783 fh_init();
1784
1785 /* Initialize the AUTH module. */
1786 auth_init(auth_file);
1787+
1788+ /* Write pidfile */
1789+ setpidpath(_PATH_MOUNTD_PIDFILE);
1790+ writepid(getpid(), 1);
1791
1792 /* Failsafe mode */
1793 if (failsafe_level)
1794diff -urN nfs-server-2.2beta47/mountd.man nfs-server-2.2beta51/mountd.man
1795--- nfs-server-2.2beta47/mountd.man Wed Jun 2 14:12:21 1999
1796+++ nfs-server-2.2beta51/mountd.man Fri Nov 8 14:45:36 2002
1797@@ -14,6 +14,8 @@
1798 .B "[\ \-\-allow\-non\-root\ ]"
1799 .B "[\ \-\-re\-export\ ]"
1800 .B "[\ \-\-no\-spoof\-trace\ ]"
1801+.B "[\ \-\-no\-tcp ]"
1802+.B "[\ \-\-loopback\-only ]"
1803 .B "[\ \-\-version\ ]"
1804 .ad b
1805 .SH DESCRIPTION
1806@@ -123,6 +125,18 @@
1807 .TP
1808 .BR \-v " or " \-\-version
1809 Report the current version number of the program.
1810+.TP
1811+.BR \-\-no\-tcp
1812+Force
1813+.I mountd
1814+to register only the UDP transport, but no TCP.
1815+This is an experimental option.
1816+.TP
1817+.BR \-\-loopback\-only
1818+Force
1819+.I mountd
1820+to bind to the loopback interface.
1821+This is an experimental option.
1822 .SS Access Control
1823 For enhanced security, access to
1824 .I mountd
1825diff -urN nfs-server-2.2beta47/nfsd.c nfs-server-2.2beta51/nfsd.c
1826--- nfs-server-2.2beta47/nfsd.c Wed Nov 10 10:33:28 1999
1827+++ nfs-server-2.2beta51/nfsd.c Fri Nov 8 14:45:36 2002
1828@@ -21,7 +21,7 @@
1829 #include "getopt.h"
1830 #include "fsusage.h"
1831 #include "rpcmisc.h"
1832-#include "failsafe.h"
1833+#include "daemon.h"
1834 #include "signals.h"
1835 #ifdef __linux__ /* XXX - MvS: for UNIX sockets. */
1836 # include <sys/un.h>
1837@@ -30,7 +30,6 @@
1838 # include <syslog.h>
1839 #endif
1840
1841-#define MULTIPLE_SERVERS
1842
1843 /* Flags for auth_fh */
1844 #define CHK_READ 0
1845@@ -51,6 +50,8 @@
1846 /*
1847 * Option table
1848 */
1849+#define OPT_NOTCP 300
1850+#define OPT_LOOPBACK 301
1851 static struct option longopts[] = {
1852 { "auth-deamon", required_argument, 0, 'a' },
1853 { "debug", required_argument, 0, 'd' },
1854@@ -68,6 +69,9 @@
1855 { "version", 0, 0, 'v' },
1856 { "no-cross-mounts", 0, 0, 'x' },
1857 { "fail-safe", optional_argument, 0, 'z' },
1858+ { "no-tcp", 0, 0, OPT_NOTCP },
1859+ { "udp-only", 0, 0, OPT_NOTCP },
1860+ { "loopback-only", 0, 0, OPT_LOOPBACK },
1861
1862 { NULL, 0, 0, 0 }
1863 };
1864@@ -173,7 +177,10 @@
1865 return NULL;
1866 }
1867
1868- auth_user(nfsmount, rqstp);
1869+ if (!auth_user(nfsmount, rqstp)) {
1870+ *statp = NFSERR_ACCES;
1871+ return NULL;
1872+ }
1873
1874 *statp = NFS_OK;
1875 return fhc;
1876@@ -211,7 +218,11 @@
1877
1878 if ((nfsmount = auth_path(nfsclient, rqstp, path)) == NULL)
1879 return NFSERR_ACCES;
1880- auth_user(nfsmount, rqstp);
1881+
1882+ /* XXX: really need to call it again here?
1883+ * Already invoked in auth_fh */
1884+ if (!auth_user(nfsmount, rqstp))
1885+ return NFSERR_ACCES;
1886
1887 return (NFS_OK);
1888 }
1889@@ -575,7 +586,8 @@
1890 #endif
1891
1892 /* MvS: Some clients use chardev 0xFFFF for a FIFO. */
1893- if (S_ISCHR(argp->attributes.mode) && dev == 0xFFFF) {
1894+ if (S_ISCHR(argp->attributes.mode)
1895+ && (dev == 0xFFFF || dev == (dev_t) -1)) {
1896 is_borc = 0;
1897 dev = 0;
1898 argp->attributes.mode &= ~S_IFMT;
1899@@ -623,7 +635,7 @@
1900 flags = (argp->attributes.size == 0 ?
1901 CREATE_OMODE | O_TRUNC : CREATE_OMODE);
1902 if (!exists)
1903- flags |= O_CREAT;
1904+ flags |= O_CREAT|O_EXCL;
1905 tmpfd = path_open(pathbuf, flags,
1906 argp->attributes.mode & ~S_IFMT);
1907 if (tmpfd < 0)
1908@@ -965,9 +977,7 @@
1909 int nfsport = 0;
1910 int failsafe_level = 0;
1911 int c;
1912-#ifdef MULTIPLE_SERVERS
1913 int i, ncopies = 1;
1914-#endif
1915
1916 program_name = argv[0];
1917 chdir("/");
1918@@ -1031,12 +1041,17 @@
1919 break;
1920 case 0:
1921 break;
1922+ case OPT_NOTCP:
1923+ udp_only = 1;
1924+ break;
1925+ case OPT_LOOPBACK:
1926+ loopback_only = 1;
1927+ break;
1928 case '?':
1929 default:
1930 usage(stderr, 1);
1931 }
1932
1933-#ifdef MULTIPLE_SERVERS
1934 if (optind == argc-1 && isdigit(argv[optind][0])) {
1935 ncopies = atoi(argv[optind++]);
1936 if (ncopies <= 0) {
1937@@ -1051,7 +1066,6 @@
1938 ncopies = 1;
1939 }
1940 }
1941-#endif
1942
1943 /* No more arguments allowed. */
1944 if (optind != argc)
1945@@ -1075,72 +1089,54 @@
1946 rpc_init("nfsd", NFS_PROGRAM, nfsd_versions, nfs_dispatch,
1947 nfsport, NFS_MAXDATA);
1948
1949- /* No more than 1 copy when run from inetd */
1950- if (_rpcpmstart && ncopies > 1) {
1951- Dprintf(L_WARNING,
1952- "nfsd: warning: can run only "
1953- "one server in inetd mode\n");
1954- ncopies = 1;
1955+ if (_rpcpmstart) {
1956+ /* Always do foreground mode */
1957+ foreground = 1;
1958+
1959+ /* ... but don't log to stderr */
1960+ background_logging();
1961+
1962+ /* No more than 1 copy when run from inetd */
1963+ if (ncopies > 1) {
1964+ Dprintf(L_WARNING,
1965+ "nfsd: warning: can run only "
1966+ "one server in inetd mode\n");
1967+ ncopies = 1;
1968+ }
1969 }
1970
1971-#ifndef MULTIPLE_SERVERS_READWRITE
1972 if (ncopies > 1)
1973 read_only = 1;
1974-#endif
1975
1976- /* We first fork off a child. */
1977- if (!foreground) {
1978- if ((c = fork()) > 0)
1979- exit(0);
1980- if (c < 0) {
1981- Dprintf(L_FATAL, "nfsd: cannot fork: %s\n",
1982- strerror(errno));
1983- }
1984- }
1985+ /*
1986+ * We first fork off a child and detach from tty
1987+ */
1988+ if (!foreground)
1989+ daemonize();
1990
1991 /* Initialize the AUTH module. */
1992 auth_init(auth_file);
1993
1994+ setpidpath(_PATH_NFSD_PIDFILE);
1995 if (failsafe_level == 0) {
1996 /* Start multiple copies of the server */
1997+ writepid(getpid(), 1);
1998 for (i = 1; i < ncopies; i++) {
1999+ pid_t pid;
2000+
2001 Dprintf(D_GENERAL, "Forking server thread...\n");
2002- if ((c = fork()) < 0) {
2003+ if ((pid = fork()) < 0) {
2004 Dprintf(L_ERROR, "Unable to fork: %s",
2005 strerror(errno));
2006- } else if (c == 0) {
2007- /* Child process */
2008- break;
2009+ } else if (pid != 0) {
2010+ writepid(pid, 0);
2011+ } else {
2012+ break; /* Child process */
2013 }
2014 }
2015 } else {
2016 /* Init for failsafe mode */
2017 failsafe(failsafe_level, ncopies);
2018- }
2019-
2020- /* Now that we've done all the required forks, we make do all the
2021- * session magic.
2022- */
2023- if (!foreground) {
2024- /* No more logging to stderr */
2025- background_logging();
2026-
2027- /* Now we remove ourselves from the foreground. */
2028- close(0);
2029- close(1);
2030- close(2);
2031-#ifdef HAVE_SETSID
2032- setsid();
2033-#else
2034- {
2035- int fd;
2036-
2037- if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
2038- ioctl(fd, TIOCNOTTY, (char *) NULL);
2039- close(fd);
2040- }
2041- }
2042-#endif
2043 }
2044
2045 /*
2046diff -urN nfs-server-2.2beta47/nfsd.man nfs-server-2.2beta51/nfsd.man
2047--- nfs-server-2.2beta47/nfsd.man Wed Jun 2 14:13:37 1999
2048+++ nfs-server-2.2beta51/nfsd.man Fri Nov 8 14:45:36 2002
2049@@ -8,7 +8,7 @@
2050 .B "[\ \-d\ facility\ ]"
2051 .B "[\ \-P\ port\ ]"
2052 .B "[\ \-R\ dirname\ ]"
2053-.B "[\ \-Fhlnprstv\ ]"
2054+.B "[\ \-Fhlnprstuv\ ]"
2055 .B "[\ \-\-debug\ facility\ ]"
2056 .B "[\ \-\-exports\-file=file\ ]"
2057 .B "[\ \-\-foreground\ ]"
2058@@ -18,6 +18,8 @@
2059 .B "[\ \-\-public\-root\ dirname\ ]"
2060 .\".B "[\ \-\-synchronous\-writes\ ]"
2061 .B "[\ \-\-no\-spoof\-trace\ ]"
2062+.B "[\ \-\-no\-tcp ]"
2063+.B "[\ \-\-loopback-only ]"
2064 .B "[\ \-\-port\ port\ ]"
2065 .B "[\ \-\-log-transfers\ ]"
2066 .B "[\ \-\-version\ ]"
2067@@ -56,7 +58,7 @@
2068 .PP
2069 When run from
2070 .IR inetd ,
2071-.i nfsd
2072+.I nfsd
2073 will terminate after a certain period of inactivity.
2074 .SH OPTIONS
2075 .TP
2076@@ -167,6 +169,14 @@
2077 .BR \-v " or " \-\-version
2078 Report the current version number of the program.
2079 .TP
2080+.BR \-\-no\-tcp
2081+Force nfsd to only register a UDP transport, but not TCP.
2082+This is an experimental option.
2083+.TP
2084+.BR \-\-loopback\-only
2085+Force nfsd to bind to the loopback interface.
2086+This is an experimental option.
2087+.TP
2088 .BR numcopies
2089 This is an experimental feature that lets you run several instances of
2090 .I nfsd
2091@@ -174,15 +184,8 @@
2092 .B numcopies
2093 greater than one,
2094 .I nfsd
2095-will fork as many times as specified by this value.
2096-However, the servers do not share a common file handle
2097-cache, which makes certain file operations impossible.
2098-.IP
2099-For this reason,
2100-.I nfsd
2101-will disallow all write operations when invoked with this option. Although
2102-this is very limiting, this feature may still prove useful for exporting
2103-public FTP areas or Usenet News spools.
2104+will fork as many times as specified by this value so it is able to
2105+handle that many NFS requests in parallel.
2106 .SS WebNFS Support
2107 WebNFS is an extension to the normal NFS protocol developed by Sun
2108 that is particularly well-suited for file retrieval over the
2109@@ -268,6 +271,19 @@
2110 .I nfsd
2111 writes out a transfer record whenever it encounters a READ or WRITE
2112 request at offset zero.
2113+.SS Generating a debug trace
2114+When suspecting a bug in nfsd, it is helpful to look at a debug trace
2115+of what's going on. You can create such a trace by first killing nfsd,
2116+and then restarting it as
2117+.PP
2118+.nf
2119+.ta +3i
2120+/usr/sbin/rpc.nfsd -F -d all
2121+.fi
2122+.PP
2123+Instead of
2124+.BR all ,
2125+you can use less verbose debug facilities as described above.
2126 .SH "SEE ALSO"
2127 exports(5), mountd(8), ugidd(8C)
2128 .SH AUTHORS
2129diff -urN nfs-server-2.2beta47/rmtab.c nfs-server-2.2beta51/rmtab.c
2130--- nfs-server-2.2beta47/rmtab.c Fri Feb 6 09:43:25 1998
2131+++ nfs-server-2.2beta51/rmtab.c Fri Nov 8 14:45:36 2002
2132@@ -8,6 +8,7 @@
2133
2134 #include "nfsd.h"
2135 #include "rmtab.h"
2136+#include "rpcmisc.h"
2137
2138 static char * rmtab_gethost(struct svc_req *);
2139 static int rmtab_insert(char *, char *);
2140diff -urN nfs-server-2.2beta47/rpcmisc.c nfs-server-2.2beta51/rpcmisc.c
2141--- nfs-server-2.2beta47/rpcmisc.c Tue Sep 7 10:42:58 1999
2142+++ nfs-server-2.2beta51/rpcmisc.c Fri Nov 8 14:45:36 2002
2143@@ -39,6 +39,8 @@
2144 int _rpcfdtype = 0;
2145 int _rpcsvcdirty = 0;
2146 const char * auth_daemon = 0;
2147+int udp_only = 0;
2148+int loopback_only = 0;
2149
2150 #ifdef AUTH_DAEMON
2151 static bool_t (*tcp_rendevouser)(SVCXPRT *, struct rpc_msg *);
2152@@ -96,7 +98,7 @@
2153 }
2154 }
2155
2156- if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
2157+ if ((_rpcfdtype == 0 && !udp_only) || (_rpcfdtype == SOCK_STREAM)) {
2158 if (_rpcfdtype == 0 && defport != 0)
2159 sock = makesock(defport, IPPROTO_TCP, bufsiz);
2160 transp = svctcp_create(sock, 0, 0);
2161@@ -199,6 +201,9 @@
2162 sin.sin_family = AF_INET;
2163 sin.sin_addr.s_addr = INADDR_ANY;
2164 sin.sin_port = htons(port);
2165+
2166+ if (loopback_only)
2167+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2168
2169 #ifdef DEBUG
2170 {
2171diff -urN nfs-server-2.2beta47/rpcmisc.h nfs-server-2.2beta51/rpcmisc.h
2172--- nfs-server-2.2beta47/rpcmisc.h Tue Sep 7 10:37:38 1999
2173+++ nfs-server-2.2beta51/rpcmisc.h Fri Nov 8 14:45:36 2002
2174@@ -9,6 +9,8 @@
2175 extern int _rpcpmstart;
2176 extern int _rpcfdtype;
2177 extern int _rpcsvcdirty;
2178+extern int udp_only;
2179+extern int loopback_only;
2180 extern const char * auth_daemon;
2181
2182 extern void rpc_init(const char *name, int prog, int *verstbl,
2183@@ -16,5 +18,13 @@
2184 int defport, int bufsize);
2185 extern void rpc_exit(int prog, int *verstbl);
2186 extern void rpc_closedown(void);
2187+
2188+/*
2189+ * Some older systems don't have svc_getcaller.
2190+ * Some, like glibc 2.2, have it but it returns some type that's
2191+ * not a sockaddr_in anymore.
2192+ */
2193+#undef svc_getcaller
2194+#define svc_getcaller(xprt) ((struct sockaddr_in *) (&(xprt)->xp_raddr))
2195
2196 #endif /* RPCMISC_H */
2197diff -urN nfs-server-2.2beta47/setattr.c nfs-server-2.2beta51/setattr.c
2198--- nfs-server-2.2beta47/setattr.c Fri Oct 30 18:29:42 1998
2199+++ nfs-server-2.2beta51/setattr.c Fri Nov 8 14:45:36 2002
2200@@ -103,6 +103,10 @@
2201 if (flags & SATTR_CHMOD) {
2202 unsigned int mode = attr->mode;
2203
2204+ /* If setuid is not allowed, silently squash them */
2205+ if (!nfsmount->o.allow_setuid && S_ISREG(s->st_mode))
2206+ mode &= ~(S_ISUID|S_ISGID) | s->st_mode;
2207+
2208 if (mode != -1 && mode != 0xFFFF /* ultrix bug */
2209 && (mode & 07777) != (s->st_mode & 07777)) {
2210 if (efs_chmod(path, mode) < 0)
2211diff -urN nfs-server-2.2beta47/showmount.c nfs-server-2.2beta51/showmount.c
2212--- nfs-server-2.2beta47/showmount.c Wed Jun 12 22:31:04 1996
2213+++ nfs-server-2.2beta51/showmount.c Fri Nov 8 14:45:36 2002
2214@@ -162,17 +162,13 @@
2215 break;
2216 }
2217
2218- if (hostname[0] >= '0' && hostname[0] <= '9') {
2219- server_addr.sin_family = AF_INET;
2220- server_addr.sin_addr.s_addr = inet_addr(hostname);
2221- }
2222- else {
2223+ server_addr.sin_family = AF_INET;
2224+ if (!inet_aton(hostname, &server_addr.sin_addr)) {
2225 if ((hp = gethostbyname(hostname)) == NULL) {
2226 fprintf(stderr, "%s: can't get address for %s\n",
2227 program_name, hostname);
2228 exit(1);
2229 }
2230- server_addr.sin_family = AF_INET;
2231 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
2232 }
2233
2234diff -urN nfs-server-2.2beta47/site.h.in nfs-server-2.2beta51/site.h.in
2235--- nfs-server-2.2beta47/site.h.in Thu Jan 1 01:00:00 1970
2236+++ nfs-server-2.2beta51/site.h.in Fri Nov 8 14:45:57 2002
2237@@ -0,0 +1,50 @@
2238+/*
2239+ * Site-specific configuration options generated by BUILD.
2240+ * Please do not edit.
2241+ */
2242+
2243+/*
2244+ * If ENABLE_DEVTAB is defined, nfsd will use the new inode
2245+ * number generation scheme for avoiding inode number clashes
2246+ * on big hard disks.
2247+ */
2248+#undef ENABLE_DEVTAB
2249+
2250+/*
2251+ * If MULTIPLE_SERVER_READWRITE is defined, you will be able
2252+ * to run several nfsd process in parallel servicing all NFS
2253+ * requests.
2254+ */
2255+#define MULTIPLE_SERVERS_READWRITE
2256+
2257+/*
2258+ * If ENABLE_UGID_DAEMON is defined, the real rpc.ugidd is built,
2259+ * nfsd is built to support ugidd queries.
2260+ * Otherwise, a dummy program is created
2261+ */
2262+#undef ENABLE_UGID_DAEMON
2263+
2264+/*
2265+ * If ENABLE_UGID_NIS is defined, nfsd will support user mapping
2266+ * vie the client's NIS server.
2267+ */
2268+#undef ENABLE_UGID_NIS
2269+
2270+/*
2271+ * if HOSTS_ACCESS is defined, ugidd uses host access control
2272+ * provided by libwrap.a from tcp_wrappers
2273+ */
2274+#define HOSTS_ACCESS
2275+
2276+/*
2277+ * Define correct ownership of export control file
2278+ */
2279+#define EXPORTSOWNERUID 0
2280+#define EXPORTSOWNERGID 0
2281+
2282+/*
2283+ * If WANT_LOG_MOUNTS is defined, every mount request will be logged
2284+ * to syslogd with the name of source site and a path that was
2285+ * it requested
2286+ */
2287+#define WANT_LOG_MOUNTS
2288diff -urN nfs-server-2.2beta47/ugidd.c nfs-server-2.2beta51/ugidd.c
2289--- nfs-server-2.2beta47/ugidd.c Wed Dec 10 12:34:16 1997
2290+++ nfs-server-2.2beta51/ugidd.c Fri Nov 8 14:45:36 2002
2291@@ -43,9 +43,7 @@
2292 };
2293
2294 int
2295-main(argc, argv)
2296-int argc;
2297-char **argv;
2298+main(int argc, char **argv)
2299 {
2300 SVCXPRT *transp;
2301 int c, longind;
2302@@ -92,32 +90,11 @@
2303 exit(1);
2304 }
2305
2306- if (!foreground) {
2307- if ((c = fork()) > 0)
2308- exit(0);
2309- if (c < 0) {
2310- fprintf(stderr, "ugidd: cannot fork: %s\n",
2311- strerror(errno));
2312- exit(-1);
2313- }
2314- close(0);
2315- close(1);
2316- close(2);
2317-#ifdef HAVE_SETSID
2318- setsid();
2319-#else
2320- {
2321- int fd;
2322-
2323- if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
2324- ioctl(fd, TIOCNOTTY, (char *) NULL);
2325- close(fd);
2326- }
2327- }
2328-#endif
2329- }
2330-
2331 log_open("ugidd", foreground);
2332+
2333+ /* Become a daemon */
2334+ if (!foreground)
2335+ daemonize();
2336
2337 svc_run();
2338 Dprintf(L_ERROR, "svc_run returned\n");
2339diff -urN nfs-server-2.2beta47/version.c nfs-server-2.2beta51/version.c
2340--- nfs-server-2.2beta47/version.c Wed Nov 10 10:33:33 1999
2341+++ nfs-server-2.2beta51/version.c Fri Nov 8 14:45:36 2002
2342@@ -1 +1 @@
2343-char version[] = "Universal NFS Server 2.2beta47";
2344+char version[] = "Universal NFS Server 2.2beta51";