diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2013-07-09 01:05:28 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2013-07-09 01:05:28 +0000 |
commit | 4050bd5a8c332830247150962d76ec30ac4b1176 (patch) | |
tree | fb833de398573277a20d524177c93d925a472b57 /sys/fs | |
parent | 3297db39d56073deb3fd4d2b69fce426ac837803 (diff) | |
download | FreeBSD-src-4050bd5a8c332830247150962d76ec30ac4b1176.zip FreeBSD-src-4050bd5a8c332830247150962d76ec30ac4b1176.tar.gz |
Add support for host-based (Kerberos 5 service principal) initiator
credentials to the kernel rpc. Modify the NFSv4 client to add
support for the gssname and allgssname mount options to use this
capability. Requires the gssd daemon to be running with the "-h" option.
Reviewed by: jhb
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/nfs/nfs.h | 1 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_commonkrpc.c | 61 | ||||
-rw-r--r-- | sys/fs/nfsclient/nfs_clvfsops.c | 5 |
3 files changed, 33 insertions, 34 deletions
diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index febb631..aaa7fb1 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -466,6 +466,7 @@ struct nfssockreq { u_int32_t nr_prog; u_int32_t nr_vers; struct __rpc_client *nr_client; + AUTH *nr_auth; }; /* diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 2ac9262..47e5a37 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -102,7 +102,6 @@ static int nfs_bufpackets = 4; static int nfs_reconnects; static int nfs3_jukebox_delay = 10; static int nfs_skip_wcc_data_onerr = 1; -static int nfs_keytab_enctype = ETYPE_DES_CBC_CRC; SYSCTL_DECL(_vfs_nfs); @@ -114,8 +113,6 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, &nfs3_jukebox_del "Number of seconds to delay a retry after receiving EJUKEBOX"); SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, &nfs_skip_wcc_data_onerr, 0, "Disable weak cache consistency checking when server returns an error"); -SYSCTL_INT(_vfs_nfs, OID_AUTO, keytab_enctype, CTLFLAG_RW, &nfs_keytab_enctype, 0, - "Encryption type for the keytab entry used by nfs"); static void nfs_down(struct nfsmount *, struct thread *, const char *, int, int); @@ -393,9 +390,6 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, { rpc_gss_service_t svc; AUTH *auth; -#ifdef notyet - rpc_gss_options_req_t req_options; -#endif switch (secflavour) { case RPCSEC_GSS_KRB5: @@ -411,28 +405,16 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, svc = rpc_gss_svc_integrity; else svc = rpc_gss_svc_privacy; -#ifdef notyet - req_options.req_flags = GSS_C_MUTUAL_FLAG; - req_options.time_req = 0; - req_options.my_cred = GSS_C_NO_CREDENTIAL; - req_options.input_channel_bindings = NULL; - req_options.enc_type = nfs_keytab_enctype; - - auth = rpc_gss_secfind_call(nrp->nr_client, cred, - clnt_principal, srv_principal, mech_oid, svc, - &req_options); -#else - /* - * Until changes to the rpcsec_gss code are committed, - * there is no support for host based initiator - * principals. As such, that case cannot yet be handled. - */ + if (clnt_principal == NULL) auth = rpc_gss_secfind_call(nrp->nr_client, cred, srv_principal, mech_oid, svc); - else - auth = NULL; -#endif + else { + auth = rpc_gss_seccreate_call(nrp->nr_client, cred, + clnt_principal, srv_principal, "kerberosv5", + svc, NULL, NULL, NULL); + return (auth); + } if (auth != NULL) return (auth); /* fallthrough */ @@ -505,7 +487,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, struct rpc_callextra ext; enum clnt_stat stat; struct nfsreq *rep = NULL; - char *srv_principal = NULL; + char *srv_principal = NULL, *clnt_principal = NULL; sigset_t oldset; struct ucred *authcred; @@ -568,6 +550,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, */ if (nmp->nm_krbnamelen > 0) { usegssname = 1; + clnt_principal = nmp->nm_krbname; } else if (nmp->nm_uid != (uid_t)-1) { KASSERT(nmp->nm_sockreq.nr_cred != NULL, ("newnfs_request: NULL nr_cred")); @@ -622,10 +605,19 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, if (nd->nd_procnum == NFSPROC_NULL) auth = authnone_create(); - else if (usegssname) - auth = nfs_getauth(nrp, secflavour, nmp->nm_krbname, - srv_principal, NULL, authcred); - else + else if (usegssname) { + /* + * For this case, the authenticator is held in the + * nfssockreq structure, so don't release the reference count + * held on it. --> Don't AUTH_DESTROY() it in this function. + */ + if (nrp->nr_auth == NULL) + nrp->nr_auth = nfs_getauth(nrp, secflavour, + clnt_principal, srv_principal, NULL, authcred); + else + rpc_gss_refresh_auth_call(nrp->nr_auth); + auth = nrp->nr_auth; + } else auth = nfs_getauth(nrp, secflavour, NULL, srv_principal, NULL, authcred); crfree(authcred); @@ -781,7 +773,8 @@ tryagain: } if (error) { m_freem(nd->nd_mreq); - AUTH_DESTROY(auth); + if (usegssname == 0) + AUTH_DESTROY(auth); if (rep != NULL) FREE((caddr_t)rep, M_NFSDREQ); if (set_sigset) @@ -991,7 +984,8 @@ tryagain: #endif m_freem(nd->nd_mreq); - AUTH_DESTROY(auth); + if (usegssname == 0) + AUTH_DESTROY(auth); if (rep != NULL) FREE((caddr_t)rep, M_NFSDREQ); if (set_sigset) @@ -1000,7 +994,8 @@ tryagain: nfsmout: mbuf_freem(nd->nd_mrep); mbuf_freem(nd->nd_mreq); - AUTH_DESTROY(auth); + if (usegssname == 0) + AUTH_DESTROY(auth); if (rep != NULL) FREE((caddr_t)rep, M_NFSDREQ); if (set_sigset) diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 45a5133..863c418 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -1446,6 +1446,8 @@ bad: nfscl_clientrelease(clp); newnfs_disconnect(&nmp->nm_sockreq); crfree(nmp->nm_sockreq.nr_cred); + if (nmp->nm_sockreq.nr_auth != NULL) + AUTH_DESTROY(nmp->nm_sockreq.nr_auth); mtx_destroy(&nmp->nm_sockreq.nr_mtx); mtx_destroy(&nmp->nm_mtx); if (nmp->nm_clp != NULL) { @@ -1516,7 +1518,8 @@ nfs_unmount(struct mount *mp, int mntflags) newnfs_disconnect(&nmp->nm_sockreq); crfree(nmp->nm_sockreq.nr_cred); FREE(nmp->nm_nam, M_SONAME); - + if (nmp->nm_sockreq.nr_auth != NULL) + AUTH_DESTROY(nmp->nm_sockreq.nr_auth); mtx_destroy(&nmp->nm_sockreq.nr_mtx); mtx_destroy(&nmp->nm_mtx); TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) |