summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/unfs-server
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
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')
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch2344
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/002-destdir.patch68
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/003-manpages.patch28
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/004-strsignal.patch48
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/005-sys-time.patch29
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch1272
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/007-map.patch78
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/008-configure.patch13
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/009-multirw.patch15
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/010-realpath.patch30
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/011-fno-strict-aliasing.patch13
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/012-nostrip.patch13
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/013-mntpathlen.patch32
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/014-uninitialized.patch12
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/015-setattr.patch26
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/016-makefile.in.patch14
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/017-wrs-dynamic-rpc.patch258
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/018-remove-tcp-wrappers.patch20
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/019-pid-before-fork.patch125
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/020-undefined-chmod-fix.patch18
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/021-nolibwrap.patch20
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/022-add-close-on-exec-descriptors.patch61
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server_2.2beta47.bb71
23 files changed, 4608 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";
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/002-destdir.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/002-destdir.patch
new file mode 100644
index 0000000000..9388332675
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/002-destdir.patch
@@ -0,0 +1,68 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/Makefile.in 2002/11/07 16:56:07 1.1
4+++ nfs-server/Makefile.in 2002/11/07 17:08:41
5@@ -74,10 +74,10 @@
6
7 bindir = $(exec_prefix)/sbin
8 #vardir = $(install_prefix)/var/lib/nfs
9-infodir = $(prefix)/info
10-man5dir = $(prefix)/man/man5
11+infodir = $(prefix)/share/info
12+man5dir = $(prefix)/share/man/man5
13 man5ext = .5
14-man8dir = $(prefix)/man/man8
15+man8dir = $(prefix)/share/man/man8
16 man8ext = .8
17
18 # Prefix to be prepended to each installed RPC program, normally `rpc.'.
19@@ -145,37 +145,37 @@
20 .PHONY: install installdirs
21 install: $(DAEMONS) $(CLIENTS) installdirs
22 @for prog in $(DAEMONS) $(CLIENTS); do \
23- echo "installing $$prog in $(bindir)"; \
24- $(INSTALL_PROGRAM) $$prog $(bindir)/$$prog; \
25+ echo "installing $$prog in $(DESTDIR)$(bindir)"; \
26+ $(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir)/$$prog; \
27 done
28 @for manp in $(MANPAGES5); do \
29- echo "installing $$manp$(man5ext) in $(man5dir)"; \
30+ echo "installing $$manp$(man5ext) in $(DESTDIR)$(man5dir)"; \
31 $(INSTALL_DATA) $(srcdir)/$$manp.man \
32- $(man5dir)/$$manp$(man5ext); \
33+ $(DESTDIR)$(man5dir)/$$manp$(man5ext); \
34 done
35 @for manp in $(MANPAGES8p); do \
36- echo "installing $$manp$(man8ext) in $(man8dir)"; \
37+ echo "installing $$manp$(man8ext) in $(DESTDIR)$(man8dir)"; \
38 $(INSTALL_DATA) $(srcdir)/$$manp.man \
39- $(man8dir)/$$manp$(man8ext); \
40+ $(DESTDIR)$(man8dir)/$$manp$(man8ext); \
41 if [ 'x$(rpcprefix)' != 'x' ]; then \
42 rm -f $(man8dir)/$(rpcprefix)$$manp$(man8ext); \
43 ln -s $$manp$(man8ext) \
44- $(man8dir)/$(rpcprefix)$$manp$(man8ext); \
45+ $(DESTDIR)$(man8dir)/$(rpcprefix)$$manp$(man8ext); \
46 fi; \
47 done
48 @for manp in $(MANPAGES8); do \
49- echo "installing $$manp$(man8ext) in $(man8dir)"; \
50+ echo "installing $$manp$(man8ext) in $(DESTDIR)$(man8dir)"; \
51 $(INSTALL_DATA) $(srcdir)/$$manp.man \
52- $(man8dir)/$$manp$(man8ext); \
53+ $(DESTDIR)$(man8dir)/$$manp$(man8ext); \
54 done
55 @if [ -n "$(DEVTAB_FILE)" -a ! -f "$(DEVTAB_FILE)" ]; then \
56 echo "Initializing $(DEVTAB_FILE)"; \
57- $(INSTALL) -m 755 -d `dirname $(DEVTAB_FILE)`; \
58- echo "# Device mapping for unfsd" > "$(DEVTAB_FILE)"; \
59+ $(INSTALL) -m 755 -d `dirname $(DESTDIR)$(DEVTAB_FILE)`; \
60+ echo "# Device mapping for unfsd" > $(DESTDIR)"$(DEVTAB_FILE)"; \
61 fi
62
63 installdirs:
64- ${srcdir}/mkinstalldirs $(bindir) $(man5dir) $(man8dir)
65+ ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(man5dir) $(DESTDIR)$(man8dir)
66
67 $(rpcprefix)mountd: $(MOUNTD_OBJS) libnfs.a
68 $(CC) $(LDFLAGS) -o $@ $(MOUNTD_OBJS) $(LIBS)
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/003-manpages.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/003-manpages.patch
new file mode 100644
index 0000000000..a17a8dcf55
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/003-manpages.patch
@@ -0,0 +1,28 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/exports.man 2002/11/07 17:15:59 1.1
4+++ nfs-server/exports.man 2002/11/07 17:17:19
5@@ -110,6 +110,14 @@
6 .TP
7 .IR link_absolute
8 Leave all symbolic link as they are. This is the default operation.
9+.SS Anonymous Entries
10+.PP
11+Entries where hosts are not specified are known as anonymous entries. They
12+have different default settings compared to normal entries. The differences
13+include
14+.IR all_squash ,
15+.IR no_secure ", and"
16+.IR ro .
17 .SS User ID Mapping
18 .PP
19 .I nfsd
20@@ -231,7 +239,7 @@
21 # Mapping for client foobar:
22 # remote local
23 uid 0-99 - # squash these
24-uid 100-500 1000 # map 100-500 to 1000-1500
25+uid 100-500 1000 # map 100-500 to 1000-1400
26 gid 0-49 - # squash these
27 gid 50-100 700 # map 50-100 to 700-750
28 .fi
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/004-strsignal.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/004-strsignal.patch
new file mode 100644
index 0000000000..3ac4ed740c
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/004-strsignal.patch
@@ -0,0 +1,48 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/failsafe.c 2002/11/07 17:12:46 1.1
4+++ nfs-server/failsafe.c 2002/11/07 17:15:16
5@@ -10,8 +10,12 @@
6 #include "logging.h"
7 #include "signals.h"
8 #include <sys/wait.h>
9+#ifdef HAVE_STRSIGNAL
10+#include <string.h>
11+#else
12
13 static const char * get_signame(int signo);
14+#endif
15
16 void
17 failsafe(int level, int ncopies)
18@@ -111,9 +115,17 @@
19 pid, running? "Continue" : "Exit");
20 } else {
21 Dprintf(L_WARNING, "failsafe: "
22+#ifdef HAVE_STRSIGNAL
23+ "child %d terminated by: %s. "
24+#else
25 "child %d terminated by %s. "
26+#endif
27 "Restarting.",
28+#ifdef HAVE_STRSIGNAL
29+ pid, strsignal(signo));
30+#else
31 pid, get_signame(signo));
32+#endif
33 child = -1; /* Restart */
34 }
35 } else if (WIFEXITED(status)) {
36@@ -159,6 +171,7 @@
37 /* NOP */
38 }
39
40+#ifndef HAVE_STRSIGNAL
41 static const char *
42 get_signame(int signo)
43 {
44@@ -199,3 +212,4 @@
45 sprintf(namebuf, "signal #%d", signo);
46 return namebuf;
47 }
48+#endif
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/005-sys-time.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/005-sys-time.patch
new file mode 100644
index 0000000000..c21fb05e8d
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/005-sys-time.patch
@@ -0,0 +1,29 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/system.h 2002/11/07 17:10:47 1.1
4+++ nfs-server/system.h 2002/11/07 17:11:53
5@@ -66,20 +66,16 @@
6 # include <grp.h> /* for setgroups */
7 #endif
8
9-#ifdef TIME_WITH_SYS_TIME
10+#ifdef HAVE_SYS_TIME_H
11 # include <sys/time.h>
12 # include <time.h>
13-#else /* not TIME_WITH_SYS_TIME */
14-# ifdef HAVE_SYS_TIME_H
15-# include <sys/time.h>
16-# else /* not HAVE_SYS_TIME_H */
17-# include <time.h>
18+#else /* not HAVE_SYS_TIME_H */
19+# include <time.h>
20 struct timeval {
21 long tv_sec;
22 long tv_usec;
23 };
24-# endif /* not HAVE_SYS_TIME_H */
25-#endif /* not TIME_WITH_SYS_TIME */
26+#endif /* not HAVE_SYS_TIME_H */
27 #ifdef HAVE_SYS_FILE_H
28 # include <sys/file.h>
29 #endif
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch
new file mode 100644
index 0000000000..abdc67476e
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch
@@ -0,0 +1,1272 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/Makefile.in
4+++ nfs-server/Makefile.in 2002/11/08 13:59:16
5@@ -100,7 +100,7 @@
6 utimes.c mkdir.c rename.c getopt.c getopt_long.c \
7 alloca.c mountlist.c xmalloc.c \
8 xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \
9- haccess.c daemon.c signals.c
10+ haccess.c daemon.c signals.c teahash3.c
11 XDRFILES = mount.x nfs_prot.x
12 GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \
13 ugid.h ugid_xdr.c ugid_clnt.c
14@@ -112,7 +112,7 @@
15 MANPAGES8 = showmount
16 MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8)
17 LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \
18- nfsmounted.o faccess.o haccess.o daemon.o \
19+ nfsmounted.o faccess.o haccess.o daemon.o teahash3.o \
20 signals.o @LIBOBJS@ @ALLOCA@
21 OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o
22 NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \
23--- nfs-server/auth.c
24+++ nfs-server/auth.c 2002/11/08 13:59:16
25@@ -83,6 +83,7 @@
26 0, /* read-only */
27 0, /* relative links */
28 0, /* noaccess */
29+ 0, /* hashed inodes */
30 1, /* cross_mounts */
31 1, /* allow setuid */
32 65534, /* default uid */
33@@ -100,6 +101,7 @@
34 0, /* relative links */
35 0, /* noaccess */
36 1, /* cross_mounts */
37+ 0, /* hashed inodes */
38 0, /* allow setuid */
39 65534, /* default uid */
40 65534, /* default gid */
41@@ -991,6 +993,7 @@
42 if (mp == 0) {
43 mp = (nfs_mount*) xmalloc(sizeof(nfs_mount));
44 memset(mp, 0, sizeof(*mp));
45+ mp->mount_dev = 0;
46 mp->origin = cp;
47 mp->client = cp;
48 mp->path = xstrdup(path);
49@@ -1169,6 +1172,8 @@
50 default_options.nobody_gid = anon_gid;
51 anonymous_options.nobody_uid = anon_uid;
52 anonymous_options.nobody_gid = anon_gid;
53+ default_options.cross_mounts = cross_mounts;
54+ default_options.hashed_inodes = hashed_inodes;
55
56 memset(cached_clients, 0, sizeof(cached_clients));
57 cached_next = 0;
58--- nfs-server/auth.h
59+++ nfs-server/auth.h 2002/11/08 13:59:16
60@@ -43,15 +43,16 @@
61
62 typedef struct nfs_options {
63 ugid_mapping_t uidmap; /* uid/gid mapping behavior */
64- int root_squash;
65- int all_squash;
66- int some_squash; /* speed up luid() etc. */
67- int secure_port;
68- int read_only;
69- int link_relative;
70- int noaccess;
71- int cross_mounts;
72- int allow_setuid;
73+ unsigned root_squash : 1;
74+ unsigned all_squash : 1;
75+ unsigned some_squash : 1; /* speed up luid() etc. */
76+ unsigned secure_port : 1;
77+ unsigned read_only : 1;
78+ unsigned link_relative : 1;
79+ unsigned noaccess : 1;
80+ unsigned cross_mounts : 1;
81+ unsigned hashed_inodes : 1;
82+ unsigned allow_setuid : 1;
83 uid_t nobody_uid;
84 gid_t nobody_gid;
85 char * clnt_nisdomain;
86@@ -64,6 +65,7 @@
87 int length;
88 char * path;
89 nfs_options o;
90+ dev_t mount_dev;
91 /* Original NFS client */
92 struct nfs_client * origin;
93 } nfs_mount;
94@@ -121,6 +123,8 @@
95 extern void auth_check_all_netmasks(void);
96 extern void auth_sort_all_mountlists(void);
97 extern void auth_log_all(void);
98+extern int auth_checkdev(nfs_mount *, dev_t dev);
99+extern int auth_checkpathdev(char *, dev_t dev);
100
101 /* This function lets us set our euid/fsuid temporarily */
102 extern void auth_override_uid(uid_t);
103--- nfs-server/auth_clnt.c
104+++ nfs-server/auth_clnt.c 2002/11/08 13:59:16
105@@ -89,6 +89,13 @@
106 return NULL;
107 }
108
109+ if (!mp->o.cross_mounts && !mp->mount_dev) {
110+ struct stat st;
111+ if (!lstat(mp->path, &st) < 0)
112+ return NULL;
113+ mp->mount_dev = st.st_dev;
114+ }
115+
116 /* Check request originated on a privileged port. */
117 if (!allow_non_root && mp->o.secure_port
118 && !SECURE_PORT(svc_getcaller(rqstp->rq_xprt)->sin_port)) {
119@@ -350,3 +357,28 @@
120 return 1;
121 }
122 #endif
123+
124+int auth_checkpathdev(char *path, dev_t dev)
125+{
126+ nfs_mount *mp = auth_match_mount(nfsclient, path);
127+ if (!mp)
128+ return 0;
129+ return auth_checkdev(mp, dev);
130+}
131+
132+int auth_checkdev(nfs_mount *mp, dev_t dev)
133+{
134+ if (!mp->mount_dev)
135+ return 1;
136+ if (mp->mount_dev != dev) {
137+ struct stat st;
138+ /* Restat in case the cd switched */
139+ if (efs_lstat(mp->path, &st) < 0) {
140+ Dprintf(L_ERROR, "Unable to stat mount point %s\n", mp->path);
141+ return 0;
142+ }
143+ mp->mount_dev = st.st_dev;
144+ }
145+ return mp->mount_dev == dev;
146+}
147+
148--- nfs-server/auth_init.c
149+++ nfs-server/auth_init.c 2002/11/08 13:59:16
150@@ -320,6 +320,14 @@
151 /* knfsd compatibility, ignore */;
152 else ifkwd(4, "sync")
153 /* knfsd compatibility, ignore */;
154+ else ifkwd(13, "hashed_inodes")
155+ mp->o.hashed_inodes = 1;
156+ else ifkwd(16, "no_hashed_inodes")
157+ mp->o.hashed_inodes = 0;
158+ else ifkwd(12, "cross_mounts")
159+ mp->o.cross_mounts = 1;
160+ else ifkwd(15, "no_cross_mounts")
161+ mp->o.cross_mounts = 0;
162 else {
163 Dprintf(L_ERROR,
164 "Unknown keyword \"%.*s\" in export file\n",
165--- nfs-server/exports.man
166+++ nfs-server/exports.man 2002/11/08 13:59:16
167@@ -208,6 +208,17 @@
168 .IR no_all_squash ,
169 which is the default setting.
170 .TP
171+.IR hashed_inodes
172+Use a special scheme to generate inode numbers that may work better with
173+reiserfs filesystems.
174+.IR no_hashed_inodes
175+which uses a direct mapping is the default.
176+.TP
177+.IR cross_mounts
178+Do not cross mount points in exports. Turning this off with
179+.IR no_cross_mounts
180+avoids inode number space conflicts when there are too many files.
181+.TP
182 .IR map_daemon
183 This option turns on dynamic uid/gid mapping. Each uid in an NFS request
184 will be translated to the equivalent server uid, and each uid in an
185--- nfs-server/fh.c
186+++ nfs-server/fh.c 2002/11/08 14:11:31
187@@ -4,8 +4,9 @@
188 *
189 * Interfaces:
190 * pseudo_inode
191- * mostly used internally, but also called from unfsd.c
192- * when reporting directory contents.
193+ * mostly used internally, for hash tables
194+ * visible_inode
195+ * generate visible inode shown to the client in the fattr.
196 * fh_init
197 * Initializes the queues and 'flush' timer
198 * fh_pr
199@@ -47,6 +48,8 @@
200 * Note: the original code mistakenly assumes that the overall path
201 * length remains within the value given by PATH_MAX... that leads
202 * to interesting buffer overflows all over the place.
203+ *
204+ * Depends that dev_t only uses 16bits.
205 */
206
207 #include <assert.h>
208@@ -137,9 +140,9 @@
209 };
210
211 /* Forward declared local functions */
212-static psi_t path_psi(char *, nfsstat *, struct stat *, int);
213+static psi_t path_psi(char *, nfsstat *, struct stat *, int, int *);
214 static psi_t path_psi_m(char *, nfsstat *, struct stat *,
215- struct stat *, int);
216+ struct stat *, int, int *);
217 static int fh_flush_fds(void);
218 static char * fh_dump(svc_fh *);
219 static void fh_insert_fdcache(fhcache *fhc);
220@@ -173,19 +176,22 @@
221 fh_list_size++;
222
223 /* Insert into hash tab. */
224- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]);
225+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]);
226 fhc->hash_next = *hash_slot;
227 *hash_slot = fhc;
228 }
229
230 static fhcache *
231-fh_lookup(psi_t psi)
232+fh_lookup(ino_t ino, dev_t dev)
233 {
234 register fhcache *fhc;
235
236- fhc = fh_hashed[psi % HASH_TAB_SIZE];
237- while (fhc != NULL && fhc->h.psi != psi)
238+ fhc = fh_hashed[pseudo_inode(ino,dev) % HASH_TAB_SIZE];
239+ while (fhc != NULL) {
240+ if (fhc->h.ino == ino && fhc->h.dev == dev)
241+ break;
242 fhc = fhc->hash_next;
243+ }
244 return (fhc);
245 }
246
247@@ -193,7 +199,8 @@
248 fh_insert_fdcache(fhcache *fhc)
249 {
250 #ifdef FHTRACE
251- Dprintf(D_FHTRACE, "insert fh %x into fdcache @%d\n", fhc->h.psi, fhc->fd);
252+ Dprintf(D_FHTRACE, "insert fh %x,%x into fdcache @%d\n",
253+ fhc->h.ino, fhc->h.dev, fhc->fd);
254 if (fhc->fd < 0) {
255 fh_complain("fd cache bug: bad fd", fhc);
256 return;
257@@ -289,8 +296,9 @@
258 #endif
259
260 Dprintf(D_FHTRACE|D_FHCACHE,
261- "fh_delete: deleting handle %x ('%s', fd=%d)\n",
262- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->fd);
263+ "fh_delete: deleting handle %x [%x,%x] ('%s', fd=%d)\n",
264+ fhc, fhc->h.dev, fhc->h.ino, fhc->path ? fhc->path : "<unnamed>",
265+ fhc->fd);
266
267 /* Remove from current posn */
268 fhc->prev->next = fhc->next;
269@@ -298,7 +306,7 @@
270 fh_list_size--;
271
272 /* Remove from hash tab */
273- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]);
274+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]);
275 while (*hash_slot != NULL && *hash_slot != fhc)
276 hash_slot = &((*hash_slot)->hash_next);
277 if (*hash_slot == NULL)
278@@ -528,6 +536,7 @@
279 index -= 8;
280 }
281
282+#if 0
283 /* If we have an XXL inode number, spew out warning (but at most
284 * once a second) */
285 if (inode & ~mask) {
286@@ -541,14 +550,34 @@
287 }
288 inode &= mask;
289 }
290-
291+#endif
292 return (psi_t) (prefix | inode);
293 #endif
294 }
295
296+/* Inode as handed out by attr calls. */
297+psi_t
298+visible_inode(ino_t ino, dev_t dev, nfs_mount *mount)
299+{
300+ if (!mount->o.cross_mounts)
301+ return ino;
302+
303+ if (mount->o.hashed_inodes) {
304+ extern __u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len);
305+
306+ struct {
307+ ino_t ino;
308+ dev_t dev;
309+ } tup = { ino,dev };
310+ return teahash3((char *) &tup, sizeof tup);
311+ }
312+
313+ return pseudo_inode(ino, dev);
314+}
315+
316 #if 1
317 static char *
318-fh_buildpath(svc_fh *h)
319+fh_buildpath(svc_fh *h, dev_t basedev)
320 {
321 char pathbuf[PATH_MAX + NAME_MAX + 1], *path;
322 long cookie_stack[HP_LEN + 1];
323@@ -565,13 +594,17 @@
324
325 if (efs_stat("/", &sbuf) < 0)
326 return (NULL);
327- psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev);
328 if (h->hash_path[0] == 0) {
329- if (psi != h->psi)
330- return (NULL);
331- return xstrdup("/");
332+ if (sbuf.st_ino == h->ino && sbuf.st_dev == h->dev)
333+ ;
334+ else
335+ return NULL;
336+ strcpy(pathbuf,"/");
337+ path = xstrdup(pathbuf);
338+ return (path);
339 }
340
341+ psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev);
342 if (hash_psi(psi) != h->hash_path[1])
343 return (NULL);
344
345@@ -599,11 +632,18 @@
346
347 psi = pseudo_inode(dp->d_ino, sbuf.st_dev);
348 if (i == h->hash_path[0] + 1) {
349- if (psi != h->psi)
350+ if (sbuf.st_dev != h->dev || dp->d_ino != h->ino)
351 continue;
352 /* GOT IT */
353 strcpy(pathbuf + pathlen, dp->d_name);
354- path = xstrdup(pathbuf);
355+ if (!basedev || sbuf.st_dev == basedev ||
356+ auth_checkpathdev(pathbuf, sbuf.st_dev)) {
357+ path = xstrdup(pathbuf);
358+ } else {
359+ dprintf(L_ERROR, "fh_buildpath: basedev %x != dev %x for %s\n",
360+ (unsigned)basedev,(unsigned)sbuf.st_dev,pathbuf);
361+ path = NULL;
362+ }
363 efs_closedir(dir);
364 auth_override_uid(auth_uid);
365 return (path);
366@@ -754,16 +794,16 @@
367 #endif
368
369 static psi_t
370-path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid)
371+path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid, int *mp)
372 {
373 struct stat smounted;
374
375- return path_psi_m(path, status, sbp, &smounted, svalid);
376+ return path_psi_m(path, status, sbp, &smounted, svalid, mp);
377 }
378
379 static psi_t
380 path_psi_m(char *path, nfsstat *status,
381- struct stat *sbp, struct stat *mbp, int svalid)
382+ struct stat *sbp, struct stat *mbp, int svalid, int *mp)
383 {
384 struct stat sbuf, ddbuf;
385
386@@ -815,6 +855,8 @@
387 DIR *dirp;
388 struct dirent *dp;
389
390+ if (mp) *mp = 1;
391+
392 errno = 0;
393 dirp = efs_opendir(dname);
394 fname[-1] = '/'; /* Restore path */
395@@ -860,9 +902,70 @@
396 }
397
398 fhcache *
399-fh_find(svc_fh *h, int mode)
400+fh_newfh(svc_fh *h, int mode, dev_t basedev)
401+{
402+ fhcache *fhc, *flush;
403+
404+ ex_state = active;
405+ for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) {
406+ /* Don't flush current head. */
407+ if (flush == &fh_head)
408+ break;
409+ fhc = flush->prev;
410+ fh_delete(flush);
411+ }
412+ fhc = (fhcache *) xmalloc(sizeof *fhc);
413+ if (mode == FHFIND_FCREATE) {
414+ /* File will be created */
415+ fhc->path = NULL;
416+ } else {
417+ /* File must exist. Attempt to construct from hash_path */
418+ char *path;
419+
420+ if ((path = fh_buildpath(h, basedev)) == NULL) {
421+#ifdef FHTRACE
422+ Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n");
423+ Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
424+#endif
425+ free(fhc);
426+ ex_state = inactive;
427+ return NULL;
428+ }
429+ fhc->path = path;
430+ }
431+ fhc->flags = 0;
432+ if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) {
433+ if (re_export && nfsmounted(fhc->path, &fhc->attrs))
434+ fhc->flags |= FHC_NFSMOUNTED;
435+ fhc->flags |= FHC_ATTRVALID;
436+ }
437+ fhc->fd = -1;
438+ fhc->last_used = curtime;
439+ fhc->h = *h;
440+ fhc->last_clnt = NULL;
441+ fhc->last_mount = NULL;
442+ fhc->last_uid = (uid_t)-1;
443+ fhc->fd_next = fhc->fd_prev = NULL;
444+ fh_inserthead(fhc);
445+ Dprintf(D_FHCACHE,
446+ "fh_find: created new handle %x (path `%s' ino:%x dev:%x)\n",
447+ fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.ino, fhc->h.dev);
448+ ex_state = inactive;
449+ if (fh_list_size > FH_CACHE_LIMIT)
450+ flush_cache(0);
451+#ifdef FHTRACE
452+ if (fhc->h.hash_path[0] == 0xFF) {
453+ Dprintf(L_ERROR, "newly created fh instantly flushed?!");
454+ return NULL;
455+ }
456+#endif
457+ return (fhc);
458+}
459+
460+fhcache *
461+fh_find(svc_fh *h, int mode, dev_t basedev)
462 {
463- register fhcache *fhc, *flush;
464+ register fhcache *fhc;
465 int check;
466
467 check = (mode & FHFIND_CHECK);
468@@ -877,12 +980,12 @@
469
470 ex_state = active;
471 time(&curtime);
472- while ((fhc = fh_lookup(h->psi)) != NULL) {
473+ while ((fhc = fh_lookup(h->ino,h->dev)) != NULL) {
474 struct stat sbuf, *s = NULL;
475 nfsstat dummy;
476
477- Dprintf(D_FHCACHE, "fh_find: psi=%lx... found '%s', fd=%d\n",
478- (unsigned long) h->psi,
479+ Dprintf(D_FHCACHE, "fh_find: (%u,%u)... found '%s', fd=%d\n",
480+ h->ino, h->dev,
481 fhc->path ? fhc->path : "<unnamed>",
482 fhc->fd);
483
484@@ -905,6 +1008,7 @@
485 Dprintf(D_FHTRACE,
486 "fh_find: stale fh: lstat: %m\n");
487 } else {
488+ int mp = 0;
489 /* If device/ino don't match, fhc->path may
490 * be a mount point (hence lstat() returns
491 * a different inode number than the readdir()
492@@ -915,19 +1019,26 @@
493
494 /* Get the dev/ino of the underlying
495 * mount point. */
496- path_psi(fhc->path, &dummy, s, 1);
497- if (fh_attrmatch(fhc, s))
498- goto fh_return;
499+ if (path_psi(fhc->path, &dummy, s, 1, &mp) &&
500+ fh_attrmatch(fhc, s)) {
501+ if (!mp)
502+ Dprintf(D_FHTRACE,"fh_find: should be mount point %x,%x\n",
503+ h->dev,h->ino);
504+
505+ }
506
507- Dprintf(D_FHTRACE, "fh_find: stale fh: %lx",
508- (unsigned long) h->psi);
509+ Dprintf(D_FHTRACE, "fh_find: stale fh: "
510+ "dev/ino %x/%lx ino:%x dev:%x",
511+ s->st_dev, s->st_ino,
512+ (unsigned)h->ino, (unsigned)h->dev);
513 }
514
515 fh_discard:
516 #ifdef FHTRACE
517 Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
518 #endif
519- Dprintf(D_FHCACHE, "fh_find: delete cached handle\n");
520+ Dprintf(D_FHCACHE, "fh_find: delete cached handle %x,%x <%x>\n",
521+ fhc->h.dev,fhc->h.ino,fhc->path ? fhc->path : "no path");
522 fh_delete(fhc);
523 break;
524 }
525@@ -947,88 +1058,13 @@
526 return (fhc);
527 }
528
529- Dprintf(D_FHCACHE, "fh_find: psi=%lx... not found\n",
530- (unsigned long) h->psi);
531-
532- if (mode == FHFIND_FCACHED) {
533- ex_state = inactive;
534- return NULL;
535- }
536-
537- for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) {
538- /* Don't flush current head. */
539- if (flush == &fh_head)
540- break;
541- fhc = flush->prev;
542- fh_delete(flush);
543- }
544-
545- fhc = (fhcache *) xmalloc(sizeof *fhc);
546- if (mode == FHFIND_FCREATE) {
547- /* File will be created */
548- fhc->path = NULL;
549- } else {
550- /* File must exist. Attempt to construct from hash_path */
551- char *path;
552-
553- if ((path = fh_buildpath(h)) == NULL) {
554-#ifdef FHTRACE
555- Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n");
556- Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
557-#endif
558- free(fhc);
559- ex_state = inactive;
560- return NULL;
561- }
562- fhc->path = path;
563- }
564-
565- fhc->flags = 0;
566- if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) {
567- if (nfsmounted(fhc->path, &fhc->attrs)) {
568- fhc->flags |= FHC_NFSMOUNTED;
569-#if 0
570- /* We must allow the client to send us the
571- * file handle for the NFS mount point itself,
572- * but not for entries within an NFS mount.
573- * XXX: needs fixing.
574- */
575- if (!re_export) {
576- Dprintf(D_FHTRACE,
577- "Attempt to use %s (non-exportable)\n",
578- fhc->path);
579- free(fhc);
580- ex_state = inactive;
581- return NULL;
582- }
583-#endif
584- }
585- fhc->flags |= FHC_ATTRVALID;
586- fhc->dev = fhc->attrs.st_dev;
587- fhc->ino = fhc->attrs.st_ino;
588- fhc->type = fhc->attrs.st_mode & S_IFMT;
589- }
590- fhc->fd = -1;
591- fhc->last_used = curtime;
592- fhc->h = *h;
593- fhc->last_clnt = NULL;
594- fhc->last_mount = NULL;
595- fhc->last_uid = (uid_t)-1;
596- fhc->fd_next = fhc->fd_prev = NULL;
597- fh_inserthead(fhc);
598- Dprintf(D_FHCACHE,
599- "fh_find: created new handle %x (path `%s' psi %08x)\n",
600- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.psi);
601 ex_state = inactive;
602- if (fh_list_size > FH_CACHE_LIMIT)
603- flush_cache(0);
604-#ifdef FHTRACE
605- if (fhc->h.hash_path[0] == 0xFF) {
606- Dprintf(L_ERROR, "newly created fh instantly flushed?!");
607+
608+ Dprintf(D_FHCACHE, "fh_find: (%u,%u) ... not found\n",
609+ h->ino, h->dev);
610+ if (mode == FHFIND_FCACHED)
611 return NULL;
612- }
613-#endif
614- return (fhc);
615+ return fh_newfh(h, mode, basedev);
616 }
617
618 /*
619@@ -1040,7 +1076,7 @@
620 {
621 fhcache *h;
622
623- if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED)) == NULL)
624+ if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED, 0)) == NULL)
625 return fh_dump((svc_fh *) fh);
626 return (h->path);
627 }
628@@ -1050,10 +1086,10 @@
629 {
630 static char buf[65];
631 char *sp;
632- int i, n = fh->hash_path[0];
633+ int i, n = fh->hash_path[0], l;
634
635- sprintf(buf, "%08x %02x ", fh->psi, fh->hash_path[0]);
636- for (i = 1, sp = buf + 12; i <= n && i < HP_LEN; i++, sp += 2)
637+ l = sprintf(buf, "%08x %04x %02x ", fh->ino, fh->dev, fh->hash_path[0]);
638+ for (i = 1, sp = buf + l; i <= n && i < HP_LEN; i++, sp += 2)
639 sprintf(sp, "%02x", fh->hash_path[i]);
640 return buf;
641 }
642@@ -1082,7 +1118,7 @@
643
644 memset(&key, 0, sizeof(key));
645 status = NFS_OK;
646- if ((psi = path_psi("/", &status, &stb, 0)) == 0)
647+ if ((psi = path_psi("/", &status, &stb, 0, NULL)) == 0)
648 return ((int) status);
649
650 s = path;
651@@ -1091,7 +1127,7 @@
652 return ((int) NFSERR_NAMETOOLONG);
653 key.hash_path[key.hash_path[0]] = hash_psi(psi);
654 *s = '\0';
655- if ((psi = path_psi(path, &status, &stb, 0)) == 0)
656+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0)
657 return ((int) status);
658 *s = '/';
659 }
660@@ -1099,11 +1135,12 @@
661 if (++(key.hash_path[0]) >= HP_LEN)
662 return ((int) NFSERR_NAMETOOLONG);
663 key.hash_path[key.hash_path[0]] = hash_psi(psi);
664- if ((psi = path_psi(path, &status, &stb, 0)) == 0)
665+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0)
666 return ((int) status);
667 }
668- key.psi = psi;
669- h = fh_find(&key, FHFIND_FCREATE);
670+ key.dev = stb.st_dev;
671+ key.ino = stb.st_ino;
672+ h = fh_find(&key, FHFIND_FCREATE, 0);
673
674 #ifdef FHTRACE
675 if (!h)
676@@ -1123,6 +1160,7 @@
677 return ((int) status);
678 }
679
680+#if 0
681 char *
682 fh_path(nfs_fh *fh, nfsstat *status)
683 {
684@@ -1135,6 +1173,7 @@
685 *status = NFS_OK;
686 return (h->path);
687 }
688+#endif
689
690 nfs_fh *
691 fh_handle(fhcache *h)
692@@ -1349,7 +1388,7 @@
693 if (sbp == NULL)
694 sbp = &sbuf;
695
696- if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS)) == NULL)
697+ if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS, 0)) == NULL)
698 return NFSERR_STALE;
699
700 /*
701@@ -1419,8 +1458,22 @@
702
703 *new_fh = dopa->dir;
704 key = (svc_fh *) new_fh;
705- if ((key->psi = path_psi_m(pathbuf, &ret, sbp, &smount, 0)) == 0)
706+
707+ if (path_psi_m(pathbuf, &ret, sbp, &smount, 0, NULL) == 0)
708 return (ret);
709+ key->ino = sbp->st_ino;
710+ key->dev = sbp->st_dev;
711+
712+ if (sbp->st_dev != dirh->h.dev) {
713+ nfs_mount *mp = dirh->last_mount;
714+ if (!mp)
715+ Dprintf(L_ERROR, "no last mount in fh_compose for %s\n", pathbuf);
716+ else if (auth_checkdev(mp, sbp->st_dev) == 0) {
717+ Dprintf(L_ERROR, "access to no cross path below mountpoint (<%s>, %x<->%x)\n",
718+ pathbuf, mp->mount_dev, sbp->st_dev);
719+ return NFSERR_STALE;
720+ }
721+ }
722
723 if (is_dd) {
724 /* Don't cd .. from root, or mysterious ailments will
725@@ -1430,11 +1483,12 @@
726 } else {
727 if (++(key->hash_path[0]) >= HP_LEN)
728 return NFSERR_NAMETOOLONG;
729- key->hash_path[key->hash_path[0]] = hash_psi(dirh->h.psi);
730+ key->hash_path[key->hash_path[0]] = hash_psi(pseudo_inode(dirh->h.ino,
731+ dirh->h.dev));
732 }
733 /* FIXME: when crossing a mount point, we'll find the real
734 * dev/ino in sbp and can store it in h... */
735- h = fh_find(key, FHFIND_FCREATE);
736+ h = fh_find(key, FHFIND_FCREATE, 0);
737
738 #ifdef FHTRACE
739 if (h == NULL)
740@@ -1456,7 +1510,7 @@
741 /* We must have cached an old file under the same inode # */
742 Dprintf(D_FHTRACE, "Disposing of fh with bad path.\n");
743 fh_delete(h);
744- h = fh_find(key, FHFIND_FCREATE);
745+ h = fh_find(key, FHFIND_FCREATE, dirh->last_mount ? dirh->last_mount->mount_dev : 0);
746 #ifdef FHTRACE
747 if (!h) return NFSERR_STALE;
748 #endif
749@@ -1511,12 +1565,14 @@
750 return (NFS_OK);
751 }
752
753+#if 0
754 psi_t
755 fh_psi(nfs_fh *fh)
756 {
757 svc_fh *h = (svc_fh *) fh;
758 return (h->psi);
759 }
760+#endif
761
762 void
763 fh_remove(char *path)
764@@ -1524,12 +1580,13 @@
765 psi_t psi;
766 nfsstat status;
767 fhcache *fhc;
768+ struct stat st;
769
770- psi = path_psi(path, &status, NULL, 0);
771+ psi = path_psi(path, &status, &st, 0, NULL);
772 if (psi == 0)
773 return;
774 ex_state = active;
775- fhc = fh_lookup(psi);
776+ fhc = fh_lookup(st.st_ino,st.st_dev);
777 if (fhc != NULL)
778 fh_delete(fhc);
779
780@@ -1634,6 +1691,11 @@
781 fh_init(void)
782 {
783 static int initialized = 0;
784+
785+ if (sizeof(svc_fh) > 32) {
786+ fprintf(stderr, "filehandle wrong size %d\n", sizeof(svc_fh));
787+ exit(10);
788+ }
789
790 if (initialized)
791 return;
792--- nfs-server/fh.h
793+++ nfs-server/fh.h 2002/11/08 13:59:16
794@@ -20,6 +20,7 @@
795 #define FHC_XONLY_PATH 001 /* NOT USED ANYMORE */
796 #define FHC_ATTRVALID 002
797 #define FHC_NFSMOUNTED 004
798+#define FHC_CROSS 010
799
800 /* Modes for fh_find */
801 #define FHFIND_FEXISTS 0 /* file must exist */
802@@ -65,11 +66,12 @@
803 *
804 * hash_path[hash_path[0]+1] ... hash_path[HP_LEN-1] == 0
805 */
806-#define HP_LEN (NFS_FHSIZE - sizeof(psi_t))
807+#define HP_LEN (NFS_FHSIZE-sizeof(u_int32_t)-sizeof(u_int16_t))
808 typedef struct {
809- psi_t psi;
810+ u_int32_t ino;
811+ u_int16_t dev;
812 __u8 hash_path[HP_LEN];
813-} svc_fh;
814+} svc_fh __attribute__((packed));
815
816 typedef enum { inactive, active } mutex;
817
818@@ -100,6 +102,7 @@
819
820 /* These are fixed during the lifetime of this object */
821 svc_fh h;
822+ psi_t psi;
823 dev_t dev;
824 ino_t ino;
825 mode_t type; /* st_mode & S_IFMT */
826@@ -122,10 +125,11 @@
827 /* Global function prototypes. */
828 extern nfsstat nfs_errno(void);
829 extern psi_t pseudo_inode(ino_t inode, dev_t dev);
830+extern psi_t visible_inode(ino_t inode, dev_t dev, nfs_mount *);
831 extern void fh_init(void);
832 extern char *fh_pr(nfs_fh *fh);
833 extern int fh_create(nfs_fh *fh, char *path);
834-extern fhcache *fh_find(svc_fh *h, int create);
835+extern fhcache *fh_find(svc_fh *h, int create, dev_t basedev);
836 extern char *fh_path(nfs_fh *fh, nfsstat *status);
837 extern int path_open(char *path, int omode, int perm);
838 extern int fh_fd(fhcache *fhc, nfsstat *status, int omode);
839@@ -139,6 +143,7 @@
840 extern void fh_flush(int force);
841 extern RETSIGTYPE flush_cache(int sig);
842 extern int nfsmounted(const char *path, struct stat *sbp);
843+extern fhcache *fh_newfh(svc_fh *fh, int mode, dev_t basedev);
844
845 #ifdef ENABLE_DEVTAB
846 extern unsigned int devtab_index(dev_t);
847--- nfs-server/getattr.c
848+++ nfs-server/getattr.c 2002/11/08 13:59:16
849@@ -43,7 +43,7 @@
850 {
851 fhcache *fhc;
852
853- if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS)) == NULL) {
854+ if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS, 0)) == NULL) {
855 Dprintf(D_CALL, "getattr: failed! No such file.\n");
856 return (NFSERR_STALE);
857 }
858@@ -103,18 +103,8 @@
859 #else
860 attr->blocks = st_blocks(s);
861 #endif
862-#if 0
863- if (nfsmount->o.cross_mounts) {
864- attr->fsid = 1;
865- attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
866- } else {
867- attr->fsid = s->st_dev;
868- attr->fileid = covered_ino(fhc->path);
869- }
870-#else
871- attr->fsid = 1;
872- attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
873-#endif
874+ attr->fsid = 1; // XXX
875+ attr->fileid = visible_inode(fhc->h.ino, fhc->h.dev, nfsmount);
876
877 /* This may be needed by some Suns... testing */
878 #define MINTIME (24 * 2600)
879--- nfs-server/mountd.c
880+++ nfs-server/mountd.c 2002/11/08 13:59:16
881@@ -36,6 +36,8 @@
882 #include "signals.h"
883 #include <rpc/pmap_clnt.h>
884
885+int cross_mounts = 1;
886+int hashed_inodes; /* dummy */
887
888 static void usage(FILE *, int);
889 static void terminate(void);
890@@ -58,9 +60,9 @@
891 { "no-spoof-trace", 0, 0, 't' },
892 { "version", 0, 0, 'v' },
893 { "fail-safe", optional_argument, 0, 'z' },
894+ { "no-cross-mounts", 0, 0, 'x' },
895 { "no-tcp", 0, 0, OPT_NOTCP },
896 { "loopback-only", 0, 0, OPT_LOOPBACK },
897-
898 { NULL, 0, 0, 0 }
899 };
900 static const char * shortopts = "Fd:f:hnpP:rtvz::";
901@@ -80,6 +82,7 @@
902 int need_reinit = 0;
903 int need_flush = 0;
904 extern char version[];
905+nfs_client *nfsclient; /* dummy */
906
907 /*
908 * NULL
909@@ -319,6 +322,9 @@
910 opterr = 0;
911 while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF)
912 switch (c) {
913+ case 'x':
914+ cross_mounts = 0;
915+ break;
916 case 'F':
917 foreground = 1;
918 break;
919@@ -444,7 +450,7 @@
920 program_name);
921 fprintf(fp, " [--debug kind] [--help] [--allow-non-root]\n");
922 fprintf(fp, " [--promiscuous] [--version] [--port portnum]\n");
923- fprintf(fp, " [--exports-file=file]\n");
924+ fprintf(fp, " [--exports-file=file] [--no-cross-mounts]\n");
925 exit(n);
926 }
927
928--- nfs-server/nfsd.c
929+++ nfs-server/nfsd.c 2002/11/08 14:20:57
930@@ -72,7 +72,7 @@
931 { "no-tcp", 0, 0, OPT_NOTCP },
932 { "udp-only", 0, 0, OPT_NOTCP },
933 { "loopback-only", 0, 0, OPT_LOOPBACK },
934-
935+ { "hashed-inodes", 0, 0, 'I' },
936 { NULL, 0, 0, 0 }
937 };
938 static const char * shortopts = "a:d:Ff:hlnP:prR:tvz::";
939@@ -91,6 +91,7 @@
940 int need_flush = 0; /* flush fh cache */
941 int read_only = 0; /* Global ro forced */
942 int cross_mounts = 1; /* Transparently cross mnts */
943+int hashed_inodes = 0;
944 int log_transfers = 0; /* Log transfers */
945 static svc_fh public_fh; /* Public NFSv2 FH */
946
947@@ -122,12 +123,17 @@
948 {
949 static int total = 0, cached = 0;
950 fhcache *fhc;
951+ int newfh = 0;
952
953- /* Try to map FH. If not cached, reconstruct path with root priv */
954- fhc = fh_find((svc_fh *)fh, FHFIND_FEXISTS|FHFIND_CHECK);
955- if (fhc == NULL) {
956- *statp = NFSERR_STALE;
957- return NULL;
958+ /* Try to map FH. */
959+ fhc = fh_find((svc_fh *)fh, FHFIND_FCACHED|FHFIND_CHECK, 0);
960+ if (!fhc) {
961+ fhc = fh_newfh((svc_fh*)fh, FHFIND_FEXISTS|FHFIND_CHECK, 0);
962+ if (!fhc) {
963+ *statp = NFSERR_STALE;
964+ return NULL;
965+ }
966+ newfh = 1;
967 }
968
969 /* Try to retrieve last client who accessed this fh */
970@@ -163,6 +169,16 @@
971 100 * (double) cached / total);
972 */
973
974+ /* Trust the crossmount check of the parent directory for creates */
975+ if (newfh &&
976+ (fhc->flags & FHC_ATTRVALID) &&
977+ auth_checkdev(nfsmount, fhc->attrs.st_dev) == 0) {
978+ Dprintf(L_ERROR, "auth_fh: fh crossed mount %s: %x<->%x\n",
979+ fhc->path ? fhc->path : "???", nfsmount->mount_dev, fhc->attrs.st_dev);
980+ *statp = NFSERR_STALE; /* or ACCES? */
981+ return NULL;
982+ }
983+
984 if (nfsmount->o.noaccess &&
985 ((flags & CHK_NOACCESS) || strcmp(nfsmount->path, fhc->path))) {
986 struct in_addr addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
987@@ -195,6 +211,7 @@
988 fhcache *fhc;
989 nfsstat status;
990 char *path = buf, *sp;
991+ struct stat st;
992
993 /* Authenticate directory file handle */
994 if ((fhc = auth_fh(rqstp, &dopa->dir, &status, flags)) == NULL)
995@@ -219,6 +236,9 @@
996 if ((nfsmount = auth_path(nfsclient, rqstp, path)) == NULL)
997 return NFSERR_ACCES;
998
999+ if (efs_lstat(path, &st) >= 0 && !auth_checkdev(nfsmount, st.st_dev))
1000+ return NFSERR_ACCES;
1001+
1002 /* XXX: really need to call it again here?
1003 * Already invoked in auth_fh */
1004 if (!auth_user(nfsmount, rqstp))
1005@@ -318,7 +338,8 @@
1006 int ispublic = 0;
1007
1008 /* First check whether this is the public FH */
1009- if (((svc_fh *) fh)->psi == 0 && !memcmp(fh, &public_fh, FHSIZE)) {
1010+ if (((svc_fh *) fh)->dev == 0 && ((svc_fh*)fh)->ino == 0 &&
1011+ !memcmp(fh, &public_fh, FHSIZE)) {
1012 if (public_root_path == NULL)
1013 return NFSERR_ACCES;
1014 memcpy(&argp->dir, &public_root, NFS_FHSIZE);
1015@@ -333,6 +354,7 @@
1016 if (!(fhc = auth_fh(rqstp, fh, &status, CHK_READ)))
1017 return status;
1018
1019+ /* FIXME: does too many stats */
1020 status = fh_compose(argp, &dp->file, &sbuf, -1, -1, ispublic);
1021 if (status != NFS_OK)
1022 return status;
1023@@ -896,6 +918,9 @@
1024 errno = 0;
1025 if (efs_lstat(h->path, &sbuf) < 0 || !(S_ISDIR(sbuf.st_mode)))
1026 return (NFSERR_NOTDIR);
1027+ if (!auth_checkdev(h->last_mount, sbuf.st_dev))
1028+ dotsonly = 1;
1029+
1030 if ((dirp = efs_opendir(h->path)) == NULL)
1031 return ((errno ? nfs_errno() : NFSERR_NAMETOOLONG));
1032
1033@@ -923,7 +948,7 @@
1034 }
1035
1036 e = *ep = (entry *) xmalloc(sizeof(entry));
1037- e->fileid = pseudo_inode(dp->d_ino, sbuf.st_dev);
1038+ e->fileid = visible_inode(dp->d_ino, sbuf.st_dev, h->last_mount);
1039 e->name = xmalloc(NLENGTH(dp) + 1);
1040 strcpy(e->name, dp->d_name);
1041 dloc = htonl(efs_telldir(dirp));
1042@@ -1033,6 +1058,9 @@
1043 case 'x':
1044 cross_mounts = 0;
1045 break;
1046+ case 'I':
1047+ hashed_inodes = 1;
1048+ break;
1049 case 'z':
1050 if (optarg)
1051 failsafe_level = atoi(optarg);
1052@@ -1189,7 +1217,7 @@
1053 " [--debug kind] [--exports-file=file] [--port port]\n"
1054 " [--allow-non-root] [--promiscuous] [--version] [--foreground]\n"
1055 " [--re-export] [--log-transfers] [--public-root path]\n"
1056-" [--no-spoof-trace] [--help]\n"
1057+" [--no-spoof-trace] [--no-cross-mounts] [--hashed-inodes] [--help]\n"
1058 , program_name);
1059 exit(n);
1060 }
1061--- nfs-server/nfsd.h
1062+++ nfs-server/nfsd.h 2002/11/08 13:59:16
1063@@ -51,6 +51,7 @@
1064 extern int need_reinit;
1065 extern int need_flush;
1066 extern time_t nfs_dispatch_time;
1067+extern int cross_mounts, hashed_inodes;
1068
1069 /* Include the other module definitions. */
1070 #include "auth.h"
1071--- nfs-server/setattr.c
1072+++ nfs-server/setattr.c 2002/11/08 13:59:16
1073@@ -17,6 +17,7 @@
1074
1075 #define IGNORE_TIME ((unsigned int) -1)
1076
1077+#if 0
1078 /*
1079 * Set file attributes based on file handle
1080 */
1081@@ -33,6 +34,7 @@
1082 }
1083 return setattr(path, attr, s, rqstp, flags);
1084 }
1085+#endif
1086
1087 /*
1088 * Set file attributes given the path. The flags argument
1089--- nfs-server/teahash3.c
1090+++ nfs-server/teahash3.c 2002/11/08 13:59:16
1091@@ -0,0 +1,168 @@
1092+/* Taken from the reiserfs source code and hacked slightly by AK.
1093+ * This is GPLed. */
1094+/*
1095+ * Keyed 32-bit hash function using TEA in a Davis-Meyer function
1096+ * H0 = Key
1097+ * Hi = E Mi(Hi-1) + Hi-1
1098+ *
1099+ * (see Applied Cryptography, 2nd edition, p448).
1100+ *
1101+ * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
1102+ *
1103+ * Jeremy has agreed to the contents of reiserfs/README. -Hans
1104+ */
1105+
1106+#include <assert.h>
1107+
1108+#if 0
1109+/* OK for Intel */
1110+typedef unsigned long u32;
1111+typedef const unsigned char u8;
1112+#else
1113+#include <inttypes.h>
1114+typedef uint32_t u32;
1115+typedef uint8_t u8;
1116+#endif
1117+
1118+
1119+#define DELTA 0x9E3779B9
1120+#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
1121+#define PARTROUNDS 6 /* 6 gets complete mixing */
1122+
1123+/* a, b, c, d - data; h0, h1 - accumulated hash */
1124+#define TEACORE(rounds) \
1125+ do { \
1126+ u32 sum = 0; \
1127+ int n = rounds; \
1128+ u32 b0, b1; \
1129+ \
1130+ b0 = h0; \
1131+ b1 = h1; \
1132+ \
1133+ do \
1134+ { \
1135+ sum += DELTA; \
1136+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); \
1137+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); \
1138+ } while(--n); \
1139+ \
1140+ h0 += b0; \
1141+ h1 += b1; \
1142+ } while(0)
1143+
1144+u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len)
1145+{
1146+ u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3};
1147+
1148+ u32 h0 = k[0], h1 = k[1];
1149+ u32 a, b, c, d;
1150+ u32 pad;
1151+ int i;
1152+
1153+ assert(len >= 0 && len < 256);
1154+
1155+ pad = (u32)len | ((u32)len << 8);
1156+ pad |= pad << 16;
1157+
1158+ while(len >= 16)
1159+ {
1160+ a = (u32)msg[ 0] |
1161+ (u32)msg[ 1] << 8 |
1162+ (u32)msg[ 2] << 16|
1163+ (u32)msg[ 3] << 24;
1164+ b = (u32)msg[ 4] |
1165+ (u32)msg[ 5] << 8 |
1166+ (u32)msg[ 6] << 16|
1167+ (u32)msg[ 7] << 24;
1168+ c = (u32)msg[ 8] |
1169+ (u32)msg[ 9] << 8 |
1170+ (u32)msg[10] << 16|
1171+ (u32)msg[11] << 24;
1172+ d = (u32)msg[12] |
1173+ (u32)msg[13] << 8 |
1174+ (u32)msg[14] << 16|
1175+ (u32)msg[15] << 24;
1176+
1177+ TEACORE(PARTROUNDS);
1178+
1179+ len -= 16;
1180+ msg += 16;
1181+ }
1182+
1183+ if (len >= 12)
1184+ {
1185+ assert(len < 16);
1186+
1187+ a = (u32)msg[ 0] |
1188+ (u32)msg[ 1] << 8 |
1189+ (u32)msg[ 2] << 16|
1190+ (u32)msg[ 3] << 24;
1191+ b = (u32)msg[ 4] |
1192+ (u32)msg[ 5] << 8 |
1193+ (u32)msg[ 6] << 16|
1194+ (u32)msg[ 7] << 24;
1195+ c = (u32)msg[ 8] |
1196+ (u32)msg[ 9] << 8 |
1197+ (u32)msg[10] << 16|
1198+ (u32)msg[11] << 24;
1199+
1200+ d = pad;
1201+ for(i = 12; i < len; i++)
1202+ {
1203+ d <<= 8;
1204+ d |= msg[i];
1205+ }
1206+ }
1207+ else if (len >= 8)
1208+ {
1209+ assert(len < 12);
1210+
1211+ a = (u32)msg[ 0] |
1212+ (u32)msg[ 1] << 8 |
1213+ (u32)msg[ 2] << 16|
1214+ (u32)msg[ 3] << 24;
1215+ b = (u32)msg[ 4] |
1216+ (u32)msg[ 5] << 8 |
1217+ (u32)msg[ 6] << 16|
1218+ (u32)msg[ 7] << 24;
1219+
1220+ c = d = pad;
1221+ for(i = 8; i < len; i++)
1222+ {
1223+ c <<= 8;
1224+ c |= msg[i];
1225+ }
1226+ }
1227+ else if (len >= 4)
1228+ {
1229+ assert(len < 8);
1230+
1231+ a = (u32)msg[ 0] |
1232+ (u32)msg[ 1] << 8 |
1233+ (u32)msg[ 2] << 16|
1234+ (u32)msg[ 3] << 24;
1235+
1236+ b = c = d = pad;
1237+ for(i = 4; i < len; i++)
1238+ {
1239+ b <<= 8;
1240+ b |= msg[i];
1241+ }
1242+ }
1243+ else
1244+ {
1245+ assert(len < 4);
1246+
1247+ a = b = c = d = pad;
1248+ for(i = 0; i < len; i++)
1249+ {
1250+ a <<= 8;
1251+ a |= msg[i];
1252+ }
1253+ }
1254+
1255+ TEACORE(FULLROUNDS);
1256+
1257+/* return 0;*/
1258+ return h0^h1;
1259+}
1260--- nfs-server/ugid_map.c
1261+++ nfs-server/ugid_map.c 2002/11/08 13:59:16
1262@@ -276,8 +276,10 @@
1263 if ((gid == 0 && mountp->o.root_squash) || mountp->o.all_squash)
1264 retgid = mountp->o.nobody_gid;
1265
1266+#if 0
1267 Dprintf(D_UGID, "lgid(%s, %d) = %d\n",
1268 inet_ntoa(mountp->client->clnt_addr), gid, retgid);
1269+#endif
1270 return retgid;
1271 }
1272
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/007-map.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/007-map.patch
new file mode 100644
index 0000000000..89baabe1c2
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/007-map.patch
@@ -0,0 +1,78 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/auth.c
4+++ nfs-server/auth.c 2002/11/08 12:49:13
5@@ -595,7 +595,6 @@
6 cp->clnt_addr.s_addr = INADDR_ANY;
7 cp->flags = 0;
8 cp->m = NULL;
9- cp->umap = NULL;
10
11 if (hname == NULL) {
12 if (anonymous_client != NULL) {
13@@ -1200,10 +1199,9 @@
14 free (mp->path);
15 if (mp->o.clnt_nisdomain)
16 free(mp->o.clnt_nisdomain);
17+ if (mp->umap)
18+ ugid_free_map(mp->umap);
19 free (mp);
20- }
21- if (cp->umap != NULL) {
22- ugid_free_map(cp->umap);
23 }
24 free (cp);
25 }
26--- nfs-server/auth.h
27+++ nfs-server/auth.h 2002/11/08 12:50:24
28@@ -66,6 +66,11 @@
29 char * path;
30 nfs_options o;
31 dev_t mount_dev;
32+ /*
33+ * This is the uid/gid map.
34+ * See ugid_map.c for details
35+ */
36+ struct ugid_map * umap;
37 /* Original NFS client */
38 struct nfs_client * origin;
39 } nfs_mount;
40@@ -77,12 +82,6 @@
41 char * clnt_name;
42 unsigned short flags;
43 nfs_mount * m;
44-
45- /*
46- * This is the uid/gid map.
47- * See ugid_map.c for details
48- */
49- struct ugid_map * umap;
50 } nfs_client;
51
52 #define AUTH_CLNT_WILDCARD 0x0001
53--- nfs-server/ugid_map.c
54+++ nfs-server/ugid_map.c 2002/11/08 12:49:14
55@@ -401,12 +401,11 @@
56 static ugid_map *
57 ugid_get_map(nfs_mount *mountp)
58 {
59- nfs_client *clientp = mountp->client;
60 struct ugid_map *umap;
61 unsigned int how;
62
63- if (clientp->umap == NULL) {
64- clientp->umap = umap = (ugid_map *) xmalloc(sizeof(ugid_map));
65+ if (mountp->umap == NULL) {
66+ mountp->umap = umap = (ugid_map *) xmalloc(sizeof(ugid_map));
67 memset(umap, 0, sizeof(ugid_map));
68
69 for (how = 0; how < 4; how++) {
70@@ -415,7 +414,7 @@
71 }
72 }
73
74- return clientp->umap;
75+ return mountp->umap;
76 }
77
78 static void
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/008-configure.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/008-configure.patch
new file mode 100644
index 0000000000..a6d45993ee
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/008-configure.patch
@@ -0,0 +1,13 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/configure.in 2002/11/08 14:24:55 1.1
4+++ nfs-server/configure.in 2002/11/08 14:25:27
5@@ -98,7 +98,7 @@
6 fi
7 if test "$enable_ugid_dynamic" = yes; then
8 AC_DEFINE(ENABLE_UGID_DAEMON)
9- UGIDD_PROG=\${rpcprefix}.ugidd
10+ UGIDD_PROG=\${rpcprefix}ugidd
11 UGIDD_MAN=ugidd
12 fi
13 if test "$enable_ugid_nis" = yes; then
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/009-multirw.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/009-multirw.patch
new file mode 100644
index 0000000000..65b0b9eee5
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/009-multirw.patch
@@ -0,0 +1,15 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/nfsd.c
4+++ nfs-server/nfsd.c
5@@ -1133,8 +1133,8 @@
6 }
7 }
8
9- if (ncopies > 1)
10- read_only = 1;
11+ /* if (ncopies > 1)
12+ read_only = 1; */
13
14 /*
15 * We first fork off a child and detach from tty
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/010-realpath.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/010-realpath.patch
new file mode 100644
index 0000000000..c3b5d58151
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/010-realpath.patch
@@ -0,0 +1,30 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/configure.in
4+++ nfs-server/configure.in
5@@ -81,7 +81,7 @@
6 AC_CHECK_LIB(rpc, main)
7 AC_CHECK_LIB(crypt, main)
8 AC_CHECK_LIB(nys, main)
9-AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred)
10+AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred realpath)
11 AC_AUTHDES_GETUCRED
12 AC_BROKEN_SETFSUID
13 AC_MOUNTLIST
14--- nfs-server/realpath.c
15+++ nfs-server/realpath.c
16@@ -53,6 +53,8 @@
17
18 #define MAX_READLINKS 32
19
20+#ifndef HAVE_REALPATH
21+
22 #ifdef __STDC__
23 char *realpath(const char *path, char resolved_path [])
24 #else
25@@ -173,3 +175,5 @@
26 strcpy (resolved_path, got_path);
27 return resolved_path;
28 }
29+
30+#endif /* HAVE_REALPATH */
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/011-fno-strict-aliasing.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/011-fno-strict-aliasing.patch
new file mode 100644
index 0000000000..695b8c7d19
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/011-fno-strict-aliasing.patch
@@ -0,0 +1,13 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/Makefile.in
4+++ nfs-server/Makefile.in
5@@ -225,7 +225,7 @@
6 $(RPCGEN) -l -o $@ $?
7
8 nfs_prot_xdr.o: nfs_prot_xdr.c
9- $(COMPILE) $(RPC_WARNFLAGS) -c nfs_prot_xdr.c
10+ $(COMPILE) $(RPC_WARNFLAGS) -fno-strict-aliasing -c nfs_prot_xdr.c
11 mount_xdr.o: mount_xdr.c
12 $(COMPILE) $(RPC_WARNFLAGS) -c mount_xdr.c
13 mount_svc.o: mount_svc.c
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/012-nostrip.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/012-nostrip.patch
new file mode 100644
index 0000000000..a815ee4373
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/012-nostrip.patch
@@ -0,0 +1,13 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/Makefile.in.xx 2006-01-12 12:43:09.000000000 +0100
4+++ nfs-server/Makefile.in 2006-01-12 12:43:10.000000000 +0100
5@@ -64,7 +64,7 @@
6 NFSD_DEFS =
7
8 CFLAGS = @CFLAGS@
9-LDFLAGS = @LDFLAGS@ -s
10+LDFLAGS = @LDFLAGS@
11 WARNFLAGS = @WARNFLAGS@
12 RPC_WARNFLAGS = @RPC_WARNFLAGS@
13 TRANSPORTFLAGS = @RPCGEN_I@ -s udp -s tcp
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/013-mntpathlen.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/013-mntpathlen.patch
new file mode 100644
index 0000000000..1f10d3c941
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/013-mntpathlen.patch
@@ -0,0 +1,32 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/mountd.c 2006/01/12 14:00:13 1.13
4+++ nfs-server/mountd.c 2006/01/12 14:37:35
5@@ -76,7 +76,7 @@
6 0
7 };
8
9-char argbuf[MNTPATHLEN + 1];
10+char argbuf[PATH_MAX + 1];
11 char *auth_file = NULL;
12 static char *program_name;
13 int need_reinit = 0;
14@@ -97,6 +97,9 @@
15 /*
16 * MOUNT
17 * This is what the whole protocol is all about
18+ *
19+ * Note: librpc gets us MNTPATHLEN length strings, but realpath
20+ * needs a PATH_MAX length output buffer.
21 */
22 fhstatus *
23 mountproc_mnt_1_svc(dirpath *argp, struct svc_req *rqstp)
24@@ -105,7 +108,7 @@
25 struct stat stbuf;
26 nfs_client *cp;
27 nfs_mount *mp;
28- char nargbuf[MNTPATHLEN + 1];
29+ char nargbuf[PATH_MAX + 1];
30 int saved_errno = 0;
31 #ifdef WANT_LOG_MOUNTS
32 struct in_addr addr;
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/014-uninitialized.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/014-uninitialized.patch
new file mode 100644
index 0000000000..233c08a2f3
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/014-uninitialized.patch
@@ -0,0 +1,12 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/mountd.c
4+++ nfs-server/mountd.c
5@@ -278,6 +278,7 @@
6 || (mp = auth_path(cp, rqstp, dir)) == NULL
7 || mp->o.noaccess) {
8 #ifdef WANT_LOG_MOUNTS
9+ addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
10 Dprintf(L_WARNING, "Blocked attempt of %s to pathconf(%s)\n",
11 inet_ntoa(addr), dir);
12 #endif /* WANT_LOG_MOUNTS */
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/015-setattr.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/015-setattr.patch
new file mode 100644
index 0000000000..cbfb8e8214
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/015-setattr.patch
@@ -0,0 +1,26 @@
1# Patch origin: nfs-server source RPM from openSUSE 10.3
2
3--- nfs-server/setattr.c.orig 2006-07-28 16:38:26.000000000 +0200
4+++ nfs-server/setattr.c 2006-07-28 16:42:28.000000000 +0200
5@@ -97,7 +97,20 @@
6 tvp[1].tv_sec = s->st_mtime;
7 tvp[1].tv_usec = 0;
8 }
9- if (efs_utimes(path, tvp) < 0)
10+ if (m_secs != IGNORE_TIME && attr->mtime.useconds == 1000000) {
11+ /*
12+ * from kernel/fs/nfsd/nfsxdr.c:
13+ * Passing the invalid value useconds=1000000 for mtime
14+ * is a Sun convention for "set both mtime and atime to
15+ * current server time". It's needed to make permissions
16+ * checks for the "touch" program across v2 mounts to
17+ * Solaris and Irix boxes work correctly. See description of
18+ * sattr in section 6.1 of "NFS Illustrated" by
19+ * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
20+ */
21+ if (utime(path, (struct utimbuf *)0) < 0)
22+ goto failure;
23+ } else if (efs_utimes(path, tvp) < 0)
24 goto failure;
25 }
26 }
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/016-makefile.in.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/016-makefile.in.patch
new file mode 100644
index 0000000000..634ce46090
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/016-makefile.in.patch
@@ -0,0 +1,14 @@
1# Makefile fix for staging to work correctly.
2# Scott Garman <scott.a.garman@intel.com>
3
4--- nfs-server-2.2beta47/Makefile.in.orig 2010-08-03 20:55:05.000000000 -0700
5+++ nfs-server-2.2beta47/Makefile.in 2010-08-03 20:55:42.000000000 -0700
6@@ -69,7 +69,7 @@
7 RPC_WARNFLAGS = @RPC_WARNFLAGS@
8 TRANSPORTFLAGS = @RPCGEN_I@ -s udp -s tcp
9
10-prefix = $(install_prefix)/usr
11+prefix = @prefix@
12 exec_prefix = $(prefix)
13
14 bindir = $(exec_prefix)/sbin
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/017-wrs-dynamic-rpc.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/017-wrs-dynamic-rpc.patch
new file mode 100644
index 0000000000..18e12de789
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/017-wrs-dynamic-rpc.patch
@@ -0,0 +1,258 @@
1# Add the ability to choose alternate RPC ports at runtime and disable
2# security so that it can run as a userland process
3# Patch origin: Wind River
4
5Index: nfs-server-2.2beta47/auth_init.c
6===================================================================
7--- nfs-server-2.2beta47.orig/auth_init.c
8+++ nfs-server-2.2beta47/auth_init.c
9@@ -409,6 +409,7 @@ auth_init(char *fname)
10 fname = EXPORTSFILE;
11 auth_file = fname; /* Save for re-initialization */
12
13+#ifdef ROOT_LEVEL_SECURITY
14 /* Check protection of exports file. */
15 switch(iCheckAccess(auth_file, EXPORTSOWNERUID, EXPORTSOWNERGID)) {
16 case FACCESSWRITABLE:
17@@ -424,6 +425,7 @@ auth_init(char *fname)
18 Dprintf(L_ERROR, "exiting because of security violation.\n");
19 exit(1);
20 }
21+#endif
22
23 if ((ef = fopen(fname, "r")) == NULL) {
24 Dprintf(L_ERROR, "Could not open exports file %s: %s\n",
25Index: nfs-server-2.2beta47/nfsd.c
26===================================================================
27--- nfs-server-2.2beta47.orig/nfsd.c
28+++ nfs-server-2.2beta47/nfsd.c
29@@ -46,6 +46,7 @@ static char pathbuf_1[NFS_MAXPATHLEN + N
30
31 extern char version[];
32 static char *program_name;
33+static int nfs_prog = NFS_PROGRAM;
34
35 /*
36 * Option table
37@@ -60,6 +61,7 @@ static struct option longopts[] = {
38 { "help", 0, 0, 'h' },
39 { "log-transfers", 0, 0, 'l' },
40 { "allow-non-root", 0, 0, 'n' },
41+ { "prog", required_argument, 0, 'g' },
42 { "port", required_argument, 0, 'P' },
43 { "promiscuous", 0, 0, 'p' },
44 { "re-export", 0, 0, 'r' },
45@@ -73,9 +75,10 @@ static struct option longopts[] = {
46 { "udp-only", 0, 0, OPT_NOTCP },
47 { "loopback-only", 0, 0, OPT_LOOPBACK },
48 { "hashed-inodes", 0, 0, 'I' },
49+ { "nfs-pid", required_argument, 0, 'N' },
50 { NULL, 0, 0, 0 }
51 };
52-static const char * shortopts = "a:d:Ff:hlnP:prR:tvz::";
53+static const char * shortopts = "a:d:Ff:g:hlnN:P:prR:tvz::";
54
55 /*
56 * Table of supported versions
57@@ -1003,6 +1006,8 @@ main(int argc, char **argv)
58 int failsafe_level = 0;
59 int c;
60 int i, ncopies = 1;
61+ char *nfs_pid_file = NULL;
62+
63
64 program_name = argv[0];
65 chdir("/");
66@@ -1026,9 +1031,15 @@ main(int argc, char **argv)
67 case 'f':
68 auth_file = optarg;
69 break;
70+ case 'g':
71+ nfs_prog = atoi(optarg);
72+ break;
73 case 'l':
74 log_transfers = 1;
75 break;
76+ case 'N':
77+ nfs_pid_file = strdup(optarg);
78+ break;
79 case 'n':
80 allow_non_root = 1;
81 break;
82@@ -1114,7 +1125,7 @@ main(int argc, char **argv)
83 log_open("nfsd", foreground);
84
85 /* Initialize RPC stuff */
86- rpc_init("nfsd", NFS_PROGRAM, nfsd_versions, nfs_dispatch,
87+ rpc_init("nfsd", nfs_prog, nfsd_versions, nfs_dispatch,
88 nfsport, NFS_MAXDATA);
89
90 if (_rpcpmstart) {
91@@ -1145,7 +1156,10 @@ main(int argc, char **argv)
92 /* Initialize the AUTH module. */
93 auth_init(auth_file);
94
95- setpidpath(_PATH_NFSD_PIDFILE);
96+ if (nfs_pid_file == 0)
97+ nfs_pid_file = _PATH_NFSD_PIDFILE;
98+ setpidpath(nfs_pid_file);
99+
100 if (failsafe_level == 0) {
101 /* Start multiple copies of the server */
102 writepid(getpid(), 1);
103@@ -1215,9 +1229,11 @@ usage(FILE *fp, int n)
104 fprintf(fp,
105 "Usage: %s [-Fhnpv] [-d kind] [-f exports-file] [-P port] [--version]\n"
106 " [--debug kind] [--exports-file=file] [--port port]\n"
107+" [--prog alternate_rpc_port_nubmer]\n"
108 " [--allow-non-root] [--promiscuous] [--version] [--foreground]\n"
109 " [--re-export] [--log-transfers] [--public-root path]\n"
110 " [--no-spoof-trace] [--no-cross-mounts] [--hashed-inodes] [--help]\n"
111+" [--nfs-pid file]\n"
112 , program_name);
113 exit(n);
114 }
115@@ -1234,7 +1250,7 @@ sigterm(int sig)
116 static void
117 terminate(void)
118 {
119- rpc_exit(NFS_PROGRAM, nfsd_versions);
120+ rpc_exit(nfs_prog, nfsd_versions);
121 efs_shutdown();
122 }
123
124Index: nfs-server-2.2beta47/mountd.c
125===================================================================
126--- nfs-server-2.2beta47.orig/mountd.c
127+++ nfs-server-2.2beta47/mountd.c
128@@ -42,6 +42,7 @@ int hashed_inodes; /* dummy */
129 static void usage(FILE *, int);
130 static void terminate(void);
131 static RETSIGTYPE sigterm(int sig);
132+int mount_prog = MOUNTPROG;
133
134 /*
135 * Option table for mountd
136@@ -55,6 +56,7 @@ static struct option longopts[] =
137 { "help", 0, 0, 'h' },
138 { "allow-non-root", 0, 0, 'n' },
139 { "port", required_argument, 0, 'P' },
140+ { "prog", required_argument, 0, 'g' },
141 { "promiscous", 0, 0, 'p' },
142 { "re-export", 0, 0, 'r' },
143 { "no-spoof-trace", 0, 0, 't' },
144@@ -63,9 +65,11 @@ static struct option longopts[] =
145 { "no-cross-mounts", 0, 0, 'x' },
146 { "no-tcp", 0, 0, OPT_NOTCP },
147 { "loopback-only", 0, 0, OPT_LOOPBACK },
148+ { "mount-pid", required_argument, 0, 'N' },
149+ { "rmtab", required_argument, 0, 'R' },
150 { NULL, 0, 0, 0 }
151 };
152-static const char * shortopts = "Fd:f:hnpP:rtvz::";
153+static const char * shortopts = "Fd:f:g:hnN:pP:rRtvz::";
154
155 /*
156 * Table of supported versions
157@@ -318,6 +322,7 @@ main(int argc, char **argv)
158 int failsafe_level = 0;
159 int port = 0;
160 int c;
161+ char *mount_pid_file = NULL;
162
163 program_name = argv[0];
164
165@@ -340,9 +345,15 @@ main(int argc, char **argv)
166 case 'f':
167 auth_file = optarg;
168 break;
169+ case 'g':
170+ mount_prog = port = atoi(optarg);
171+ break;
172 case 'n':
173 allow_non_root = 1;
174 break;
175+ case 'N':
176+ mount_pid_file = strdup(optarg);
177+ break;
178 case 'P':
179 port = atoi(optarg);
180 if (port <= 0 || port > 65535) {
181@@ -354,6 +365,9 @@ main(int argc, char **argv)
182 case 'p':
183 promiscuous = 1;
184 break;
185+ case 'R':
186+ _PATH_RMTAB = strdup(optarg);
187+ break;
188 case 'r':
189 re_export = 1;
190 break;
191@@ -401,7 +415,7 @@ main(int argc, char **argv)
192 log_open("mountd", foreground);
193
194 /* Create services and register with portmapper */
195- rpc_init("mountd", MOUNTPROG, mountd_versions, mount_dispatch, port, 0);
196+ rpc_init("mountd", mount_prog, mountd_versions, mount_dispatch, port, 0);
197
198 if (_rpcpmstart) {
199 /* Always foreground mode */
200@@ -422,7 +436,9 @@ main(int argc, char **argv)
201 auth_init(auth_file);
202
203 /* Write pidfile */
204- setpidpath(_PATH_MOUNTD_PIDFILE);
205+ if (mount_pid_file == 0)
206+ mount_pid_file = _PATH_MOUNTD_PIDFILE;
207+ setpidpath(mount_pid_file);
208 writepid(getpid(), 1);
209
210 /* Failsafe mode */
211@@ -453,7 +469,9 @@ usage(FILE *fp, int n)
212 program_name);
213 fprintf(fp, " [--debug kind] [--help] [--allow-non-root]\n");
214 fprintf(fp, " [--promiscuous] [--version] [--port portnum]\n");
215+ fprintf(fp, " [--prog alternate_rpc_port_nubmer]\n");
216 fprintf(fp, " [--exports-file=file] [--no-cross-mounts]\n");
217+ fprintf(fp, " [--mount-pid file] [--rmtab file]\n");
218 exit(n);
219 }
220
221@@ -467,7 +485,7 @@ sigterm(int sig)
222 static void
223 terminate(void)
224 {
225- rpc_exit(MOUNTPROG, mountd_versions);
226+ rpc_exit(mount_prog, mountd_versions);
227 }
228
229 RETSIGTYPE
230Index: nfs-server-2.2beta47/rmtab.c
231===================================================================
232--- nfs-server-2.2beta47.orig/rmtab.c
233+++ nfs-server-2.2beta47/rmtab.c
234@@ -14,6 +14,8 @@ static char * rmtab_gethost(struct svc_r
235 static int rmtab_insert(char *, char *);
236 static void rmtab_file(char);
237
238+char *_PATH_RMTAB = _PATH_RMTAB_VAL;
239+
240 /*
241 * global top to linklist
242 */
243Index: nfs-server-2.2beta47/rmtab.h
244===================================================================
245--- nfs-server-2.2beta47.orig/rmtab.h
246+++ nfs-server-2.2beta47/rmtab.h
247@@ -11,8 +11,9 @@
248 * Location of rmtab file. /etc/rmtab is the standard on most systems.
249 */
250 #include <paths.h>
251-#ifndef _PATH_RMTAB
252-#define _PATH_RMTAB "/etc/rmtab"
253+extern char *_PATH_RMTAB;
254+#ifndef _PATH_RMTAB_VAL
255+#define _PATH_RMTAB_VAL "/etc/rmtab"
256 #endif
257
258 extern void rmtab_add_client(dirpath, struct svc_req *);
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/018-remove-tcp-wrappers.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/018-remove-tcp-wrappers.patch
new file mode 100644
index 0000000000..95ecdee611
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/018-remove-tcp-wrappers.patch
@@ -0,0 +1,20 @@
1# Remove the requirement to link with libwrap
2# Patch origin: Wind River
3
4Index: nfs-server-2.2beta47/haccess.c
5===================================================================
6--- nfs-server-2.2beta47.orig/haccess.c 1999-04-08 08:47:19.000000000 -0400
7+++ nfs-server-2.2beta47/haccess.c 2006-08-07 17:05:31.868221639 -0400
8@@ -79,8 +79,12 @@
9 clients[hash] = hp;
10
11 hp->clnt_addr = addr;
12+#ifdef USE_TCP_WRAPPERS
13 hp->status = hosts_ctl(rpcprog, "unknown",
14 inet_ntoa(addr), "root");
15+#else
16+ hp->status = 1;
17+#endif
18 nrhosts++;
19 }
20
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/019-pid-before-fork.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/019-pid-before-fork.patch
new file mode 100644
index 0000000000..960ca8e47f
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/019-pid-before-fork.patch
@@ -0,0 +1,125 @@
1# Write a pid file before forking
2# Patch origin: Wind River
3
4Index: nfs-server-2.2beta47/daemon.c
5===================================================================
6--- nfs-server-2.2beta47.orig/daemon.c
7+++ nfs-server-2.2beta47/daemon.c
8@@ -15,6 +15,19 @@
9 static const char * pidfilename = 0;
10 static const char * get_signame(int signo);
11
12+void
13+writepid(pid_t pid, int clear)
14+{
15+ FILE *fp;
16+
17+ fp = fopen(pidfilename, clear? "w" : "a");
18+ if (fp == NULL)
19+ Dprintf(L_FATAL, "Unable to open %s: %m", pidfilename);
20+ fprintf(fp, "%d\n", pid);
21+ fclose(fp);
22+ return;
23+}
24+
25 /*
26 * Do the Crawley Thing
27 */
28@@ -33,8 +46,10 @@ daemonize(void)
29 Dprintf(L_FATAL, "unable to fork: %s", strerror(errno));
30
31 /* Parent process: exit */
32- if (c > 0)
33+ if (c > 0) {
34+ writepid(c, 1);
35 exit(0);
36+ }
37
38 /* Do the session stuff */
39 close(0);
40@@ -60,19 +75,6 @@ setpidpath(const char *filename)
41 }
42
43 void
44-writepid(pid_t pid, int clear)
45-{
46- FILE *fp;
47-
48- fp = fopen(pidfilename, clear? "w" : "a");
49- if (fp == NULL)
50- Dprintf(L_FATAL, "Unable to open %s: %m", pidfilename);
51- fprintf(fp, "%d\n", pid);
52- fclose(fp);
53- return;
54-}
55-
56-void
57 failsafe(int level, int ncopies)
58 {
59 int *servers, running, child, i;
60Index: nfs-server-2.2beta47/mountd.c
61===================================================================
62--- nfs-server-2.2beta47.orig/mountd.c
63+++ nfs-server-2.2beta47/mountd.c
64@@ -425,9 +425,6 @@ main(int argc, char **argv)
65 background_logging();
66 }
67
68- /* Become a daemon */
69- if (!foreground)
70- daemonize();
71
72 /* Initialize the FH module. */
73 fh_init();
74@@ -435,11 +432,15 @@ main(int argc, char **argv)
75 /* Initialize the AUTH module. */
76 auth_init(auth_file);
77
78- /* Write pidfile */
79 if (mount_pid_file == 0)
80 mount_pid_file = _PATH_MOUNTD_PIDFILE;
81 setpidpath(mount_pid_file);
82- writepid(getpid(), 1);
83+
84+ /* Become a daemon */
85+ if (!foreground)
86+ daemonize();
87+ else
88+ writepid(getpid(), 1);
89
90 /* Failsafe mode */
91 if (failsafe_level)
92Index: nfs-server-2.2beta47/nfsd.c
93===================================================================
94--- nfs-server-2.2beta47.orig/nfsd.c
95+++ nfs-server-2.2beta47/nfsd.c
96@@ -1147,11 +1147,6 @@ main(int argc, char **argv)
97 /* if (ncopies > 1)
98 read_only = 1; */
99
100- /*
101- * We first fork off a child and detach from tty
102- */
103- if (!foreground)
104- daemonize();
105
106 /* Initialize the AUTH module. */
107 auth_init(auth_file);
108@@ -1160,9 +1155,16 @@ main(int argc, char **argv)
109 nfs_pid_file = _PATH_NFSD_PIDFILE;
110 setpidpath(nfs_pid_file);
111
112+ /*
113+ * We first fork off a child and detach from tty
114+ */
115+ if (!foreground)
116+ daemonize();
117+ else
118+ writepid(getpid(), 1);
119+
120 if (failsafe_level == 0) {
121 /* Start multiple copies of the server */
122- writepid(getpid(), 1);
123 for (i = 1; i < ncopies; i++) {
124 pid_t pid;
125
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/020-undefined-chmod-fix.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/020-undefined-chmod-fix.patch
new file mode 100644
index 0000000000..0f1108c214
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/020-undefined-chmod-fix.patch
@@ -0,0 +1,18 @@
1# Fix a problem with chmod attributes when using no_squash_all
2# Patch origin: Wind River
3
4---
5 setattr.c | 2 +-
6 1 file changed, 1 insertion(+), 1 deletion(-)
7
8--- a/setattr.c
9+++ b/setattr.c
10@@ -115,7 +115,7 @@ nfsstat setattr(char *path, sattr *attr,
11 }
12 }
13
14- if (flags & SATTR_CHMOD) {
15+ if (flags & SATTR_CHMOD && attr->mode != -1) {
16 unsigned int mode = attr->mode;
17
18 /* If setuid is not allowed, silently squash them */
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/021-nolibwrap.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/021-nolibwrap.patch
new file mode 100644
index 0000000000..c0901fadcc
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/021-nolibwrap.patch
@@ -0,0 +1,20 @@
1# Remove libwrap linkage
2# Patch origin: Wind River
3
4---
5 configure.in | 4 ++--
6 1 file changed, 2 insertions(+), 2 deletions(-)
7
8--- a/configure.in
9+++ b/configure.in
10@@ -86,8 +86,8 @@ AC_AUTHDES_GETUCRED
11 AC_BROKEN_SETFSUID
12 AC_MOUNTLIST
13 AC_FSUSAGE
14-AC_CHECK_LIB(wrap, main)
15-AC_LIBWRAP_BUG
16+dnl AC_CHECK_LIB(wrap, main)
17+dnl AC_LIBWRAP_BUG
18 AC_BSD_SIGNALS
19
20 dnl **************************************************************
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/022-add-close-on-exec-descriptors.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/022-add-close-on-exec-descriptors.patch
new file mode 100644
index 0000000000..011ae74cde
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/022-add-close-on-exec-descriptors.patch
@@ -0,0 +1,61 @@
1# Force socket fds to close on exec when used in conjunction with pseudo
2# Patch origin: Wind River
3
4---
5 nfsd.c | 8 ++++++++
6 rpcmisc.c | 9 +++++++++
7 ugidd.c | 8 ++++++++
8 3 files changed, 25 insertions(+)
9
10--- a/nfsd.c
11+++ b/nfsd.c
12@@ -630,6 +630,14 @@ nfsd_nfsproc_create_2(createargs *argp,
13 if (S_ISSOCK(argp->attributes.mode)) {
14 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
15 return(nfs_errno());
16+ /* if there is a pseudo exec mark the socket to be
17+ * closed automatically
18+ */
19+ {
20+ long f_flags;
21+ f_flags = fcntl(s, F_GETFD);
22+ f_flags = fcntl(s, F_SETFD, f_flags | FD_CLOEXEC);
23+ }
24 sa.sun_family = AF_UNIX;
25 strncpy(sa.sun_path, pathbuf, sizeof(sa.sun_path));
26 sa.sun_path[sizeof(sa.sun_path)-1] = '\0';
27--- a/rpcmisc.c
28+++ b/rpcmisc.c
29@@ -197,6 +197,15 @@ makesock(int port, int proto, int socksz
30 Dprintf(L_FATAL, "Could not make a %s socket: %s\n",
31 prot_name, strerror(errno));
32
33+ /* if there is a pseudo exec mark the socket to be
34+ * closed automatically
35+ */
36+ {
37+ long f_flags;
38+ f_flags = fcntl(s, F_GETFD);
39+ f_flags = fcntl(s, F_SETFD, f_flags | FD_CLOEXEC);
40+ }
41+ fcntl(s, FD_CLOEXEC, 1);
42 memset((char *) &sin, 0, sizeof(sin));
43 sin.sin_family = AF_INET;
44 sin.sin_addr.s_addr = INADDR_ANY;
45--- a/ugidd.c
46+++ b/ugidd.c
47@@ -195,6 +195,14 @@ authenticate_1_svc(argp, rqstp)
48 destaddr.sin_port = htons(*argp);
49 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
50 goto bad;
51+ /* if there is a pseudo exec mark the socket to be
52+ * closed automatically
53+ */
54+ {
55+ long f_flags;
56+ f_flags = fcntl(s, F_GETFD);
57+ f_flags = fcntl(s, F_SETFD, f_flags | FD_CLOEXEC);
58+ }
59 setsockopt(s, SOL_SOCKET, SO_LINGER, 0, 0);
60 bzero((char *) &sendaddr, sizeof sendaddr);
61 /* find a reserved port */
diff --git a/meta/recipes-devtools/unfs-server/unfs-server_2.2beta47.bb b/meta/recipes-devtools/unfs-server/unfs-server_2.2beta47.bb
new file mode 100644
index 0000000000..ecba4525a2
--- /dev/null
+++ b/meta/recipes-devtools/unfs-server/unfs-server_2.2beta47.bb
@@ -0,0 +1,71 @@
1DESCRIPTION = "Userspace NFS server"
2SECTION = "console/network"
3LICENSE = "GPLv2+"
4LIC_FILES_CHKSUM = "file://COPYING;md5=8ca43cbc842c2336e835926c2166c28b"
5
6PR = "r0"
7
8SRC_URI = "ftp://linux.mathematik.tu-darmstadt.de/pub/linux/oldstuff/people/okir/nfs-server-${PV}.tar.gz \
9 file://001-2.2b47-2.2b51.patch \
10 file://002-destdir.patch \
11 file://003-manpages.patch \
12 file://004-strsignal.patch \
13 file://005-sys-time.patch \
14 file://006-reiserfs.patch \
15 file://007-map.patch \
16 file://008-configure.patch \
17 file://009-multirw.patch \
18 file://010-realpath.patch \
19 file://011-fno-strict-aliasing.patch \
20 file://012-nostrip.patch \
21 file://013-mntpathlen.patch \
22 file://014-uninitialized.patch \
23 file://015-setattr.patch \
24 file://016-makefile.in.patch \
25 file://017-wrs-dynamic-rpc.patch \
26 file://018-remove-tcp-wrappers.patch \
27 file://019-pid-before-fork.patch \
28 file://020-undefined-chmod-fix.patch \
29 file://021-nolibwrap.patch \
30 file://022-add-close-on-exec-descriptors.patch \
31 "
32
33SRC_URI[md5sum] = "79a29fe9f79b2f3241d4915767b8c511"
34SRC_URI[sha256sum] = "7eeaf3cf0b9d96167a5ba03bf1046e39b4585de1339a55b285e673c06ba415cb"
35
36S = "${WORKDIR}/nfs-server-${PV}/"
37
38inherit autotools
39
40BBCLASSEXTEND = "native nativesdk"
41
42CFLAGS = "-fPIE -fstack-protector-all"
43LDFLAGS = "-pie"
44
45EXTRA_OECONF = "--enable-ugid-dynamic \
46 --enable-ugid-nis \
47 --enable-host-access \
48 --with-exports-uid=0 \
49 --with-exports-gid=0 \
50 --enable-mount-logging \
51 --with-devtab=${DESTDIR}${base_prefix}/var/lib/nfs/devtab \
52 "
53
54do_configure_prepend () {
55 # Remove pregenerated xdr functions. They use long
56 # instead of u32, which produces incorrect code on
57 # 64-bit architectures:
58 rm -f *_xdr.c
59
60 mv aclocal.m4 acinclude.m4
61}
62
63# This recipe is intended for -native and -nativesdk builds only,
64# not target installs:
65python __anonymous () {
66 import re
67
68 pn = bb.data.getVar("PN", d, 1)
69 if not pn.endswith('-native') and not pn.endswith('-nativesdk'):
70 raise bb.parse.SkipPackage("unfs-server is intended for native/nativesdk builds only")
71}