[PATCH] NFS: Fix keytabless mounts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit 05f4c350 "NFS: Discover NFSv4 server trunking when mounting"
Fri Sep 14 17:24:32 2012 introduced Uniform Client String support,
which forces our NFS client to establish a client ID immediately
during a mount operation rather than waiting until a user wants to
open a file.

Normally machine credentials (eg. from a keytab) are used to perform
a mount operation that is protected by Kerberos.  Before 05f4c350,
SETCLIENTID uses a machine credential, or falls back to a regular
user's credential if no keytab is available.

05f4c350 seems to have broken the ability to mount with sec=krb5 on
clients that don't have a keytab.  Performing SETCLIENTID early
means there may be no user credential to fall back on, since during
system initialization no regular user has kinit'd yet.

Typically, root is required to kinit in this situation anyway to
make a sec=krb5 mount work.  So, the kernel should try to use root's
credential for lease management if there's no keytab.

The new logic should cause the root credential to be tried only
after both the machine cred and a user cred are found to be
unavailable.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---

Hi Neil-

Here's a wacky idea to continue our conversation.  Tested just
enough to confirm it may do something useful.  Applies to 3.7.
Something similar might work for 3.8 and 3.9.

 fs/nfs/nfs4proc.c  |   15 ++++++++++-----
 fs/nfs/nfs4state.c |   12 ++++--------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 50bf31d..7e4934e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4215,7 +4215,8 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
 	dprintk("NFS call  setclientid auth=%s, '%.*s'\n",
 		clp->cl_rpcclient->cl_auth->au_ops->au_name,
 		setclientid.sc_name_len, setclientid.sc_name);
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg,
+					RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
 	dprintk("NFS reply setclientid: %d\n", status);
 	return status;
 }
@@ -4246,7 +4247,8 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
 		clp->cl_rpcclient->cl_auth->au_ops->au_name,
 		clp->cl_clientid);
 	now = jiffies;
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg,
+					RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
 	if (status == 0) {
 		spin_lock(&clp->cl_lock);
 		clp->cl_lease_time = fsinfo.lease_time * HZ;
@@ -5458,7 +5460,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 		goto out_server_scope;
 	}
 
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg,
+					RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
 	if (status == 0)
 		status = nfs4_check_cl_exchange_flags(res.flags);
 
@@ -5518,7 +5521,8 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 	};
 	int status;
 
-	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+	status = rpc_call_sync(clp->cl_rpcclient, &msg,
+					RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
 	if (status)
 		dprintk("NFS: Got error %d from the server %s on "
 			"DESTROY_CLIENTID.", status, clp->cl_hostname);
@@ -5926,7 +5930,8 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
 	nfs4_init_channel_attrs(&args);
 	args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
 
-	status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+	status = rpc_call_sync(session->clp->cl_rpcclient, &msg,
+					RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
 
 	if (!status)
 		/* Verify the session's negotiated channel_attrs values */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index b1c96e7..2a9bed3 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1740,10 +1740,9 @@ static int nfs4_establish_lease(struct nfs_client *clp)
 	int status;
 
 	cred = ops->get_clid_cred(clp);
-	if (cred == NULL)
-		return -ENOENT;
 	status = ops->establish_clid(clp, cred);
-	put_rpccred(cred);
+	if (cred)
+		put_rpccred(cred);
 	if (status != 0)
 		return status;
 	pnfs_destroy_all_layouts(clp);
@@ -1827,11 +1826,9 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
 	status  = -ENOENT;
 again:
 	cred = ops->get_clid_cred(clp);
-	if (cred == NULL)
-		goto out_unlock;
-
 	status = ops->detect_trunking(clp, result, cred);
-	put_rpccred(cred);
+	if (cred)
+		put_rpccred(cred);
 	switch (status) {
 	case 0:
 		break;
@@ -1878,7 +1875,6 @@ again:
 		status = -EKEYEXPIRED;
 	}
 
-out_unlock:
 	mutex_unlock(&nfs_clid_init_mutex);
 out_free:
 	kfree(flavors);

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux