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 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright (c) 1989, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif not lint 42 43#ifndef lint 44static char sccsid[] = "@(#)nfsd.c 8.7 (Berkeley) 2/22/94"; 45#endif not lint 46 47#include <sys/param.h> 48#include <sys/syslog.h> 49#include <sys/ioctl.h> 50#include <sys/stat.h> 51#include <sys/wait.h> 52#include <sys/uio.h> 53#include <sys/ucred.h> 54#include <sys/mount.h> 55#include <sys/socket.h> 56#include <sys/socketvar.h> 57 58#include <rpc/rpc.h> 59#include <rpc/pmap_clnt.h> 60#include <rpc/pmap_prot.h> 61 62#ifdef ISO 63#include <netiso/iso.h> 64#endif 65#include <nfs/rpcv2.h> 66#include <nfs/nfsv2.h> 67#include <nfs/nfs.h> 68 69#ifdef KERBEROS 70#include <kerberosIV/des.h> 71#include <kerberosIV/krb.h> 72#endif 73 74#include <err.h> 75#include <errno.h> 76#include <fcntl.h> 77#include <grp.h> 78#include <pwd.h> 79#include <signal.h> 80#include <stdio.h> 81#include <stdlib.h> 82#include <strings.h> 83#include <unistd.h> 84 85/* Global defs */ 86#ifdef DEBUG 87#define syslog(e, s) fprintf(stderr,(s)) 88int debug = 1; 89#else 90int debug = 0; 91#endif 92 93struct nfsd_srvargs nsd; 94char **Argv = NULL; /* pointer to argument vector */ 95char *LastArg = NULL; /* end of argv */ 96 97#ifdef KERBEROS 98char lnam[ANAME_SZ]; 99KTEXT_ST kt; 100AUTH_DAT auth; 101char inst[INST_SZ]; 102#endif 103 104void nonfs __P((int)); 105void reapchild __P((int)); 106void setproctitle __P((char *)); 107void usage __P((void)); 108 109/* 110 * Nfs server daemon mostly just a user context for nfssvc() 111 * 112 * 1 - do file descriptor and signal cleanup 113 * 2 - fork the nfsd(s) 114 * 3 - create server socket(s) 115 * 4 - register socket with portmap 116 * 117 * For connectionless protocols, just pass the socket into the kernel via. 118 * nfssvc(). 119 * For connection based sockets, loop doing accepts. When you get a new 120 * socket from accept, pass the msgsock into the kernel via. nfssvc(). 121 * The arguments are: 122 * -c - support iso cltp clients 123 * -r - reregister with portmapper 124 * -t - support tcp nfs clients 125 * -u - support udp nfs clients 126 * followed by "n" which is the number of nfsds' to fork off 127 */ 128int 129main(argc, argv, envp) 130 int argc; 131 char *argv[], *envp[]; 132{ 133 extern int optind; 134 struct group *grp; 135 struct nfsd_args nfsdargs; 136 struct passwd *pwd; 137 struct ucred *cr; 138 struct sockaddr_in inetaddr, inetpeer; 139#ifdef ISO 140 struct sockaddr_iso isoaddr, isopeer; 141#endif 142 fd_set ready, sockbits; 143 int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock; 144 int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; 145 int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag; 146 char *cp, **cpp;
| 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 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright (c) 1989, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif not lint 42 43#ifndef lint 44static char sccsid[] = "@(#)nfsd.c 8.7 (Berkeley) 2/22/94"; 45#endif not lint 46 47#include <sys/param.h> 48#include <sys/syslog.h> 49#include <sys/ioctl.h> 50#include <sys/stat.h> 51#include <sys/wait.h> 52#include <sys/uio.h> 53#include <sys/ucred.h> 54#include <sys/mount.h> 55#include <sys/socket.h> 56#include <sys/socketvar.h> 57 58#include <rpc/rpc.h> 59#include <rpc/pmap_clnt.h> 60#include <rpc/pmap_prot.h> 61 62#ifdef ISO 63#include <netiso/iso.h> 64#endif 65#include <nfs/rpcv2.h> 66#include <nfs/nfsv2.h> 67#include <nfs/nfs.h> 68 69#ifdef KERBEROS 70#include <kerberosIV/des.h> 71#include <kerberosIV/krb.h> 72#endif 73 74#include <err.h> 75#include <errno.h> 76#include <fcntl.h> 77#include <grp.h> 78#include <pwd.h> 79#include <signal.h> 80#include <stdio.h> 81#include <stdlib.h> 82#include <strings.h> 83#include <unistd.h> 84 85/* Global defs */ 86#ifdef DEBUG 87#define syslog(e, s) fprintf(stderr,(s)) 88int debug = 1; 89#else 90int debug = 0; 91#endif 92 93struct nfsd_srvargs nsd; 94char **Argv = NULL; /* pointer to argument vector */ 95char *LastArg = NULL; /* end of argv */ 96 97#ifdef KERBEROS 98char lnam[ANAME_SZ]; 99KTEXT_ST kt; 100AUTH_DAT auth; 101char inst[INST_SZ]; 102#endif 103 104void nonfs __P((int)); 105void reapchild __P((int)); 106void setproctitle __P((char *)); 107void usage __P((void)); 108 109/* 110 * Nfs server daemon mostly just a user context for nfssvc() 111 * 112 * 1 - do file descriptor and signal cleanup 113 * 2 - fork the nfsd(s) 114 * 3 - create server socket(s) 115 * 4 - register socket with portmap 116 * 117 * For connectionless protocols, just pass the socket into the kernel via. 118 * nfssvc(). 119 * For connection based sockets, loop doing accepts. When you get a new 120 * socket from accept, pass the msgsock into the kernel via. nfssvc(). 121 * The arguments are: 122 * -c - support iso cltp clients 123 * -r - reregister with portmapper 124 * -t - support tcp nfs clients 125 * -u - support udp nfs clients 126 * followed by "n" which is the number of nfsds' to fork off 127 */ 128int 129main(argc, argv, envp) 130 int argc; 131 char *argv[], *envp[]; 132{ 133 extern int optind; 134 struct group *grp; 135 struct nfsd_args nfsdargs; 136 struct passwd *pwd; 137 struct ucred *cr; 138 struct sockaddr_in inetaddr, inetpeer; 139#ifdef ISO 140 struct sockaddr_iso isoaddr, isopeer; 141#endif 142 fd_set ready, sockbits; 143 int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock; 144 int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; 145 int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag; 146 char *cp, **cpp;
|
148 /* Save start and extent of argv for setproctitle. */ 149 Argv = argv; 150 if (envp == 0 || *envp == 0) 151 envp = argv; 152 while (*envp) 153 envp++; 154 LastArg = envp[-1] + strlen(envp[-1]); 155 156#define MAXNFSDCNT 20 157#define DEFNFSDCNT 4 158 nfsdcnt = DEFNFSDCNT; 159 cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0; 160 tpipflag = udpflag = 0; 161#ifdef ISO 162#define GETOPT "cn:rtu" 163#define USAGE "[-crtu] [-n num_servers]" 164#else 165#define GETOPT "n:rtu" 166#define USAGE "[-rtu] [-n num_servers]" 167#endif 168 while ((ch = getopt(argc, argv, GETOPT)) != EOF) 169 switch (ch) { 170 case 'n': 171 nfsdcnt = atoi(optarg); 172 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 173 warnx("nfsd count %d; reset to %d", DEFNFSDCNT); 174 nfsdcnt = DEFNFSDCNT; 175 } 176 break; 177 case 'r': 178 reregister = 1; 179 break; 180 case 't': 181 tcpflag = 1; 182 break; 183 case 'u': 184 udpflag = 1; 185 break; 186#ifdef ISO 187 case 'c': 188 cltpflag = 1; 189 break; 190#ifdef notyet 191 case 'i': 192 tp4cnt = 1; 193 break; 194 case 'p': 195 tpipcnt = 1; 196 break; 197#endif /* notyet */ 198#endif /* ISO */ 199 default: 200 case '?': 201 usage(); 202 }; 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", DEFNFSDCNT); 216 nfsdcnt = DEFNFSDCNT; 217 } 218 } 219 220 if (debug == 0) { 221 daemon(0, 0); 222 (void)signal(SIGHUP, SIG_IGN); 223 (void)signal(SIGINT, SIG_IGN); 224 (void)signal(SIGQUIT, SIG_IGN); 225 (void)signal(SIGSYS, nonfs); 226 (void)signal(SIGTERM, SIG_IGN); 227 } 228 (void)signal(SIGCHLD, reapchild); 229 230 if (reregister) { 231 if (udpflag && 232 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) 233 err(1, "can't register with portmap for UDP."); 234 if (tcpflag && 235 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) 236 err(1, "can't register with portmap for TCP."); 237 exit(0); 238 } 239 openlog("nfsd:", LOG_PID, LOG_DAEMON); 240 241 for (i = 0; i < nfsdcnt; i++) { 242 switch (fork()) { 243 case -1: 244 syslog(LOG_ERR, "fork: %m"); 245 exit (1); 246 case 0: 247 break; 248 default: 249 continue; 250 } 251 252 setproctitle("nfsd-srv"); 253 nfssvc_flag = NFSSVC_NFSD; 254 nsd.nsd_nfsd = NULL; 255#ifdef KERBEROS 256 nsd.nsd_authstr = (char *)kt.dat; 257#endif 258 while (nfssvc(nfssvc_flag, &nsd) < 0) { 259 if (errno != ENEEDAUTH) { 260 syslog(LOG_ERR, "nfssvc: %m"); 261 exit(1); 262 } 263 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; 264#ifdef KERBEROS 265 kt.length = nsd.nsd_authlen; 266 kt.mbz = 0; 267 (void)strcpy(inst, "*"); 268 if (krb_rd_req(&kt, "rcmd", 269 inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK && 270 krb_kntoln(&auth, lnam) == KSUCCESS && 271 (pwd = getpwnam(lnam)) != NULL) { 272 cr = &nsd.nsd_cr; 273 cr->cr_uid = pwd->pw_uid; 274 cr->cr_groups[0] = pwd->pw_gid; 275 cr->cr_ngroups = 1; 276 setgrent(); 277 while ((grp = getgrent()) != NULL) { 278 if (grp->gr_gid == cr->cr_groups[0]) 279 continue; 280 for (cpp = grp->gr_mem; 281 *cpp != NULL; ++cpp) 282 if (!strcmp(*cpp, lnam)) 283 break; 284 if (*cpp == NULL) 285 continue; 286 cr->cr_groups[cr->cr_ngroups++] 287 = grp->gr_gid; 288 if (cr->cr_ngroups == NGROUPS) 289 break; 290 } 291 endgrent(); 292 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; 293 } 294#endif /* KERBEROS */ 295 } 296 exit(0); 297 } 298 299 /* If we are serving udp, set up the socket. */ 300 if (udpflag) { 301 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 302 syslog(LOG_ERR, "can't create udp socket"); 303 exit(1); 304 } 305 inetaddr.sin_family = AF_INET; 306 inetaddr.sin_addr.s_addr = INADDR_ANY; 307 inetaddr.sin_port = htons(NFS_PORT); 308 inetaddr.sin_len = sizeof(inetaddr); 309 if (bind(sock, 310 (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 311 syslog(LOG_ERR, "can't bind udp addr"); 312 exit(1); 313 } 314 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 315 syslog(LOG_ERR, "can't register with udp portmap"); 316 exit(1); 317 } 318 nfsdargs.sock = sock; 319 nfsdargs.name = NULL; 320 nfsdargs.namelen = 0; 321 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 322 syslog(LOG_ERR, "can't Add UDP socket"); 323 exit(1); 324 } 325 (void)close(sock); 326 } 327 328#ifdef ISO 329 /* If we are serving cltp, set up the socket. */ 330 if (cltpflag) { 331 if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) { 332 syslog(LOG_ERR, "can't create cltp socket"); 333 exit(1); 334 } 335 memset(&isoaddr, 0, sizeof(isoaddr)); 336 isoaddr.siso_family = AF_ISO; 337 isoaddr.siso_tlen = 2; 338 cp = TSEL(&isoaddr); 339 *cp++ = (NFS_PORT >> 8); 340 *cp = (NFS_PORT & 0xff); 341 isoaddr.siso_len = sizeof(isoaddr); 342 if (bind(sock, 343 (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) { 344 syslog(LOG_ERR, "can't bind cltp addr"); 345 exit(1); 346 } 347#ifdef notyet 348 /* 349 * XXX 350 * Someday this should probably use "rpcbind", the son of 351 * portmap. 352 */ 353 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 354 syslog(LOG_ERR, "can't register with udp portmap"); 355 exit(1); 356 } 357#endif /* notyet */ 358 nfsdargs.sock = sock; 359 nfsdargs.name = NULL; 360 nfsdargs.namelen = 0; 361 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 362 syslog(LOG_ERR, "can't add UDP socket"); 363 exit(1); 364 } 365 close(sock); 366 } 367#endif /* ISO */ 368 369 /* Now set up the master server socket waiting for tcp connections. */ 370 on = 1; 371 FD_ZERO(&sockbits); 372 connect_type_cnt = 0; 373 if (tcpflag) { 374 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 375 syslog(LOG_ERR, "can't create tcp socket"); 376 exit(1); 377 } 378 if (setsockopt(tcpsock, 379 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 380 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 381 inetaddr.sin_family = AF_INET; 382 inetaddr.sin_addr.s_addr = INADDR_ANY; 383 inetaddr.sin_port = htons(NFS_PORT); 384 inetaddr.sin_len = sizeof(inetaddr); 385 if (bind(tcpsock, 386 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 387 syslog(LOG_ERR, "can't bind tcp addr"); 388 exit(1); 389 } 390 if (listen(tcpsock, 5) < 0) { 391 syslog(LOG_ERR, "listen failed"); 392 exit(1); 393 } 394 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 395 syslog(LOG_ERR, "can't register tcp with portmap"); 396 exit(1); 397 } 398 FD_SET(tcpsock, &sockbits); 399 maxsock = tcpsock; 400 connect_type_cnt++; 401 } 402 403#ifdef notyet 404 /* Now set up the master server socket waiting for tp4 connections. */ 405 if (tp4flag) { 406 if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) { 407 syslog(LOG_ERR, "can't create tp4 socket"); 408 exit(1); 409 } 410 if (setsockopt(tp4sock, 411 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 412 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 413 memset(&isoaddr, 0, sizeof(isoaddr)); 414 isoaddr.siso_family = AF_ISO; 415 isoaddr.siso_tlen = 2; 416 cp = TSEL(&isoaddr); 417 *cp++ = (NFS_PORT >> 8); 418 *cp = (NFS_PORT & 0xff); 419 isoaddr.siso_len = sizeof(isoaddr); 420 if (bind(tp4sock, 421 (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) { 422 syslog(LOG_ERR, "can't bind tp4 addr"); 423 exit(1); 424 } 425 if (listen(tp4sock, 5) < 0) { 426 syslog(LOG_ERR, "listen failed"); 427 exit(1); 428 } 429 /* 430 * XXX 431 * Someday this should probably use "rpcbind", the son of 432 * portmap. 433 */ 434 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 435 syslog(LOG_ERR, "can't register tcp with portmap"); 436 exit(1); 437 } 438 FD_SET(tp4sock, &sockbits); 439 maxsock = tp4sock; 440 connect_type_cnt++; 441 } 442 443 /* Now set up the master server socket waiting for tpip connections. */ 444 if (tpipflag) { 445 if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) { 446 syslog(LOG_ERR, "can't create tpip socket"); 447 exit(1); 448 } 449 if (setsockopt(tpipsock, 450 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 451 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 452 inetaddr.sin_family = AF_INET; 453 inetaddr.sin_addr.s_addr = INADDR_ANY; 454 inetaddr.sin_port = htons(NFS_PORT); 455 inetaddr.sin_len = sizeof(inetaddr); 456 if (bind(tpipsock, 457 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 458 syslog(LOG_ERR, "can't bind tcp addr"); 459 exit(1); 460 } 461 if (listen(tpipsock, 5) < 0) { 462 syslog(LOG_ERR, "listen failed"); 463 exit(1); 464 } 465 /* 466 * XXX 467 * Someday this should probably use "rpcbind", the son of 468 * portmap. 469 */ 470 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 471 syslog(LOG_ERR, "can't register tcp with portmap"); 472 exit(1); 473 } 474 FD_SET(tpipsock, &sockbits); 475 maxsock = tpipsock; 476 connect_type_cnt++; 477 } 478#endif /* notyet */ 479 480 if (connect_type_cnt == 0) 481 exit(0); 482 483 setproctitle("nfsd-master"); 484 485 /* 486 * Loop forever accepting connections and passing the sockets 487 * into the kernel for the mounts. 488 */ 489 for (;;) { 490 ready = sockbits; 491 if (connect_type_cnt > 1) { 492 if (select(maxsock + 1, 493 &ready, NULL, NULL, NULL) < 1) { 494 syslog(LOG_ERR, "select failed: %m"); 495 exit(1); 496 } 497 } 498 if (tcpflag && FD_ISSET(tcpsock, &ready)) { 499 len = sizeof(inetpeer); 500 if ((msgsock = accept(tcpsock, 501 (struct sockaddr *)&inetpeer, &len)) < 0) { 502 syslog(LOG_ERR, "accept failed: %m"); 503 exit(1); 504 } 505 memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero)); 506 if (setsockopt(msgsock, SOL_SOCKET, 507 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 508 syslog(LOG_ERR, 509 "setsockopt SO_KEEPALIVE: %m"); 510 nfsdargs.sock = msgsock; 511 nfsdargs.name = (caddr_t)&inetpeer; 512 nfsdargs.namelen = sizeof(inetpeer); 513 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 514 (void)close(msgsock); 515 } 516#ifdef notyet 517 if (tp4flag && FD_ISSET(tp4sock, &ready)) { 518 len = sizeof(isopeer); 519 if ((msgsock = accept(tp4sock, 520 (struct sockaddr *)&isopeer, &len)) < 0) { 521 syslog(LOG_ERR, "accept failed: %m"); 522 exit(1); 523 } 524 if (setsockopt(msgsock, SOL_SOCKET, 525 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 526 syslog(LOG_ERR, 527 "setsockopt SO_KEEPALIVE: %m"); 528 nfsdargs.sock = msgsock; 529 nfsdargs.name = (caddr_t)&isopeer; 530 nfsdargs.namelen = len; 531 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 532 (void)close(msgsock); 533 } 534 if (tpipflag && FD_ISSET(tpipsock, &ready)) { 535 len = sizeof(inetpeer); 536 if ((msgsock = accept(tpipsock, 537 (struct sockaddr *)&inetpeer, &len)) < 0) { 538 syslog(LOG_ERR, "Accept failed: %m"); 539 exit(1); 540 } 541 if (setsockopt(msgsock, SOL_SOCKET, 542 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 543 syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m"); 544 nfsdargs.sock = msgsock; 545 nfsdargs.name = (caddr_t)&inetpeer; 546 nfsdargs.namelen = len; 547 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 548 (void)close(msgsock); 549 } 550#endif /* notyet */ 551 } 552} 553 554void 555usage() 556{ 557 (void)fprintf(stderr, "nfsd %s\n", USAGE); 558 exit(1); 559} 560 561void 562nonfs(signo) 563 int signo; 564{ 565 syslog(LOG_ERR, "missing system call: NFS not available."); 566} 567 568void 569reapchild(signo) 570 int signo; 571{ 572 573 while (wait3(NULL, WNOHANG, NULL)); 574} 575 576void 577setproctitle(a) 578 char *a; 579{ 580 register char *cp; 581 char buf[80]; 582 583 cp = Argv[0]; 584 (void)snprintf(buf, sizeof(buf), "%s", a); 585 (void)strncpy(cp, buf, LastArg - cp); 586 cp += strlen(cp); 587 while (cp < LastArg) 588 *cp++ = '\0'; 589}
| 160 /* Save start and extent of argv for setproctitle. */ 161 Argv = argv; 162 if (envp == 0 || *envp == 0) 163 envp = argv; 164 while (*envp) 165 envp++; 166 LastArg = envp[-1] + strlen(envp[-1]); 167 168#define MAXNFSDCNT 20 169#define DEFNFSDCNT 4 170 nfsdcnt = DEFNFSDCNT; 171 cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0; 172 tpipflag = udpflag = 0; 173#ifdef ISO 174#define GETOPT "cn:rtu" 175#define USAGE "[-crtu] [-n num_servers]" 176#else 177#define GETOPT "n:rtu" 178#define USAGE "[-rtu] [-n num_servers]" 179#endif 180 while ((ch = getopt(argc, argv, GETOPT)) != EOF) 181 switch (ch) { 182 case 'n': 183 nfsdcnt = atoi(optarg); 184 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 185 warnx("nfsd count %d; reset to %d", DEFNFSDCNT); 186 nfsdcnt = DEFNFSDCNT; 187 } 188 break; 189 case 'r': 190 reregister = 1; 191 break; 192 case 't': 193 tcpflag = 1; 194 break; 195 case 'u': 196 udpflag = 1; 197 break; 198#ifdef ISO 199 case 'c': 200 cltpflag = 1; 201 break; 202#ifdef notyet 203 case 'i': 204 tp4cnt = 1; 205 break; 206 case 'p': 207 tpipcnt = 1; 208 break; 209#endif /* notyet */ 210#endif /* ISO */ 211 default: 212 case '?': 213 usage(); 214 }; 215 argv += optind; 216 argc -= optind; 217 218 /* 219 * XXX 220 * Backward compatibility, trailing number is the count of daemons. 221 */ 222 if (argc > 1) 223 usage(); 224 if (argc == 1) { 225 nfsdcnt = atoi(argv[0]); 226 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 227 warnx("nfsd count %d; reset to %d", DEFNFSDCNT); 228 nfsdcnt = DEFNFSDCNT; 229 } 230 } 231 232 if (debug == 0) { 233 daemon(0, 0); 234 (void)signal(SIGHUP, SIG_IGN); 235 (void)signal(SIGINT, SIG_IGN); 236 (void)signal(SIGQUIT, SIG_IGN); 237 (void)signal(SIGSYS, nonfs); 238 (void)signal(SIGTERM, SIG_IGN); 239 } 240 (void)signal(SIGCHLD, reapchild); 241 242 if (reregister) { 243 if (udpflag && 244 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) 245 err(1, "can't register with portmap for UDP."); 246 if (tcpflag && 247 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) 248 err(1, "can't register with portmap for TCP."); 249 exit(0); 250 } 251 openlog("nfsd:", LOG_PID, LOG_DAEMON); 252 253 for (i = 0; i < nfsdcnt; i++) { 254 switch (fork()) { 255 case -1: 256 syslog(LOG_ERR, "fork: %m"); 257 exit (1); 258 case 0: 259 break; 260 default: 261 continue; 262 } 263 264 setproctitle("nfsd-srv"); 265 nfssvc_flag = NFSSVC_NFSD; 266 nsd.nsd_nfsd = NULL; 267#ifdef KERBEROS 268 nsd.nsd_authstr = (char *)kt.dat; 269#endif 270 while (nfssvc(nfssvc_flag, &nsd) < 0) { 271 if (errno != ENEEDAUTH) { 272 syslog(LOG_ERR, "nfssvc: %m"); 273 exit(1); 274 } 275 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; 276#ifdef KERBEROS 277 kt.length = nsd.nsd_authlen; 278 kt.mbz = 0; 279 (void)strcpy(inst, "*"); 280 if (krb_rd_req(&kt, "rcmd", 281 inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK && 282 krb_kntoln(&auth, lnam) == KSUCCESS && 283 (pwd = getpwnam(lnam)) != NULL) { 284 cr = &nsd.nsd_cr; 285 cr->cr_uid = pwd->pw_uid; 286 cr->cr_groups[0] = pwd->pw_gid; 287 cr->cr_ngroups = 1; 288 setgrent(); 289 while ((grp = getgrent()) != NULL) { 290 if (grp->gr_gid == cr->cr_groups[0]) 291 continue; 292 for (cpp = grp->gr_mem; 293 *cpp != NULL; ++cpp) 294 if (!strcmp(*cpp, lnam)) 295 break; 296 if (*cpp == NULL) 297 continue; 298 cr->cr_groups[cr->cr_ngroups++] 299 = grp->gr_gid; 300 if (cr->cr_ngroups == NGROUPS) 301 break; 302 } 303 endgrent(); 304 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; 305 } 306#endif /* KERBEROS */ 307 } 308 exit(0); 309 } 310 311 /* If we are serving udp, set up the socket. */ 312 if (udpflag) { 313 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 314 syslog(LOG_ERR, "can't create udp socket"); 315 exit(1); 316 } 317 inetaddr.sin_family = AF_INET; 318 inetaddr.sin_addr.s_addr = INADDR_ANY; 319 inetaddr.sin_port = htons(NFS_PORT); 320 inetaddr.sin_len = sizeof(inetaddr); 321 if (bind(sock, 322 (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 323 syslog(LOG_ERR, "can't bind udp addr"); 324 exit(1); 325 } 326 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 327 syslog(LOG_ERR, "can't register with udp portmap"); 328 exit(1); 329 } 330 nfsdargs.sock = sock; 331 nfsdargs.name = NULL; 332 nfsdargs.namelen = 0; 333 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 334 syslog(LOG_ERR, "can't Add UDP socket"); 335 exit(1); 336 } 337 (void)close(sock); 338 } 339 340#ifdef ISO 341 /* If we are serving cltp, set up the socket. */ 342 if (cltpflag) { 343 if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) { 344 syslog(LOG_ERR, "can't create cltp socket"); 345 exit(1); 346 } 347 memset(&isoaddr, 0, sizeof(isoaddr)); 348 isoaddr.siso_family = AF_ISO; 349 isoaddr.siso_tlen = 2; 350 cp = TSEL(&isoaddr); 351 *cp++ = (NFS_PORT >> 8); 352 *cp = (NFS_PORT & 0xff); 353 isoaddr.siso_len = sizeof(isoaddr); 354 if (bind(sock, 355 (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) { 356 syslog(LOG_ERR, "can't bind cltp addr"); 357 exit(1); 358 } 359#ifdef notyet 360 /* 361 * XXX 362 * Someday this should probably use "rpcbind", the son of 363 * portmap. 364 */ 365 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 366 syslog(LOG_ERR, "can't register with udp portmap"); 367 exit(1); 368 } 369#endif /* notyet */ 370 nfsdargs.sock = sock; 371 nfsdargs.name = NULL; 372 nfsdargs.namelen = 0; 373 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 374 syslog(LOG_ERR, "can't add UDP socket"); 375 exit(1); 376 } 377 close(sock); 378 } 379#endif /* ISO */ 380 381 /* Now set up the master server socket waiting for tcp connections. */ 382 on = 1; 383 FD_ZERO(&sockbits); 384 connect_type_cnt = 0; 385 if (tcpflag) { 386 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 387 syslog(LOG_ERR, "can't create tcp socket"); 388 exit(1); 389 } 390 if (setsockopt(tcpsock, 391 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 392 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 393 inetaddr.sin_family = AF_INET; 394 inetaddr.sin_addr.s_addr = INADDR_ANY; 395 inetaddr.sin_port = htons(NFS_PORT); 396 inetaddr.sin_len = sizeof(inetaddr); 397 if (bind(tcpsock, 398 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 399 syslog(LOG_ERR, "can't bind tcp addr"); 400 exit(1); 401 } 402 if (listen(tcpsock, 5) < 0) { 403 syslog(LOG_ERR, "listen failed"); 404 exit(1); 405 } 406 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 407 syslog(LOG_ERR, "can't register tcp with portmap"); 408 exit(1); 409 } 410 FD_SET(tcpsock, &sockbits); 411 maxsock = tcpsock; 412 connect_type_cnt++; 413 } 414 415#ifdef notyet 416 /* Now set up the master server socket waiting for tp4 connections. */ 417 if (tp4flag) { 418 if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) { 419 syslog(LOG_ERR, "can't create tp4 socket"); 420 exit(1); 421 } 422 if (setsockopt(tp4sock, 423 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 424 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 425 memset(&isoaddr, 0, sizeof(isoaddr)); 426 isoaddr.siso_family = AF_ISO; 427 isoaddr.siso_tlen = 2; 428 cp = TSEL(&isoaddr); 429 *cp++ = (NFS_PORT >> 8); 430 *cp = (NFS_PORT & 0xff); 431 isoaddr.siso_len = sizeof(isoaddr); 432 if (bind(tp4sock, 433 (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) { 434 syslog(LOG_ERR, "can't bind tp4 addr"); 435 exit(1); 436 } 437 if (listen(tp4sock, 5) < 0) { 438 syslog(LOG_ERR, "listen failed"); 439 exit(1); 440 } 441 /* 442 * XXX 443 * Someday this should probably use "rpcbind", the son of 444 * portmap. 445 */ 446 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 447 syslog(LOG_ERR, "can't register tcp with portmap"); 448 exit(1); 449 } 450 FD_SET(tp4sock, &sockbits); 451 maxsock = tp4sock; 452 connect_type_cnt++; 453 } 454 455 /* Now set up the master server socket waiting for tpip connections. */ 456 if (tpipflag) { 457 if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) { 458 syslog(LOG_ERR, "can't create tpip socket"); 459 exit(1); 460 } 461 if (setsockopt(tpipsock, 462 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 463 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 464 inetaddr.sin_family = AF_INET; 465 inetaddr.sin_addr.s_addr = INADDR_ANY; 466 inetaddr.sin_port = htons(NFS_PORT); 467 inetaddr.sin_len = sizeof(inetaddr); 468 if (bind(tpipsock, 469 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 470 syslog(LOG_ERR, "can't bind tcp addr"); 471 exit(1); 472 } 473 if (listen(tpipsock, 5) < 0) { 474 syslog(LOG_ERR, "listen failed"); 475 exit(1); 476 } 477 /* 478 * XXX 479 * Someday this should probably use "rpcbind", the son of 480 * portmap. 481 */ 482 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 483 syslog(LOG_ERR, "can't register tcp with portmap"); 484 exit(1); 485 } 486 FD_SET(tpipsock, &sockbits); 487 maxsock = tpipsock; 488 connect_type_cnt++; 489 } 490#endif /* notyet */ 491 492 if (connect_type_cnt == 0) 493 exit(0); 494 495 setproctitle("nfsd-master"); 496 497 /* 498 * Loop forever accepting connections and passing the sockets 499 * into the kernel for the mounts. 500 */ 501 for (;;) { 502 ready = sockbits; 503 if (connect_type_cnt > 1) { 504 if (select(maxsock + 1, 505 &ready, NULL, NULL, NULL) < 1) { 506 syslog(LOG_ERR, "select failed: %m"); 507 exit(1); 508 } 509 } 510 if (tcpflag && FD_ISSET(tcpsock, &ready)) { 511 len = sizeof(inetpeer); 512 if ((msgsock = accept(tcpsock, 513 (struct sockaddr *)&inetpeer, &len)) < 0) { 514 syslog(LOG_ERR, "accept failed: %m"); 515 exit(1); 516 } 517 memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero)); 518 if (setsockopt(msgsock, SOL_SOCKET, 519 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 520 syslog(LOG_ERR, 521 "setsockopt SO_KEEPALIVE: %m"); 522 nfsdargs.sock = msgsock; 523 nfsdargs.name = (caddr_t)&inetpeer; 524 nfsdargs.namelen = sizeof(inetpeer); 525 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 526 (void)close(msgsock); 527 } 528#ifdef notyet 529 if (tp4flag && FD_ISSET(tp4sock, &ready)) { 530 len = sizeof(isopeer); 531 if ((msgsock = accept(tp4sock, 532 (struct sockaddr *)&isopeer, &len)) < 0) { 533 syslog(LOG_ERR, "accept failed: %m"); 534 exit(1); 535 } 536 if (setsockopt(msgsock, SOL_SOCKET, 537 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 538 syslog(LOG_ERR, 539 "setsockopt SO_KEEPALIVE: %m"); 540 nfsdargs.sock = msgsock; 541 nfsdargs.name = (caddr_t)&isopeer; 542 nfsdargs.namelen = len; 543 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 544 (void)close(msgsock); 545 } 546 if (tpipflag && FD_ISSET(tpipsock, &ready)) { 547 len = sizeof(inetpeer); 548 if ((msgsock = accept(tpipsock, 549 (struct sockaddr *)&inetpeer, &len)) < 0) { 550 syslog(LOG_ERR, "Accept failed: %m"); 551 exit(1); 552 } 553 if (setsockopt(msgsock, SOL_SOCKET, 554 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 555 syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m"); 556 nfsdargs.sock = msgsock; 557 nfsdargs.name = (caddr_t)&inetpeer; 558 nfsdargs.namelen = len; 559 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 560 (void)close(msgsock); 561 } 562#endif /* notyet */ 563 } 564} 565 566void 567usage() 568{ 569 (void)fprintf(stderr, "nfsd %s\n", USAGE); 570 exit(1); 571} 572 573void 574nonfs(signo) 575 int signo; 576{ 577 syslog(LOG_ERR, "missing system call: NFS not available."); 578} 579 580void 581reapchild(signo) 582 int signo; 583{ 584 585 while (wait3(NULL, WNOHANG, NULL)); 586} 587 588void 589setproctitle(a) 590 char *a; 591{ 592 register char *cp; 593 char buf[80]; 594 595 cp = Argv[0]; 596 (void)snprintf(buf, sizeof(buf), "%s", a); 597 (void)strncpy(cp, buf, LastArg - cp); 598 cp += strlen(cp); 599 while (cp < LastArg) 600 *cp++ = '\0'; 601}
|