summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-27 23:54:12 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-27 23:54:12 +0000
commitd3e71cb08747743fce908122bab08b479eb403a5 (patch)
treecbec6948fdbdee9af81cf3ecfb504070d2745d7b /net/sunrpc/auth.c
parentfe7ff1706e323d0e5ed83972960a1ecc1ee538b3 (diff)
Merge with Linux 2.3.99-pre3.
Diffstat (limited to 'net/sunrpc/auth.c')
-rw-r--r--net/sunrpc/auth.c121
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);
}