nfsd.c (2999) | nfsd.c (9336) |
---|---|
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 --- 49 unchanged lines hidden (view full) --- 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> | 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 --- 49 unchanged lines hidden (view full) --- 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> | 66#include <nfs/nfsproto.h> |
67#include <nfs/nfs.h> 68 | 67#include <nfs/nfs.h> 68 |
69#ifdef KERBEROS | 69#ifdef NFSKERB |
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> --- 11 unchanged lines hidden (view full) --- 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 | 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> --- 11 unchanged lines hidden (view full) --- 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 | 97#ifdef NFSKERB |
98char lnam[ANAME_SZ]; 99KTEXT_ST kt; | 98char lnam[ANAME_SZ]; 99KTEXT_ST kt; |
100AUTH_DAT auth; | 100AUTH_DAT kauth; |
101char inst[INST_SZ]; | 101char inst[INST_SZ]; |
102struct nfsrpc_fullblock kin, kout; 103struct nfsrpc_fullverf kverf; 104NFSKERBKEY_T kivec; 105struct timeval ktv; 106NFSKERBKEYSCHED_T kerb_keysched; |
|
102#endif 103 104void nonfs __P((int)); 105void reapchild __P((int)); | 107#endif 108 109void nonfs __P((int)); 110void reapchild __P((int)); |
111#ifdef __FreeBSD__ |
|
106void setproctitle __P((char *)); | 112void setproctitle __P((char *)); |
113#endif |
|
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) --- 19 unchanged lines hidden (view full) --- 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 | 114void usage __P((void)); 115 116/* 117 * Nfs server daemon mostly just a user context for nfssvc() 118 * 119 * 1 - do file descriptor and signal cleanup 120 * 2 - fork the nfsd(s) 121 * 3 - create server socket(s) --- 19 unchanged lines hidden (view full) --- 141 struct group *grp; 142 struct nfsd_args nfsdargs; 143 struct passwd *pwd; 144 struct ucred *cr; 145 struct sockaddr_in inetaddr, inetpeer; 146#ifdef ISO 147 struct sockaddr_iso isoaddr, isopeer; 148#endif |
149 struct timeval ktv; |
|
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; | 150 fd_set ready, sockbits; 151 int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock; 152 int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; 153 int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag; 154 char *cp, **cpp; |
155#ifdef __FreeBSD__ |
|
147 struct vfsconf *vfc; 148 149 vfc = getvfsbyname("nfs"); 150 if(!vfc && vfsisloadable("nfs")) { 151 if(vfsload("nfs")) 152 err(1, "vfsload(nfs)"); 153 endvfsent(); /* flush cache */ 154 vfc = getvfsbyname("nfs"); /* probably unnecessary */ 155 } 156 if(!vfc) { 157 errx(1, "NFS is not available in the running kernel"); 158 } | 156 struct vfsconf *vfc; 157 158 vfc = getvfsbyname("nfs"); 159 if(!vfc && vfsisloadable("nfs")) { 160 if(vfsload("nfs")) 161 err(1, "vfsload(nfs)"); 162 endvfsent(); /* flush cache */ 163 vfc = getvfsbyname("nfs"); /* probably unnecessary */ 164 } 165 if(!vfc) { 166 errx(1, "NFS is not available in the running kernel"); 167 } |
168#endif |
|
159 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]); --- 69 unchanged lines hidden (view full) --- 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 && | 169 170 /* Save start and extent of argv for setproctitle. */ 171 Argv = argv; 172 if (envp == 0 || *envp == 0) 173 envp = argv; 174 while (*envp) 175 envp++; 176 LastArg = envp[-1] + strlen(envp[-1]); --- 69 unchanged lines hidden (view full) --- 246 (void)signal(SIGQUIT, SIG_IGN); 247 (void)signal(SIGSYS, nonfs); 248 (void)signal(SIGTERM, SIG_IGN); 249 } 250 (void)signal(SIGCHLD, reapchild); 251 252 if (reregister) { 253 if (udpflag && |
244 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) | 254 (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || 255 !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT))) |
245 err(1, "can't register with portmap for UDP."); 246 if (tcpflag && | 256 err(1, "can't register with portmap for UDP."); 257 if (tcpflag && |
247 !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) | 258 (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || 259 !pmap_set(RPCPROG_NFS, 3, 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 | 260 err(1, "can't register with portmap for TCP."); 261 exit(0); 262 } 263 openlog("nfsd:", LOG_PID, LOG_DAEMON); 264 265 for (i = 0; i < nfsdcnt; i++) { 266 switch (fork()) { 267 case -1: 268 syslog(LOG_ERR, "fork: %m"); 269 exit (1); 270 case 0: 271 break; 272 default: 273 continue; 274 } 275 |
264 setproctitle("nfsd-srv"); | 276 setproctitle("server"); |
265 nfssvc_flag = NFSSVC_NFSD; 266 nsd.nsd_nfsd = NULL; | 277 nfssvc_flag = NFSSVC_NFSD; 278 nsd.nsd_nfsd = NULL; |
267#ifdef KERBEROS 268 nsd.nsd_authstr = (char *)kt.dat; | 279#ifdef NFSKERB 280 if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF || 281 sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK) 282 syslog(LOG_ERR, "Yikes NFSKERB structs not packed!"); 283 nsd.nsd_authstr = (u_char *)&kt; 284 nsd.nsd_authlen = sizeof (kt); 285 nsd.nsd_verfstr = (u_char *)&kverf; 286 nsd.nsd_verflen = sizeof (kverf); |
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; | 287#endif 288 while (nfssvc(nfssvc_flag, &nsd) < 0) { 289 if (errno != ENEEDAUTH) { 290 syslog(LOG_ERR, "nfssvc: %m"); 291 exit(1); 292 } 293 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) { | 294#ifdef NFSKERB 295 /* 296 * Get the Kerberos ticket out of the authenticator 297 * verify it and convert the principal name to a user 298 * name. The user name is then converted to a set of 299 * user credentials via the password and group file. 300 * Finally, decrypt the timestamp and validate it. 301 * For more info see the IETF Draft "Authentication 302 * in ONC RPC". 303 */ 304 kt.length = ntohl(kt.length); 305 if (gettimeofday(&ktv, (struct timezone *)0) == 0 && 306 kt.length > 0 && kt.length <= 307 (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) { 308 kin.w1 = NFS_KERBW1(kt); 309 kt.mbz = 0; 310 (void)strcpy(inst, "*"); 311 if (krb_rd_req(&kt, NFS_KERBSRV, 312 inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK && 313 krb_kntoln(&kauth, lnam) == KSUCCESS && 314 (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; --- 4 unchanged lines hidden (view full) --- 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(); | 315 cr = &nsd.nsd_cr; 316 cr->cr_uid = pwd->pw_uid; 317 cr->cr_groups[0] = pwd->pw_gid; 318 cr->cr_ngroups = 1; 319 setgrent(); 320 while ((grp = getgrent()) != NULL) { 321 if (grp->gr_gid == cr->cr_groups[0]) 322 continue; --- 4 unchanged lines hidden (view full) --- 327 if (*cpp == NULL) 328 continue; 329 cr->cr_groups[cr->cr_ngroups++] 330 = grp->gr_gid; 331 if (cr->cr_ngroups == NGROUPS) 332 break; 333 } 334 endgrent(); |
304 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; | 335 336 /* 337 * Get the timestamp verifier out of the 338 * authenticator and verifier strings. 339 */ 340 kin.t1 = kverf.t1; 341 kin.t2 = kverf.t2; 342 kin.w2 = kverf.w2; 343 bzero((caddr_t)kivec, sizeof (kivec)); 344 bcopy((caddr_t)kauth.session, 345 (caddr_t)nsd.nsd_key,sizeof(kauth.session)); 346 347 /* 348 * Decrypt the timestamp verifier in CBC mode. 349 */ 350 XXX 351 352 /* 353 * Validate the timestamp verifier, to 354 * check that the session key is ok. 355 */ 356 nsd.nsd_timestamp.tv_sec = ntohl(kout.t1); 357 nsd.nsd_timestamp.tv_usec = ntohl(kout.t2); 358 nsd.nsd_ttl = ntohl(kout.w1); 359 if ((nsd.nsd_ttl - 1) == ntohl(kout.w2)) 360 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; |
305 } | 361 } |
306#endif /* KERBEROS */ | 362#endif /* NFSKERB */ |
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 } | 363 } 364 exit(0); 365 } 366 367 /* If we are serving udp, set up the socket. */ 368 if (udpflag) { 369 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 370 syslog(LOG_ERR, "can't create udp socket"); 371 exit(1); 372 } 373 inetaddr.sin_family = AF_INET; 374 inetaddr.sin_addr.s_addr = INADDR_ANY; 375 inetaddr.sin_port = htons(NFS_PORT); 376 inetaddr.sin_len = sizeof(inetaddr); 377 if (bind(sock, 378 (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 379 syslog(LOG_ERR, "can't bind udp addr"); 380 exit(1); 381 } |
326 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { | 382 if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || 383 !pmap_set(RPCPROG_NFS, 3, 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"); --- 63 unchanged lines hidden (view full) --- 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 } | 384 syslog(LOG_ERR, "can't register with udp portmap"); 385 exit(1); 386 } 387 nfsdargs.sock = sock; 388 nfsdargs.name = NULL; 389 nfsdargs.namelen = 0; 390 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 391 syslog(LOG_ERR, "can't Add UDP socket"); --- 63 unchanged lines hidden (view full) --- 455 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 456 syslog(LOG_ERR, "can't bind tcp addr"); 457 exit(1); 458 } 459 if (listen(tcpsock, 5) < 0) { 460 syslog(LOG_ERR, "listen failed"); 461 exit(1); 462 } |
406 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { | 463 if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || 464 !pmap_set(RPCPROG_NFS, 3, 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 --- 72 unchanged lines hidden (view full) --- 487 maxsock = tpipsock; 488 connect_type_cnt++; 489 } 490#endif /* notyet */ 491 492 if (connect_type_cnt == 0) 493 exit(0); 494 | 465 syslog(LOG_ERR, "can't register tcp with portmap"); 466 exit(1); 467 } 468 FD_SET(tcpsock, &sockbits); 469 maxsock = tcpsock; 470 connect_type_cnt++; 471 } 472 --- 72 unchanged lines hidden (view full) --- 545 maxsock = tpipsock; 546 connect_type_cnt++; 547 } 548#endif /* notyet */ 549 550 if (connect_type_cnt == 0) 551 exit(0); 552 |
495 setproctitle("nfsd-master"); | 553 setproctitle("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) { --- 57 unchanged lines hidden (view full) --- 561 } 562#endif /* notyet */ 563 } 564} 565 566void 567usage() 568{ | 554 555 /* 556 * Loop forever accepting connections and passing the sockets 557 * into the kernel for the mounts. 558 */ 559 for (;;) { 560 ready = sockbits; 561 if (connect_type_cnt > 1) { --- 57 unchanged lines hidden (view full) --- 619 } 620#endif /* notyet */ 621 } 622} 623 624void 625usage() 626{ |
569 (void)fprintf(stderr, "nfsd %s\n", USAGE); | 627 (void)fprintf(stderr, "usage: 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 | 628 exit(1); 629} 630 631void 632nonfs(signo) 633 int signo; 634{ 635 syslog(LOG_ERR, "missing system call: NFS not available."); 636} 637 638void 639reapchild(signo) 640 int signo; 641{ 642 |
585 while (wait3(NULL, WNOHANG, NULL)); | 643 while (wait3(NULL, WNOHANG, NULL) > 0); |
586} 587 | 644} 645 |
646#ifdef __FreeBSD__ |
|
588void 589setproctitle(a) 590 char *a; 591{ 592 register char *cp; 593 char buf[80]; 594 595 cp = Argv[0]; | 647void 648setproctitle(a) 649 char *a; 650{ 651 register char *cp; 652 char buf[80]; 653 654 cp = Argv[0]; |
596 (void)snprintf(buf, sizeof(buf), "%s", a); | 655 (void)snprintf(buf, sizeof(buf), "nfsd-%s", a); |
597 (void)strncpy(cp, buf, LastArg - cp); 598 cp += strlen(cp); 599 while (cp < LastArg) 600 *cp++ = '\0'; 601} | 656 (void)strncpy(cp, buf, LastArg - cp); 657 cp += strlen(cp); 658 while (cp < LastArg) 659 *cp++ = '\0'; 660} |
661#endif /* __FreeBSD__ */ |
|