Home | History | Annotate | Line # | Download | only in nfsd
nfsd.c revision 1.31.6.1
      1  1.31.6.1  minoura /*	$NetBSD: nfsd.c,v 1.31.6.1 2000/06/22 18:01:04 minoura Exp $	*/
      2      1.16      cgd 
      3       1.1      cgd /*
      4      1.11  mycroft  * Copyright (c) 1989, 1993, 1994
      5      1.11  mycroft  *	The Regents of the University of California.  All rights reserved.
      6       1.1      cgd  *
      7       1.1      cgd  * This code is derived from software contributed to Berkeley by
      8       1.1      cgd  * Rick Macklem at The University of Guelph.
      9       1.1      cgd  *
     10       1.1      cgd  * Redistribution and use in source and binary forms, with or without
     11       1.1      cgd  * modification, are permitted provided that the following conditions
     12       1.1      cgd  * are met:
     13       1.1      cgd  * 1. Redistributions of source code must retain the above copyright
     14       1.1      cgd  *    notice, this list of conditions and the following disclaimer.
     15       1.1      cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1      cgd  *    notice, this list of conditions and the following disclaimer in the
     17       1.1      cgd  *    documentation and/or other materials provided with the distribution.
     18       1.1      cgd  * 3. All advertising materials mentioning features or use of this software
     19       1.1      cgd  *    must display the following acknowledgement:
     20       1.1      cgd  *	This product includes software developed by the University of
     21       1.1      cgd  *	California, Berkeley and its contributors.
     22       1.1      cgd  * 4. Neither the name of the University nor the names of its contributors
     23       1.1      cgd  *    may be used to endorse or promote products derived from this software
     24       1.1      cgd  *    without specific prior written permission.
     25       1.1      cgd  *
     26       1.1      cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27       1.1      cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28       1.1      cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29       1.1      cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30       1.1      cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31       1.1      cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32       1.1      cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33       1.1      cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34       1.1      cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35       1.1      cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36       1.1      cgd  * SUCH DAMAGE.
     37       1.1      cgd  */
     38       1.1      cgd 
     39      1.23    lukem #include <sys/cdefs.h>
     40       1.1      cgd #ifndef lint
     41      1.23    lukem __COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\n\
     42      1.23    lukem 	The Regents of the University of California.  All rights reserved.\n");
     43       1.1      cgd #endif not lint
     44       1.1      cgd 
     45       1.1      cgd #ifndef lint
     46      1.16      cgd #if 0
     47      1.18     fvdl static char sccsid[] = "@(#)nfsd.c	8.9 (Berkeley) 3/29/95";
     48      1.16      cgd #else
     49  1.31.6.1  minoura __RCSID("$NetBSD: nfsd.c,v 1.31.6.1 2000/06/22 18:01:04 minoura Exp $");
     50      1.16      cgd #endif
     51      1.18     fvdl #endif /* not lint */
     52       1.1      cgd 
     53      1.11  mycroft #include <sys/param.h>
     54       1.1      cgd #include <sys/ioctl.h>
     55       1.1      cgd #include <sys/stat.h>
     56       1.1      cgd #include <sys/wait.h>
     57      1.11  mycroft #include <sys/uio.h>
     58      1.11  mycroft #include <sys/ucred.h>
     59       1.1      cgd #include <sys/mount.h>
     60       1.1      cgd #include <sys/socket.h>
     61       1.1      cgd #include <sys/socketvar.h>
     62      1.11  mycroft 
     63       1.1      cgd #include <rpc/rpc.h>
     64       1.1      cgd #include <rpc/pmap_clnt.h>
     65       1.1      cgd #include <rpc/pmap_prot.h>
     66      1.11  mycroft 
     67      1.11  mycroft #ifdef ISO
     68      1.11  mycroft #include <netiso/iso.h>
     69      1.11  mycroft #endif
     70       1.1      cgd #include <nfs/rpcv2.h>
     71      1.18     fvdl #include <nfs/nfsproto.h>
     72      1.11  mycroft #include <nfs/nfs.h>
     73      1.11  mycroft 
     74      1.18     fvdl #ifdef NFSKERB
     75      1.11  mycroft #include <kerberosIV/des.h>
     76      1.11  mycroft #include <kerberosIV/krb.h>
     77      1.11  mycroft #endif
     78      1.11  mycroft 
     79      1.11  mycroft #include <err.h>
     80      1.11  mycroft #include <errno.h>
     81      1.11  mycroft #include <fcntl.h>
     82      1.11  mycroft #include <grp.h>
     83      1.11  mycroft #include <pwd.h>
     84      1.11  mycroft #include <signal.h>
     85      1.11  mycroft #include <stdio.h>
     86      1.11  mycroft #include <stdlib.h>
     87      1.25    perry #include <string.h>
     88      1.19  mycroft #include <syslog.h>
     89      1.11  mycroft #include <unistd.h>
     90  1.31.6.1  minoura #include <netdb.h>
     91       1.1      cgd 
     92       1.1      cgd /* Global defs */
     93       1.1      cgd #ifdef DEBUG
     94       1.1      cgd #define	syslog(e, s)	fprintf(stderr,(s))
     95       1.1      cgd int	debug = 1;
     96       1.1      cgd #else
     97       1.1      cgd int	debug = 0;
     98       1.1      cgd #endif
     99      1.11  mycroft 
    100      1.11  mycroft struct	nfsd_srvargs nsd;
    101      1.11  mycroft 
    102      1.18     fvdl #ifdef NFSKERB
    103      1.11  mycroft char		lnam[ANAME_SZ];
    104      1.11  mycroft KTEXT_ST	kt;
    105      1.18     fvdl AUTH_DAT	kauth;
    106      1.11  mycroft char		inst[INST_SZ];
    107      1.18     fvdl struct nfsrpc_fullblock kin, kout;
    108      1.18     fvdl struct nfsrpc_fullverf kverf;
    109      1.18     fvdl NFSKERBKEY_T	kivec;
    110      1.18     fvdl struct timeval	ktv;
    111      1.18     fvdl NFSKERBKEYSCHED_T kerb_keysched;
    112      1.11  mycroft #endif
    113      1.11  mycroft 
    114      1.23    lukem int	main __P((int, char **));
    115      1.11  mycroft void	nonfs __P((int));
    116      1.11  mycroft void	reapchild __P((int));
    117      1.11  mycroft void	usage __P((void));
    118       1.1      cgd 
    119       1.1      cgd /*
    120       1.1      cgd  * Nfs server daemon mostly just a user context for nfssvc()
    121      1.11  mycroft  *
    122       1.1      cgd  * 1 - do file descriptor and signal cleanup
    123      1.11  mycroft  * 2 - fork the nfsd(s)
    124      1.11  mycroft  * 3 - create server socket(s)
    125      1.11  mycroft  * 4 - register socket with portmap
    126      1.11  mycroft  *
    127      1.28    lukem  * For connectionless protocols, just pass the socket into the kernel via
    128      1.11  mycroft  * nfssvc().
    129      1.11  mycroft  * For connection based sockets, loop doing accepts. When you get a new
    130      1.28    lukem  * socket from accept, pass the msgsock into the kernel via nfssvc().
    131       1.1      cgd  * The arguments are:
    132      1.11  mycroft  *	-c - support iso cltp clients
    133      1.11  mycroft  *	-r - reregister with portmapper
    134      1.11  mycroft  *	-t - support tcp nfs clients
    135      1.11  mycroft  *	-u - support udp nfs clients
    136      1.11  mycroft  * followed by "n" which is the number of nfsds' to fork off
    137       1.1      cgd  */
    138      1.11  mycroft int
    139      1.23    lukem main(argc, argv)
    140       1.1      cgd 	int argc;
    141      1.23    lukem 	char *argv[];
    142       1.1      cgd {
    143      1.11  mycroft 	struct nfsd_args nfsdargs;
    144  1.31.6.1  minoura 	struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
    145  1.31.6.1  minoura 	struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
    146  1.31.6.1  minoura 	struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
    147  1.31.6.1  minoura 	struct sockaddr_in inetpeer;
    148  1.31.6.1  minoura 	struct sockaddr_in6 inet6peer;
    149      1.11  mycroft #ifdef ISO
    150      1.11  mycroft 	struct sockaddr_iso isoaddr, isopeer;
    151      1.11  mycroft #endif
    152      1.11  mycroft 	fd_set ready, sockbits;
    153      1.11  mycroft 	int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
    154  1.31.6.1  minoura 	int nfsdcnt, nfssvc_flag, on = 1, reregister, sock, tcpflag, tcpsock;
    155  1.31.6.1  minoura 	int tcp6sock, ip6flag;
    156  1.31.6.1  minoura 	int tp4cnt, tp4flag, tpipcnt, tpipflag, udpflag, ecode, s;
    157      1.23    lukem #ifdef NFSKERB
    158      1.23    lukem 	struct group *grp;
    159      1.23    lukem 	struct passwd *pwd;
    160      1.23    lukem 	struct ucred *cr;
    161      1.23    lukem 	struct timeval ktv;
    162      1.23    lukem 	int tp4sock, tpipsock;
    163      1.11  mycroft 	char *cp, **cpp;
    164      1.23    lukem #endif
    165      1.11  mycroft 
    166      1.11  mycroft #define	MAXNFSDCNT	20
    167      1.11  mycroft #define	DEFNFSDCNT	 4
    168      1.11  mycroft 	nfsdcnt = DEFNFSDCNT;
    169      1.11  mycroft 	cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
    170  1.31.6.1  minoura 	tpipflag = udpflag = ip6flag = 0;
    171      1.23    lukem 	maxsock = tcpsock = 0;
    172      1.11  mycroft #ifdef ISO
    173  1.31.6.1  minoura #define	GETOPT	"6cn:rtu"
    174      1.11  mycroft #define	USAGE	"[-crtu] [-n num_servers]"
    175      1.11  mycroft #else
    176  1.31.6.1  minoura #define	GETOPT	"6n:rtu"
    177      1.11  mycroft #define	USAGE	"[-rtu] [-n num_servers]"
    178      1.11  mycroft #endif
    179      1.30  thorpej 	while ((ch = getopt(argc, argv, GETOPT)) != -1) {
    180      1.11  mycroft 		switch (ch) {
    181  1.31.6.1  minoura 		case '6':
    182  1.31.6.1  minoura 			ip6flag = 1;
    183  1.31.6.1  minoura 			s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    184  1.31.6.1  minoura 			if (s < 0 && (errno == EPROTONOSUPPORT ||
    185  1.31.6.1  minoura 			    errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
    186  1.31.6.1  minoura 				ip6flag = 0;
    187  1.31.6.1  minoura 			else
    188  1.31.6.1  minoura 				close(s);
    189  1.31.6.1  minoura 			break;
    190      1.11  mycroft 		case 'n':
    191      1.11  mycroft 			nfsdcnt = atoi(optarg);
    192      1.11  mycroft 			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
    193      1.21     fvdl 				warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
    194      1.11  mycroft 				nfsdcnt = DEFNFSDCNT;
    195      1.11  mycroft 			}
    196      1.11  mycroft 			break;
    197       1.1      cgd 		case 'r':
    198      1.11  mycroft 			reregister = 1;
    199       1.1      cgd 			break;
    200       1.1      cgd 		case 't':
    201      1.11  mycroft 			tcpflag = 1;
    202       1.1      cgd 			break;
    203       1.1      cgd 		case 'u':
    204      1.11  mycroft 			udpflag = 1;
    205      1.11  mycroft 			break;
    206      1.11  mycroft #ifdef ISO
    207      1.11  mycroft 		case 'c':
    208      1.11  mycroft 			cltpflag = 1;
    209       1.1      cgd 			break;
    210      1.11  mycroft #ifdef notyet
    211      1.11  mycroft 		case 'i':
    212      1.11  mycroft 			tp4cnt = 1;
    213      1.11  mycroft 			break;
    214      1.11  mycroft 		case 'p':
    215      1.11  mycroft 			tpipcnt = 1;
    216      1.11  mycroft 			break;
    217      1.11  mycroft #endif /* notyet */
    218      1.11  mycroft #endif /* ISO */
    219       1.1      cgd 		default:
    220       1.1      cgd 		case '?':
    221       1.1      cgd 			usage();
    222      1.11  mycroft 		};
    223      1.30  thorpej 	}
    224      1.11  mycroft 	argv += optind;
    225      1.11  mycroft 	argc -= optind;
    226       1.1      cgd 
    227       1.1      cgd 	/*
    228      1.11  mycroft 	 * XXX
    229      1.11  mycroft 	 * Backward compatibility, trailing number is the count of daemons.
    230       1.1      cgd 	 */
    231      1.11  mycroft 	if (argc > 1)
    232      1.11  mycroft 		usage();
    233      1.11  mycroft 	if (argc == 1) {
    234      1.11  mycroft 		nfsdcnt = atoi(argv[0]);
    235      1.11  mycroft 		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
    236      1.21     fvdl 			warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
    237      1.11  mycroft 			nfsdcnt = DEFNFSDCNT;
    238      1.11  mycroft 		}
    239       1.1      cgd 	}
    240      1.31    soren 
    241      1.31    soren 	/*
    242      1.31    soren 	 * If none of TCP or UDP are specified, default to UDP only.
    243      1.31    soren 	 */
    244      1.31    soren 	if (tcpflag == 0 && udpflag == 0)
    245      1.31    soren 		udpflag = 1;
    246       1.1      cgd 
    247       1.1      cgd 	if (debug == 0) {
    248       1.1      cgd 		daemon(0, 0);
    249      1.11  mycroft 		(void)signal(SIGHUP, SIG_IGN);
    250      1.11  mycroft 		(void)signal(SIGINT, SIG_IGN);
    251      1.11  mycroft 		(void)signal(SIGQUIT, SIG_IGN);
    252      1.11  mycroft 		(void)signal(SIGSYS, nonfs);
    253       1.1      cgd 	}
    254      1.11  mycroft 	(void)signal(SIGCHLD, reapchild);
    255      1.11  mycroft 
    256  1.31.6.1  minoura 	if (udpflag) {
    257  1.31.6.1  minoura 		memset(&hints, 0, sizeof hints);
    258  1.31.6.1  minoura 		hints.ai_flags = AI_PASSIVE;
    259  1.31.6.1  minoura 		hints.ai_family = PF_INET;
    260  1.31.6.1  minoura 		hints.ai_socktype = SOCK_DGRAM;
    261  1.31.6.1  minoura 		hints.ai_protocol = IPPROTO_UDP;
    262  1.31.6.1  minoura 
    263  1.31.6.1  minoura 		ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
    264  1.31.6.1  minoura 		if (ecode != 0) {
    265  1.31.6.1  minoura 			syslog(LOG_ERR, "getaddrinfo udp: %s",
    266  1.31.6.1  minoura 			    gai_strerror(ecode));
    267  1.31.6.1  minoura 			exit(1);
    268  1.31.6.1  minoura 		}
    269  1.31.6.1  minoura 
    270  1.31.6.1  minoura 		nconf_udp = getnetconfigent("udp");
    271  1.31.6.1  minoura 
    272  1.31.6.1  minoura 		if (nconf_udp == NULL)
    273  1.31.6.1  minoura 			err(1, "getnetconfigent udp failed");
    274  1.31.6.1  minoura 
    275  1.31.6.1  minoura 		nb_udp.buf = ai_udp->ai_addr;
    276  1.31.6.1  minoura 		nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
    277  1.31.6.1  minoura 		if (reregister)
    278  1.31.6.1  minoura 			if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp))
    279  1.31.6.1  minoura 				err(1, "rpcb_set udp failed");
    280  1.31.6.1  minoura 	}
    281  1.31.6.1  minoura 
    282  1.31.6.1  minoura 	if (tcpflag) {
    283  1.31.6.1  minoura 		memset(&hints, 0, sizeof hints);
    284  1.31.6.1  minoura 		hints.ai_flags = AI_PASSIVE;
    285  1.31.6.1  minoura 		hints.ai_family = PF_INET;
    286  1.31.6.1  minoura 		hints.ai_socktype = SOCK_STREAM;
    287  1.31.6.1  minoura 		hints.ai_protocol = IPPROTO_TCP;
    288  1.31.6.1  minoura 
    289  1.31.6.1  minoura 		ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
    290  1.31.6.1  minoura 		if (ecode != 0) {
    291  1.31.6.1  minoura 			syslog(LOG_ERR, "getaddrinfo udp: %s",
    292  1.31.6.1  minoura 			    gai_strerror(ecode));
    293  1.31.6.1  minoura 			exit(1);
    294  1.31.6.1  minoura 		}
    295  1.31.6.1  minoura 
    296  1.31.6.1  minoura 		nconf_tcp = getnetconfigent("tcp");
    297  1.31.6.1  minoura 
    298  1.31.6.1  minoura 		if (nconf_tcp == NULL)
    299  1.31.6.1  minoura 			err(1, "getnetconfigent tcp failed");
    300  1.31.6.1  minoura 
    301  1.31.6.1  minoura 		nb_tcp.buf = ai_tcp->ai_addr;
    302  1.31.6.1  minoura 		nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
    303  1.31.6.1  minoura 		if (reregister)
    304  1.31.6.1  minoura 			if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp))
    305  1.31.6.1  minoura 				err(1, "rpcb_set tcp failed");
    306       1.8      cgd 	}
    307  1.31.6.1  minoura 
    308  1.31.6.1  minoura 	if (udpflag && ip6flag) {
    309  1.31.6.1  minoura 		memset(&hints, 0, sizeof hints);
    310  1.31.6.1  minoura 		hints.ai_flags = AI_PASSIVE;
    311  1.31.6.1  minoura 		hints.ai_family = PF_INET6;
    312  1.31.6.1  minoura 		hints.ai_socktype = SOCK_DGRAM;
    313  1.31.6.1  minoura 		hints.ai_protocol = IPPROTO_UDP;
    314  1.31.6.1  minoura 
    315  1.31.6.1  minoura 		ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
    316  1.31.6.1  minoura 		if (ecode != 0) {
    317  1.31.6.1  minoura 			syslog(LOG_ERR, "getaddrinfo udp: %s",
    318  1.31.6.1  minoura 			    gai_strerror(ecode));
    319  1.31.6.1  minoura 			exit(1);
    320  1.31.6.1  minoura 		}
    321  1.31.6.1  minoura 
    322  1.31.6.1  minoura 		nconf_udp6 = getnetconfigent("udp6");
    323  1.31.6.1  minoura 
    324  1.31.6.1  minoura 		if (nconf_udp6 == NULL)
    325  1.31.6.1  minoura 			err(1, "getnetconfigent udp6 failed");
    326  1.31.6.1  minoura 
    327  1.31.6.1  minoura 		nb_udp6.buf = ai_udp6->ai_addr;
    328  1.31.6.1  minoura 		nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
    329  1.31.6.1  minoura 		if (reregister)
    330  1.31.6.1  minoura 			if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6))
    331  1.31.6.1  minoura 				err(1, "rpcb_set udp6 failed");
    332  1.31.6.1  minoura 	}
    333  1.31.6.1  minoura 
    334  1.31.6.1  minoura 	if (tcpflag && ip6flag) {
    335  1.31.6.1  minoura 		memset(&hints, 0, sizeof hints);
    336  1.31.6.1  minoura 		hints.ai_flags = AI_PASSIVE;
    337  1.31.6.1  minoura 		hints.ai_family = PF_INET6;
    338  1.31.6.1  minoura 		hints.ai_socktype = SOCK_STREAM;
    339  1.31.6.1  minoura 		hints.ai_protocol = IPPROTO_TCP;
    340  1.31.6.1  minoura 
    341  1.31.6.1  minoura 		ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
    342  1.31.6.1  minoura 		if (ecode != 0) {
    343  1.31.6.1  minoura 			syslog(LOG_ERR, "getaddrinfo udp: %s",
    344  1.31.6.1  minoura 			    gai_strerror(ecode));
    345  1.31.6.1  minoura 			exit(1);
    346  1.31.6.1  minoura 		}
    347  1.31.6.1  minoura 
    348  1.31.6.1  minoura 		nconf_tcp6 = getnetconfigent("tcp6");
    349  1.31.6.1  minoura 
    350  1.31.6.1  minoura 		if (nconf_tcp6 == NULL)
    351  1.31.6.1  minoura 			err(1, "getnetconfigent tcp6 failed");
    352  1.31.6.1  minoura 
    353  1.31.6.1  minoura 		nb_tcp6.buf = ai_tcp6->ai_addr;
    354  1.31.6.1  minoura 		nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
    355  1.31.6.1  minoura 		if (reregister)
    356  1.31.6.1  minoura 			if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6))
    357  1.31.6.1  minoura 				err(1, "rpcb_set tcp6 failed");
    358  1.31.6.1  minoura 	}
    359  1.31.6.1  minoura 
    360      1.11  mycroft 	openlog("nfsd:", LOG_PID, LOG_DAEMON);
    361      1.11  mycroft 
    362      1.11  mycroft 	for (i = 0; i < nfsdcnt; i++) {
    363      1.11  mycroft 		switch (fork()) {
    364      1.11  mycroft 		case -1:
    365      1.11  mycroft 			syslog(LOG_ERR, "fork: %m");
    366      1.11  mycroft 			exit (1);
    367      1.11  mycroft 		case 0:
    368      1.11  mycroft 			break;
    369      1.11  mycroft 		default:
    370      1.11  mycroft 			continue;
    371       1.1      cgd 		}
    372      1.11  mycroft 
    373      1.13  mycroft 		setproctitle("server");
    374      1.11  mycroft 		nfssvc_flag = NFSSVC_NFSD;
    375      1.11  mycroft 		nsd.nsd_nfsd = NULL;
    376      1.18     fvdl #ifdef NFSKERB
    377      1.18     fvdl 		if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF ||
    378      1.18     fvdl 		    sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK)
    379      1.18     fvdl 		    syslog(LOG_ERR, "Yikes NFSKERB structs not packed!");
    380      1.18     fvdl 		nsd.nsd_authstr = (u_char *)&kt;
    381      1.18     fvdl 		nsd.nsd_authlen = sizeof (kt);
    382      1.18     fvdl 		nsd.nsd_verfstr = (u_char *)&kverf;
    383      1.18     fvdl 		nsd.nsd_verflen = sizeof (kverf);
    384      1.11  mycroft #endif
    385      1.11  mycroft 		while (nfssvc(nfssvc_flag, &nsd) < 0) {
    386      1.11  mycroft 			if (errno != ENEEDAUTH) {
    387      1.11  mycroft 				syslog(LOG_ERR, "nfssvc: %m");
    388      1.11  mycroft 				exit(1);
    389      1.11  mycroft 			}
    390      1.11  mycroft 			nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
    391      1.18     fvdl #ifdef NFSKERB
    392      1.18     fvdl 			/*
    393      1.18     fvdl 			 * Get the Kerberos ticket out of the authenticator
    394      1.18     fvdl 			 * verify it and convert the principal name to a user
    395      1.18     fvdl 			 * name. The user name is then converted to a set of
    396      1.18     fvdl 			 * user credentials via the password and group file.
    397      1.18     fvdl 			 * Finally, decrypt the timestamp and validate it.
    398      1.18     fvdl 			 * For more info see the IETF Draft "Authentication
    399      1.18     fvdl 			 * in ONC RPC".
    400      1.18     fvdl 			 */
    401      1.18     fvdl 			kt.length = ntohl(kt.length);
    402      1.18     fvdl 			if (gettimeofday(&ktv, (struct timezone *)0) == 0 &&
    403      1.18     fvdl 			    kt.length > 0 && kt.length <=
    404      1.18     fvdl 			    (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) {
    405      1.30  thorpej 				kin.w1 = NFS_KERBW1(kt);
    406      1.30  thorpej 				kt.mbz = 0;
    407      1.30  thorpej 				(void)strcpy(inst, "*");
    408      1.30  thorpej 				if (krb_rd_req(&kt, NFS_KERBSRV,
    409      1.30  thorpej 				     inst, nsd.nsd_haddr, &kauth, "") ==
    410      1.30  thorpej 				     RD_AP_OK &&
    411      1.30  thorpej 				    krb_kntoln(&kauth, lnam) == KSUCCESS &&
    412      1.30  thorpej 				    (pwd = getpwnam(lnam)) != NULL) {
    413      1.30  thorpej 					cr = &nsd.nsd_cr;
    414      1.30  thorpej 					cr->cr_uid = pwd->pw_uid;
    415      1.30  thorpej 					cr->cr_groups[0] = pwd->pw_gid;
    416      1.30  thorpej 					cr->cr_ngroups = 1;
    417      1.30  thorpej 					setgrent();
    418      1.30  thorpej 					while ((grp = getgrent()) != NULL) {
    419      1.30  thorpej 						if (grp->gr_gid ==
    420      1.30  thorpej 						    cr->cr_groups[0])
    421      1.30  thorpej 							continue;
    422      1.30  thorpej 						for (cpp = grp->gr_mem;
    423      1.30  thorpej 						    *cpp != NULL; ++cpp)
    424      1.30  thorpej 							if (!strcmp(*cpp, lnam))
    425      1.30  thorpej 								break;
    426      1.30  thorpej 						if (*cpp == NULL)
    427      1.30  thorpej 							continue;
    428      1.30  thorpej 						cr->cr_groups[cr->cr_ngroups++]
    429      1.30  thorpej 						    = grp->gr_gid;
    430      1.30  thorpej 						if (cr->cr_ngroups == NGROUPS)
    431      1.11  mycroft 							break;
    432      1.30  thorpej 					}
    433      1.30  thorpej 					endgrent();
    434      1.30  thorpej 
    435      1.30  thorpej 					/*
    436      1.30  thorpej 					 * Get the timestamp verifier out of
    437      1.30  thorpej 					 * the authenticator and verifier
    438      1.30  thorpej 					 * strings.
    439      1.30  thorpej 					 */
    440      1.30  thorpej 					kin.t1 = kverf.t1;
    441      1.30  thorpej 					kin.t2 = kverf.t2;
    442      1.30  thorpej 					kin.w2 = kverf.w2;
    443      1.30  thorpej 					memset((caddr_t)kivec, 0,
    444      1.30  thorpej 					    sizeof(kivec));
    445      1.30  thorpej 					memmove((caddr_t)nsd.nsd_key,
    446      1.30  thorpej 					    (caddr_t)kauth.session,
    447      1.30  thorpej 					    sizeof(kauth.session));
    448      1.30  thorpej 
    449      1.30  thorpej 					/*
    450      1.30  thorpej 					 * Decrypt the timestamp verifier
    451      1.30  thorpej 					 * in CBC mode.
    452      1.30  thorpej 					 */
    453      1.30  thorpej 					XXX
    454      1.30  thorpej 
    455      1.30  thorpej 					/*
    456      1.30  thorpej 					 * Validate the timestamp verifier, to
    457      1.30  thorpej 					 * check that the session key is ok.
    458      1.30  thorpej 					 */
    459      1.30  thorpej 					nsd.nsd_timestamp.tv_sec =
    460      1.30  thorpej 					    ntohl(kout.t1);
    461      1.30  thorpej 					nsd.nsd_timestamp.tv_usec =
    462      1.30  thorpej 					    ntohl(kout.t2);
    463      1.30  thorpej 					nsd.nsd_ttl = ntohl(kout.w1);
    464      1.30  thorpej 					if ((nsd.nsd_ttl - 1) == ntohl(kout.w2))
    465      1.30  thorpej 					    nfssvc_flag =
    466      1.30  thorpej 					        NFSSVC_NFSD | NFSSVC_AUTHIN;
    467      1.11  mycroft 				}
    468      1.11  mycroft 			}
    469      1.18     fvdl #endif /* NFSKERB */
    470       1.1      cgd 		}
    471       1.1      cgd 		exit(0);
    472       1.1      cgd 	}
    473      1.11  mycroft 
    474      1.11  mycroft 	/* If we are serving udp, set up the socket. */
    475       1.1      cgd 	if (udpflag) {
    476  1.31.6.1  minoura 		if ((sock = socket(ai_udp->ai_family, ai_udp->ai_socktype,
    477  1.31.6.1  minoura 		    ai_udp->ai_protocol)) < 0) {
    478      1.11  mycroft 			syslog(LOG_ERR, "can't create udp socket");
    479       1.1      cgd 			exit(1);
    480       1.1      cgd 		}
    481  1.31.6.1  minoura 		if (bind(sock, ai_udp->ai_addr, ai_udp->ai_addrlen) < 0) {
    482      1.11  mycroft 			syslog(LOG_ERR, "can't bind udp addr");
    483       1.1      cgd 			exit(1);
    484       1.1      cgd 		}
    485  1.31.6.1  minoura 		if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp) ||
    486  1.31.6.1  minoura 		    !rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)) {
    487      1.11  mycroft 			syslog(LOG_ERR, "can't register with udp portmap");
    488      1.11  mycroft 			exit(1);
    489      1.11  mycroft 		}
    490      1.11  mycroft 		nfsdargs.sock = sock;
    491      1.11  mycroft 		nfsdargs.name = NULL;
    492      1.11  mycroft 		nfsdargs.namelen = 0;
    493      1.11  mycroft 		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
    494  1.31.6.1  minoura 			syslog(LOG_ERR, "can't add UDP socket");
    495  1.31.6.1  minoura 			exit(1);
    496  1.31.6.1  minoura 		}
    497  1.31.6.1  minoura 		(void)close(sock);
    498  1.31.6.1  minoura 	}
    499  1.31.6.1  minoura 
    500  1.31.6.1  minoura 	if (udpflag &&ip6flag) {
    501  1.31.6.1  minoura 		if ((sock = socket(ai_udp6->ai_family, ai_udp6->ai_socktype,
    502  1.31.6.1  minoura 		    ai_udp6->ai_protocol)) < 0) {
    503  1.31.6.1  minoura 			syslog(LOG_ERR, "can't create udp socket");
    504  1.31.6.1  minoura 			exit(1);
    505  1.31.6.1  minoura 		}
    506  1.31.6.1  minoura 		if (setsockopt(sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
    507  1.31.6.1  minoura 		    &on, sizeof on) < 0) {
    508  1.31.6.1  minoura 			syslog(LOG_ERR, "can't set v6-only binding for udp6 "
    509  1.31.6.1  minoura 					"socket: %m");
    510  1.31.6.1  minoura 			exit(1);
    511  1.31.6.1  minoura 		}
    512  1.31.6.1  minoura 		if (bind(sock, ai_udp6->ai_addr, ai_udp6->ai_addrlen) < 0) {
    513  1.31.6.1  minoura 			syslog(LOG_ERR, "can't bind udp addr");
    514  1.31.6.1  minoura 			exit(1);
    515  1.31.6.1  minoura 		}
    516  1.31.6.1  minoura 		if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6) ||
    517  1.31.6.1  minoura 		    !rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)) {
    518  1.31.6.1  minoura 			syslog(LOG_ERR, "can't register with udp portmap");
    519  1.31.6.1  minoura 			exit(1);
    520  1.31.6.1  minoura 		}
    521  1.31.6.1  minoura 		nfsdargs.sock = sock;
    522  1.31.6.1  minoura 		nfsdargs.name = NULL;
    523  1.31.6.1  minoura 		nfsdargs.namelen = 0;
    524  1.31.6.1  minoura 		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
    525  1.31.6.1  minoura 			syslog(LOG_ERR, "can't add UDP6 socket");
    526      1.11  mycroft 			exit(1);
    527      1.11  mycroft 		}
    528      1.11  mycroft 		(void)close(sock);
    529      1.11  mycroft 	}
    530      1.11  mycroft 
    531      1.11  mycroft #ifdef ISO
    532      1.11  mycroft 	/* If we are serving cltp, set up the socket. */
    533      1.11  mycroft 	if (cltpflag) {
    534      1.11  mycroft 		if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) {
    535      1.11  mycroft 			syslog(LOG_ERR, "can't create cltp socket");
    536      1.11  mycroft 			exit(1);
    537      1.11  mycroft 		}
    538      1.11  mycroft 		memset(&isoaddr, 0, sizeof(isoaddr));
    539      1.11  mycroft 		isoaddr.siso_family = AF_ISO;
    540      1.11  mycroft 		isoaddr.siso_tlen = 2;
    541      1.11  mycroft 		cp = TSEL(&isoaddr);
    542      1.11  mycroft 		*cp++ = (NFS_PORT >> 8);
    543      1.11  mycroft 		*cp = (NFS_PORT & 0xff);
    544      1.11  mycroft 		isoaddr.siso_len = sizeof(isoaddr);
    545      1.11  mycroft 		if (bind(sock,
    546      1.11  mycroft 		    (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) {
    547      1.11  mycroft 			syslog(LOG_ERR, "can't bind cltp addr");
    548       1.1      cgd 			exit(1);
    549       1.1      cgd 		}
    550      1.11  mycroft #ifdef notyet
    551       1.1      cgd 		/*
    552      1.11  mycroft 		 * XXX
    553      1.11  mycroft 		 * Someday this should probably use "rpcbind", the son of
    554      1.11  mycroft 		 * portmap.
    555       1.1      cgd 		 */
    556      1.11  mycroft 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
    557      1.11  mycroft 			syslog(LOG_ERR, "can't register with udp portmap");
    558      1.11  mycroft 			exit(1);
    559      1.11  mycroft 		}
    560      1.11  mycroft #endif /* notyet */
    561      1.11  mycroft 		nfsdargs.sock = sock;
    562      1.11  mycroft 		nfsdargs.name = NULL;
    563      1.11  mycroft 		nfsdargs.namelen = 0;
    564      1.11  mycroft 		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
    565      1.11  mycroft 			syslog(LOG_ERR, "can't add UDP socket");
    566      1.11  mycroft 			exit(1);
    567      1.11  mycroft 		}
    568       1.1      cgd 		close(sock);
    569       1.1      cgd 	}
    570      1.11  mycroft #endif /* ISO */
    571       1.1      cgd 
    572      1.11  mycroft 	/* Now set up the master server socket waiting for tcp connections. */
    573      1.11  mycroft 	on = 1;
    574      1.11  mycroft 	FD_ZERO(&sockbits);
    575      1.11  mycroft 	connect_type_cnt = 0;
    576       1.1      cgd 	if (tcpflag) {
    577  1.31.6.1  minoura 		if ((tcpsock = socket(ai_tcp->ai_family, ai_tcp->ai_socktype,
    578  1.31.6.1  minoura 		    ai_tcp->ai_protocol)) < 0) {
    579      1.11  mycroft 			syslog(LOG_ERR, "can't create tcp socket");
    580      1.11  mycroft 			exit(1);
    581      1.11  mycroft 		}
    582      1.11  mycroft 		if (setsockopt(tcpsock,
    583      1.11  mycroft 		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
    584      1.11  mycroft 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
    585  1.31.6.1  minoura 		if (bind(tcpsock, ai_tcp->ai_addr, ai_tcp->ai_addrlen) < 0) {
    586      1.11  mycroft 			syslog(LOG_ERR, "can't bind tcp addr");
    587      1.11  mycroft 			exit(1);
    588      1.11  mycroft 		}
    589      1.11  mycroft 		if (listen(tcpsock, 5) < 0) {
    590      1.11  mycroft 			syslog(LOG_ERR, "listen failed");
    591      1.11  mycroft 			exit(1);
    592      1.11  mycroft 		}
    593  1.31.6.1  minoura 		if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp) ||
    594  1.31.6.1  minoura 		    !rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp)) {
    595  1.31.6.1  minoura 			syslog(LOG_ERR, "can't register tcp with rpcbind");
    596      1.11  mycroft 			exit(1);
    597      1.11  mycroft 		}
    598      1.11  mycroft 		FD_SET(tcpsock, &sockbits);
    599      1.11  mycroft 		maxsock = tcpsock;
    600      1.11  mycroft 		connect_type_cnt++;
    601      1.11  mycroft 	}
    602       1.1      cgd 
    603  1.31.6.1  minoura 	if (tcpflag && ip6flag) {
    604  1.31.6.1  minoura 		if ((tcp6sock = socket(ai_tcp6->ai_family, ai_tcp6->ai_socktype,
    605  1.31.6.1  minoura 		    ai_tcp6->ai_protocol)) < 0) {
    606  1.31.6.1  minoura 			syslog(LOG_ERR, "can't create tcp socket");
    607  1.31.6.1  minoura 			exit(1);
    608  1.31.6.1  minoura 		}
    609  1.31.6.1  minoura 		if (setsockopt(tcp6sock,
    610  1.31.6.1  minoura 		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
    611  1.31.6.1  minoura 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
    612  1.31.6.1  minoura 		if (setsockopt(tcp6sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
    613  1.31.6.1  minoura 		    &on, sizeof on) < 0) {
    614  1.31.6.1  minoura 			syslog(LOG_ERR, "can't set v6-only binding for tcp6 "
    615  1.31.6.1  minoura 					"socket: %m");
    616  1.31.6.1  minoura 			exit(1);
    617  1.31.6.1  minoura 		}
    618  1.31.6.1  minoura 		if (bind(tcp6sock, ai_tcp6->ai_addr, ai_tcp6->ai_addrlen) < 0) {
    619  1.31.6.1  minoura 			syslog(LOG_ERR, "can't bind tcp6 addr");
    620  1.31.6.1  minoura 			exit(1);
    621  1.31.6.1  minoura 		}
    622  1.31.6.1  minoura 		if (listen(tcp6sock, 5) < 0) {
    623  1.31.6.1  minoura 			syslog(LOG_ERR, "listen failed");
    624  1.31.6.1  minoura 			exit(1);
    625  1.31.6.1  minoura 		}
    626  1.31.6.1  minoura 		if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6) ||
    627  1.31.6.1  minoura 		    !rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)) {
    628  1.31.6.1  minoura 			syslog(LOG_ERR, "can't register tcp6 with rpcbind");
    629  1.31.6.1  minoura 			exit(1);
    630  1.31.6.1  minoura 		}
    631  1.31.6.1  minoura 		FD_SET(tcp6sock, &sockbits);
    632  1.31.6.1  minoura 		maxsock = tcp6sock;
    633  1.31.6.1  minoura 		connect_type_cnt++;
    634  1.31.6.1  minoura 	}
    635  1.31.6.1  minoura 
    636      1.11  mycroft #ifdef notyet
    637      1.11  mycroft 	/* Now set up the master server socket waiting for tp4 connections. */
    638      1.11  mycroft 	if (tp4flag) {
    639      1.11  mycroft 		if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) {
    640      1.11  mycroft 			syslog(LOG_ERR, "can't create tp4 socket");
    641       1.1      cgd 			exit(1);
    642       1.1      cgd 		}
    643      1.11  mycroft 		if (setsockopt(tp4sock,
    644      1.11  mycroft 		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
    645       1.1      cgd 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
    646      1.11  mycroft 		memset(&isoaddr, 0, sizeof(isoaddr));
    647      1.11  mycroft 		isoaddr.siso_family = AF_ISO;
    648      1.11  mycroft 		isoaddr.siso_tlen = 2;
    649      1.11  mycroft 		cp = TSEL(&isoaddr);
    650      1.11  mycroft 		*cp++ = (NFS_PORT >> 8);
    651      1.11  mycroft 		*cp = (NFS_PORT & 0xff);
    652      1.11  mycroft 		isoaddr.siso_len = sizeof(isoaddr);
    653      1.11  mycroft 		if (bind(tp4sock,
    654      1.12  mycroft 		    (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) {
    655      1.11  mycroft 			syslog(LOG_ERR, "can't bind tp4 addr");
    656       1.1      cgd 			exit(1);
    657       1.1      cgd 		}
    658      1.11  mycroft 		if (listen(tp4sock, 5) < 0) {
    659      1.11  mycroft 			syslog(LOG_ERR, "listen failed");
    660       1.1      cgd 			exit(1);
    661       1.1      cgd 		}
    662      1.11  mycroft 		/*
    663      1.11  mycroft 		 * XXX
    664      1.11  mycroft 		 * Someday this should probably use "rpcbind", the son of
    665      1.11  mycroft 		 * portmap.
    666      1.11  mycroft 		 */
    667       1.1      cgd 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
    668      1.11  mycroft 			syslog(LOG_ERR, "can't register tcp with portmap");
    669      1.11  mycroft 			exit(1);
    670      1.11  mycroft 		}
    671      1.11  mycroft 		FD_SET(tp4sock, &sockbits);
    672      1.11  mycroft 		maxsock = tp4sock;
    673      1.11  mycroft 		connect_type_cnt++;
    674      1.11  mycroft 	}
    675      1.11  mycroft 
    676      1.11  mycroft 	/* Now set up the master server socket waiting for tpip connections. */
    677      1.11  mycroft 	if (tpipflag) {
    678      1.11  mycroft 		if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) {
    679      1.11  mycroft 			syslog(LOG_ERR, "can't create tpip socket");
    680      1.11  mycroft 			exit(1);
    681      1.11  mycroft 		}
    682      1.11  mycroft 		if (setsockopt(tpipsock,
    683      1.11  mycroft 		    SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
    684      1.11  mycroft 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
    685      1.11  mycroft 		inetaddr.sin_family = AF_INET;
    686      1.11  mycroft 		inetaddr.sin_addr.s_addr = INADDR_ANY;
    687      1.11  mycroft 		inetaddr.sin_port = htons(NFS_PORT);
    688      1.11  mycroft 		inetaddr.sin_len = sizeof(inetaddr);
    689      1.20  mycroft 		memset(inetaddr.sin_zero, 0, sizeof(inetaddr.sin_zero));
    690      1.11  mycroft 		if (bind(tpipsock,
    691      1.11  mycroft 		    (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) {
    692      1.11  mycroft 			syslog(LOG_ERR, "can't bind tcp addr");
    693      1.11  mycroft 			exit(1);
    694      1.11  mycroft 		}
    695      1.11  mycroft 		if (listen(tpipsock, 5) < 0) {
    696      1.11  mycroft 			syslog(LOG_ERR, "listen failed");
    697       1.1      cgd 			exit(1);
    698       1.1      cgd 		}
    699       1.1      cgd 		/*
    700      1.11  mycroft 		 * XXX
    701      1.11  mycroft 		 * Someday this should probably use "rpcbind", the son of
    702      1.11  mycroft 		 * portmap.
    703       1.1      cgd 		 */
    704      1.11  mycroft 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
    705      1.11  mycroft 			syslog(LOG_ERR, "can't register tcp with portmap");
    706      1.11  mycroft 			exit(1);
    707      1.11  mycroft 		}
    708      1.11  mycroft 		FD_SET(tpipsock, &sockbits);
    709      1.11  mycroft 		maxsock = tpipsock;
    710      1.11  mycroft 		connect_type_cnt++;
    711      1.11  mycroft 	}
    712      1.11  mycroft #endif /* notyet */
    713      1.11  mycroft 
    714      1.11  mycroft 	if (connect_type_cnt == 0)
    715      1.11  mycroft 		exit(0);
    716      1.11  mycroft 
    717      1.13  mycroft 	setproctitle("master");
    718      1.11  mycroft 
    719      1.11  mycroft 	/*
    720      1.11  mycroft 	 * Loop forever accepting connections and passing the sockets
    721      1.11  mycroft 	 * into the kernel for the mounts.
    722      1.11  mycroft 	 */
    723      1.11  mycroft 	for (;;) {
    724      1.11  mycroft 		ready = sockbits;
    725      1.11  mycroft 		if (connect_type_cnt > 1) {
    726      1.11  mycroft 			if (select(maxsock + 1,
    727      1.11  mycroft 			    &ready, NULL, NULL, NULL) < 1) {
    728      1.11  mycroft 				syslog(LOG_ERR, "select failed: %m");
    729      1.11  mycroft 				exit(1);
    730      1.11  mycroft 			}
    731      1.11  mycroft 		}
    732      1.11  mycroft 		if (tcpflag && FD_ISSET(tcpsock, &ready)) {
    733      1.11  mycroft 			len = sizeof(inetpeer);
    734      1.11  mycroft 			if ((msgsock = accept(tcpsock,
    735      1.11  mycroft 			    (struct sockaddr *)&inetpeer, &len)) < 0) {
    736      1.11  mycroft 				syslog(LOG_ERR, "accept failed: %m");
    737       1.1      cgd 				exit(1);
    738       1.1      cgd 			}
    739      1.11  mycroft 			memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero));
    740      1.11  mycroft 			if (setsockopt(msgsock, SOL_SOCKET,
    741      1.11  mycroft 			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
    742      1.11  mycroft 				syslog(LOG_ERR,
    743      1.11  mycroft 				    "setsockopt SO_KEEPALIVE: %m");
    744      1.11  mycroft 			nfsdargs.sock = msgsock;
    745      1.11  mycroft 			nfsdargs.name = (caddr_t)&inetpeer;
    746      1.11  mycroft 			nfsdargs.namelen = sizeof(inetpeer);
    747      1.11  mycroft 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
    748      1.11  mycroft 			(void)close(msgsock);
    749      1.11  mycroft 		}
    750  1.31.6.1  minoura 
    751  1.31.6.1  minoura 		if (tcpflag && ip6flag && FD_ISSET(tcp6sock, &ready)) {
    752  1.31.6.1  minoura 			len = sizeof(inet6peer);
    753  1.31.6.1  minoura 			if ((msgsock = accept(tcp6sock,
    754  1.31.6.1  minoura 			    (struct sockaddr *)&inet6peer, &len)) < 0) {
    755  1.31.6.1  minoura 				syslog(LOG_ERR, "accept failed: %m");
    756  1.31.6.1  minoura 				exit(1);
    757  1.31.6.1  minoura 			}
    758  1.31.6.1  minoura 			if (setsockopt(msgsock, SOL_SOCKET,
    759  1.31.6.1  minoura 			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
    760  1.31.6.1  minoura 				syslog(LOG_ERR,
    761  1.31.6.1  minoura 				    "setsockopt SO_KEEPALIVE: %m");
    762  1.31.6.1  minoura 			nfsdargs.sock = msgsock;
    763  1.31.6.1  minoura 			nfsdargs.name = (caddr_t)&inet6peer;
    764  1.31.6.1  minoura 			nfsdargs.namelen = sizeof(inet6peer);
    765  1.31.6.1  minoura 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
    766  1.31.6.1  minoura 			(void)close(msgsock);
    767  1.31.6.1  minoura 		}
    768  1.31.6.1  minoura 
    769      1.11  mycroft #ifdef notyet
    770      1.11  mycroft 		if (tp4flag && FD_ISSET(tp4sock, &ready)) {
    771      1.11  mycroft 			len = sizeof(isopeer);
    772      1.11  mycroft 			if ((msgsock = accept(tp4sock,
    773      1.11  mycroft 			    (struct sockaddr *)&isopeer, &len)) < 0) {
    774      1.11  mycroft 				syslog(LOG_ERR, "accept failed: %m");
    775      1.11  mycroft 				exit(1);
    776       1.1      cgd 			}
    777      1.11  mycroft 			if (setsockopt(msgsock, SOL_SOCKET,
    778      1.11  mycroft 			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
    779      1.11  mycroft 				syslog(LOG_ERR,
    780      1.11  mycroft 				    "setsockopt SO_KEEPALIVE: %m");
    781      1.11  mycroft 			nfsdargs.sock = msgsock;
    782      1.11  mycroft 			nfsdargs.name = (caddr_t)&isopeer;
    783      1.11  mycroft 			nfsdargs.namelen = len;
    784      1.11  mycroft 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
    785      1.11  mycroft 			(void)close(msgsock);
    786      1.11  mycroft 		}
    787      1.11  mycroft 		if (tpipflag && FD_ISSET(tpipsock, &ready)) {
    788      1.11  mycroft 			len = sizeof(inetpeer);
    789      1.11  mycroft 			if ((msgsock = accept(tpipsock,
    790      1.11  mycroft 			    (struct sockaddr *)&inetpeer, &len)) < 0) {
    791      1.11  mycroft 				syslog(LOG_ERR, "Accept failed: %m");
    792       1.1      cgd 				exit(1);
    793       1.1      cgd 			}
    794      1.11  mycroft 			if (setsockopt(msgsock, SOL_SOCKET,
    795      1.11  mycroft 			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
    796      1.11  mycroft 				syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m");
    797      1.11  mycroft 			nfsdargs.sock = msgsock;
    798      1.11  mycroft 			nfsdargs.name = (caddr_t)&inetpeer;
    799      1.11  mycroft 			nfsdargs.namelen = len;
    800      1.11  mycroft 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
    801      1.11  mycroft 			(void)close(msgsock);
    802       1.1      cgd 		}
    803      1.11  mycroft #endif /* notyet */
    804       1.1      cgd 	}
    805       1.1      cgd }
    806       1.1      cgd 
    807      1.11  mycroft void
    808       1.1      cgd usage()
    809       1.1      cgd {
    810      1.26      mrg 
    811      1.15  mycroft 	(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
    812       1.1      cgd 	exit(1);
    813       1.1      cgd }
    814       1.1      cgd 
    815       1.1      cgd void
    816      1.11  mycroft nonfs(signo)
    817      1.11  mycroft 	int signo;
    818       1.1      cgd {
    819      1.15  mycroft 
    820      1.11  mycroft 	syslog(LOG_ERR, "missing system call: NFS not available.");
    821       1.1      cgd }
    822       1.4    glass 
    823      1.11  mycroft void
    824      1.11  mycroft reapchild(signo)
    825      1.11  mycroft 	int signo;
    826       1.4    glass {
    827      1.11  mycroft 
    828      1.18     fvdl 	while (wait3(NULL, WNOHANG, NULL) > 0);
    829       1.4    glass }
    830