summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfs/nfs_commonkrpc.c
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2009-05-24 03:22:49 +0000
committerrmacklem <rmacklem@FreeBSD.org>2009-05-24 03:22:49 +0000
commit954e72359d24b9f8bd6c78a22ef55047886577d5 (patch)
treeb92d5380399581617ef62785a8e76b5c787a77c1 /sys/fs/nfs/nfs_commonkrpc.c
parent7b70260976b9a4d6919e3a56f0ba2b10b33bb1eb (diff)
downloadFreeBSD-src-954e72359d24b9f8bd6c78a22ef55047886577d5.zip
FreeBSD-src-954e72359d24b9f8bd6c78a22ef55047886577d5.tar.gz
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)
Diffstat (limited to 'sys/fs/nfs/nfs_commonkrpc.c')
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 7abff32..d487703 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -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;
@@ -423,6 +426,14 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
}
/*
+ * 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);
OpenPOWER on IntegriCloud