diff options
author | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2007-10-13 17:38:44 +0000 |
---|---|---|
committer | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2007-10-13 17:38:44 +0000 |
commit | 03aa0da667eb224b857f57c160d3591493908b2b (patch) | |
tree | 72dfddec616fd537e2330a14662d1d4f6915dbbd /sys/nfs | |
parent | ee5aa9284d2c54b661f4c287b7aa777421036800 (diff) |
Remove alot of dead kerberos code (add sane comments too).
Cleanup and partly redo the way we create the RPC header, by having
nfsm_rpchead() do a bit more work. Right now this is pretty RPCAUTH_UNIX
centric, but since it is the only auth method we support right now thats
fine.
Make sure we can never generate a zero xid, thats forbidden by the RFC.
Misc cleanup.
tested by a few.
Diffstat (limited to 'sys/nfs')
-rw-r--r-- | sys/nfs/nfs_socket.c | 75 | ||||
-rw-r--r-- | sys/nfs/nfs_subs.c | 199 | ||||
-rw-r--r-- | sys/nfs/nfs_var.h | 7 |
3 files changed, 91 insertions, 190 deletions
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index b01c9f45369..8cf2daef3c4 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.51 2007/09/20 15:30:41 blambert Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.52 2007/10/13 17:38:43 thib Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -836,16 +836,11 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp) u_int32_t *tl; int i; struct nfsmount *nmp; - struct mbuf *md, *mheadend; - char nickv[RPCX_NICKVERF]; + struct mbuf *md; time_t reqtime, waituntil; caddr_t dpos, cp2; - int t1, s, error = 0, mrest_len, auth_len, auth_type; - int trylater_delay, failed_auth = 0; - int verf_len, verf_type; - u_int32_t xid; - char *auth_str, *verf_str; - NFSKERBKEY_T key; /* save session key */ + int t1, s, error = 0, mrest_len; + int trylater_delay; trylater_delay = NFS_MINTIMEO; @@ -863,36 +858,9 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp) } mrest_len = i; - /* - * Get the RPC header with authorization. - */ -kerbauth: - verf_str = auth_str = (char *)0; - if (nmp->nm_flag & NFSMNT_KERB) { - verf_str = nickv; - verf_len = sizeof (nickv); - auth_type = RPCAUTH_KERB4; - bzero((caddr_t)key, sizeof (key)); - if (failed_auth || nfs_getnickauth(nmp, cred, &auth_str, - &auth_len, verf_str, verf_len)) { - error = nfs_getauth(nmp, rep, cred, &auth_str, - &auth_len, verf_str, &verf_len, key); - if (error) { - pool_put(&nfsreqpl, rep); - m_freem(mrest); - return (error); - } - } - } else { - auth_type = RPCAUTH_UNIX; - auth_len = (((cred->cr_ngroups > nmp->nm_numgrps) ? - nmp->nm_numgrps : cred->cr_ngroups) << 2) + - 5 * NFSX_UNSIGNED; - } - m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len, - auth_str, verf_len, verf_str, mrest, mrest_len, &mheadend, &xid); - if (auth_str) - free(auth_str, M_TEMP); + /* Get the RPC header with authorization. */ + nfsm_rpchead(rep, cred, RPCAUTH_UNIX, mrest, mrest_len); + m = rep->r_mreq; /* * For stream protocols, insert a Sun RPC Record Mark. @@ -902,8 +870,7 @@ kerbauth: *mtod(m, u_int32_t *) = htonl(0x80000000 | (m->m_pkthdr.len - NFSX_UNSIGNED)); } - rep->r_mreq = m; - rep->r_xid = xid; + tryagain: if (nmp->nm_flag & NFSMNT_SOFT) rep->r_retry = nmp->nm_retry; @@ -1001,16 +968,7 @@ tryagain: if (*tl++ == rpc_msgdenied) { if (*tl == rpc_mismatch) error = EOPNOTSUPP; - else if ((nmp->nm_flag & NFSMNT_KERB) && *tl++ == rpc_autherr) { - if (!failed_auth) { - failed_auth++; - mheadend->m_next = (struct mbuf *)0; - m_freem(mrep); - m_freem(rep->r_mreq); - goto kerbauth; - } else - error = EAUTH; - } else + else error = EACCES; m_freem(mrep); m_freem(rep->r_mreq); @@ -1019,16 +977,15 @@ tryagain: } /* - * Grab any Kerberos verifier, otherwise just throw it away. + * Since we only support RPCAUTH_UNIX atm we step over the + * reply verifer type, and if the (error) case that there really + * is any data init, we advance over it. */ - verf_type = fxdr_unsigned(int, *tl++); + tl++; /* Step over verifer type */ i = fxdr_unsigned(int32_t, *tl); - if ((nmp->nm_flag & NFSMNT_KERB) && verf_type == RPCAUTH_KERB4) { - error = nfs_savenickauth(nmp, cred, i, key, &md, &dpos, mrep); - if (error) - goto nfsmout; - } else if (i > 0) - nfsm_adv(nfsm_rndup(i)); + if (i > 0) + nfsm_adv(nfsm_rndup(i)); /* Should not happen */ + nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); /* 0 == ok */ if (*tl == 0) { diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index 796e7f81ee8..2938cb488ee 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_subs.c,v 1.64 2007/10/08 17:39:52 deraadt Exp $ */ +/* $OpenBSD: nfs_subs.c,v 1.65 2007/10/13 17:38:43 thib Exp $ */ /* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */ /* @@ -93,7 +93,6 @@ u_int32_t nfs_prog, nfs_true, nfs_false; /* And other global data */ static u_int32_t nfs_xid = 0; -static u_int32_t nfs_xid_touched = 0; nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFNON, NFCHR, NFNON }; nfstype nfsv3_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, @@ -555,158 +554,104 @@ nfsm_reqh(vp, procid, hsiz, bposp) /* * Build the RPC header and fill in the authorization info. - * The authorization string argument is only used when the credentials - * come from outside of the kernel. - * Returns the head of the mbuf list. + * Right now we are pretty centric around RPCAUTH_UNIX, in the + * future, this function will need some love to be able to handle + * other authorization methods, such as Kerberos. */ -struct mbuf * -nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, - verf_str, mrest, mrest_len, mbp, xidp) - struct ucred *cr; - int nmflag; - int procid; - int auth_type; - int auth_len; - char *auth_str; - int verf_len; - char *verf_str; - struct mbuf *mrest; - int mrest_len; - struct mbuf **mbp; - u_int32_t *xidp; +void +nfsm_rpchead(struct nfsreq *req, struct ucred *cr, int auth_type, + struct mbuf *mrest, int mrest_len) { - struct mbuf *mb; - u_int32_t *tl; - caddr_t bpos; - int i; - struct mbuf *mreq, *mb2; - int siz, grpsiz, authsiz; + struct mbuf *mb, *mb2; + u_int32_t *tl; + u_int32_t xid; + caddr_t bpos; + int i, authsiz, auth_len, ngroups; - authsiz = nfsm_rndup(auth_len); + KASSERT(auth_type == RPCAUTH_UNIX); + + /* + * RPCAUTH_UNIX fits in an hdr mbuf, in the future other + * authorization methods need to figure out there own sizes + * and allocate and chain mbuf's accorindgly. + */ MGETHDR(mb, M_WAIT, MT_DATA); - if ((authsiz + 10 * NFSX_UNSIGNED) >= MINCLSIZE) { - MCLGET(mb, M_WAIT); - } else if ((authsiz + 10 * NFSX_UNSIGNED) < MHLEN) { + + /* + * We need to start out by finding how big the authorization cred + * and verifer are for the auth_type, to be able to correctly + * align the mbuf header/chain. + */ + switch (auth_type) { + case RPCAUTH_UNIX: + /* + * In the RPCAUTH_UNIX case, the size is the static + * part as shown in RFC1831 + the number of groups, + * RPCAUTH_UNIX has a zero verifer. + */ + if (cr->cr_ngroups > req->r_nmp->nm_numgrps) + ngroups = req->r_nmp->nm_numgrps; + else + ngroups = cr->cr_ngroups; + + auth_len = (ngroups << 2) + 5 * NFSX_UNSIGNED; + authsiz = nfsm_rndup(auth_len); + /* The authorization size + the size of the static part */ MH_ALIGN(mb, authsiz + 10 * NFSX_UNSIGNED); - } else { - MH_ALIGN(mb, 8 * NFSX_UNSIGNED); + break; } + mb->m_len = 0; - mreq = mb; bpos = mtod(mb, caddr_t); - /* - * First the RPC header. - */ - nfsm_build(tl, u_int32_t *, 8 * NFSX_UNSIGNED); + /* First the RPC header. */ + nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED); /* Get a new (non-zero) xid */ - - if ((nfs_xid == 0) && (nfs_xid_touched == 0)) { - nfs_xid = arc4random(); - nfs_xid_touched = 1; - } else { - while ((*xidp = arc4random() % 256) == 0) + do { + while ((xid = arc4random() % 256) == 0) ; - nfs_xid += *xidp; - } - - *tl++ = *xidp = txdr_unsigned(nfs_xid); + nfs_xid += xid; + } while (nfs_xid == 0); + + + *tl++ = req->r_xid = txdr_unsigned(nfs_xid); *tl++ = rpc_call; *tl++ = rpc_vers; - *tl++ = txdr_unsigned(NFS_PROG); - if (nmflag & NFSMNT_NFSV3) + *tl++ = nfs_prog; + if (ISSET(req->r_nmp->nm_flag, NFSMNT_NFSV3)) { *tl++ = txdr_unsigned(NFS_VER3); - else + *tl = txdr_unsigned(req->r_procnum); + } else { *tl++ = txdr_unsigned(NFS_VER2); - if (nmflag & NFSMNT_NFSV3) - *tl++ = txdr_unsigned(procid); - else - *tl++ = txdr_unsigned(nfsv2_procid[procid]); + *tl = txdr_unsigned(nfsv2_procid[req->r_procnum]); + } - /* - * And then the authorization cred. - */ - *tl++ = txdr_unsigned(auth_type); - *tl = txdr_unsigned(authsiz); + /* The Authorization cred and its verifier */ switch (auth_type) { case RPCAUTH_UNIX: - nfsm_build(tl, u_int32_t *, auth_len); - *tl++ = 0; /* stamp ?? */ + nfsm_build(tl, u_int32_t *, auth_len + 4 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(RPCAUTH_UNIX); + *tl++ = txdr_unsigned(authsiz); + + /* The authorization cred */ + *tl++ = 0; /* stamp */ *tl++ = 0; /* NULL hostname */ *tl++ = txdr_unsigned(cr->cr_uid); *tl++ = txdr_unsigned(cr->cr_gid); - grpsiz = (auth_len >> 2) - 5; - *tl++ = txdr_unsigned(grpsiz); - for (i = 0; i < grpsiz; i++) + *tl++ = txdr_unsigned(ngroups); + for (i = 0; i < ngroups; i++) *tl++ = txdr_unsigned(cr->cr_groups[i]); - break; - case RPCAUTH_KERB4: - siz = auth_len; - while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - MGET(mb2, M_WAIT, MT_DATA); - if (siz >= MINCLSIZE) - MCLGET(mb2, M_WAIT); - mb->m_next = mb2; - mb = mb2; - mb->m_len = 0; - bpos = mtod(mb, caddr_t); - } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(auth_str, bpos, i); - mb->m_len += i; - auth_str += i; - bpos += i; - siz -= i; - } - if ((siz = (nfsm_rndup(auth_len) - auth_len)) > 0) { - for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; - } - break; - }; - - /* - * And the verifier... - */ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (verf_str) { - *tl++ = txdr_unsigned(RPCAUTH_KERB4); - *tl = txdr_unsigned(verf_len); - siz = verf_len; - while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - MGET(mb2, M_WAIT, MT_DATA); - if (siz >= MINCLSIZE) - MCLGET(mb2, M_WAIT); - mb->m_next = mb2; - mb = mb2; - mb->m_len = 0; - bpos = mtod(mb, caddr_t); - } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(verf_str, bpos, i); - mb->m_len += i; - verf_str += i; - bpos += i; - siz -= i; - } - if ((siz = (nfsm_rndup(verf_len) - verf_len)) > 0) { - for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; - } - } else { + /* The authorization verifier */ *tl++ = txdr_unsigned(RPCAUTH_NULL); *tl = 0; + break; } + mb->m_next = mrest; - mreq->m_pkthdr.len = authsiz + 10 * NFSX_UNSIGNED + mrest_len; - mreq->m_pkthdr.rcvif = (struct ifnet *)0; - *mbp = mb; - return (mreq); + mb->m_pkthdr.len = authsiz + 10 * NFSX_UNSIGNED + mrest_len; + mb->m_pkthdr.rcvif = NULL; + req->r_mreq = mb; } /* diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h index 7b2302d5134..ef208b888c1 100644 --- a/sys/nfs/nfs_var.h +++ b/sys/nfs/nfs_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_var.h,v 1.28 2007/06/21 22:59:49 thib Exp $ */ +/* $OpenBSD: nfs_var.h,v 1.29 2007/10/13 17:38:43 thib Exp $ */ /* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */ /* @@ -238,9 +238,8 @@ void nfsrv_cleancache(void); /* nfs_subs.c */ struct mbuf *nfsm_reqh(struct vnode *, u_long, int, caddr_t *); -struct mbuf *nfsm_rpchead(struct ucred *, int, int, int, int, char *, int, - char *, struct mbuf *, int, struct mbuf **, - u_int32_t *); +void nfsm_rpchead(struct nfsreq *, struct ucred *, int, struct mbuf *, int); + int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *); int nfsm_uiotombuf(struct uio *, struct mbuf **, int, caddr_t *); int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *); |