1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * 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 char copyright[] = 13 "@(#) Copyright (c) 1989 Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif not lint 16 17 #ifndef lint 18 static char sccsid[] = "@(#)nfsd.c 5.11 (Berkeley) 02/15/92"; 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/krb.h> 51 #endif 52 53 /* Global defs */ 54 #ifdef DEBUG 55 #define syslog(e, s) fprintf(stderr,(s)) 56 int debug = 1; 57 #else 58 int debug = 0; 59 #endif 60 struct nfsd_srvargs nsd; 61 extern int errno; 62 char **Argv = NULL; /* pointer to argument vector */ 63 char *LastArg = NULL; /* end of argv */ 64 void reapchild(); 65 66 #ifdef KERBEROS 67 char lnam[ANAME_SZ]; 68 KTEXT_ST kt; 69 AUTH_DAT auth; 70 char inst[INST_SZ]; 71 #endif /* KERBEROS */ 72 73 /* 74 * Nfs server daemon mostly just a user context for nfssvc() 75 * 1 - do file descriptor and signal cleanup 76 * 2 - fork the nfsd(s) 77 * 3 - create server socket(s) 78 * 4 - register socket with portmap 79 * For connectionless protocols, just pass the socket into the kernel via. 80 * nfssvc(). 81 * For connection based sockets, loop doing accepts. When you get a new socket 82 * from accept, pass the msgsock into the kernel via. nfssvc(). 83 * The arguments are: 84 * -u - support udp nfs clients 85 * -t - support tcp nfs clients 86 * -c - support iso cltp clients 87 * -r - reregister with portmapper 88 * followed by "n" which is the number of nfsds' to fork off 89 */ 90 main(argc, argv, envp) 91 int argc; 92 char *argv[], *envp[]; 93 { 94 register int i; 95 register char *cp, **cpp; 96 register struct ucred *cr = &nsd.nsd_cr; 97 struct passwd *pwd; 98 struct group *grp; 99 int sock, msgsock, tcpflag = 0, udpflag = 0, ret, len; 100 int cltpflag = 0, tp4flag = 0, tpipflag = 0, connect_type_cnt = 0; 101 int maxsock, tcpsock, tp4sock, tpipsock, nfsdcnt = 4; 102 int nfssvc_flag, opt, on = 1, reregister = 0; 103 struct sockaddr_in inetaddr, inetpeer; 104 #ifdef ISO 105 struct sockaddr_iso isoaddr, isopeer; 106 #endif 107 struct nfsd_args nfsdargs; 108 fd_set ready, sockbits; 109 extern int optind; 110 extern char *optarg; 111 112 /* 113 * Save start and extent of argv for setproctitle. 114 */ 115 Argv = argv; 116 if (envp == 0 || *envp == 0) 117 envp = argv; 118 while (*envp) 119 envp++; 120 LastArg = envp[-1] + strlen(envp[-1]); 121 while ((opt = getopt(argc, argv, "utcr")) != EOF) 122 switch (opt) { 123 case 'u': 124 udpflag++; 125 break; 126 case 't': 127 tcpflag++; 128 break; 129 case 'r': 130 reregister++; 131 break; 132 #ifdef ISO 133 case 'c': 134 cltpflag++; 135 break; 136 #ifdef notyet 137 case 'i': 138 tp4cnt++; 139 break; 140 case 'p': 141 tpipcnt++; 142 break; 143 #endif /* notyet */ 144 #endif /* ISO */ 145 default: 146 case '?': 147 usage(); 148 }; 149 if (optind < argc) 150 nfsdcnt = atoi(argv[optind]); 151 if (nfsdcnt < 1 || nfsdcnt > 20) 152 nfsdcnt = 4; 153 154 if (debug == 0) { 155 daemon(0, 0); 156 signal(SIGINT, SIG_IGN); 157 signal(SIGQUIT, SIG_IGN); 158 signal(SIGTERM, SIG_IGN); 159 signal(SIGHUP, SIG_IGN); 160 } 161 signal(SIGCHLD, reapchild); 162 163 if (reregister) { 164 if (udpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, 165 NFS_PORT)) { 166 fprintf(stderr, 167 "Can't register with portmap for UDP\n"); 168 exit(1); 169 } 170 if (tcpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, 171 NFS_PORT)) { 172 fprintf(stderr, 173 "Can't register with portmap for TCP\n"); 174 exit(1); 175 } 176 exit(0); 177 } 178 openlog("nfsd:", LOG_PID, LOG_DAEMON); 179 180 for (i = 0; i < nfsdcnt; i++) 181 if (fork() == 0) { 182 setproctitle("nfsd-srv"); 183 nfssvc_flag = NFSSVC_NFSD; 184 nsd.nsd_nfsd = (struct nfsd *)0; 185 #ifdef KERBEROS 186 nsd.nsd_authstr = (char *)kt.dat; 187 #endif 188 while (nfssvc(nfssvc_flag, (caddr_t)&nsd) < 0) { 189 if (errno == ENEEDAUTH) { 190 nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHINFAIL); 191 #ifdef KERBEROS 192 kt.length = nsd.nsd_authlen; 193 kt.mbz = 0; 194 strcpy(inst, "*"); 195 if (krb_rd_req(&kt, "rcmd", inst, nsd.nsd_haddr, 196 &auth, "") == RD_AP_OK && 197 krb_kntoln(&auth, lnam) == KSUCCESS && 198 (pwd = getpwnam(lnam))) { 199 cr->cr_uid = pwd->pw_uid; 200 cr->cr_groups[0] = pwd->pw_gid; 201 cr->cr_ngroups = 1; 202 setgrent(); 203 while (grp = getgrent()) { 204 if (grp->gr_gid == cr->cr_groups[0]) 205 continue; 206 cpp = grp->gr_mem; 207 while (*cpp) { 208 if (!strcmp(*cpp, lnam)) 209 break; 210 cpp++; 211 } 212 if (*cpp) { 213 cr->cr_groups[cr->cr_ngroups++] = grp->gr_gid; 214 if (cr->cr_ngroups == NGROUPS) 215 break; 216 } 217 } 218 endgrent(); 219 nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHIN); 220 } 221 #endif /* KERBEROS */ 222 } else { 223 fprintf(stderr, "errno=%d\n",errno); 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 if (setsockopt(msgsock, SOL_SOCKET, 434 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 435 syslog(LOG_ERR, 436 "setsockopt SO_KEEPALIVE: %m"); 437 nfsdargs.sock = msgsock; 438 nfsdargs.name = (caddr_t)&inetpeer; 439 nfsdargs.namelen = len; 440 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 441 close(msgsock); 442 } 443 #ifdef notyet 444 if (tp4flag && FD_ISSET(tp4sock, &ready)) { 445 len = sizeof(isopeer); 446 if ((msgsock = accept(tp4sock, 447 (struct sockaddr *)&isopeer, &len)) < 0) { 448 syslog(LOG_ERR, "Accept failed: %m"); 449 exit(1); 450 } 451 if (setsockopt(msgsock, SOL_SOCKET, 452 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 453 syslog(LOG_ERR, 454 "setsockopt SO_KEEPALIVE: %m"); 455 nfsdargs.sock = msgsock; 456 nfsdargs.name = (caddr_t)&isopeer; 457 nfsdargs.namelen = len; 458 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 459 close(msgsock); 460 } 461 if (tpipflag && FD_ISSET(tpipsock, &ready)) { 462 len = sizeof(inetpeer); 463 if ((msgsock = accept(tpipsock, 464 (struct sockaddr *)&inetpeer, &len)) < 0) { 465 syslog(LOG_ERR, "Accept failed: %m"); 466 exit(1); 467 } 468 if (setsockopt(msgsock, SOL_SOCKET, 469 SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) 470 syslog(LOG_ERR, 471 "setsockopt SO_KEEPALIVE: %m"); 472 nfsdargs.sock = msgsock; 473 nfsdargs.name = (caddr_t)&inetpeer; 474 nfsdargs.namelen = len; 475 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 476 close(msgsock); 477 } 478 #endif /* notyet */ 479 } 480 } 481 482 usage() 483 { 484 fprintf(stderr, "nfsd [-u] [-t] [-c] [-r] [num_nfsds]\n"); 485 exit(1); 486 } 487 488 void 489 reapchild() 490 { 491 492 while (wait3((int *) NULL, WNOHANG, (struct rusage *) NULL)) 493 ; 494 } 495 496 setproctitle(a) 497 char *a; 498 { 499 register char *cp; 500 char buf[80]; 501 502 cp = Argv[0]; 503 (void) sprintf(buf, "%s", a); 504 (void) strncpy(cp, buf, LastArg - cp); 505 cp += strlen(cp); 506 while (cp < LastArg) 507 *cp++ = ' '; 508 } 509