1 /* 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef lint 34 static const char copyright[] = 35 "@(#) Copyright (c) 1989, 1993, 1994\n\ 36 The Regents of the University of California. All rights reserved.\n"; 37 #endif /* not lint */ 38 39 #ifndef lint 40 #if 0 41 static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95"; 42 #endif 43 static const char rcsid[] = 44 "$FreeBSD$"; 45 #endif /* not lint */ 46 47 #include <sys/param.h> 48 #include <sys/syslog.h> 49 #include <sys/wait.h> 50 #include <sys/mount.h> 51 #include <sys/fcntl.h> 52 #include <sys/linker.h> 53 #include <sys/module.h> 54 55 #include <rpc/rpc.h> 56 #include <rpc/pmap_clnt.h> 57 #include <rpcsvc/nfs_prot.h> 58 59 #include <netdb.h> 60 #include <arpa/inet.h> 61 #include <nfsserver/nfs.h> 62 #include <nfs/nfssvc.h> 63 64 #include <err.h> 65 #include <errno.h> 66 #include <signal.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <string.h> 70 #include <unistd.h> 71 #include <netdb.h> 72 73 /* Global defs */ 74 #ifdef DEBUG 75 #define syslog(e, s...) fprintf(stderr,s) 76 int debug = 1; 77 #else 78 int debug = 0; 79 #endif 80 81 #define NFSD_STABLERESTART "/var/db/nfs-stablerestart" 82 #define MAXNFSDCNT 256 83 #define DEFNFSDCNT 4 84 pid_t children[MAXNFSDCNT]; /* PIDs of children */ 85 int nfsdcnt; /* number of children */ 86 int new_syscall; 87 int run_v4server = 0; /* Force running of nfsv4 server */ 88 int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */ 89 90 void cleanup(int); 91 void child_cleanup(int); 92 void killchildren(void); 93 void nfsd_exit(int); 94 void nonfs(int); 95 void reapchild(int); 96 int setbindhost(struct addrinfo **ia, const char *bindhost, 97 struct addrinfo hints); 98 void start_server(int); 99 void unregistration(void); 100 void usage(void); 101 102 /* 103 * Nfs server daemon mostly just a user context for nfssvc() 104 * 105 * 1 - do file descriptor and signal cleanup 106 * 2 - fork the nfsd(s) 107 * 3 - create server socket(s) 108 * 4 - register socket with rpcbind 109 * 110 * For connectionless protocols, just pass the socket into the kernel via. 111 * nfssvc(). 112 * For connection based sockets, loop doing accepts. When you get a new 113 * socket from accept, pass the msgsock into the kernel via. nfssvc(). 114 * The arguments are: 115 * -r - reregister with rpcbind 116 * -d - unregister with rpcbind 117 * -t - support tcp nfs clients 118 * -u - support udp nfs clients 119 * -e - forces it to run a server that supports nfsv4 120 * followed by "n" which is the number of nfsds' to fork off 121 */ 122 int 123 main(int argc, char **argv) 124 { 125 struct nfsd_addsock_args addsockargs; 126 struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints; 127 struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6; 128 struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6; 129 struct sockaddr_in inetpeer; 130 struct sockaddr_in6 inet6peer; 131 fd_set ready, sockbits; 132 fd_set v4bits, v6bits; 133 int ch, connect_type_cnt, i, maxsock, msgsock; 134 socklen_t len; 135 int on = 1, unregister, reregister, sock; 136 int tcp6sock, ip6flag, tcpflag, tcpsock; 137 int udpflag, ecode, s, srvcnt; 138 int bindhostc, bindanyflag, rpcbreg, rpcbregcnt; 139 int stablefd, nfssvc_addsock; 140 char **bindhost = NULL; 141 pid_t pid; 142 143 nfsdcnt = DEFNFSDCNT; 144 unregister = reregister = tcpflag = maxsock = 0; 145 bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; 146 #define GETOPT "ah:n:rdtue" 147 #define USAGE "[-ardtue] [-n num_servers] [-h bindip]" 148 while ((ch = getopt(argc, argv, GETOPT)) != -1) 149 switch (ch) { 150 case 'a': 151 bindanyflag = 1; 152 break; 153 case 'n': 154 nfsdcnt = atoi(optarg); 155 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 156 warnx("nfsd count %d; reset to %d", nfsdcnt, 157 DEFNFSDCNT); 158 nfsdcnt = DEFNFSDCNT; 159 } 160 break; 161 case 'h': 162 bindhostc++; 163 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 164 if (bindhost == NULL) 165 errx(1, "Out of memory"); 166 bindhost[bindhostc-1] = strdup(optarg); 167 if (bindhost[bindhostc-1] == NULL) 168 errx(1, "Out of memory"); 169 break; 170 case 'r': 171 reregister = 1; 172 break; 173 case 'd': 174 unregister = 1; 175 break; 176 case 't': 177 tcpflag = 1; 178 break; 179 case 'u': 180 udpflag = 1; 181 break; 182 case 'e': 183 run_v4server = 1; 184 break; 185 default: 186 case '?': 187 usage(); 188 }; 189 if (!tcpflag && !udpflag) 190 udpflag = 1; 191 argv += optind; 192 argc -= optind; 193 194 /* 195 * XXX 196 * Backward compatibility, trailing number is the count of daemons. 197 */ 198 if (argc > 1) 199 usage(); 200 if (argc == 1) { 201 nfsdcnt = atoi(argv[0]); 202 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 203 warnx("nfsd count %d; reset to %d", nfsdcnt, 204 DEFNFSDCNT); 205 nfsdcnt = DEFNFSDCNT; 206 } 207 } 208 209 /* 210 * If the "-e" option was specified OR only the nfsd module is 211 * found in the server, run "nfsd". 212 * Otherwise, try and run "nfsserver". 213 */ 214 if (run_v4server > 0) { 215 if (modfind("nfsd") < 0) { 216 /* Not present in kernel, try loading it */ 217 if (kldload("nfsd") < 0 || modfind("nfsd") < 0) 218 errx(1, "NFS server is not available"); 219 } 220 } else if (modfind("nfsserver") < 0 && modfind("nfsd") >= 0) { 221 run_v4server = 1; 222 } else if (modfind("nfsserver") < 0) { 223 /* Not present in kernel, try loading it */ 224 if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) 225 errx(1, "NFS server is not available"); 226 } 227 228 ip6flag = 1; 229 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 230 if (s == -1) { 231 if (errno != EPROTONOSUPPORT) 232 err(1, "socket"); 233 ip6flag = 0; 234 } else if (getnetconfigent("udp6") == NULL || 235 getnetconfigent("tcp6") == NULL) { 236 ip6flag = 0; 237 } 238 if (s != -1) 239 close(s); 240 241 if (bindhostc == 0 || bindanyflag) { 242 bindhostc++; 243 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 244 if (bindhost == NULL) 245 errx(1, "Out of memory"); 246 bindhost[bindhostc-1] = strdup("*"); 247 if (bindhost[bindhostc-1] == NULL) 248 errx(1, "Out of memory"); 249 } 250 251 if (unregister) { 252 unregistration(); 253 exit (0); 254 } 255 if (reregister) { 256 if (udpflag) { 257 memset(&hints, 0, sizeof hints); 258 hints.ai_flags = AI_PASSIVE; 259 hints.ai_family = AF_INET; 260 hints.ai_socktype = SOCK_DGRAM; 261 hints.ai_protocol = IPPROTO_UDP; 262 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp); 263 if (ecode != 0) 264 err(1, "getaddrinfo udp: %s", gai_strerror(ecode)); 265 nconf_udp = getnetconfigent("udp"); 266 if (nconf_udp == NULL) 267 err(1, "getnetconfigent udp failed"); 268 nb_udp.buf = ai_udp->ai_addr; 269 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen; 270 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) || 271 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp))) 272 err(1, "rpcb_set udp failed"); 273 freeaddrinfo(ai_udp); 274 } 275 if (udpflag && ip6flag) { 276 memset(&hints, 0, sizeof hints); 277 hints.ai_flags = AI_PASSIVE; 278 hints.ai_family = AF_INET6; 279 hints.ai_socktype = SOCK_DGRAM; 280 hints.ai_protocol = IPPROTO_UDP; 281 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6); 282 if (ecode != 0) 283 err(1, "getaddrinfo udp6: %s", gai_strerror(ecode)); 284 nconf_udp6 = getnetconfigent("udp6"); 285 if (nconf_udp6 == NULL) 286 err(1, "getnetconfigent udp6 failed"); 287 nb_udp6.buf = ai_udp6->ai_addr; 288 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen; 289 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) || 290 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6))) 291 err(1, "rpcb_set udp6 failed"); 292 freeaddrinfo(ai_udp6); 293 } 294 if (tcpflag) { 295 memset(&hints, 0, sizeof hints); 296 hints.ai_flags = AI_PASSIVE; 297 hints.ai_family = AF_INET; 298 hints.ai_socktype = SOCK_STREAM; 299 hints.ai_protocol = IPPROTO_TCP; 300 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp); 301 if (ecode != 0) 302 err(1, "getaddrinfo tcp: %s", gai_strerror(ecode)); 303 nconf_tcp = getnetconfigent("tcp"); 304 if (nconf_tcp == NULL) 305 err(1, "getnetconfigent tcp failed"); 306 nb_tcp.buf = ai_tcp->ai_addr; 307 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen; 308 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp, &nb_tcp)) || 309 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp, &nb_tcp))) 310 err(1, "rpcb_set tcp failed"); 311 freeaddrinfo(ai_tcp); 312 } 313 if (tcpflag && ip6flag) { 314 memset(&hints, 0, sizeof hints); 315 hints.ai_flags = AI_PASSIVE; 316 hints.ai_family = AF_INET6; 317 hints.ai_socktype = SOCK_STREAM; 318 hints.ai_protocol = IPPROTO_TCP; 319 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6); 320 if (ecode != 0) 321 err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode)); 322 nconf_tcp6 = getnetconfigent("tcp6"); 323 if (nconf_tcp6 == NULL) 324 err(1, "getnetconfigent tcp6 failed"); 325 nb_tcp6.buf = ai_tcp6->ai_addr; 326 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen; 327 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) || 328 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6))) 329 err(1, "rpcb_set tcp6 failed"); 330 freeaddrinfo(ai_tcp6); 331 } 332 exit (0); 333 } 334 if (debug == 0) { 335 daemon(0, 0); 336 (void)signal(SIGHUP, SIG_IGN); 337 (void)signal(SIGINT, SIG_IGN); 338 /* 339 * nfsd sits in the kernel most of the time. It needs 340 * to ignore SIGTERM/SIGQUIT in order to stay alive as long 341 * as possible during a shutdown, otherwise loopback 342 * mounts will not be able to unmount. 343 */ 344 (void)signal(SIGTERM, SIG_IGN); 345 (void)signal(SIGQUIT, SIG_IGN); 346 } 347 (void)signal(SIGSYS, nonfs); 348 (void)signal(SIGCHLD, reapchild); 349 350 openlog("nfsd", LOG_PID, LOG_DAEMON); 351 352 /* 353 * For V4, we open the stablerestart file and call nfssvc() 354 * to get it loaded. This is done before the daemons do the 355 * regular nfssvc() call to service NFS requests. 356 * (This way the file remains open until the last nfsd is killed 357 * off.) 358 * Note that this file is not created by this daemon and can 359 * only be relocated by recompiling the daemon, in order to 360 * minimize accidentally starting up with the wrong file. 361 * If should be created as an empty file Read and Write for 362 * root before the first time you run NFS v4 and should never 363 * be re-initialized if at all possible. It should live on a 364 * local, non-volatile storage device that does not do hardware 365 * level write-back caching. (See SCSI doc for more information 366 * on how to prevent write-back caching on SCSI disks.) 367 */ 368 if (run_v4server > 0) { 369 stablefd = open(NFSD_STABLERESTART, O_RDWR, 0); 370 if (stablefd < 0) { 371 syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART); 372 exit(1); 373 } 374 if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { 375 syslog(LOG_ERR, "Can't read stable storage file\n"); 376 exit(1); 377 } 378 nfssvc_addsock = NFSSVC_NFSDADDSOCK; 379 nfssvc_nfsd = NFSSVC_NFSDNFSD; 380 new_syscall = TRUE; 381 } else { 382 nfssvc_addsock = NFSSVC_ADDSOCK; 383 nfssvc_nfsd = NFSSVC_NFSD; 384 /* 385 * Figure out if the kernel supports the new-style 386 * NFSSVC_NFSD. Old kernels will return ENXIO because they 387 * don't recognise the flag value, new ones will return EINVAL 388 * because argp is NULL. 389 */ 390 new_syscall = FALSE; 391 if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) 392 new_syscall = TRUE; 393 } 394 395 if (!new_syscall) { 396 /* If we use UDP only, we start the last server below. */ 397 srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1; 398 for (i = 0; i < srvcnt; i++) { 399 switch ((pid = fork())) { 400 case -1: 401 syslog(LOG_ERR, "fork: %m"); 402 nfsd_exit(1); 403 case 0: 404 break; 405 default: 406 children[i] = pid; 407 continue; 408 } 409 (void)signal(SIGUSR1, child_cleanup); 410 setproctitle("server"); 411 412 start_server(0); 413 } 414 } else if (tcpflag) { 415 /* 416 * For TCP mode, we fork once to start the first 417 * kernel nfsd thread. The kernel will add more 418 * threads as needed. 419 */ 420 pid = fork(); 421 if (pid == -1) { 422 syslog(LOG_ERR, "fork: %m"); 423 nfsd_exit(1); 424 } 425 if (pid) { 426 children[0] = pid; 427 } else { 428 (void)signal(SIGUSR1, child_cleanup); 429 setproctitle("server"); 430 start_server(0); 431 } 432 } 433 434 (void)signal(SIGUSR1, cleanup); 435 FD_ZERO(&v4bits); 436 FD_ZERO(&v6bits); 437 FD_ZERO(&sockbits); 438 439 rpcbregcnt = 0; 440 /* Set up the socket for udp and rpcb register it. */ 441 if (udpflag) { 442 rpcbreg = 0; 443 for (i = 0; i < bindhostc; i++) { 444 memset(&hints, 0, sizeof hints); 445 hints.ai_flags = AI_PASSIVE; 446 hints.ai_family = AF_INET; 447 hints.ai_socktype = SOCK_DGRAM; 448 hints.ai_protocol = IPPROTO_UDP; 449 if (setbindhost(&ai_udp, bindhost[i], hints) == 0) { 450 rpcbreg = 1; 451 rpcbregcnt++; 452 if ((sock = socket(ai_udp->ai_family, 453 ai_udp->ai_socktype, 454 ai_udp->ai_protocol)) < 0) { 455 syslog(LOG_ERR, 456 "can't create udp socket"); 457 nfsd_exit(1); 458 } 459 if (bind(sock, ai_udp->ai_addr, 460 ai_udp->ai_addrlen) < 0) { 461 syslog(LOG_ERR, 462 "can't bind udp addr %s: %m", 463 bindhost[i]); 464 nfsd_exit(1); 465 } 466 freeaddrinfo(ai_udp); 467 addsockargs.sock = sock; 468 addsockargs.name = NULL; 469 addsockargs.namelen = 0; 470 if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { 471 syslog(LOG_ERR, "can't Add UDP socket"); 472 nfsd_exit(1); 473 } 474 (void)close(sock); 475 } 476 } 477 if (rpcbreg == 1) { 478 memset(&hints, 0, sizeof hints); 479 hints.ai_flags = AI_PASSIVE; 480 hints.ai_family = AF_INET; 481 hints.ai_socktype = SOCK_DGRAM; 482 hints.ai_protocol = IPPROTO_UDP; 483 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp); 484 if (ecode != 0) { 485 syslog(LOG_ERR, "getaddrinfo udp: %s", 486 gai_strerror(ecode)); 487 nfsd_exit(1); 488 } 489 nconf_udp = getnetconfigent("udp"); 490 if (nconf_udp == NULL) 491 err(1, "getnetconfigent udp failed"); 492 nb_udp.buf = ai_udp->ai_addr; 493 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen; 494 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) || 495 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp))) 496 err(1, "rpcb_set udp failed"); 497 freeaddrinfo(ai_udp); 498 } 499 } 500 501 /* Set up the socket for udp6 and rpcb register it. */ 502 if (udpflag && ip6flag) { 503 rpcbreg = 0; 504 for (i = 0; i < bindhostc; i++) { 505 memset(&hints, 0, sizeof hints); 506 hints.ai_flags = AI_PASSIVE; 507 hints.ai_family = AF_INET6; 508 hints.ai_socktype = SOCK_DGRAM; 509 hints.ai_protocol = IPPROTO_UDP; 510 if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) { 511 rpcbreg = 1; 512 rpcbregcnt++; 513 if ((sock = socket(ai_udp6->ai_family, 514 ai_udp6->ai_socktype, 515 ai_udp6->ai_protocol)) < 0) { 516 syslog(LOG_ERR, 517 "can't create udp6 socket"); 518 nfsd_exit(1); 519 } 520 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, 521 &on, sizeof on) < 0) { 522 syslog(LOG_ERR, 523 "can't set v6-only binding for " 524 "udp6 socket: %m"); 525 nfsd_exit(1); 526 } 527 if (bind(sock, ai_udp6->ai_addr, 528 ai_udp6->ai_addrlen) < 0) { 529 syslog(LOG_ERR, 530 "can't bind udp6 addr %s: %m", 531 bindhost[i]); 532 nfsd_exit(1); 533 } 534 freeaddrinfo(ai_udp6); 535 addsockargs.sock = sock; 536 addsockargs.name = NULL; 537 addsockargs.namelen = 0; 538 if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { 539 syslog(LOG_ERR, 540 "can't add UDP6 socket"); 541 nfsd_exit(1); 542 } 543 (void)close(sock); 544 } 545 } 546 if (rpcbreg == 1) { 547 memset(&hints, 0, sizeof hints); 548 hints.ai_flags = AI_PASSIVE; 549 hints.ai_family = AF_INET6; 550 hints.ai_socktype = SOCK_DGRAM; 551 hints.ai_protocol = IPPROTO_UDP; 552 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6); 553 if (ecode != 0) { 554 syslog(LOG_ERR, "getaddrinfo udp6: %s", 555 gai_strerror(ecode)); 556 nfsd_exit(1); 557 } 558 nconf_udp6 = getnetconfigent("udp6"); 559 if (nconf_udp6 == NULL) 560 err(1, "getnetconfigent udp6 failed"); 561 nb_udp6.buf = ai_udp6->ai_addr; 562 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen; 563 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) || 564 (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6))) 565 err(1, "rpcb_set udp6 failed"); 566 freeaddrinfo(ai_udp6); 567 } 568 } 569 570 /* Set up the socket for tcp and rpcb register it. */ 571 if (tcpflag) { 572 rpcbreg = 0; 573 for (i = 0; i < bindhostc; i++) { 574 memset(&hints, 0, sizeof hints); 575 hints.ai_flags = AI_PASSIVE; 576 hints.ai_family = AF_INET; 577 hints.ai_socktype = SOCK_STREAM; 578 hints.ai_protocol = IPPROTO_TCP; 579 if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) { 580 rpcbreg = 1; 581 rpcbregcnt++; 582 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 583 0)) < 0) { 584 syslog(LOG_ERR, 585 "can't create tpc socket"); 586 nfsd_exit(1); 587 } 588 if (setsockopt(tcpsock, SOL_SOCKET, 589 SO_REUSEADDR, 590 (char *)&on, sizeof(on)) < 0) 591 syslog(LOG_ERR, 592 "setsockopt SO_REUSEADDR: %m"); 593 if (bind(tcpsock, ai_tcp->ai_addr, 594 ai_tcp->ai_addrlen) < 0) { 595 syslog(LOG_ERR, 596 "can't bind tcp addr %s: %m", 597 bindhost[i]); 598 nfsd_exit(1); 599 } 600 if (listen(tcpsock, 5) < 0) { 601 syslog(LOG_ERR, "listen failed"); 602 nfsd_exit(1); 603 } 604 freeaddrinfo(ai_tcp); 605 FD_SET(tcpsock, &sockbits); 606 FD_SET(tcpsock, &v4bits); 607 maxsock = tcpsock; 608 connect_type_cnt++; 609 } 610 } 611 if (rpcbreg == 1) { 612 memset(&hints, 0, sizeof hints); 613 hints.ai_flags = AI_PASSIVE; 614 hints.ai_family = AF_INET; 615 hints.ai_socktype = SOCK_STREAM; 616 hints.ai_protocol = IPPROTO_TCP; 617 ecode = getaddrinfo(NULL, "nfs", &hints, 618 &ai_tcp); 619 if (ecode != 0) { 620 syslog(LOG_ERR, "getaddrinfo tcp: %s", 621 gai_strerror(ecode)); 622 nfsd_exit(1); 623 } 624 nconf_tcp = getnetconfigent("tcp"); 625 if (nconf_tcp == NULL) 626 err(1, "getnetconfigent tcp failed"); 627 nb_tcp.buf = ai_tcp->ai_addr; 628 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen; 629 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp, 630 &nb_tcp)) || (!rpcb_set(NFS_PROGRAM, 3, 631 nconf_tcp, &nb_tcp))) 632 err(1, "rpcb_set tcp failed"); 633 freeaddrinfo(ai_tcp); 634 } 635 } 636 637 /* Set up the socket for tcp6 and rpcb register it. */ 638 if (tcpflag && ip6flag) { 639 rpcbreg = 0; 640 for (i = 0; i < bindhostc; i++) { 641 memset(&hints, 0, sizeof hints); 642 hints.ai_flags = AI_PASSIVE; 643 hints.ai_family = AF_INET6; 644 hints.ai_socktype = SOCK_STREAM; 645 hints.ai_protocol = IPPROTO_TCP; 646 if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) { 647 rpcbreg = 1; 648 rpcbregcnt++; 649 if ((tcp6sock = socket(ai_tcp6->ai_family, 650 ai_tcp6->ai_socktype, 651 ai_tcp6->ai_protocol)) < 0) { 652 syslog(LOG_ERR, 653 "can't create tcp6 socket"); 654 nfsd_exit(1); 655 } 656 if (setsockopt(tcp6sock, SOL_SOCKET, 657 SO_REUSEADDR, 658 (char *)&on, sizeof(on)) < 0) 659 syslog(LOG_ERR, 660 "setsockopt SO_REUSEADDR: %m"); 661 if (setsockopt(tcp6sock, IPPROTO_IPV6, 662 IPV6_V6ONLY, &on, sizeof on) < 0) { 663 syslog(LOG_ERR, 664 "can't set v6-only binding for tcp6 " 665 "socket: %m"); 666 nfsd_exit(1); 667 } 668 if (bind(tcp6sock, ai_tcp6->ai_addr, 669 ai_tcp6->ai_addrlen) < 0) { 670 syslog(LOG_ERR, 671 "can't bind tcp6 addr %s: %m", 672 bindhost[i]); 673 nfsd_exit(1); 674 } 675 if (listen(tcp6sock, 5) < 0) { 676 syslog(LOG_ERR, "listen failed"); 677 nfsd_exit(1); 678 } 679 freeaddrinfo(ai_tcp6); 680 FD_SET(tcp6sock, &sockbits); 681 FD_SET(tcp6sock, &v6bits); 682 if (maxsock < tcp6sock) 683 maxsock = tcp6sock; 684 connect_type_cnt++; 685 } 686 } 687 if (rpcbreg == 1) { 688 memset(&hints, 0, sizeof hints); 689 hints.ai_flags = AI_PASSIVE; 690 hints.ai_family = AF_INET6; 691 hints.ai_socktype = SOCK_STREAM; 692 hints.ai_protocol = IPPROTO_TCP; 693 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6); 694 if (ecode != 0) { 695 syslog(LOG_ERR, "getaddrinfo tcp6: %s", 696 gai_strerror(ecode)); 697 nfsd_exit(1); 698 } 699 nconf_tcp6 = getnetconfigent("tcp6"); 700 if (nconf_tcp6 == NULL) 701 err(1, "getnetconfigent tcp6 failed"); 702 nb_tcp6.buf = ai_tcp6->ai_addr; 703 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen; 704 if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) || 705 (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6))) 706 err(1, "rpcb_set tcp6 failed"); 707 freeaddrinfo(ai_tcp6); 708 } 709 } 710 711 if (rpcbregcnt == 0) { 712 syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m"); 713 nfsd_exit(1); 714 } 715 716 if (tcpflag && connect_type_cnt == 0) { 717 syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m"); 718 nfsd_exit(1); 719 } 720 721 setproctitle("master"); 722 /* 723 * We always want a master to have a clean way to to shut nfsd down 724 * (with unregistration): if the master is killed, it unregisters and 725 * kills all children. If we run for UDP only (and so do not have to 726 * loop waiting waiting for accept), we instead make the parent 727 * a "server" too. start_server will not return. 728 */ 729 if (!tcpflag) 730 start_server(1); 731 732 /* 733 * Loop forever accepting connections and passing the sockets 734 * into the kernel for the mounts. 735 */ 736 for (;;) { 737 ready = sockbits; 738 if (connect_type_cnt > 1) { 739 if (select(maxsock + 1, 740 &ready, NULL, NULL, NULL) < 1) { 741 syslog(LOG_ERR, "select failed: %m"); 742 if (errno == EINTR) 743 continue; 744 nfsd_exit(1); 745 } 746 } 747 for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) { 748 if (FD_ISSET(tcpsock, &ready)) { 749 if (FD_ISSET(tcpsock, &v4bits)) { 750 len = sizeof(inetpeer); 751 if ((msgsock = accept(tcpsock, 752 (struct sockaddr *)&inetpeer, &len)) < 0) { 753 syslog(LOG_ERR, "accept failed: %m"); 754 if (errno == ECONNABORTED || 755 errno == EINTR) 756 continue; 757 nfsd_exit(1); 758 } 759 memset(inetpeer.sin_zero, 0, 760 sizeof(inetpeer.sin_zero)); 761 if (setsockopt(msgsock, SOL_SOCKET, 762 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 763 syslog(LOG_ERR, 764 "setsockopt SO_KEEPALIVE: %m"); 765 addsockargs.sock = msgsock; 766 addsockargs.name = (caddr_t)&inetpeer; 767 addsockargs.namelen = len; 768 nfssvc(nfssvc_addsock, &addsockargs); 769 (void)close(msgsock); 770 } else if (FD_ISSET(tcpsock, &v6bits)) { 771 len = sizeof(inet6peer); 772 if ((msgsock = accept(tcpsock, 773 (struct sockaddr *)&inet6peer, 774 &len)) < 0) { 775 syslog(LOG_ERR, 776 "accept failed: %m"); 777 if (errno == ECONNABORTED || 778 errno == EINTR) 779 continue; 780 nfsd_exit(1); 781 } 782 if (setsockopt(msgsock, SOL_SOCKET, 783 SO_KEEPALIVE, (char *)&on, 784 sizeof(on)) < 0) 785 syslog(LOG_ERR, "setsockopt " 786 "SO_KEEPALIVE: %m"); 787 addsockargs.sock = msgsock; 788 addsockargs.name = (caddr_t)&inet6peer; 789 addsockargs.namelen = len; 790 nfssvc(nfssvc_addsock, &addsockargs); 791 (void)close(msgsock); 792 } 793 } 794 } 795 } 796 } 797 798 int 799 setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints) 800 { 801 int ecode; 802 u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 803 const char *hostptr; 804 805 if (bindhost == NULL || strcmp("*", bindhost) == 0) 806 hostptr = NULL; 807 else 808 hostptr = bindhost; 809 810 if (hostptr != NULL) { 811 switch (hints.ai_family) { 812 case AF_INET: 813 if (inet_pton(AF_INET, hostptr, host_addr) == 1) { 814 hints.ai_flags = AI_NUMERICHOST; 815 } else { 816 if (inet_pton(AF_INET6, hostptr, 817 host_addr) == 1) 818 return (1); 819 } 820 break; 821 case AF_INET6: 822 if (inet_pton(AF_INET6, hostptr, host_addr) == 1) { 823 hints.ai_flags = AI_NUMERICHOST; 824 } else { 825 if (inet_pton(AF_INET, hostptr, 826 host_addr) == 1) 827 return (1); 828 } 829 break; 830 default: 831 break; 832 } 833 } 834 835 ecode = getaddrinfo(hostptr, "nfs", &hints, ai); 836 if (ecode != 0) { 837 syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost, 838 gai_strerror(ecode)); 839 return (1); 840 } 841 return (0); 842 } 843 844 void 845 usage(void) 846 { 847 (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); 848 exit(1); 849 } 850 851 void 852 nonfs(__unused int signo) 853 { 854 syslog(LOG_ERR, "missing system call: NFS not available"); 855 } 856 857 void 858 reapchild(__unused int signo) 859 { 860 pid_t pid; 861 int i; 862 863 while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) { 864 for (i = 0; i < nfsdcnt; i++) 865 if (pid == children[i]) 866 children[i] = -1; 867 } 868 } 869 870 void 871 unregistration(void) 872 { 873 if ((!rpcb_unset(NFS_PROGRAM, 2, NULL)) || 874 (!rpcb_unset(NFS_PROGRAM, 3, NULL))) 875 syslog(LOG_ERR, "rpcb_unset failed"); 876 } 877 878 void 879 killchildren(void) 880 { 881 int i; 882 883 for (i = 0; i < nfsdcnt; i++) { 884 if (children[i] > 0) 885 kill(children[i], SIGKILL); 886 } 887 } 888 889 /* 890 * Cleanup master after SIGUSR1. 891 */ 892 void 893 cleanup(__unused int signo) 894 { 895 nfsd_exit(0); 896 } 897 898 /* 899 * Cleanup child after SIGUSR1. 900 */ 901 void 902 child_cleanup(__unused int signo) 903 { 904 exit(0); 905 } 906 907 void 908 nfsd_exit(int status) 909 { 910 killchildren(); 911 unregistration(); 912 exit(status); 913 } 914 915 void 916 start_server(int master) 917 { 918 char principal[MAXHOSTNAMELEN + 5]; 919 struct nfsd_nfsd_args nfsdargs; 920 int status, error; 921 char hostname[MAXHOSTNAMELEN + 1], *cp; 922 struct addrinfo *aip, hints; 923 924 status = 0; 925 if (new_syscall) { 926 gethostname(hostname, sizeof (hostname)); 927 snprintf(principal, sizeof (principal), "nfs@%s", hostname); 928 if ((cp = strchr(hostname, '.')) == NULL || 929 *(cp + 1) == '\0') { 930 /* If not fully qualified, try getaddrinfo() */ 931 memset((void *)&hints, 0, sizeof (hints)); 932 hints.ai_flags = AI_CANONNAME; 933 error = getaddrinfo(hostname, NULL, &hints, &aip); 934 if (error == 0) { 935 if (aip->ai_canonname != NULL && 936 (cp = strchr(aip->ai_canonname, '.')) != 937 NULL && *(cp + 1) != '\0') 938 snprintf(principal, sizeof (principal), 939 "nfs@%s", aip->ai_canonname); 940 freeaddrinfo(aip); 941 } 942 } 943 nfsdargs.principal = principal; 944 nfsdargs.minthreads = nfsdcnt; 945 nfsdargs.maxthreads = nfsdcnt; 946 error = nfssvc(nfssvc_nfsd, &nfsdargs); 947 if (error < 0 && errno == EAUTH) { 948 /* 949 * This indicates that it could not register the 950 * rpcsec_gss credentials, usually because the 951 * gssd daemon isn't running. 952 * (only the experimental server with nfsv4) 953 */ 954 syslog(LOG_ERR, "No gssd, using AUTH_SYS only"); 955 principal[0] = '\0'; 956 error = nfssvc(nfssvc_nfsd, &nfsdargs); 957 } 958 if (error < 0) { 959 syslog(LOG_ERR, "nfssvc: %m"); 960 status = 1; 961 } 962 } else { 963 if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) { 964 syslog(LOG_ERR, "nfssvc: %m"); 965 status = 1; 966 } 967 } 968 if (master) 969 nfsd_exit(status); 970 else 971 exit(status); 972 } 973