aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@poochiereds.net>2014-06-21 20:52:17 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-07-12 18:41:25 -0400
commitf11b2a1cfbf5dd783eb55cb470509d06e20d1c78 (patch)
tree3e7ecb73670953ef7067551582dd3c432736a86c /fs
parenta0337d1ddb5a4bd609e3ff0955551cb240340340 (diff)
nfs4: copy acceptor name from context to nfs_client
The current CB_COMPOUND handling code tries to compare the principal name of the request with the cl_hostname in the client. This is not guaranteed to ever work, particularly if the client happened to mount a CNAME of the server or a non-fqdn. Fix this by instead comparing the cr_principal string with the acceptor name that we get from gssd. In the event that gssd didn't send one down (i.e. it was too old), then we fall back to trying to use the cl_hostname as we do today. Signed-off-by: Jeff Layton <jlayton@poochiereds.net> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/callback.c12
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/nfs4proc.c33
3 files changed, 45 insertions, 1 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 073b4cf67ed9..54de482143cc 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -428,6 +428,18 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
428 if (p == NULL) 428 if (p == NULL)
429 return 0; 429 return 0;
430 430
431 /*
432 * Did we get the acceptor from userland during the SETCLIENID
433 * negotiation?
434 */
435 if (clp->cl_acceptor)
436 return !strcmp(p, clp->cl_acceptor);
437
438 /*
439 * Otherwise try to verify it using the cl_hostname. Note that this
440 * doesn't work if a non-canonical hostname was used in the devname.
441 */
442
431 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ 443 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
432 444
433 if (memcmp(p, "nfs@", 4) != 0) 445 if (memcmp(p, "nfs@", 4) != 0)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index b213ee8fb012..168aa0df2658 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -252,6 +252,7 @@ void nfs_free_client(struct nfs_client *clp)
252 put_net(clp->cl_net); 252 put_net(clp->cl_net);
253 put_nfs_version(clp->cl_nfs_mod); 253 put_nfs_version(clp->cl_nfs_mod);
254 kfree(clp->cl_hostname); 254 kfree(clp->cl_hostname);
255 kfree(clp->cl_acceptor);
255 kfree(clp); 256 kfree(clp);
256 257
257 dprintk("<-- nfs_free_client()\n"); 258 dprintk("<-- nfs_free_client()\n");
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0b8490eab486..b7babb3b8a4d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4936,6 +4936,18 @@ nfs4_init_callback_netid(const struct nfs_client *clp, char *buf, size_t len)
4936 return scnprintf(buf, len, "tcp"); 4936 return scnprintf(buf, len, "tcp");
4937} 4937}
4938 4938
4939static void nfs4_setclientid_done(struct rpc_task *task, void *calldata)
4940{
4941 struct nfs4_setclientid *sc = calldata;
4942
4943 if (task->tk_status == 0)
4944 sc->sc_cred = get_rpccred(task->tk_rqstp->rq_cred);
4945}
4946
4947static const struct rpc_call_ops nfs4_setclientid_ops = {
4948 .rpc_call_done = nfs4_setclientid_done,
4949};
4950
4939/** 4951/**
4940 * nfs4_proc_setclientid - Negotiate client ID 4952 * nfs4_proc_setclientid - Negotiate client ID
4941 * @clp: state data structure 4953 * @clp: state data structure
@@ -4962,6 +4974,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
4962 .rpc_resp = res, 4974 .rpc_resp = res,
4963 .rpc_cred = cred, 4975 .rpc_cred = cred,
4964 }; 4976 };
4977 struct rpc_task *task;
4978 struct rpc_task_setup task_setup_data = {
4979 .rpc_client = clp->cl_rpcclient,
4980 .rpc_message = &msg,
4981 .callback_ops = &nfs4_setclientid_ops,
4982 .callback_data = &setclientid,
4983 .flags = RPC_TASK_TIMEOUT,
4984 };
4965 int status; 4985 int status;
4966 4986
4967 /* nfs_client_id4 */ 4987 /* nfs_client_id4 */
@@ -4988,7 +5008,18 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
4988 dprintk("NFS call setclientid auth=%s, '%.*s'\n", 5008 dprintk("NFS call setclientid auth=%s, '%.*s'\n",
4989 clp->cl_rpcclient->cl_auth->au_ops->au_name, 5009 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4990 setclientid.sc_name_len, setclientid.sc_name); 5010 setclientid.sc_name_len, setclientid.sc_name);
4991 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5011 task = rpc_run_task(&task_setup_data);
5012 if (IS_ERR(task)) {
5013 status = PTR_ERR(task);
5014 goto out;
5015 }
5016 status = task->tk_status;
5017 if (setclientid.sc_cred) {
5018 clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
5019 put_rpccred(setclientid.sc_cred);
5020 }
5021 rpc_put_task(task);
5022out:
4992 trace_nfs4_setclientid(clp, status); 5023 trace_nfs4_setclientid(clp, status);
4993 dprintk("NFS reply setclientid: %d\n", status); 5024 dprintk("NFS reply setclientid: %d\n", status);
4994 return status; 5025 return status;