diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-11-01 16:31:02 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-07 19:31:35 -0500 |
commit | c6bb3ca27d78b902baa143b931a8d9ef53298afa (patch) | |
tree | 22bf022af19f0f2b39c4e77b8da8210a7e81e92a /fs/nfsd/nfs4callback.c | |
parent | acb2887e04c2140c2c63c8bf94e0b446efcc7001 (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.c | 49 |
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 | ||
633 | static struct rpc_cred *callback_cred; | ||
634 | |||
635 | int 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 | |||
645 | struct 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 | ||
634 | static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) | 659 | static 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 | ||
717 | static struct rpc_cred *callback_cred; | ||
718 | |||
719 | int 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 | |||
729 | static struct workqueue_struct *callback_wq; | 749 | static struct workqueue_struct *callback_wq; |
730 | 750 | ||
731 | static void run_nfsd4_cb(struct nfsd4_callback *cb) | 751 | static 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 | ||