diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
commit | d3e71cb08747743fce908122bab08b479eb403a5 (patch) | |
tree | cbec6948fdbdee9af81cf3ecfb504070d2745d7b /net/sunrpc/auth.c | |
parent | fe7ff1706e323d0e5ed83972960a1ecc1ee538b3 (diff) |
Merge with Linux 2.3.99-pre3.
Diffstat (limited to 'net/sunrpc/auth.c')
-rw-r--r-- | net/sunrpc/auth.c | 121 |
1 files changed, 73 insertions, 48 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index af9923ec8..b8c0a7be8 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -4,12 +4,9 @@ * Generic RPC authentication API. * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> - * - * Modified May 1999, Horst von Brand <vonbrand@sleipnir.valparaiso.cl> */ #include <linux/types.h> -#include <linux/string.h> #include <linux/sched.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -84,6 +81,15 @@ rpcauth_init_credcache(struct rpc_auth *auth) auth->au_nextgc = jiffies + (auth->au_expire >> 1); } +static inline void +rpcauth_crdestroy(struct rpc_auth *auth, struct rpc_cred *cred) +{ + if (auth->au_ops->crdestroy) + auth->au_ops->crdestroy(cred); + else + rpc_free(cred); +} + /* * Clear the RPC credential cache */ @@ -115,18 +121,15 @@ static void rpcauth_gc_credcache(struct rpc_auth *auth) { struct rpc_cred **q, *cred, *free = NULL; - int i, safe = 0; + int i; dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); spin_lock(&rpc_credcache_lock); for (i = 0; i < RPC_CREDCACHE_NR; i++) { q = &auth->au_credcache[i]; while ((cred = *q) != NULL) { - if (++safe > 500) { - printk("RPC: rpcauth_gc_credcache looping!\n"); - break; - } - if (!cred->cr_count && time_before(cred->cr_expire, jiffies)) { + if (!cred->cr_count && + time_before(cred->cr_expire, jiffies)) { *q = cred->cr_next; cred->cr_next = free; free = cred; @@ -138,7 +141,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth) spin_unlock(&rpc_credcache_lock); while ((cred = free) != NULL) { free = cred->cr_next; - rpc_free(cred); + rpcauth_crdestroy(auth, cred); } auth->au_nextgc = jiffies + auth->au_expire; } @@ -146,7 +149,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth) /* * Insert credential into cache */ -inline void +void rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { int nr; @@ -155,8 +158,8 @@ rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) spin_lock(&rpc_credcache_lock); cred->cr_next = auth->au_credcache[nr]; auth->au_credcache[nr] = cred; - cred->cr_expire = jiffies + auth->au_expire; cred->cr_count++; + cred->cr_expire = jiffies + auth->au_expire; spin_unlock(&rpc_credcache_lock); } @@ -164,13 +167,13 @@ rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) * Look up a process' credentials in the authentication cache */ static struct rpc_cred * -rpcauth_lookup_credcache(struct rpc_task *task) +rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) { - struct rpc_auth *auth = task->tk_auth; struct rpc_cred **q, *cred = NULL; - int nr; + int nr = 0; - nr = RPC_DO_ROOTOVERRIDE(task)? 0 : (current->uid % RPC_CREDCACHE_NR); + if (!(taskflags & RPC_TASK_ROOTCREDS)) + nr = current->uid % RPC_CREDCACHE_NR; if (time_before(auth->au_nextgc, jiffies)) rpcauth_gc_credcache(auth); @@ -178,7 +181,8 @@ rpcauth_lookup_credcache(struct rpc_task *task) spin_lock(&rpc_credcache_lock); q = &auth->au_credcache[nr]; while ((cred = *q) != NULL) { - if (auth->au_ops->crmatch(task, cred)) { + if (!(cred->cr_flags & RPCAUTH_CRED_DEAD) && + auth->au_ops->crmatch(cred, taskflags)) { *q = cred->cr_next; break; } @@ -187,7 +191,7 @@ rpcauth_lookup_credcache(struct rpc_task *task) spin_unlock(&rpc_credcache_lock); if (!cred) - cred = auth->au_ops->crcreate(task); + cred = auth->au_ops->crcreate(taskflags); if (cred) rpcauth_insert_credcache(auth, cred); @@ -198,7 +202,7 @@ rpcauth_lookup_credcache(struct rpc_task *task) /* * Remove cred handle from cache */ -static inline void +static void rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { struct rpc_cred **q, *cr; @@ -210,7 +214,8 @@ rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred) while ((cr = *q) != NULL) { if (cred == cr) { *q = cred->cr_next; - return; + cred->cr_next = NULL; + break; } q = &cred->cr_next; } @@ -218,58 +223,78 @@ rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred) } struct rpc_cred * -rpcauth_lookupcred(struct rpc_task *task) +rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) +{ + dprintk("RPC: looking up %s cred\n", + auth->au_ops->au_name); + return rpcauth_lookup_credcache(auth, taskflags); +} + +struct rpc_cred * +rpcauth_bindcred(struct rpc_task *task) { + struct rpc_auth *auth = task->tk_auth; + dprintk("RPC: %4d looking up %s cred\n", task->tk_pid, task->tk_auth->au_ops->au_name); - return task->tk_cred = rpcauth_lookup_credcache(task); + task->tk_msg.rpc_cred = rpcauth_lookup_credcache(auth, task->tk_flags); + if (task->tk_msg.rpc_cred == 0) + task->tk_status = -ENOMEM; + return task->tk_msg.rpc_cred; } int -rpcauth_matchcred(struct rpc_task *task, struct rpc_cred *cred) +rpcauth_matchcred(struct rpc_auth *auth, struct rpc_cred *cred, int taskflags) { - struct rpc_auth *auth = task->tk_auth; - - dprintk("RPC: %4d matching %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); - return auth->au_ops->crmatch(task, cred); + dprintk("RPC: matching %s cred %d\n", + auth->au_ops->au_name, taskflags); + return auth->au_ops->crmatch(cred, taskflags); } void rpcauth_holdcred(struct rpc_task *task) { dprintk("RPC: %4d holding %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_cred); - if (task->tk_cred) - task->tk_cred->cr_count++; + task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred); + if (task->tk_msg.rpc_cred) { + task->tk_msg.rpc_cred->cr_count++; + task->tk_msg.rpc_cred->cr_expire = jiffies + task->tk_auth->au_expire; + } } void -rpcauth_releasecred(struct rpc_task *task) +rpcauth_releasecred(struct rpc_auth *auth, struct rpc_cred *cred) { - struct rpc_auth *auth = task->tk_auth; - struct rpc_cred *cred; - - dprintk("RPC: %4d releasing %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); - if ((cred = task->tk_cred) != NULL) { + if (cred != NULL && cred->cr_count > 0) { cred->cr_count--; if (cred->cr_flags & RPCAUTH_CRED_DEAD) { rpcauth_remove_credcache(auth, cred); if (!cred->cr_count) - auth->au_ops->crdestroy(cred); + rpcauth_crdestroy(auth, cred); } - task->tk_cred = NULL; } } +void +rpcauth_unbindcred(struct rpc_task *task) +{ + struct rpc_auth *auth = task->tk_auth; + struct rpc_cred *cred = task->tk_msg.rpc_cred; + + dprintk("RPC: %4d releasing %s cred %p\n", + task->tk_pid, auth->au_ops->au_name, cred); + + rpcauth_releasecred(auth, cred); + task->tk_msg.rpc_cred = NULL; +} + u32 * rpcauth_marshcred(struct rpc_task *task, u32 *p) { struct rpc_auth *auth = task->tk_auth; dprintk("RPC: %4d marshaling %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); + task->tk_pid, auth->au_ops->au_name, task->tk_msg.rpc_cred); return auth->au_ops->crmarshal(task, p, task->tk_flags & RPC_CALL_REALUID); } @@ -280,7 +305,7 @@ rpcauth_checkverf(struct rpc_task *task, u32 *p) struct rpc_auth *auth = task->tk_auth; dprintk("RPC: %4d validating %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); + task->tk_pid, auth->au_ops->au_name, task->tk_msg.rpc_cred); return auth->au_ops->crvalidate(task, p); } @@ -290,7 +315,7 @@ rpcauth_refreshcred(struct rpc_task *task) struct rpc_auth *auth = task->tk_auth; dprintk("RPC: %4d refreshing %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); + task->tk_pid, auth->au_ops->au_name, task->tk_msg.rpc_cred); task->tk_status = auth->au_ops->crrefresh(task); return task->tk_status; } @@ -299,14 +324,14 @@ void rpcauth_invalcred(struct rpc_task *task) { dprintk("RPC: %4d invalidating %s cred %p\n", - task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_cred); - if (task->tk_cred) - task->tk_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; + task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred); + if (task->tk_msg.rpc_cred) + task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; } int rpcauth_uptodatecred(struct rpc_task *task) { - return !(task->tk_cred) || - (task->tk_cred->cr_flags & RPCAUTH_CRED_UPTODATE); + return !(task->tk_msg.rpc_cred) || + (task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE); } |