mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 09:41:03 -04:00
Fix the experimental nfsv4 client so that it works for the
case of a kerberized mount without a host based principal name. This will only work for mounts being done by a user other than root. Support for a host based principal name will not work until proposed changes to the rpcsec_gss part of the krpc are committed. It now builds for "options KGSSAPI". Approved by: kib (mentor)
This commit is contained in:
parent
20d0a5e544
commit
63bde62e9a
2 changed files with 49 additions and 22 deletions
|
|
@ -341,7 +341,9 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal,
|
|||
else
|
||||
auth = NULL;
|
||||
#endif
|
||||
return (auth);
|
||||
if (auth != NULL)
|
||||
return (auth);
|
||||
/* fallthrough */
|
||||
#endif /* KGSSAPI */
|
||||
case AUTH_SYS:
|
||||
default:
|
||||
|
|
@ -402,7 +404,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
{
|
||||
u_int32_t *tl;
|
||||
time_t waituntil;
|
||||
int i, j;
|
||||
int i, j, set_uid = 0;
|
||||
int trycnt, error = 0, usegssname = 0, secflavour = AUTH_SYS;
|
||||
u_int16_t procnum;
|
||||
u_int trylater_delay = 1;
|
||||
|
|
@ -413,6 +415,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
enum clnt_stat stat;
|
||||
struct nfsreq *rep = NULL;
|
||||
char *srv_principal = NULL;
|
||||
uid_t saved_uid = (uid_t)-1;
|
||||
|
||||
if (xidp != NULL)
|
||||
*xidp = 0;
|
||||
|
|
@ -422,6 +425,14 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
return (ESTALE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX if not already connected call nfs_connect now. Longer
|
||||
* term, change nfs_mount to call nfs_connect unconditionally
|
||||
* and let clnt_reconnect_create handle reconnects.
|
||||
*/
|
||||
if (nrp->nr_client == NULL)
|
||||
newnfs_connect(nmp, nrp, cred, td, 0);
|
||||
|
||||
/*
|
||||
* For a client side mount, nmp is != NULL and clp == NULL. For
|
||||
* server calls (callbacks or upcalls), nmp == NULL.
|
||||
|
|
@ -442,8 +453,30 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
nd->nd_procnum != NFSPROC_NULL) {
|
||||
if (NFSHASALLGSSNAME(nmp) && nmp->nm_krbnamelen > 0)
|
||||
nd->nd_flag |= ND_USEGSSNAME;
|
||||
if ((nd->nd_flag & ND_USEGSSNAME) && nmp->nm_krbnamelen > 0)
|
||||
usegssname = 1;
|
||||
if ((nd->nd_flag & ND_USEGSSNAME) != 0) {
|
||||
/*
|
||||
* If there is a client side host based credential,
|
||||
* use that, otherwise use the system uid, if set.
|
||||
*/
|
||||
if (nmp->nm_krbnamelen > 0) {
|
||||
usegssname = 1;
|
||||
} else if (nmp->nm_uid != (uid_t)-1) {
|
||||
saved_uid = cred->cr_uid;
|
||||
cred->cr_uid = nmp->nm_uid;
|
||||
set_uid = 1;
|
||||
}
|
||||
} else if (nmp->nm_krbnamelen == 0 &&
|
||||
nmp->nm_uid != (uid_t)-1 && cred->cr_uid == (uid_t)0) {
|
||||
/*
|
||||
* If there is no host based principal name and
|
||||
* the system uid is set and this is root, use the
|
||||
* system uid, since root won't have user
|
||||
* credentials in a credentials cache file.
|
||||
*/
|
||||
saved_uid = cred->cr_uid;
|
||||
cred->cr_uid = nmp->nm_uid;
|
||||
set_uid = 1;
|
||||
}
|
||||
if (NFSHASINTEGRITY(nmp))
|
||||
secflavour = RPCSEC_GSS_KRB5I;
|
||||
else if (NFSHASPRIVACY(nmp))
|
||||
|
|
@ -462,14 +495,6 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
((nmp->nm_tprintf_delay)-(nmp->nm_tprintf_initial_delay));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX if not already connected call nfs_connect now. Longer
|
||||
* term, change nfs_mount to call nfs_connect unconditionally
|
||||
* and let clnt_reconnect_create handle reconnects.
|
||||
*/
|
||||
if (nrp->nr_client == NULL)
|
||||
newnfs_connect(nmp, nrp, cred, td, 0);
|
||||
|
||||
if (nd->nd_procnum == NFSPROC_NULL)
|
||||
auth = authnone_create();
|
||||
else if (usegssname)
|
||||
|
|
@ -478,6 +503,8 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
|||
else
|
||||
auth = nfs_getauth(nrp, secflavour, NULL,
|
||||
srv_principal, NULL, cred);
|
||||
if (set_uid)
|
||||
cred->cr_uid = saved_uid;
|
||||
if (auth == NULL) {
|
||||
m_freem(nd->nd_mreq);
|
||||
return (EACCES);
|
||||
|
|
|
|||
|
|
@ -1062,20 +1062,20 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
|||
nmp->nm_krbnamelen = argp->krbnamelen;
|
||||
nmp->nm_dirpathlen = argp->dirlen;
|
||||
nmp->nm_srvkrbnamelen = argp->srvkrbnamelen;
|
||||
if (nmp->nm_dirpathlen > 0) {
|
||||
if (td->td_ucred->cr_uid != (uid_t)0) {
|
||||
/*
|
||||
* Since we will be doing dirpath as root,
|
||||
* set nm_uid to the real uid doing the mount,
|
||||
* since that is normally the user with a valid TGT.
|
||||
* nm_uid is used to get KerberosV credentials for
|
||||
* the nfsv4 state handling operations if there is
|
||||
* no host based principal set. Use the uid of
|
||||
* this user if not root, since they are doing the
|
||||
* mount. I don't think setting this for root will
|
||||
* work, since root normally does not have user
|
||||
* credentials in a credentials cache.
|
||||
*/
|
||||
nmp->nm_uid = td->td_ucred->cr_ruid;
|
||||
nmp->nm_uid = td->td_ucred->cr_uid;
|
||||
} else {
|
||||
/*
|
||||
* Just set to -1, so the first Op
|
||||
* will set it later, to the uid of
|
||||
* the process doing that (usually
|
||||
* from a first open in the mount
|
||||
* point).
|
||||
* Just set to -1, so it won't be used.
|
||||
*/
|
||||
nmp->nm_uid = (uid_t)-1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue