1 /* 2 * Copyright (c) 1989, 1993 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 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char copyright[] = 13 "@(#) Copyright (c) 1989, 1993\n\ 14 The Regents of the University of California. All rights reserved.\n"; 15 #endif not lint 16 17 #ifndef lint 18 static char sccsid[] = "@(#)nfsd.c 8.1 (Berkeley) 06/05/93"; 19 #endif not lint 20 21 #include <stdio.h> 22 #include <signal.h> 23 #include <fcntl.h> 24 #include <strings.h> 25 #include <pwd.h> 26 #include <grp.h> 27 #include <sys/types.h> 28 #include <sys/syslog.h> 29 #include <sys/param.h> 30 #include <sys/errno.h> 31 #include <sys/ioctl.h> 32 #include <sys/stat.h> 33 #include <sys/wait.h> 34 #include <sys/uio.h> 35 #include <sys/namei.h> 36 #include <sys/ucred.h> 37 #include <sys/mount.h> 38 #include <sys/socket.h> 39 #include <sys/socketvar.h> 40 #include <rpc/rpc.h> 41 #include <rpc/pmap_clnt.h> 42 #include <rpc/pmap_prot.h> 43 #ifdef ISO 44 #include <netiso/iso.h> 45 #endif 46 #include <nfs/rpcv2.h> 47 #include <nfs/nfsv2.h> 48 #include <nfs/nfs.h> 49 #ifdef KERBEROS 50 #include <kerberosIV/des.h> 51 #include <kerberosIV/krb.h> 52 #endif 53 54 /* Global defs */ 55 #ifdef DEBUG 56 #define syslog(e, s) fprintf(stderr,(s)) 57 int debug = 1; 58 #else 59 int debug = 0; 60 #endif 61 struct nfsd_srvargs nsd; 62 extern int errno; 63 char **Argv = NULL; /* pointer to argument vector */ 64 char *LastArg = NULL; /* end of argv */ 65 void reapchild(); 66 67 #ifdef KERBEROS 68 char lnam[ANAME_SZ]; 69 KTEXT_ST kt; 70 AUTH_DAT auth; 71 char inst[INST_SZ]; 72 #endif /* KERBEROS */ 73 74 /* 75 * Nfs server daemon mostly just a user context for nfssvc() 76 * 1 - do file descriptor and signal cleanup 77 * 2 - fork the nfsd(s) 78 * 3 - create server socket(s) 79 * 4 - register socket with portmap 80 * For connectionless protocols, just pass the socket into the kernel via. 81 * nfssvc(). 82 * For connection based sockets, loop doing accepts. When you get a new socket 83 * from accept, pass the msgsock into the kernel via. nfssvc(). 84 * The arguments are: 85 * -u - support udp nfs clients 86 * -t - support tcp nfs clients 87 * -c - support iso cltp clients 88 * -r - reregister with portmapper 89 * followed by "n" which is the number of nfsds' to fork off 90 */ 91 main(argc, argv, envp) 92 int argc; 93 char *argv[], *envp[]; 94 { 95 register int i; 96 register char *cp, **cpp; 97 register struct ucred *cr = &nsd.nsd_cr; 98 struct passwd *pwd; 99 struct group *grp; 100 int sock, msgsock, tcpflag = 0, udpflag = 0, ret, len; 101 int cltpflag = 0, tp4flag = 0, tpipflag = 0, connect_type_cnt = 0; 102 int maxsock, tcpsock, tp4sock, tpipsock, nfsdcnt = 4; 103 int nfssvc_flag, opt, on = 1, reregister = 0; 104 struct sockaddr_in inetaddr, inetpeer; 105 #ifdef ISO 106 struct sockaddr_iso isoaddr, isopeer; 107 #endif 108 struct nfsd_args nfsdargs; 109 fd_set ready, sockbits; 110 extern int optind; 111 extern char *optarg; 112 113 /* 114 * Save start and extent of argv for setproctitle. 115 */ 116 Argv = argv; 117 if (envp == 0 || *envp == 0) 118 envp = argv; 119 while (*envp) 120 envp++; 121 LastArg = envp[-1] + strlen(envp[-1]); 122 while ((opt = getopt(argc, argv, "utcr")) != EOF) 123 switch (opt) { 124 case 'u': 125 udpflag++; 126 break; 127 case 't': 128 tcpflag++; 129 break; 130 case 'r': 131 reregister++; 132 break; 133 #ifdef ISO 134 case 'c': 135 cltpflag++; 136 break; 137 #ifdef notyet 138 case 'i': 139 tp4cnt++; 140 break; 141 case 'p': 142 tpipcnt++; 143 break; 144 #endif /* notyet */ 145 #endif /* ISO */ 146 default: 147 case '?': 148 usage(); 149 }; 150 if (optind < argc) 151 nfsdcnt = atoi(argv[optind]); 152 if (nfsdcnt < 1 || nfsdcnt > 20) 153 nfsdcnt = 4; 154 155 if (debug == 0) { 156 daemon(0, 0); 157 signal(SIGINT, SIG_IGN); 158 signal(SIGQUIT, SIG_IGN); 159 signal(SIGTERM, SIG_IGN); 160 signal(SIGHUP, SIG_IGN); 161 } 162 signal(SIGCHLD, reapchild); 163 164 if (reregister) { 165 if (udpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, 166 NFS_PORT)) { 167 fprintf(stderr, 168 "Can't register with portmap for UDP\n"); 169 exit(1); 170 } 171 if (tcpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, 172 NFS_PORT)) { 173 fprintf(stderr, 174 "Can't register with portmap for TCP\n"); 175 exit(1); 176 } 177 exit(0); 178 } 179 openlog("nfsd:", LOG_PID, LOG_DAEMON); 180 181 for (i = 0; i < nfsdcnt; i++) 182 if (fork() == 0) { 183 setproctitle("nfsd-srv"); 184 nfssvc_flag = NFSSVC_NFSD; 185 nsd.nsd_nfsd = (struct nfsd *)0; 186 #ifdef KERBEROS 187 nsd.nsd_authstr = (char *)kt.dat; 188 #endif 189 while (nfssvc(nfssvc_flag, (caddr_t)&nsd) < 0) { 190 if (errno == ENEEDAUTH) { 191 nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHINFAIL); 192 #ifdef KERBEROS 193 kt.length = nsd.nsd_authlen; 194 kt.mbz = 0; 195 strcpy(inst, "*"); 196 if (krb_rd_req(&kt, "rcmd", inst, nsd.nsd_haddr, 197 &auth, "") == RD_AP_OK && 198 krb_kntoln(&auth, lnam) == KSUCCESS && 199 (pwd = getpwnam(lnam))) { 200 cr->cr_uid = pwd->pw_uid; 201 cr->cr_groups[0] = pwd->pw_gid; 202 cr->cr_ngroups = 1; 203 setgrent(); 204 while (grp = getgrent()) { 205 if (grp->gr_gid == cr->cr_groups[0]) 206 continue; 207 cpp = grp->gr_mem; 208 while (*cpp) { 209 if (!strcmp(*cpp, lnam)) 210 break; 211 cpp++; 212 } 213 if (*cpp) { 214 cr->cr_groups[cr->cr_ngroups++] = grp->gr_gid; 215 if (cr->cr_ngroups == NGROUPS) 216 break; 217 } 218 } 219 endgrent(); 220 nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHIN); 221 } 222 #endif /* KERBEROS */ 223 } else { 224 syslog(LOG_ERR, "Nfsd died %m"); 225 exit(1); 226 } 227 } 228 exit(); 229 } 230 231 /* 232 * If we are serving udp, set up the socket. 233 */ 234 if (udpflag) { 235 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 236 syslog(LOG_ERR, "Can't create udp socket"); 237 exit(1); 238 } 239 inetaddr.sin_family = AF_INET; 240 inetaddr.sin_addr.s_addr = INADDR_ANY; 241 inetaddr.sin_port = htons(NFS_PORT); 242 inetaddr.sin_len = sizeof(inetaddr); 243 if (bind(sock, (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 244 syslog(LOG_ERR, "Can't bind udp addr"); 245 exit(1); 246 } 247 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 248 syslog(LOG_ERR, "Can't register with udp portmap"); 249 exit(1); 250 } 251 nfsdargs.sock = sock; 252 nfsdargs.name = (caddr_t)0; 253 nfsdargs.namelen = 0; 254 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 255 syslog(LOG_ERR, "Can't Add UDP socket"); 256 exit(1); 257 } 258 close(sock); 259 } 260 261 /* 262 * If we are serving cltp, set up the socket. 263 */ 264 #ifdef ISO 265 if (cltpflag) { 266 if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) { 267 syslog(LOG_ERR, "Can't create cltp socket"); 268 exit(1); 269 } 270 bzero((caddr_t)&isoaddr, sizeof (isoaddr)); 271 isoaddr.siso_family = AF_ISO; 272 isoaddr.siso_tlen = 2; 273 cp = TSEL(&isoaddr); 274 *cp++ = (NFS_PORT >> 8); 275 *cp = (NFS_PORT & 0xff); 276 isoaddr.siso_len = sizeof(isoaddr); 277 if (bind(sock, (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) { 278 syslog(LOG_ERR, "Can't bind cltp addr"); 279 exit(1); 280 } 281 #ifdef notyet 282 /* 283 * Someday this should probably use "rpcbind", the son of 284 * portmap. 285 */ 286 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 287 syslog(LOG_ERR, "Can't register with udp portmap"); 288 exit(1); 289 } 290 #endif /* notyet */ 291 nfsdargs.sock = sock; 292 nfsdargs.name = (caddr_t)0; 293 nfsdargs.namelen = 0; 294 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 295 syslog(LOG_ERR, "Can't Add UDP socket"); 296 exit(); 297 } 298 close(sock); 299 } 300 #endif /* ISO */ 301 302 /* 303 * Now set up the master server socket waiting for tcp connections. 304 */ 305 FD_ZERO(&sockbits); 306 if (tcpflag) { 307 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 308 syslog(LOG_ERR, "Can't create tcp socket"); 309 exit(1); 310 } 311 if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, 312 (char *) &on, sizeof(on)) < 0) 313 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 314 inetaddr.sin_family = AF_INET; 315 inetaddr.sin_addr.s_addr = INADDR_ANY; 316 inetaddr.sin_port = htons(NFS_PORT); 317 inetaddr.sin_len = sizeof (inetaddr); 318 if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 319 syslog(LOG_ERR, "Can't bind tcp addr"); 320 exit(1); 321 } 322 if (listen(tcpsock, 5) < 0) { 323 syslog(LOG_ERR, "Listen failed"); 324 exit(1); 325 } 326 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 327 syslog(LOG_ERR, "Can't register tcp with portmap"); 328 exit(1); 329 } 330 FD_SET(tcpsock, &sockbits); 331 maxsock = tcpsock; 332 connect_type_cnt++; 333 } 334 335 #ifdef notyet 336 /* 337 * Now set up the master server socket waiting for tp4 connections. 338 */ 339 if (tp4flag) { 340 if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) { 341 syslog(LOG_ERR, "Can't create tp4 socket"); 342 exit(1); 343 } 344 if (setsockopt(tp4sock, SOL_SOCKET, SO_REUSEADDR, 345 (char *) &on, sizeof(on)) < 0) 346 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 347 bzero((caddr_t)&isoaddr, 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(tp4sock, (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) { 355 syslog(LOG_ERR, "Can't bind tp4 addr"); 356 exit(1); 357 } 358 if (listen(tp4sock, 5) < 0) { 359 syslog(LOG_ERR, "Listen failed"); 360 exit(1); 361 } 362 /* 363 * Someday this should probably use "rpcbind". 364 */ 365 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 366 syslog(LOG_ERR, "Can't register tcp with portmap"); 367 exit(1); 368 } 369 FD_SET(tp4sock, &sockbits); 370 maxsock = tp4sock; 371 connect_type_cnt++; 372 } 373 374 /* 375 * Now set up the master server socket waiting for tpip connections. 376 */ 377 if (tpipflag) { 378 if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) { 379 syslog(LOG_ERR, "Can't create tpip socket"); 380 exit(1); 381 } 382 if (setsockopt(tpipsock, SOL_SOCKET, SO_REUSEADDR, 383 (char *) &on, sizeof(on)) < 0) 384 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 385 inetaddr.sin_family = AF_INET; 386 inetaddr.sin_addr.s_addr = INADDR_ANY; 387 inetaddr.sin_port = htons(NFS_PORT); 388 inetaddr.sin_len = sizeof (inetaddr); 389 if (bind(tpipsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 390 syslog(LOG_ERR, "Can't bind tcp addr"); 391 exit(1); 392 } 393 if (listen(tpipsock, 5) < 0) { 394 syslog(LOG_ERR, "Listen failed"); 395 exit(1); 396 } 397 /* 398 * Someday this should use "rpcbind" 399 */ 400 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 401 syslog(LOG_ERR, "Can't register tcp with portmap"); 402 exit(1); 403 } 404 FD_SET(tpipsock, &sockbits); 405 maxsock = tpipsock; 406 connect_type_cnt++; 407 } 408 #endif /* notyet */ 409 410 if (connect_type_cnt == 0) 411 exit(); 412 setproctitle("nfsd-master"); 413 /* 414 * Loop forever accepting connections and passing the sockets 415 * into the kernel for the mounts. 416 */ 417 for (;;) { 418 ready = sockbits; 419 if (connect_type_cnt > 1) { 420 if (select(maxsock + 1, &ready, (fd_set *)0, 421 (fd_set *)0, (struct timeval *)0) < 1) { 422 syslog(LOG_ERR, "Select failed"); 423 exit(1); 424 } 425 } 426 if (tcpflag && FD_ISSET(tcpsock, &ready)) { 427 len = sizeof(inetpeer); 428 if ((msgsock = accept(tcpsock, 429 (struct sockaddr *)&inetpeer, &len)) < 0) { 430 syslog(LOG_ERR, "Accept failed: %m"); 431 exit(1); 432 } 433 bzero((char *)inetpeer.sin_zero, 434 sizeof(inetpeer.sin_zero)); 435 if (setsockopt(msgsock, SOL_SOCKET, 436 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 437 syslog(LOG_ERR, 438 "setsockopt SO_KEEPALIVE: %m"); 439 nfsdargs.sock = msgsock; 440 nfsdargs.name = (caddr_t)&inetpeer; 441 nfsdargs.namelen = sizeof(inetpeer); 442 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 443 close(msgsock); 444 } 445 #ifdef notyet 446 if (tp4flag && FD_ISSET(tp4sock, &ready)) { 447 len = sizeof(isopeer); 448 if ((msgsock = accept(tp4sock, 449 (struct sockaddr *)&isopeer, &len)) < 0) { 450 syslog(LOG_ERR, "Accept failed: %m"); 451 exit(1); 452 } 453 if (setsockopt(msgsock, SOL_SOCKET, 454 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 455 syslog(LOG_ERR, 456 "setsockopt SO_KEEPALIVE: %m"); 457 nfsdargs.sock = msgsock; 458 nfsdargs.name = (caddr_t)&isopeer; 459 nfsdargs.namelen = len; 460 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 461 close(msgsock); 462 } 463 if (tpipflag && FD_ISSET(tpipsock, &ready)) { 464 len = sizeof(inetpeer); 465 if ((msgsock = accept(tpipsock, 466 (struct sockaddr *)&inetpeer, &len)) < 0) { 467 syslog(LOG_ERR, "Accept failed: %m"); 468 exit(1); 469 } 470 if (setsockopt(msgsock, SOL_SOCKET, 471 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 472 syslog(LOG_ERR, 473 "setsockopt SO_KEEPALIVE: %m"); 474 nfsdargs.sock = msgsock; 475 nfsdargs.name = (caddr_t)&inetpeer; 476 nfsdargs.namelen = len; 477 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 478 close(msgsock); 479 } 480 #endif /* notyet */ 481 } 482 } 483 484 usage() 485 { 486 fprintf(stderr, "nfsd [-u] [-t] [-c] [-r] [num_nfsds]\n"); 487 exit(1); 488 } 489 490 void 491 reapchild() 492 { 493 494 while (wait3((int *) NULL, WNOHANG, (struct rusage *) NULL)) 495 ; 496 } 497 498 setproctitle(a) 499 char *a; 500 { 501 register char *cp; 502 char buf[80]; 503 504 cp = Argv[0]; 505 (void) sprintf(buf, "%s", a); 506 (void) strncpy(cp, buf, LastArg - cp); 507 cp += strlen(cp); 508 while (cp < LastArg) 509 *cp++ = ' '; 510 } 511