summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-01-11 23:57:39 +0000
committerjhb <jhb@FreeBSD.org>2008-01-11 23:57:39 +0000
commit41560caefda371e018be6f679ded9c36742c2360 (patch)
treeac7d8d15c5502c5f5153283626cab40183a2fa33 /sys/nfsclient
parent171437d67cfa236655fe6e9050a0827c2e4af500 (diff)
downloadFreeBSD-src-41560caefda371e018be6f679ded9c36742c2360.zip
FreeBSD-src-41560caefda371e018be6f679ded9c36742c2360.tar.gz
The previous revision broke the case of reconnecting to a TCP NFS server
via a new socket during an NFS operation as that reconnect takes place in the context of an arbitrary thread with an arbitrary credential. Ideally we would like to use the mount point's credential for the entire process of setting up the socket to connect to the NFS server. Since some of the APIs (sobind(), etc.) only take a thread pointer and infer the credential from that instead of a direct credential, work around the problem by temporarily changing the current thread's credential to that of the mount point while connecting the socket and then reverting back to the original credential when we are done. Reviewed by: rwatson Tested on: UDP, TCP, TCP with forced reconnect
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs_socket.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index c4fe562..9edd157 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -264,7 +264,22 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
int error, rcvreserve, sndreserve;
int pktscale;
struct sockaddr *saddr;
- struct thread *td = curthread; /* only used for socreate and sobind */
+ struct ucred *origcred;
+ struct thread *td = curthread;
+
+ /*
+ * We need to establish the socket using the credentials of
+ * the mountpoint. Some parts of this process (such as
+ * sobind() and soconnect()) will use the curent thread's
+ * credential instead of the socket credential. To work
+ * around this, temporarily change the current thread's
+ * credential to that of the mountpoint.
+ *
+ * XXX: It would be better to explicitly pass the correct
+ * credential to sobind() and soconnect().
+ */
+ origcred = td->td_ucred;
+ td->td_ucred = nmp->nm_mountp->mnt_cred;
if (nmp->nm_sotype == SOCK_STREAM) {
mtx_lock(&nmp->nm_mtx);
@@ -453,6 +468,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
so->so_snd.sb_flags |= SB_NOINTR;
SOCKBUF_UNLOCK(&so->so_snd);
+ /* Restore current thread's credentials. */
+ td->td_ucred = origcred;
+
mtx_lock(&nmp->nm_mtx);
/* Initialize other non-zero congestion variables */
nfs_init_rtt(nmp);
@@ -463,6 +481,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
return (0);
bad:
+ /* Restore current thread's credentials. */
+ td->td_ucred = origcred;
+
nfs_disconnect(nmp);
return (error);
}
OpenPOWER on IntegriCloud