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