diff options
author | Scott Garman <scott.a.garman@intel.com> | 2010-08-12 21:02:58 -0700 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-20 16:20:09 +0100 |
commit | b5b3825ce6df45b16e1f3e15001da213bc8b0a55 (patch) | |
tree | b2577de0765074d6e2bdbbdf1862220b52e8d7c1 /meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch | |
parent | 735210556dc709b3c2367389fa6ea9c0109412b1 (diff) | |
download | poky-b5b3825ce6df45b16e1f3e15001da213bc8b0a55.tar.gz |
unfs-server: new userspace nfs recipe
This is a simple userspace NFS server, derived from one which was
previously used in openSUSE 10.x. Wind River contributed many of the
patches.
This package is not intended for target installations, only -native
and -nativesdk use.
Enabling nativesdk for readline, sqlite3, and pseudo was required, as
well as a few new autoconf siteconfig entries.
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
Diffstat (limited to 'meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch')
-rw-r--r-- | meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch | 2344 |
1 files changed, 2344 insertions, 0 deletions
diff --git a/meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch b/meta/packages/unfs-server/unfs-server-2.2beta47/001-2.2b47-2.2b51.patch new file mode 100644 index 0000000000..886ce92b34 --- /dev/null +++ b/meta/packages/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 | |||
3 | diff -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 | ||
9 | diff -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 | |||
72 | diff -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) | ||
171 | diff -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) | ||
197 | diff -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; | ||
232 | diff -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 *); | ||
267 | diff -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 | ||
565 | diff -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 | } | ||
680 | diff -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 | |||
692 | diff -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) | ||
789 | diff -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 | +} | ||
1063 | diff -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 */ | ||
1085 | diff -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 | ||
1137 | diff -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); | ||
1637 | diff -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; | ||
1654 | diff -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; | ||
1674 | diff -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, | ||
1699 | diff -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) | ||
1794 | diff -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 | ||
1825 | diff -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 | /* | ||
2046 | diff -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 | ||
2129 | diff -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 *); | ||
2140 | diff -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 | { | ||
2171 | diff -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 */ | ||
2197 | diff -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) | ||
2211 | diff -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 | |||
2234 | diff -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 | ||
2288 | diff -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"); | ||
2339 | diff -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"; | ||