diff options
author | dfr <dfr@FreeBSD.org> | 1995-06-27 11:07:30 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1995-06-27 11:07:30 +0000 |
commit | 666343f7f055c064375d48bb9a608730d7145beb (patch) | |
tree | 372bad41f8c547f40d0826ed596c53dc772ab986 /usr.sbin/nfsd | |
parent | 6da3ef32238f37b3b45cf709205fcff60bcbda7f (diff) | |
download | FreeBSD-src-666343f7f055c064375d48bb9a608730d7145beb.zip FreeBSD-src-666343f7f055c064375d48bb9a608730d7145beb.tar.gz |
Changes to support version 3 of the NFS protocol.
The version 2 support has been tested (client+server) against FreeBSD-2.0,
IRIX 5.3 and FreeBSD-current (using a loopback mount). The version 2 support
is stable AFAIK.
The version 3 support has been tested with a loopback mount and minimally
against an IRIX 5.3 server. It needs more testing and may have problems.
I have patched amd to support the new variable length filehandles although
it will still only use version 2 of the protocol.
Before booting a kernel with these changes, nfs clients will need to at least
build and install /usr/sbin/mount_nfs. Servers will need to build and
install /usr/sbin/mountd.
NFS diskless support is untested.
Obtained from: Rick Macklem <rick@snowhite.cis.uoguelph.ca>
Diffstat (limited to 'usr.sbin/nfsd')
-rw-r--r-- | usr.sbin/nfsd/nfsd.8 | 3 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsd.c | 110 |
2 files changed, 87 insertions, 26 deletions
diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8 index a54a564..24573d9 100644 --- a/usr.sbin/nfsd/nfsd.8 +++ b/usr.sbin/nfsd/nfsd.8 @@ -98,7 +98,8 @@ listens for service requests at the port indicated in the .Tn NFS server specification; see .%T "Network File System Protocol Specification" , -RFC1094. +RFC1094 and +.%T "NFS: Network File System Version 3 Protocol Specification" . .Pp If .Nm nfsd diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index 9d4d226..8c8731d 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -63,10 +63,10 @@ static char sccsid[] = "@(#)nfsd.c 8.7 (Berkeley) 2/22/94"; #include <netiso/iso.h> #endif #include <nfs/rpcv2.h> -#include <nfs/nfsv2.h> +#include <nfs/nfsproto.h> #include <nfs/nfs.h> -#ifdef KERBEROS +#ifdef NFSKERB #include <kerberosIV/des.h> #include <kerberosIV/krb.h> #endif @@ -94,16 +94,23 @@ struct nfsd_srvargs nsd; char **Argv = NULL; /* pointer to argument vector */ char *LastArg = NULL; /* end of argv */ -#ifdef KERBEROS +#ifdef NFSKERB char lnam[ANAME_SZ]; KTEXT_ST kt; -AUTH_DAT auth; +AUTH_DAT kauth; char inst[INST_SZ]; +struct nfsrpc_fullblock kin, kout; +struct nfsrpc_fullverf kverf; +NFSKERBKEY_T kivec; +struct timeval ktv; +NFSKERBKEYSCHED_T kerb_keysched; #endif void nonfs __P((int)); void reapchild __P((int)); +#ifdef __FreeBSD__ void setproctitle __P((char *)); +#endif void usage __P((void)); /* @@ -139,11 +146,13 @@ main(argc, argv, envp) #ifdef ISO struct sockaddr_iso isoaddr, isopeer; #endif + struct timeval ktv; fd_set ready, sockbits; int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock; int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag; char *cp, **cpp; +#ifdef __FreeBSD__ struct vfsconf *vfc; vfc = getvfsbyname("nfs"); @@ -156,6 +165,7 @@ main(argc, argv, envp) if(!vfc) { errx(1, "NFS is not available in the running kernel"); } +#endif /* Save start and extent of argv for setproctitle. */ Argv = argv; @@ -241,10 +251,12 @@ main(argc, argv, envp) if (reregister) { if (udpflag && - !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) + (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || + !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT))) err(1, "can't register with portmap for UDP."); if (tcpflag && - !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) + (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || + !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT))) err(1, "can't register with portmap for TCP."); exit(0); } @@ -261,11 +273,17 @@ main(argc, argv, envp) continue; } - setproctitle("nfsd-srv"); + setproctitle("server"); nfssvc_flag = NFSSVC_NFSD; nsd.nsd_nfsd = NULL; -#ifdef KERBEROS - nsd.nsd_authstr = (char *)kt.dat; +#ifdef NFSKERB + if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF || + sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK) + syslog(LOG_ERR, "Yikes NFSKERB structs not packed!"); + nsd.nsd_authstr = (u_char *)&kt; + nsd.nsd_authlen = sizeof (kt); + nsd.nsd_verfstr = (u_char *)&kverf; + nsd.nsd_verflen = sizeof (kverf); #endif while (nfssvc(nfssvc_flag, &nsd) < 0) { if (errno != ENEEDAUTH) { @@ -273,14 +291,27 @@ main(argc, argv, envp) exit(1); } nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; -#ifdef KERBEROS - kt.length = nsd.nsd_authlen; - kt.mbz = 0; - (void)strcpy(inst, "*"); - if (krb_rd_req(&kt, "rcmd", - inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK && - krb_kntoln(&auth, lnam) == KSUCCESS && - (pwd = getpwnam(lnam)) != NULL) { +#ifdef NFSKERB + /* + * Get the Kerberos ticket out of the authenticator + * verify it and convert the principal name to a user + * name. The user name is then converted to a set of + * user credentials via the password and group file. + * Finally, decrypt the timestamp and validate it. + * For more info see the IETF Draft "Authentication + * in ONC RPC". + */ + kt.length = ntohl(kt.length); + if (gettimeofday(&ktv, (struct timezone *)0) == 0 && + kt.length > 0 && kt.length <= + (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) { + kin.w1 = NFS_KERBW1(kt); + kt.mbz = 0; + (void)strcpy(inst, "*"); + if (krb_rd_req(&kt, NFS_KERBSRV, + inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK && + krb_kntoln(&kauth, lnam) == KSUCCESS && + (pwd = getpwnam(lnam)) != NULL) { cr = &nsd.nsd_cr; cr->cr_uid = pwd->pw_uid; cr->cr_groups[0] = pwd->pw_gid; @@ -301,9 +332,34 @@ main(argc, argv, envp) break; } endgrent(); - nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; + + /* + * Get the timestamp verifier out of the + * authenticator and verifier strings. + */ + kin.t1 = kverf.t1; + kin.t2 = kverf.t2; + kin.w2 = kverf.w2; + bzero((caddr_t)kivec, sizeof (kivec)); + bcopy((caddr_t)kauth.session, + (caddr_t)nsd.nsd_key,sizeof(kauth.session)); + + /* + * Decrypt the timestamp verifier in CBC mode. + */ + XXX + + /* + * Validate the timestamp verifier, to + * check that the session key is ok. + */ + nsd.nsd_timestamp.tv_sec = ntohl(kout.t1); + nsd.nsd_timestamp.tv_usec = ntohl(kout.t2); + nsd.nsd_ttl = ntohl(kout.w1); + if ((nsd.nsd_ttl - 1) == ntohl(kout.w2)) + nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; } -#endif /* KERBEROS */ +#endif /* NFSKERB */ } exit(0); } @@ -323,7 +379,8 @@ main(argc, argv, envp) syslog(LOG_ERR, "can't bind udp addr"); exit(1); } - if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { + if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || + !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) { syslog(LOG_ERR, "can't register with udp portmap"); exit(1); } @@ -403,7 +460,8 @@ main(argc, argv, envp) syslog(LOG_ERR, "listen failed"); exit(1); } - if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { + if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || + !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)) { syslog(LOG_ERR, "can't register tcp with portmap"); exit(1); } @@ -492,7 +550,7 @@ main(argc, argv, envp) if (connect_type_cnt == 0) exit(0); - setproctitle("nfsd-master"); + setproctitle("master"); /* * Loop forever accepting connections and passing the sockets @@ -566,7 +624,7 @@ main(argc, argv, envp) void usage() { - (void)fprintf(stderr, "nfsd %s\n", USAGE); + (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); exit(1); } @@ -582,9 +640,10 @@ reapchild(signo) int signo; { - while (wait3(NULL, WNOHANG, NULL)); + while (wait3(NULL, WNOHANG, NULL) > 0); } +#ifdef __FreeBSD__ void setproctitle(a) char *a; @@ -593,9 +652,10 @@ setproctitle(a) char buf[80]; cp = Argv[0]; - (void)snprintf(buf, sizeof(buf), "%s", a); + (void)snprintf(buf, sizeof(buf), "nfsd-%s", a); (void)strncpy(cp, buf, LastArg - cp); cp += strlen(cp); while (cp < LastArg) *cp++ = '\0'; } +#endif /* __FreeBSD__ */ |