mirror of https://gitee.com/openkylin/linux.git
SUNRPC: add side channel to use non-generic cred for rpc call.
The credential passed in rpc_message.rpc_cred is always a generic credential except in one instance. When gss_destroying_context() calls rpc_call_null(), it passes a specific credential that it needs to destroy. In this case the RPC acts *on* the credential rather than being authorized by it. This special case deserves explicit support and providing that will mean that rpc_message.rpc_cred is *always* generic, allowing some optimizations. So add "tk_op_cred" to rpc_task and "rpc_op_cred" to the setup data. Use this to pass the cred down from rpc_call_null(), and have rpcauth_bindcred() notice it and bind it in place. Credit to kernel test robot <fengguang.wu@intel.com> for finding a bug in earlier version of this patch. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
a68a72e135
commit
1de7eea929
|
@ -71,6 +71,7 @@ struct rpc_task {
|
|||
|
||||
struct rpc_clnt * tk_client; /* RPC client */
|
||||
struct rpc_xprt * tk_xprt; /* Transport */
|
||||
struct rpc_cred * tk_op_cred; /* cred being operated on */
|
||||
|
||||
struct rpc_rqst * tk_rqstp; /* RPC request */
|
||||
|
||||
|
@ -105,6 +106,7 @@ struct rpc_task_setup {
|
|||
struct rpc_task *task;
|
||||
struct rpc_clnt *rpc_client;
|
||||
struct rpc_xprt *rpc_xprt;
|
||||
struct rpc_cred *rpc_op_cred; /* credential being operated on */
|
||||
const struct rpc_message *rpc_message;
|
||||
const struct rpc_call_ops *callback_ops;
|
||||
void *callback_data;
|
||||
|
|
|
@ -751,7 +751,11 @@ rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
|
|||
|
||||
if (flags & RPC_TASK_ASYNC)
|
||||
lookupflags |= RPCAUTH_LOOKUP_NEW;
|
||||
if (cred != NULL && cred != &machine_cred)
|
||||
if (task->tk_op_cred)
|
||||
/* Task must use exactly this rpc_cred */
|
||||
new = task->tk_op_cred->cr_ops->crbind(task, task->tk_op_cred,
|
||||
lookupflags);
|
||||
else if (cred != NULL && cred != &machine_cred)
|
||||
new = cred->cr_ops->crbind(task, cred, lookupflags);
|
||||
else if (cred == &machine_cred)
|
||||
new = rpcauth_bind_machine_cred(task, lookupflags);
|
||||
|
|
|
@ -2534,12 +2534,12 @@ struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt,
|
|||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &rpcproc_null,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
struct rpc_task_setup task_setup_data = {
|
||||
.rpc_client = clnt,
|
||||
.rpc_xprt = xprt,
|
||||
.rpc_message = &msg,
|
||||
.rpc_op_cred = cred,
|
||||
.callback_ops = (ops != NULL) ? ops : &rpc_default_ops,
|
||||
.callback_data = data,
|
||||
.flags = flags,
|
||||
|
|
|
@ -997,6 +997,8 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
|
|||
|
||||
task->tk_xprt = xprt_get(task_setup_data->rpc_xprt);
|
||||
|
||||
task->tk_op_cred = get_rpccred(task_setup_data->rpc_op_cred);
|
||||
|
||||
if (task->tk_ops->rpc_call_prepare != NULL)
|
||||
task->tk_action = rpc_prepare_task;
|
||||
|
||||
|
@ -1054,6 +1056,7 @@ static void rpc_free_task(struct rpc_task *task)
|
|||
{
|
||||
unsigned short tk_flags = task->tk_flags;
|
||||
|
||||
put_rpccred(task->tk_op_cred);
|
||||
rpc_release_calldata(task->tk_ops, task->tk_calldata);
|
||||
|
||||
if (tk_flags & RPC_TASK_DYNAMIC) {
|
||||
|
|
Loading…
Reference in New Issue