patch-2.3.99-pre3 linux/net/sunrpc/auth.c

Next file: linux/net/sunrpc/auth_null.c
Previous file: linux/net/sched/sch_atm.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre2/linux/net/sunrpc/auth.c linux/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 @@
 	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 @@
 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 @@
 	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 @@
 /*
  * Insert credential into cache
  */
-inline void
+void
 rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred)
 {
 	int		nr;
@@ -155,8 +158,8 @@
 	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 @@
  * 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 @@
 	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 @@
 	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 @@
 /*
  * 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 @@
 	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 @@
 }
 
 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 @@
 	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 @@
 	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 @@
 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);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)