aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/auth.c')
-rw-r--r--net/sunrpc/auth.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index eca941ce298b..6bfea9ed6869 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/hash.h>
14#include <linux/sunrpc/clnt.h> 15#include <linux/sunrpc/clnt.h>
15#include <linux/spinlock.h> 16#include <linux/spinlock.h>
16 17
@@ -219,6 +220,9 @@ rpcauth_destroy_credcache(struct rpc_auth *auth)
219} 220}
220EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache); 221EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache);
221 222
223
224#define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ)
225
222/* 226/*
223 * Remove stale credentials. Avoid sleeping inside the loop. 227 * Remove stale credentials. Avoid sleeping inside the loop.
224 */ 228 */
@@ -227,6 +231,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
227{ 231{
228 spinlock_t *cache_lock; 232 spinlock_t *cache_lock;
229 struct rpc_cred *cred; 233 struct rpc_cred *cred;
234 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM;
230 235
231 while (!list_empty(&cred_unused)) { 236 while (!list_empty(&cred_unused)) {
232 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru); 237 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru);
@@ -234,6 +239,10 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
234 number_cred_unused--; 239 number_cred_unused--;
235 if (atomic_read(&cred->cr_count) != 0) 240 if (atomic_read(&cred->cr_count) != 0)
236 continue; 241 continue;
242 /* Enforce a 5 second garbage collection moratorium */
243 if (time_in_range(cred->cr_expire, expired, jiffies) &&
244 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
245 continue;
237 cache_lock = &cred->cr_auth->au_credcache->lock; 246 cache_lock = &cred->cr_auth->au_credcache->lock;
238 spin_lock(cache_lock); 247 spin_lock(cache_lock);
239 if (atomic_read(&cred->cr_count) == 0) { 248 if (atomic_read(&cred->cr_count) == 0) {
@@ -280,10 +289,9 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
280 struct hlist_node *pos; 289 struct hlist_node *pos;
281 struct rpc_cred *cred = NULL, 290 struct rpc_cred *cred = NULL,
282 *entry, *new; 291 *entry, *new;
283 int nr = 0; 292 unsigned int nr;
284 293
285 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) 294 nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS);
286 nr = acred->uid & RPC_CREDCACHE_MASK;
287 295
288 rcu_read_lock(); 296 rcu_read_lock();
289 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { 297 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
@@ -356,7 +364,6 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
356 put_group_info(acred.group_info); 364 put_group_info(acred.group_info);
357 return ret; 365 return ret;
358} 366}
359EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
360 367
361void 368void
362rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, 369rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
@@ -375,41 +382,58 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
375} 382}
376EXPORT_SYMBOL_GPL(rpcauth_init_cred); 383EXPORT_SYMBOL_GPL(rpcauth_init_cred);
377 384
378struct rpc_cred * 385void
379rpcauth_bindcred(struct rpc_task *task) 386rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred)
387{
388 task->tk_msg.rpc_cred = get_rpccred(cred);
389 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
390 cred->cr_auth->au_ops->au_name, cred);
391}
392EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred);
393
394static void
395rpcauth_bind_root_cred(struct rpc_task *task)
380{ 396{
381 struct rpc_auth *auth = task->tk_client->cl_auth; 397 struct rpc_auth *auth = task->tk_client->cl_auth;
382 struct auth_cred acred = { 398 struct auth_cred acred = {
383 .uid = current->fsuid, 399 .uid = 0,
384 .gid = current->fsgid, 400 .gid = 0,
385 .group_info = current->group_info,
386 }; 401 };
387 struct rpc_cred *ret; 402 struct rpc_cred *ret;
388 int flags = 0;
389 403
390 dprintk("RPC: %5u looking up %s cred\n", 404 dprintk("RPC: %5u looking up %s cred\n",
391 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); 405 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
392 get_group_info(acred.group_info); 406 ret = auth->au_ops->lookup_cred(auth, &acred, 0);
393 if (task->tk_flags & RPC_TASK_ROOTCREDS) 407 if (!IS_ERR(ret))
394 flags |= RPCAUTH_LOOKUP_ROOTCREDS; 408 task->tk_msg.rpc_cred = ret;
395 ret = auth->au_ops->lookup_cred(auth, &acred, flags); 409 else
410 task->tk_status = PTR_ERR(ret);
411}
412
413static void
414rpcauth_bind_new_cred(struct rpc_task *task)
415{
416 struct rpc_auth *auth = task->tk_client->cl_auth;
417 struct rpc_cred *ret;
418
419 dprintk("RPC: %5u looking up %s cred\n",
420 task->tk_pid, auth->au_ops->au_name);
421 ret = rpcauth_lookupcred(auth, 0);
396 if (!IS_ERR(ret)) 422 if (!IS_ERR(ret))
397 task->tk_msg.rpc_cred = ret; 423 task->tk_msg.rpc_cred = ret;
398 else 424 else
399 task->tk_status = PTR_ERR(ret); 425 task->tk_status = PTR_ERR(ret);
400 put_group_info(acred.group_info);
401 return ret;
402} 426}
403 427
404void 428void
405rpcauth_holdcred(struct rpc_task *task) 429rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
406{ 430{
407 struct rpc_cred *cred = task->tk_msg.rpc_cred; 431 if (cred != NULL)
408 if (cred != NULL) { 432 cred->cr_ops->crbind(task, cred);
409 get_rpccred(cred); 433 else if (flags & RPC_TASK_ROOTCREDS)
410 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, 434 rpcauth_bind_root_cred(task);
411 cred->cr_auth->au_ops->au_name, cred); 435 else
412 } 436 rpcauth_bind_new_cred(task);
413} 437}
414 438
415void 439void
@@ -550,6 +574,7 @@ static struct shrinker rpc_cred_shrinker = {
550void __init rpcauth_init_module(void) 574void __init rpcauth_init_module(void)
551{ 575{
552 rpc_init_authunix(); 576 rpc_init_authunix();
577 rpc_init_generic_auth();
553 register_shrinker(&rpc_cred_shrinker); 578 register_shrinker(&rpc_cred_shrinker);
554} 579}
555 580