diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-12-30 10:12:14 +0000 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-12-30 10:12:14 +0000 |
commit | 59ad91a880695808c5b4efe88fa46286662e4cfc (patch) | |
tree | 52a40efec182c732157be1553609c9bb0d74892d /meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47 | |
parent | acf3b8e884657101b736d32f4216655b96659f49 (diff) | |
download | poky-59ad91a880695808c5b4efe88fa46286662e4cfc.tar.gz |
unfs-server: Fix PV so it obeys the version number policy
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47')
22 files changed, 4537 insertions, 0 deletions
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/001-2.2b47-2.2b51.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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"; | ||
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/002-destdir.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/002-destdir.patch new file mode 100644 index 0000000000..9388332675 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/003-manpages.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/003-manpages.patch new file mode 100644 index 0000000000..a17a8dcf55 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/004-strsignal.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/004-strsignal.patch new file mode 100644 index 0000000000..3ac4ed740c --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/005-sys-time.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/005-sys-time.patch new file mode 100644 index 0000000000..c21fb05e8d --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/006-reiserfs.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch new file mode 100644 index 0000000000..abdc67476e --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/007-map.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/007-map.patch new file mode 100644 index 0000000000..89baabe1c2 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/008-configure.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/008-configure.patch new file mode 100644 index 0000000000..a6d45993ee --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/009-multirw.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/009-multirw.patch new file mode 100644 index 0000000000..65b0b9eee5 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/010-realpath.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/010-realpath.patch new file mode 100644 index 0000000000..c3b5d58151 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/011-fno-strict-aliasing.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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.1+2.2beta47/012-nostrip.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/012-nostrip.patch new file mode 100644 index 0000000000..a815ee4373 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/013-mntpathlen.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/013-mntpathlen.patch new file mode 100644 index 0000000000..1f10d3c941 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/014-uninitialized.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/014-uninitialized.patch new file mode 100644 index 0000000000..233c08a2f3 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/015-setattr.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/015-setattr.patch new file mode 100644 index 0000000000..cbfb8e8214 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/016-makefile.in.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/016-makefile.in.patch new file mode 100644 index 0000000000..634ce46090 --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/017-wrs-dynamic-rpc.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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 | |||
5 | Index: 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", | ||
25 | Index: 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 | |||
124 | Index: 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 | ||
230 | Index: 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 | */ | ||
243 | Index: 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.1+2.2beta47/018-remove-tcp-wrappers.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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 | |||
4 | Index: 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.1+2.2beta47/019-pid-before-fork.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/019-pid-before-fork.patch | |||
@@ -0,0 +1,125 @@ | |||
1 | # Write a pid file before forking | ||
2 | # Patch origin: Wind River | ||
3 | |||
4 | Index: 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; | ||
60 | Index: 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) | ||
92 | Index: 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.1+2.2beta47/020-undefined-chmod-fix.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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.1+2.2beta47/021-nolibwrap.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/021-nolibwrap.patch new file mode 100644 index 0000000000..c0901fadcc --- /dev/null +++ b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+2.2beta47/022-add-close-on-exec-descriptors.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+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.1+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 */ | ||