Date: Mon, 05 May 1997 18:50:23 +0200 From: Mark Murray <mark@grondar.za> To: rick@snowhite.cis.uoguelph.ca, wollman@freebsd.org, dfr@freebsd.org Cc: current@freebsd.org Subject: Kerberised NFSD is broken. Message-ID: <199705051650.SAA11805@grackle.grondar.za>
next in thread | raw e-mail | index | archive | help
Hello
Way back in June '95, we broke Kerberised NFSD with this commit. (And
nobody noticed :-) )
In it, the #ifdef's enabling Kerberos were changed from KERBEROS
to NFSKERB, and some (obviously) broken code was inserted between
the #if / #endif pair.
Has anyone got a repaired version of this? Has anyone made it work?
Can anyone spend some time on it to make it work?
(Methinks the Kerberos bits can be just backed out, But I have other
things on my plate right now)
Here Is the log entry:
RCS file: /home/ncvs/src/sbin/nfsd/nfsd.c,v
keyword substitution: kv
total revisions: 17; selected revisions: 1
description:
----------------------------
revision 1.4
date: 1995/06/27 11:06:22; author: dfr; state: Exp; lines: +85 -25
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>
...and here is the diff itself (Hunt down for the exposed "XXX" that
breaks this - showing incomplete code?):
Index: nfsd.c
===================================================================
RCS file: /home/ncvs/src/sbin/nfsd/nfsd.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nfsd.c 1994/09/22 22:16:56 1.3
+++ nfsd.c 1995/06/27 11:06:22 1.4
@@ -63,10 +63,10 @@
#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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if (connect_type_cnt == 0)
exit(0);
- setproctitle("nfsd-master");
+ setproctitle("master");
/*
* Loop forever accepting connections and passing the sockets
@@ -566,7 +624,7 @@
void
usage()
{
- (void)fprintf(stderr, "nfsd %s\n", USAGE);
+ (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
exit(1);
}
@@ -582,9 +640,10 @@
int signo;
{
- while (wait3(NULL, WNOHANG, NULL));
+ while (wait3(NULL, WNOHANG, NULL) > 0);
}
+#ifdef __FreeBSD__
void
setproctitle(a)
char *a;
@@ -593,9 +652,10 @@
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__ */
--
Mark Murray PGP key fingerprint = 80 36 6E 40 83 D6 8A 36
This .sig is umop ap!sdn. BC 06 EA 0E 7A F2 CE CE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705051650.SAA11805>
