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