aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-11-01 16:31:02 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-11-07 19:31:35 -0500
commitc6bb3ca27d78b902baa143b931a8d9ef53298afa (patch)
tree22bf022af19f0f2b39c4e77b8da8210a7e81e92a /fs/nfsd/nfs4callback.c
parentacb2887e04c2140c2c63c8bf94e0b446efcc7001 (diff)
nfsd4: use callback security parameters in create_session
We're currently ignoring the callback security parameters specified in create_session, and just assuming the client wants auth_sys, because that's all the current linux client happens to care about. But this could cause us callbacks to fail to a client that wanted something different. For now, all we're doing is no longer ignoring the uid and gid passed in the auth_sys case. Further patches will add support for auth_null and gss (and possibly use more of the auth_sys information; the spec wants us to use exactly the credential we're passed, though it's hard to imagine why a client would care). Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index bdf29c96e4cd..b32639ee0a42 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -630,6 +630,31 @@ static int max_cb_time(void)
630 return max(nfsd4_lease/10, (time_t)1) * HZ; 630 return max(nfsd4_lease/10, (time_t)1) * HZ;
631} 631}
632 632
633static struct rpc_cred *callback_cred;
634
635int set_callback_cred(void)
636{
637 if (callback_cred)
638 return 0;
639 callback_cred = rpc_lookup_machine_cred("nfs");
640 if (!callback_cred)
641 return -ENOMEM;
642 return 0;
643}
644
645struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
646{
647 if (clp->cl_minorversion == 0) {
648 return get_rpccred(callback_cred);
649 } else {
650 struct rpc_auth *auth = client->cl_auth;
651 struct auth_cred acred = {};
652
653 acred.uid = ses->se_cb_sec.uid;
654 acred.gid = ses->se_cb_sec.gid;
655 return auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
656 }
657}
633 658
634static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) 659static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
635{ 660{
@@ -648,6 +673,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
648 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 673 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
649 }; 674 };
650 struct rpc_clnt *client; 675 struct rpc_clnt *client;
676 struct rpc_cred *cred;
651 677
652 if (clp->cl_minorversion == 0) { 678 if (clp->cl_minorversion == 0) {
653 if (!clp->cl_cred.cr_principal && 679 if (!clp->cl_cred.cr_principal &&
@@ -675,7 +701,13 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
675 PTR_ERR(client)); 701 PTR_ERR(client));
676 return PTR_ERR(client); 702 return PTR_ERR(client);
677 } 703 }
704 cred = get_backchannel_cred(clp, client, ses);
705 if (IS_ERR(cred)) {
706 rpc_shutdown_client(client);
707 return PTR_ERR(cred);
708 }
678 clp->cl_cb_client = client; 709 clp->cl_cb_client = client;
710 clp->cl_cb_cred = cred;
679 return 0; 711 return 0;
680 712
681} 713}
@@ -714,18 +746,6 @@ static const struct rpc_call_ops nfsd4_cb_probe_ops = {
714 .rpc_call_done = nfsd4_cb_probe_done, 746 .rpc_call_done = nfsd4_cb_probe_done,
715}; 747};
716 748
717static struct rpc_cred *callback_cred;
718
719int set_callback_cred(void)
720{
721 if (callback_cred)
722 return 0;
723 callback_cred = rpc_lookup_machine_cred("nfs");
724 if (!callback_cred)
725 return -ENOMEM;
726 return 0;
727}
728
729static struct workqueue_struct *callback_wq; 749static struct workqueue_struct *callback_wq;
730 750
731static void run_nfsd4_cb(struct nfsd4_callback *cb) 751static void run_nfsd4_cb(struct nfsd4_callback *cb)
@@ -743,7 +763,6 @@ static void do_probe_callback(struct nfs4_client *clp)
743 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL]; 763 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL];
744 cb->cb_msg.rpc_argp = NULL; 764 cb->cb_msg.rpc_argp = NULL;
745 cb->cb_msg.rpc_resp = NULL; 765 cb->cb_msg.rpc_resp = NULL;
746 cb->cb_msg.rpc_cred = callback_cred;
747 766
748 cb->cb_ops = &nfsd4_cb_probe_ops; 767 cb->cb_ops = &nfsd4_cb_probe_ops;
749 768
@@ -962,6 +981,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
962 if (clp->cl_cb_client) { 981 if (clp->cl_cb_client) {
963 rpc_shutdown_client(clp->cl_cb_client); 982 rpc_shutdown_client(clp->cl_cb_client);
964 clp->cl_cb_client = NULL; 983 clp->cl_cb_client = NULL;
984 put_rpccred(clp->cl_cb_cred);
985 clp->cl_cb_cred = NULL;
965 } 986 }
966 if (clp->cl_cb_conn.cb_xprt) { 987 if (clp->cl_cb_conn.cb_xprt) {
967 svc_xprt_put(clp->cl_cb_conn.cb_xprt); 988 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
@@ -1010,6 +1031,7 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
1010 nfsd4_release_cb(cb); 1031 nfsd4_release_cb(cb);
1011 return; 1032 return;
1012 } 1033 }
1034 cb->cb_msg.rpc_cred = clp->cl_cb_cred;
1013 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN, 1035 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
1014 cb->cb_ops, cb); 1036 cb->cb_ops, cb);
1015} 1037}
@@ -1025,7 +1047,6 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp)
1025 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL]; 1047 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
1026 cb->cb_msg.rpc_argp = cb; 1048 cb->cb_msg.rpc_argp = cb;
1027 cb->cb_msg.rpc_resp = cb; 1049 cb->cb_msg.rpc_resp = cb;
1028 cb->cb_msg.rpc_cred = callback_cred;
1029 1050
1030 cb->cb_ops = &nfsd4_cb_recall_ops; 1051 cb->cb_ops = &nfsd4_cb_recall_ops;
1031 1052