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