1 /* $NetBSD: nfsd.c,v 1.41 2002/09/24 17:32:03 mycroft 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.41 2002/09/24 17:32:03 mycroft 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 <kerberosIV/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