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