Commit 2fc8c6f3 authored by Trond Myklebust's avatar Trond Myklebust

RPC: Make rpc_auth credential cache optional.

  Some RPC authentication flavours are not related to the uid (AUTH_NULL
  springs to mind). This patch moves control over the caching mechanism
  into the auth-specific code.

  Also ensure that expired creds are removed from the cache.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9d956f5b
...@@ -91,6 +91,7 @@ struct rpc_authops { ...@@ -91,6 +91,7 @@ struct rpc_authops {
struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t); struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t);
void (*destroy)(struct rpc_auth *); void (*destroy)(struct rpc_auth *);
struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
}; };
......
...@@ -137,16 +137,17 @@ rpcauth_free_credcache(struct rpc_auth *auth) ...@@ -137,16 +137,17 @@ rpcauth_free_credcache(struct rpc_auth *auth)
rpcauth_destroy_credlist(&free); rpcauth_destroy_credlist(&free);
} }
static inline int static void
rpcauth_prune_expired(struct rpc_cred *cred, struct list_head *free) rpcauth_prune_expired(struct rpc_cred *cred, struct list_head *free)
{ {
if (atomic_read(&cred->cr_count) != 1) if (atomic_read(&cred->cr_count) != 1)
return 0; return;
if (time_before(jiffies, cred->cr_expire + cred->cr_auth->au_expire)) if (time_after(jiffies, cred->cr_expire + cred->cr_auth->au_expire))
return 0; cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
cred->cr_auth = NULL; if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) {
list_move(&cred->cr_hash, free); cred->cr_auth = NULL;
return 1; list_move(&cred->cr_hash, free);
}
} }
/* /*
...@@ -191,13 +192,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, ...@@ -191,13 +192,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
list_for_each_safe(pos, next, &auth->au_credcache[nr]) { list_for_each_safe(pos, next, &auth->au_credcache[nr]) {
struct rpc_cred *entry; struct rpc_cred *entry;
entry = list_entry(pos, struct rpc_cred, cr_hash); entry = list_entry(pos, struct rpc_cred, cr_hash);
if (rpcauth_prune_expired(entry, &free))
continue;
if (entry->cr_ops->crmatch(acred, entry, taskflags)) { if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
list_del(&entry->cr_hash); list_del(&entry->cr_hash);
cred = entry; cred = entry;
break; break;
} }
rpcauth_prune_expired(entry, &free);
} }
if (new) { if (new) {
if (cred) if (cred)
...@@ -240,7 +240,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) ...@@ -240,7 +240,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
dprintk("RPC: looking up %s cred\n", dprintk("RPC: looking up %s cred\n",
auth->au_ops->au_name); auth->au_ops->au_name);
ret = rpcauth_lookup_credcache(auth, &acred, taskflags); ret = auth->au_ops->lookup_cred(auth, &acred, taskflags);
put_group_info(current->group_info); put_group_info(current->group_info);
return ret; return ret;
} }
...@@ -259,7 +259,7 @@ rpcauth_bindcred(struct rpc_task *task) ...@@ -259,7 +259,7 @@ rpcauth_bindcred(struct rpc_task *task)
dprintk("RPC: %4d looking up %s cred\n", dprintk("RPC: %4d looking up %s cred\n",
task->tk_pid, task->tk_auth->au_ops->au_name); task->tk_pid, task->tk_auth->au_ops->au_name);
task->tk_msg.rpc_cred = rpcauth_lookup_credcache(auth, &acred, task->tk_flags); task->tk_msg.rpc_cred = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags);
if (task->tk_msg.rpc_cred == 0) if (task->tk_msg.rpc_cred == 0)
task->tk_status = -ENOMEM; task->tk_status = -ENOMEM;
ret = task->tk_msg.rpc_cred; ret = task->tk_msg.rpc_cred;
......
...@@ -654,6 +654,15 @@ gss_destroy_cred(struct rpc_cred *rc) ...@@ -654,6 +654,15 @@ gss_destroy_cred(struct rpc_cred *rc)
kfree(cred); kfree(cred);
} }
/*
* Lookup RPCSEC_GSS cred for the current process
*/
static struct rpc_cred *
gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
{
return rpcauth_lookup_credcache(auth, acred, taskflags);
}
static struct rpc_cred * static struct rpc_cred *
gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
{ {
...@@ -1004,6 +1013,7 @@ static struct rpc_authops authgss_ops = { ...@@ -1004,6 +1013,7 @@ static struct rpc_authops authgss_ops = {
#endif #endif
.create = gss_create, .create = gss_create,
.destroy = gss_destroy, .destroy = gss_destroy,
.lookup_cred = gss_lookup_cred,
.crcreate = gss_create_cred .crcreate = gss_create_cred
}; };
......
...@@ -46,6 +46,15 @@ nul_destroy(struct rpc_auth *auth) ...@@ -46,6 +46,15 @@ nul_destroy(struct rpc_auth *auth)
kfree(auth); kfree(auth);
} }
/*
* Lookup NULL creds for current process
*/
static struct rpc_cred *
nul_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
return rpcauth_lookup_credcache(auth, acred, flags);
}
/* /*
* Create NULL creds for current process * Create NULL creds for current process
*/ */
...@@ -135,6 +144,7 @@ struct rpc_authops authnull_ops = { ...@@ -135,6 +144,7 @@ struct rpc_authops authnull_ops = {
#endif #endif
.create = nul_create, .create = nul_create,
.destroy = nul_destroy, .destroy = nul_destroy,
.lookup_cred = nul_lookup_cred,
.crcreate = nul_create_cred, .crcreate = nul_create_cred,
}; };
......
...@@ -65,6 +65,15 @@ unx_destroy(struct rpc_auth *auth) ...@@ -65,6 +65,15 @@ unx_destroy(struct rpc_auth *auth)
kfree(auth); kfree(auth);
} }
/*
* Lookup AUTH_UNIX creds for current process
*/
static struct rpc_cred *
unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
return rpcauth_lookup_credcache(auth, acred, flags);
}
static struct rpc_cred * static struct rpc_cred *
unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{ {
...@@ -225,6 +234,7 @@ struct rpc_authops authunix_ops = { ...@@ -225,6 +234,7 @@ struct rpc_authops authunix_ops = {
#endif #endif
.create = unx_create, .create = unx_create,
.destroy = unx_destroy, .destroy = unx_destroy,
.lookup_cred = unx_lookup_cred,
.crcreate = unx_create_cred, .crcreate = unx_create_cred,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment