1 --- nfs-user-server-2.2beta47.orig/BUILD
2 +++ nfs-user-server-2.2beta47/BUILD
19 prompt="$2 [default $3 $4] "
24 echo -n "Please press return to continue"
29 version=`cat .version`
30 --- nfs-user-server-2.2beta47.orig/Makefile.in
31 +++ nfs-user-server-2.2beta47/Makefile.in
33 LIBSRCS = fileblocks.c fsusage.c realpath.c strerror.c \
34 utimes.c mkdir.c rename.c getopt.c getopt_long.c \
35 alloca.c mountlist.c xmalloc.c \
36 - xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \
37 + xstrdup.c strdup.c strstr.c nfsmounted.c \
38 haccess.c failsafe.c signals.c
39 XDRFILES = mount.x nfs_prot.x
40 GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \
41 ugid.h ugid_xdr.c ugid_clnt.c
42 HDRS = system.h nfsd.h auth.h fh.h logging.h fakefsuid.h \
43 - rpcmisc.h faccess.h rquotad.h rquota.h haccess.h
44 + rpcmisc.h rquotad.h rquota.h haccess.h
45 LIBHDRS = fsusage.h getopt.h mountlist.h failsafe.h signals.h
47 MANPAGES8p = mountd nfsd $(UGIDD_MAN)
49 MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8)
50 LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \
51 - nfsmounted.o faccess.o haccess.o failsafe.o \
52 + nfsmounted.o haccess.o failsafe.o \
53 signals.o @LIBOBJS@ @ALLOCA@
54 OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o
55 NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \
57 MOUNTD_OBJS = mountd.o rpcmisc.o mount_dispatch.o mount_xdr.o rmtab.o \
59 SHOWMOUNT_OBJS = showmount.o mount_xdr.o
60 -UGIDD_OBJS = ugidd.o ugid_xdr.o logging.o
61 +UGIDD_OBJS = ugidd.o ugid_xdr.o logging.o rpcmisc.o
62 DAEMONS = $(rpcprefix)mountd $(rpcprefix)nfsd $(UGIDD_PROG)
65 --- nfs-user-server-2.2beta47.orig/auth.c
66 +++ nfs-user-server-2.2beta47/auth.c
72 +auth_atob(const char *name, struct in_addr *ap)
76 + if (!isdigit(*name))
78 + for (m = 0; isdigit(*name); name++)
79 + m = m * 10 + (unsigned char) *name - '0';
82 + ap->s_addr = m ? ~((1 << (32 - m)) - 1) : 0;
87 * Get a client entry for a specific name or pattern.
88 * If necessary, this function performs a hostname lookup to
90 if (auth_aton(hname, &haddr, &ename)) {
93 - else if (*ename == '/' && auth_aton(ename+1, &hmask, NULL))
94 + else if (*ename == '/' &&
95 + (auth_aton(ename+1, &hmask, NULL) ||
96 + auth_atob(ename+1, &hmask)))
99 is_special = is_wildcard + is_netgroup + is_netmask;
100 --- nfs-user-server-2.2beta47.orig/auth_init.c
101 +++ nfs-user-server-2.2beta47/auth_init.c
103 #define EXPORTSFILE "/etc/exports"
107 /* Support for file access control on /etc/exports by Alex Yuriev. */
109 #ifndef EXPORTSOWNERUID
111 #ifndef EXPORTSOWNERGID
112 #define EXPORTSOWNERGID ((gid_t) 0)
116 exportnode * export_list = NULL;
117 int allow_non_root = 0;
119 auth_file = fname; /* Save for re-initialization */
121 /* Check protection of exports file. */
122 +#if 0 /* A man's house is his castle. */
123 switch(iCheckAccess(auth_file, EXPORTSOWNERUID, EXPORTSOWNERGID)) {
124 case FACCESSWRITABLE:
127 Dprintf(L_ERROR, "exiting because of security violation.\n");
132 if ((ef = fopen(fname, "r")) == NULL) {
133 Dprintf(L_ERROR, "Could not open exports file %s: %s\n",
136 /* Build the RPC mount export list data structure. */
137 resex = (exportnode *) xmalloc(sizeof *resex);
138 - resex->ex_dir = mount_point;
139 + resex->ex_dir = xstrdup(path);
140 resex->ex_groups = NULL;
142 #ifndef NEW_STYLE_EXPORTS_FILE
143 --- nfs-user-server-2.2beta47.orig/configure.in
144 +++ nfs-user-server-2.2beta47/configure.in
146 AC_CHECK_LIB(crypt, main)
147 AC_CHECK_LIB(nys, main)
148 AC_REPLACE_FUNCS(strerror realpath mkdir rename utimes strdup strstr getopt getopt_long)
149 -AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred)
150 +AC_HAVE_FUNCS(getcwd seteuid setreuid getdtablesize setgroups lchown setsid setfsuid setfsgid innetgr quotactl authdes_getucred strsignal)
154 --- nfs-user-server-2.2beta47.orig/exports.man
155 +++ nfs-user-server-2.2beta47/exports.man
159 serves as the access control list for file systems which may be
160 -exported to NFS clients. It it used by both the NFS mount daemon,
161 +exported to NFS clients. It is used by both the NFS mount daemon,
163 and the NFS file server daemon
170 +Disallow the client to modify files and directories. The client is only
171 +allowed to issue read-only requests.
174 -Allow the client to modify files and directories. The default is to
175 -restrict the client to read-only request, which can be made explicit
178 +Allow the client to modify files and directories. This is the default.
181 This makes everything below the directory inaccessible for the named
185 Leave all symbolic link as they are. This is the default operation.
186 +.SS Anonymous Entries
188 +Entries where hosts are not specified are known as anonymous entries. They
189 +have different default settings compared to normal entries. The differences
192 +.IR no_secure ", and"
197 --- nfs-user-server-2.2beta47.orig/failsafe.c
198 +++ nfs-user-server-2.2beta47/failsafe.c
202 #include <sys/wait.h>
203 +#ifdef HAVE_STRSIGNAL
207 static const char * get_signame(int signo);
211 failsafe(int level, int ncopies)
213 pid, running? "Continue" : "Exit");
215 Dprintf(L_WARNING, "failsafe: "
216 +#ifdef HAVE_STRSIGNAL
217 + "child %d terminated by: %s. "
219 "child %d terminated by %s. "
222 +#ifdef HAVE_STRSIGNAL
223 + pid, strsignal(signo));
225 pid, get_signame(signo));
227 child = -1; /* Restart */
229 } else if (WIFEXITED(status)) {
234 +#ifndef HAVE_STRSIGNAL
236 get_signame(int signo)
239 sprintf(namebuf, "signal #%d", signo);
243 --- nfs-user-server-2.2beta47.orig/mount_dispatch.c
244 +++ nfs-user-server-2.2beta47/mount_dispatch.c
246 dent = &dtbl[proc_index];
248 memset(&argument, 0, dent->arg_size);
249 - if (!svc_getargs(transp, (xdrproc_t) dent->xdr_argument, &argument)) {
250 + if (!svc_getargs(transp, (xdrproc_t) dent->xdr_argument, (caddr_t) &argument)) {
251 svcerr_decode(transp);
255 if (!svc_sendreply(transp, dent->xdr_result, (caddr_t) resp)) {
256 svcerr_systemerr(transp);
258 - if (!svc_freeargs(transp, (xdrproc_t) dent->xdr_argument, &argument)) {
259 + if (!svc_freeargs(transp, (xdrproc_t) dent->xdr_argument, (caddr_t) &argument)) {
260 Dprintf(L_ERROR, "unable to free RPC arguments, exiting\n");
263 --- nfs-user-server-2.2beta47.orig/mount_xdr.c
264 +++ nfs-user-server-2.2beta47/mount_xdr.c
266 xdr_ppathcnf(XDR *xdrs, ppathcnf *objp)
269 - register long *buf=buf;
274 --- nfs-user-server-2.2beta47.orig/mountd.c
275 +++ nfs-user-server-2.2beta47/mountd.c
279 program_name = argv[0];
282 /* Parse the command line options and arguments. */
284 --- nfs-user-server-2.2beta47.orig/nfs_dispatch.c
285 +++ nfs-user-server-2.2beta47/nfs_dispatch.c
289 memset(&argument, 0, dent->arg_size);
290 - if (!svc_getargs(transp, (xdrproc_t) dent->xdr_argument, &argument)) {
291 + if (!svc_getargs(transp, (xdrproc_t) dent->xdr_argument, (caddr_t) &argument)) {
292 svcerr_decode(transp);
296 svc_sendreply(transp, dent->xdr_result, (caddr_t) &result);
299 - if (!svc_freeargs(transp, (xdrproc_t) dent->xdr_argument, &argument)) {
300 + if (!svc_freeargs(transp, (xdrproc_t) dent->xdr_argument, (caddr_t) &argument)) {
301 Dprintf(L_ERROR, "unable to free RPC arguments, exiting\n");
304 --- nfs-user-server-2.2beta47.orig/nfs_prot_xdr.c
305 +++ nfs-user-server-2.2beta47/nfs_prot_xdr.c
307 xdr_fattr(XDR *xdrs, fattr *objp)
310 - register long *buf=buf;
314 if (xdrs->x_op == XDR_ENCODE) {
316 xdr_sattr(XDR *xdrs, sattr *objp)
319 - register long *buf=buf;
323 if (xdrs->x_op == XDR_ENCODE) {
325 xdr_writeargs(XDR *xdrs, writeargs *objp)
328 - register long *buf = buf;
329 + int32_t *buf = buf;
332 if (xdrs->x_op == XDR_ENCODE) {
334 xdr_statfsokres(XDR *xdrs, statfsokres *objp)
337 - register long *buf=buf;
341 if (xdrs->x_op == XDR_ENCODE) {
342 --- nfs-user-server-2.2beta47.orig/nfsd.c
343 +++ nfs-user-server-2.2beta47/nfsd.c
347 #define CHK_NOACCESS 2
350 /* Make larger reads possible. Without crashing the machine :-) */
356 - auth_user(nfsmount, rqstp);
357 + if (!(flags & CHK_ROOT) || strcmp(nfsmount->path, fhc->path))
358 + auth_user(nfsmount, rqstp);
366 - fhc = auth_fh(rqstp, argp, &status, CHK_READ);
367 + fhc = auth_fh(rqstp, argp, &status, CHK_READ | CHK_ROOT);
374 /* MvS: Some clients use chardev 0xFFFF for a FIFO. */
375 +#if defined(major) && defined(minor)
376 + if (S_ISCHR(argp->attributes.mode) &&
377 + major(dev) == 0xff && minor(dev) == 0xff) {
379 if (S_ISCHR(argp->attributes.mode) && dev == 0xFFFF) {
383 argp->attributes.mode &= ~S_IFMT;
386 /* This code is from Mark Shand's version */
388 - if (efs_lstat(h->path, &sbuf) < 0 || !(S_ISDIR(sbuf.st_mode)))
389 + if (efs_lstat(h->path, &sbuf) < 0)
390 + return (NFSERR_ACCES);
391 + if (!S_ISDIR(sbuf.st_mode))
392 return (NFSERR_NOTDIR);
393 if ((dirp = efs_opendir(h->path)) == NULL)
394 return ((errno ? nfs_errno() : NFSERR_NAMETOOLONG));
399 - fhc = auth_fh(rqstp, argp, &status, CHK_READ | CHK_NOACCESS);
400 + fhc = auth_fh(rqstp, argp, &status, CHK_READ | CHK_NOACCESS | CHK_ROOT);
404 --- nfs-user-server-2.2beta47.orig/rpcmisc.c
405 +++ nfs-user-server-2.2beta47/rpcmisc.c
407 asize = sizeof(saddr);
409 if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0) {
410 - int ssize = sizeof (int);
411 + int ssize = sizeof (i);
413 if (saddr.sin_family != AF_INET)
415 - if (getsockopt(0, SOL_SOCKET, SO_TYPE, &_rpcfdtype, &ssize) < 0)
416 + if (getsockopt(0, SOL_SOCKET, SO_TYPE, &i, &ssize) < 0)
419 background_logging(); /* no more logging to stderr */
420 closedown = time(NULL) + _RPCSVC_CLOSEDOWN;
425 for (i = 0; (vers = verstbl[i]) != 0; i++)
426 pmap_unset(prog, vers);
430 if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
431 - if (_rpcfdtype == 0 && defport != 0)
432 + if (_rpcpmstart == 0 && defport != 0)
433 sock = makesock(defport, IPPROTO_UDP, bufsiz);
434 transp = svcudp_create(sock);
439 if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
440 - if (_rpcfdtype == 0 && defport != 0)
441 + if (_rpcpmstart == 0 && defport != 0)
442 sock = makesock(defport, IPPROTO_TCP, bufsiz);
443 transp = svctcp_create(sock, 0, 0);
445 @@ -220,11 +220,14 @@
447 #endif /* SO_SNDBUF */
449 - if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1)
450 - Dprintf(L_FATAL, "Could not bind %s socket to %s:%d: %s\n",
451 + if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
452 + Dprintf(L_ERROR, "Could not bind %s socket to %s:%d: %s\n",
453 prot_name, inet_ntoa(sin.sin_addr),
462 --- nfs-user-server-2.2beta47.orig/showmount.c
463 +++ nfs-user-server-2.2beta47/showmount.c
465 memset(&exportlist, '\0', sizeof(exportlist));
466 clnt_stat = clnt_call(mclient, MOUNTPROC_EXPORT,
467 (xdrproc_t) xdr_void, NULL,
468 - (xdrproc_t) xdr_exports, &exportlist,
469 + (xdrproc_t) xdr_exports, (caddr_t) &exportlist,
471 if (clnt_stat != RPC_SUCCESS) {
472 clnt_perror(mclient, "rpc mount export");
474 memset(&dumplist, '\0', sizeof(dumplist));
475 clnt_stat = clnt_call(mclient, MOUNTPROC_DUMP,
476 (xdrproc_t) xdr_void, NULL,
477 - (xdrproc_t) xdr_mountlist, &dumplist,
478 + (xdrproc_t) xdr_mountlist, (caddr_t) &dumplist,
480 if (clnt_stat != RPC_SUCCESS) {
481 clnt_perror(mclient, "rpc mount dump");
482 --- nfs-user-server-2.2beta47.orig/ugid_clnt.c
483 +++ nfs-user-server-2.2beta47/ugid_clnt.c
487 memset((char *)&clnt_res, 0, sizeof(clnt_res));
488 - if (clnt_call(clnt, AUTHENTICATE, (xdrproc_t) xdr_int, argp, (xdrproc_t) xdr_int, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
489 + if (clnt_call(clnt, AUTHENTICATE, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
496 memset((char *)&clnt_res, 0, sizeof(clnt_res));
497 - if (clnt_call(clnt, NAME_UID, (xdrproc_t) xdr_ugname, argp, (xdrproc_t) xdr_int, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
498 + if (clnt_call(clnt, NAME_UID, (xdrproc_t) xdr_ugname, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
505 memset((char *)&clnt_res, 0, sizeof(clnt_res));
506 - if (clnt_call(clnt, GROUP_GID, (xdrproc_t) xdr_ugname, argp, (xdrproc_t) xdr_int, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
507 + if (clnt_call(clnt, GROUP_GID, (xdrproc_t) xdr_ugname, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
512 static ugname clnt_res;
514 memset((char *)&clnt_res, 0, sizeof(clnt_res));
515 - if (clnt_call(clnt, UID_NAME, (xdrproc_t) xdr_int, argp, (xdrproc_t) xdr_ugname, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
516 + if (clnt_call(clnt, UID_NAME, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_ugname, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
521 static ugname clnt_res;
523 memset((char *)&clnt_res, 0, sizeof(clnt_res));
524 - if (clnt_call(clnt, GID_GROUP, (xdrproc_t) xdr_int, argp, (xdrproc_t) xdr_ugname, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
525 + if (clnt_call(clnt, GID_GROUP, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_ugname, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
529 --- nfs-user-server-2.2beta47.orig/ugid_map.c
530 +++ nfs-user-server-2.2beta47/ugid_map.c
532 * the server's port after clntudp_create, so we fetch it
535 - clnt_control(clnt, CLGET_SERVER_ADDR, &addr);
536 + clnt_control(clnt, CLGET_SERVER_ADDR, (caddr_t) &addr);
537 if (!SECURE_PORT(addr.sin_port)) {
538 Dprintf(L_ERROR, "%s on %s runs on unprivileged port.\n",
539 name, inet_ntoa(addr.sin_addr));
540 --- nfs-user-server-2.2beta47.orig/ugidd.c
541 +++ nfs-user-server-2.2beta47/ugidd.c
546 +#include "rpcmisc.h"
547 +#include "signals.h"
548 #ifdef HAVE_LIBWRAP_BUG
553 static void ugidprog_1(struct svc_req *rqstp, SVCXPRT *transp);
554 static void usage(void);
555 +static void terminate(void);
556 +static RETSIGTYPE sigterm(int sig);
558 #ifndef HAVE_RPCGEN_C
559 #define authenticate_1_svc authenticate_1
562 static struct option longopts[] = {
563 { "debug", 0, 0, 'd' },
564 + { "port", required_argument, 0, 'P' },
568 +static int ugidd_versions[] = {
589 - while ((c = getopt_long(argc, argv, "d", longopts, &longind)) != EOF) {
592 + while ((c = getopt_long(argc, argv, "dP:", longopts, &longind)) != EOF) {
596 enable_logging("ugid");
599 + port = atoi(optarg);
600 + if (port <= 0 || port > 65535) {
601 + fprintf(stderr, "ugidd: bad port number: %s\n",
611 - (void)pmap_unset(UGIDPROG, UGIDVERS);
612 + log_open("ugidd", foreground);
614 - transp = svcudp_create(RPC_ANYSOCK);
615 - if (transp == NULL) {
616 - (void)fprintf(stderr, "cannot create udp service.\n");
619 - if (!svc_register(transp, UGIDPROG, UGIDVERS, ugidprog_1, IPPROTO_UDP)) {
620 - fprintf(stderr, "unable to register (UGIDPROG, UGIDVERS, UDP)\n");
624 - transp = svctcp_create(RPC_ANYSOCK, 0, 0);
625 - if (transp == NULL) {
626 - fprintf(stderr, "cannot create tcp service.\n");
629 - if (!svc_register(transp, UGIDPROG, UGIDVERS, ugidprog_1, IPPROTO_TCP)) {
630 - fprintf(stderr, "unable to register (UGIDPROG, UGIDVERS, TCP)\n");
633 + /* Create services and register with portmapper */
634 + _rpcfdtype = SOCK_DGRAM;
635 + rpc_init("ugidd", UGIDPROG, ugidd_versions, ugidprog_1, port, 0);
638 + if (!foreground && !_rpcpmstart) {
639 if ((c = fork()) > 0)
646 - log_open("ugidd", foreground);
647 + install_signal_handler(SIGTERM, sigterm);
651 Dprintf(L_ERROR, "svc_run returned\n");
656 - fprintf(stderr, "rpc.ugidd: [-d]\n");
657 + fprintf(stderr, "rpc.ugidd: [-d] [-P port]\n");
664 bzero((char *)&argument, sizeof(argument));
665 - if (!svc_getargs(transp, xdr_argument, &argument)) {
666 + if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
667 svcerr_decode(transp);
671 if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
672 svcerr_systemerr(transp);
674 - if (!svc_freeargs(transp, xdr_argument, &argument)) {
675 + if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
676 (void)fprintf(stderr, "unable to free arguments\n");
692 + rpc_exit(UGIDPROG, ugidd_versions);
697 #else /* ENABLE_UGID_DAEMON */