Blame view
net/sunrpc/auth.c
13.3 KB
1da177e4c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * linux/net/sunrpc/auth.c * * Generic RPC client authentication API. * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> */ #include <linux/types.h> #include <linux/sched.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/errno.h> |
25337fdc8
|
14 |
#include <linux/hash.h> |
1da177e4c
|
15 16 17 18 19 20 |
#include <linux/sunrpc/clnt.h> #include <linux/spinlock.h> #ifdef RPC_DEBUG # define RPCDBG_FACILITY RPCDBG_AUTH #endif |
fc1b356f5
|
21 |
static DEFINE_SPINLOCK(rpc_authflavor_lock); |
f1c0a8615
|
22 |
static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { |
1da177e4c
|
23 24 25 26 |
&authnull_ops, /* AUTH_NULL */ &authunix_ops, /* AUTH_UNIX */ NULL, /* others can be loadable modules */ }; |
e092bdcd9
|
27 |
static LIST_HEAD(cred_unused); |
f5c2187cf
|
28 |
static unsigned long number_cred_unused; |
e092bdcd9
|
29 |
|
1da177e4c
|
30 31 32 33 34 35 36 37 |
static u32 pseudoflavor_to_flavor(u32 flavor) { if (flavor >= RPC_AUTH_MAXFLAVOR) return RPC_AUTH_GSS; return flavor; } int |
f1c0a8615
|
38 |
rpcauth_register(const struct rpc_authops *ops) |
1da177e4c
|
39 40 |
{ rpc_authflavor_t flavor; |
fc1b356f5
|
41 |
int ret = -EPERM; |
1da177e4c
|
42 43 44 |
if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) return -EINVAL; |
fc1b356f5
|
45 46 47 48 49 50 51 |
spin_lock(&rpc_authflavor_lock); if (auth_flavors[flavor] == NULL) { auth_flavors[flavor] = ops; ret = 0; } spin_unlock(&rpc_authflavor_lock); return ret; |
1da177e4c
|
52 |
} |
e8914c65f
|
53 |
EXPORT_SYMBOL_GPL(rpcauth_register); |
1da177e4c
|
54 55 |
int |
f1c0a8615
|
56 |
rpcauth_unregister(const struct rpc_authops *ops) |
1da177e4c
|
57 58 |
{ rpc_authflavor_t flavor; |
fc1b356f5
|
59 |
int ret = -EPERM; |
1da177e4c
|
60 61 62 |
if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) return -EINVAL; |
fc1b356f5
|
63 64 65 66 67 68 69 |
spin_lock(&rpc_authflavor_lock); if (auth_flavors[flavor] == ops) { auth_flavors[flavor] = NULL; ret = 0; } spin_unlock(&rpc_authflavor_lock); return ret; |
1da177e4c
|
70 |
} |
e8914c65f
|
71 |
EXPORT_SYMBOL_GPL(rpcauth_unregister); |
1da177e4c
|
72 73 74 75 76 |
struct rpc_auth * rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) { struct rpc_auth *auth; |
f1c0a8615
|
77 |
const struct rpc_authops *ops; |
1da177e4c
|
78 |
u32 flavor = pseudoflavor_to_flavor(pseudoflavor); |
f344f6df4
|
79 80 81 |
auth = ERR_PTR(-EINVAL); if (flavor >= RPC_AUTH_MAXFLAVOR) goto out; |
f344f6df4
|
82 83 |
if ((ops = auth_flavors[flavor]) == NULL) request_module("rpc-auth-%u", flavor); |
fc1b356f5
|
84 85 86 87 |
spin_lock(&rpc_authflavor_lock); ops = auth_flavors[flavor]; if (ops == NULL || !try_module_get(ops->owner)) { spin_unlock(&rpc_authflavor_lock); |
f344f6df4
|
88 |
goto out; |
fc1b356f5
|
89 90 |
} spin_unlock(&rpc_authflavor_lock); |
1da177e4c
|
91 |
auth = ops->create(clnt, pseudoflavor); |
fc1b356f5
|
92 |
module_put(ops->owner); |
6a19275ad
|
93 94 |
if (IS_ERR(auth)) return auth; |
1da177e4c
|
95 |
if (clnt->cl_auth) |
de7a8ce38
|
96 |
rpcauth_release(clnt->cl_auth); |
1da177e4c
|
97 |
clnt->cl_auth = auth; |
f344f6df4
|
98 99 |
out: |
1da177e4c
|
100 101 |
return auth; } |
e8914c65f
|
102 |
EXPORT_SYMBOL_GPL(rpcauth_create); |
1da177e4c
|
103 104 |
void |
de7a8ce38
|
105 |
rpcauth_release(struct rpc_auth *auth) |
1da177e4c
|
106 107 108 109 110 111 112 |
{ if (!atomic_dec_and_test(&auth->au_count)) return; auth->au_ops->destroy(auth); } static DEFINE_SPINLOCK(rpc_credcache_lock); |
31be5bf15
|
113 114 115 116 117 118 119 |
static void rpcauth_unhash_cred_locked(struct rpc_cred *cred) { hlist_del_rcu(&cred->cr_hash); smp_mb__before_clear_bit(); clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); } |
9499b4341
|
120 121 122 123 124 125 126 127 128 129 130 |
static void rpcauth_unhash_cred(struct rpc_cred *cred) { spinlock_t *cache_lock; cache_lock = &cred->cr_auth->au_credcache->lock; spin_lock(cache_lock); if (atomic_read(&cred->cr_count) == 0) rpcauth_unhash_cred_locked(cred); spin_unlock(cache_lock); } |
1da177e4c
|
131 132 133 134 |
/* * Initialize RPC credential cache */ int |
f5c2187cf
|
135 |
rpcauth_init_credcache(struct rpc_auth *auth) |
1da177e4c
|
136 137 138 |
{ struct rpc_cred_cache *new; int i; |
8b3a70058
|
139 |
new = kmalloc(sizeof(*new), GFP_KERNEL); |
1da177e4c
|
140 141 142 143 |
if (!new) return -ENOMEM; for (i = 0; i < RPC_CREDCACHE_NR; i++) INIT_HLIST_HEAD(&new->hashtable[i]); |
9499b4341
|
144 |
spin_lock_init(&new->lock); |
1da177e4c
|
145 146 147 |
auth->au_credcache = new; return 0; } |
e8914c65f
|
148 |
EXPORT_SYMBOL_GPL(rpcauth_init_credcache); |
1da177e4c
|
149 150 151 152 153 |
/* * Destroy a list of credentials */ static inline |
e092bdcd9
|
154 |
void rpcauth_destroy_credlist(struct list_head *head) |
1da177e4c
|
155 156 |
{ struct rpc_cred *cred; |
e092bdcd9
|
157 158 159 |
while (!list_empty(head)) { cred = list_entry(head->next, struct rpc_cred, cr_lru); list_del_init(&cred->cr_lru); |
1da177e4c
|
160 161 162 163 164 165 166 167 168 |
put_rpccred(cred); } } /* * Clear the RPC credential cache, and delete those credentials * that are not referenced. */ void |
3ab9bb724
|
169 |
rpcauth_clear_credcache(struct rpc_cred_cache *cache) |
1da177e4c
|
170 |
{ |
e092bdcd9
|
171 172 |
LIST_HEAD(free); struct hlist_head *head; |
1da177e4c
|
173 174 175 176 |
struct rpc_cred *cred; int i; spin_lock(&rpc_credcache_lock); |
9499b4341
|
177 |
spin_lock(&cache->lock); |
1da177e4c
|
178 |
for (i = 0; i < RPC_CREDCACHE_NR; i++) { |
e092bdcd9
|
179 180 181 182 |
head = &cache->hashtable[i]; while (!hlist_empty(head)) { cred = hlist_entry(head->first, struct rpc_cred, cr_hash); get_rpccred(cred); |
f5c2187cf
|
183 184 185 186 187 |
if (!list_empty(&cred->cr_lru)) { list_del(&cred->cr_lru); number_cred_unused--; } list_add_tail(&cred->cr_lru, &free); |
31be5bf15
|
188 |
rpcauth_unhash_cred_locked(cred); |
1da177e4c
|
189 190 |
} } |
9499b4341
|
191 |
spin_unlock(&cache->lock); |
1da177e4c
|
192 193 194 |
spin_unlock(&rpc_credcache_lock); rpcauth_destroy_credlist(&free); } |
3ab9bb724
|
195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
/* * Destroy the RPC credential cache */ void rpcauth_destroy_credcache(struct rpc_auth *auth) { struct rpc_cred_cache *cache = auth->au_credcache; if (cache) { auth->au_credcache = NULL; rpcauth_clear_credcache(cache); kfree(cache); } } |
e8914c65f
|
209 |
EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache); |
3ab9bb724
|
210 |
|
d2b831416
|
211 212 |
#define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ) |
e092bdcd9
|
213 214 215 |
/* * Remove stale credentials. Avoid sleeping inside the loop. */ |
f5c2187cf
|
216 217 |
static int rpcauth_prune_expired(struct list_head *free, int nr_to_scan) |
1da177e4c
|
218 |
{ |
9499b4341
|
219 |
spinlock_t *cache_lock; |
eac0d18d4
|
220 |
struct rpc_cred *cred, *next; |
d2b831416
|
221 |
unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; |
e092bdcd9
|
222 |
|
eac0d18d4
|
223 224 225 |
list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { /* Enforce a 60 second garbage collection moratorium */ |
64672d55d
|
226 |
if (time_in_range_open(cred->cr_expire, expired, jiffies) && |
eac0d18d4
|
227 228 |
test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) continue; |
e092bdcd9
|
229 |
list_del_init(&cred->cr_lru); |
f5c2187cf
|
230 |
number_cred_unused--; |
e092bdcd9
|
231 232 |
if (atomic_read(&cred->cr_count) != 0) continue; |
eac0d18d4
|
233 |
|
9499b4341
|
234 235 236 237 238 239 |
cache_lock = &cred->cr_auth->au_credcache->lock; spin_lock(cache_lock); if (atomic_read(&cred->cr_count) == 0) { get_rpccred(cred); list_add_tail(&cred->cr_lru, free); rpcauth_unhash_cred_locked(cred); |
f5c2187cf
|
240 |
nr_to_scan--; |
9499b4341
|
241 242 |
} spin_unlock(cache_lock); |
f5c2187cf
|
243 244 |
if (nr_to_scan == 0) break; |
1da177e4c
|
245 |
} |
f5c2187cf
|
246 |
return nr_to_scan; |
1da177e4c
|
247 248 249 |
} /* |
f5c2187cf
|
250 |
* Run memory cache shrinker. |
1da177e4c
|
251 |
*/ |
f5c2187cf
|
252 253 |
static int rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) |
1da177e4c
|
254 |
{ |
f5c2187cf
|
255 256 257 258 259 |
LIST_HEAD(free); int res; if (list_empty(&cred_unused)) return 0; |
31be5bf15
|
260 |
spin_lock(&rpc_credcache_lock); |
f5c2187cf
|
261 262 |
nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan); res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure; |
31be5bf15
|
263 |
spin_unlock(&rpc_credcache_lock); |
f5c2187cf
|
264 265 |
rpcauth_destroy_credlist(&free); return res; |
1da177e4c
|
266 267 268 269 270 271 272 |
} /* * Look up a process' credentials in the authentication cache */ struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, |
8a3177604
|
273 |
int flags) |
1da177e4c
|
274 |
{ |
e092bdcd9
|
275 |
LIST_HEAD(free); |
1da177e4c
|
276 |
struct rpc_cred_cache *cache = auth->au_credcache; |
e092bdcd9
|
277 |
struct hlist_node *pos; |
31be5bf15
|
278 279 |
struct rpc_cred *cred = NULL, *entry, *new; |
25337fdc8
|
280 281 282 |
unsigned int nr; nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS); |
1da177e4c
|
283 |
|
31be5bf15
|
284 285 |
rcu_read_lock(); hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { |
e092bdcd9
|
286 287 |
if (!entry->cr_ops->crmatch(acred, entry, flags)) continue; |
9499b4341
|
288 |
spin_lock(&cache->lock); |
31be5bf15
|
289 |
if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) { |
9499b4341
|
290 |
spin_unlock(&cache->lock); |
31be5bf15
|
291 292 |
continue; } |
e092bdcd9
|
293 |
cred = get_rpccred(entry); |
9499b4341
|
294 |
spin_unlock(&cache->lock); |
e092bdcd9
|
295 |
break; |
1da177e4c
|
296 |
} |
31be5bf15
|
297 |
rcu_read_unlock(); |
9499b4341
|
298 |
if (cred != NULL) |
31be5bf15
|
299 |
goto found; |
1da177e4c
|
300 |
|
31be5bf15
|
301 302 303 304 305 |
new = auth->au_ops->crcreate(auth, acred, flags); if (IS_ERR(new)) { cred = new; goto out; } |
1da177e4c
|
306 |
|
9499b4341
|
307 |
spin_lock(&cache->lock); |
31be5bf15
|
308 309 310 311 312 313 314 |
hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) { if (!entry->cr_ops->crmatch(acred, entry, flags)) continue; cred = get_rpccred(entry); break; } if (cred == NULL) { |
5fe4755e2
|
315 |
cred = new; |
31be5bf15
|
316 317 318 319 |
set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); } else list_add_tail(&new->cr_lru, &free); |
9499b4341
|
320 |
spin_unlock(&cache->lock); |
31be5bf15
|
321 322 |
found: if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) |
fba3bad48
|
323 324 325 326 327 328 329 |
&& cred->cr_ops->cr_init != NULL && !(flags & RPCAUTH_LOOKUP_NEW)) { int res = cred->cr_ops->cr_init(auth, cred); if (res < 0) { put_rpccred(cred); cred = ERR_PTR(res); } |
1da177e4c
|
330 |
} |
31be5bf15
|
331 332 333 |
rpcauth_destroy_credlist(&free); out: return cred; |
1da177e4c
|
334 |
} |
e8914c65f
|
335 |
EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache); |
1da177e4c
|
336 337 |
struct rpc_cred * |
8a3177604
|
338 |
rpcauth_lookupcred(struct rpc_auth *auth, int flags) |
1da177e4c
|
339 |
{ |
86a264abe
|
340 |
struct auth_cred acred; |
1da177e4c
|
341 |
struct rpc_cred *ret; |
86a264abe
|
342 |
const struct cred *cred = current_cred(); |
1da177e4c
|
343 |
|
46121cf7d
|
344 345 |
dprintk("RPC: looking up %s cred ", |
1da177e4c
|
346 |
auth->au_ops->au_name); |
86a264abe
|
347 348 349 350 351 |
memset(&acred, 0, sizeof(acred)); acred.uid = cred->fsuid; acred.gid = cred->fsgid; acred.group_info = get_group_info(((struct cred *)cred)->group_info); |
8a3177604
|
352 |
ret = auth->au_ops->lookup_cred(auth, &acred, flags); |
1da177e4c
|
353 354 355 |
put_group_info(acred.group_info); return ret; } |
5fe4755e2
|
356 357 358 359 360 |
void rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, struct rpc_auth *auth, const struct rpc_credops *ops) { INIT_HLIST_NODE(&cred->cr_hash); |
e092bdcd9
|
361 |
INIT_LIST_HEAD(&cred->cr_lru); |
5fe4755e2
|
362 363 364 365 366 367 368 369 370 |
atomic_set(&cred->cr_count, 1); cred->cr_auth = auth; cred->cr_ops = ops; cred->cr_expire = jiffies; #ifdef RPC_DEBUG cred->cr_magic = RPCAUTH_CRED_MAGIC; #endif cred->cr_uid = acred->uid; } |
e8914c65f
|
371 |
EXPORT_SYMBOL_GPL(rpcauth_init_cred); |
5fe4755e2
|
372 |
|
5c691044e
|
373 |
void |
4ccda2cdd
|
374 375 376 377 378 379 380 |
rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred) { task->tk_msg.rpc_cred = get_rpccred(cred); dprintk("RPC: %5u holding %s cred %p ", task->tk_pid, cred->cr_auth->au_ops->au_name, cred); } |
5c691044e
|
381 |
EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred); |
4ccda2cdd
|
382 383 |
static void |
af0938357
|
384 |
rpcauth_bind_root_cred(struct rpc_task *task) |
1da177e4c
|
385 |
{ |
1be27f366
|
386 |
struct rpc_auth *auth = task->tk_client->cl_auth; |
1da177e4c
|
387 |
struct auth_cred acred = { |
af0938357
|
388 389 |
.uid = 0, .gid = 0, |
1da177e4c
|
390 391 |
}; struct rpc_cred *ret; |
46121cf7d
|
392 393 |
dprintk("RPC: %5u looking up %s cred ", |
1be27f366
|
394 |
task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); |
af0938357
|
395 396 397 398 399 400 |
ret = auth->au_ops->lookup_cred(auth, &acred, 0); if (!IS_ERR(ret)) task->tk_msg.rpc_cred = ret; else task->tk_status = PTR_ERR(ret); } |
4ccda2cdd
|
401 402 |
static void rpcauth_bind_new_cred(struct rpc_task *task) |
af0938357
|
403 404 405 406 407 408 409 410 |
{ struct rpc_auth *auth = task->tk_client->cl_auth; struct rpc_cred *ret; dprintk("RPC: %5u looking up %s cred ", task->tk_pid, auth->au_ops->au_name); ret = rpcauth_lookupcred(auth, 0); |
1da177e4c
|
411 412 413 414 |
if (!IS_ERR(ret)) task->tk_msg.rpc_cred = ret; else task->tk_status = PTR_ERR(ret); |
1da177e4c
|
415 416 417 |
} void |
4ccda2cdd
|
418 |
rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) |
1da177e4c
|
419 |
{ |
4ccda2cdd
|
420 |
if (cred != NULL) |
5c691044e
|
421 |
cred->cr_ops->crbind(task, cred); |
4ccda2cdd
|
422 423 424 425 |
else if (flags & RPC_TASK_ROOTCREDS) rpcauth_bind_root_cred(task); else rpcauth_bind_new_cred(task); |
1da177e4c
|
426 427 428 429 430 |
} void put_rpccred(struct rpc_cred *cred) { |
e092bdcd9
|
431 |
/* Fast path for unhashed credentials */ |
31be5bf15
|
432 |
if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) |
e092bdcd9
|
433 |
goto need_lock; |
1da177e4c
|
434 435 |
if (!atomic_dec_and_test(&cred->cr_count)) return; |
e092bdcd9
|
436 |
goto out_destroy; |
e092bdcd9
|
437 438 439 |
need_lock: if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock)) return; |
f5c2187cf
|
440 441 |
if (!list_empty(&cred->cr_lru)) { number_cred_unused--; |
e092bdcd9
|
442 |
list_del_init(&cred->cr_lru); |
f5c2187cf
|
443 |
} |
e092bdcd9
|
444 |
if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) |
9499b4341
|
445 |
rpcauth_unhash_cred(cred); |
5f707eb42
|
446 |
if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { |
e092bdcd9
|
447 448 |
cred->cr_expire = jiffies; list_add_tail(&cred->cr_lru, &cred_unused); |
f5c2187cf
|
449 |
number_cred_unused++; |
e092bdcd9
|
450 451 452 453 454 |
spin_unlock(&rpc_credcache_lock); return; } spin_unlock(&rpc_credcache_lock); out_destroy: |
1da177e4c
|
455 456 |
cred->cr_ops->crdestroy(cred); } |
e8914c65f
|
457 |
EXPORT_SYMBOL_GPL(put_rpccred); |
1da177e4c
|
458 459 460 461 |
void rpcauth_unbindcred(struct rpc_task *task) { |
1da177e4c
|
462 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
463 464 |
dprintk("RPC: %5u releasing %s cred %p ", |
1be27f366
|
465 |
task->tk_pid, cred->cr_auth->au_ops->au_name, cred); |
1da177e4c
|
466 467 468 469 |
put_rpccred(cred); task->tk_msg.rpc_cred = NULL; } |
d8ed029d6
|
470 471 |
__be32 * rpcauth_marshcred(struct rpc_task *task, __be32 *p) |
1da177e4c
|
472 |
{ |
1da177e4c
|
473 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
474 475 |
dprintk("RPC: %5u marshaling %s cred %p ", |
1be27f366
|
476 |
task->tk_pid, cred->cr_auth->au_ops->au_name, cred); |
0bbacc402
|
477 |
|
1da177e4c
|
478 479 |
return cred->cr_ops->crmarshal(task, p); } |
d8ed029d6
|
480 481 |
__be32 * rpcauth_checkverf(struct rpc_task *task, __be32 *p) |
1da177e4c
|
482 |
{ |
1da177e4c
|
483 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
484 485 |
dprintk("RPC: %5u validating %s cred %p ", |
1be27f366
|
486 |
task->tk_pid, cred->cr_auth->au_ops->au_name, cred); |
0bbacc402
|
487 |
|
1da177e4c
|
488 489 490 491 492 |
return cred->cr_ops->crvalidate(task, p); } int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, |
d8ed029d6
|
493 |
__be32 *data, void *obj) |
1da177e4c
|
494 495 |
{ struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
496 497 |
dprintk("RPC: %5u using %s cred %p to wrap rpc data ", |
1da177e4c
|
498 499 500 501 |
task->tk_pid, cred->cr_ops->cr_name, cred); if (cred->cr_ops->crwrap_req) return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); /* By default, we encode the arguments normally. */ |
88a9fe8ca
|
502 |
return encode(rqstp, data, obj); |
1da177e4c
|
503 504 505 506 |
} int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, |
d8ed029d6
|
507 |
__be32 *data, void *obj) |
1da177e4c
|
508 509 |
{ struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
510 511 |
dprintk("RPC: %5u using %s cred %p to unwrap rpc data ", |
1da177e4c
|
512 513 514 515 516 |
task->tk_pid, cred->cr_ops->cr_name, cred); if (cred->cr_ops->crunwrap_resp) return cred->cr_ops->crunwrap_resp(task, decode, rqstp, data, obj); /* By default, we decode the arguments normally. */ |
88a9fe8ca
|
517 |
return decode(rqstp, data, obj); |
1da177e4c
|
518 519 520 521 522 |
} int rpcauth_refreshcred(struct rpc_task *task) { |
1da177e4c
|
523 524 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; int err; |
46121cf7d
|
525 526 |
dprintk("RPC: %5u refreshing %s cred %p ", |
1be27f366
|
527 |
task->tk_pid, cred->cr_auth->au_ops->au_name, cred); |
0bbacc402
|
528 |
|
1da177e4c
|
529 530 531 532 533 534 535 536 537 |
err = cred->cr_ops->crrefresh(task); if (err < 0) task->tk_status = err; return err; } void rpcauth_invalcred(struct rpc_task *task) { |
fc432dd90
|
538 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; |
46121cf7d
|
539 540 |
dprintk("RPC: %5u invalidating %s cred %p ", |
1be27f366
|
541 |
task->tk_pid, cred->cr_auth->au_ops->au_name, cred); |
fc432dd90
|
542 543 |
if (cred) clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); |
1da177e4c
|
544 545 546 547 548 |
} int rpcauth_uptodatecred(struct rpc_task *task) { |
fc432dd90
|
549 550 551 552 |
struct rpc_cred *cred = task->tk_msg.rpc_cred; return cred == NULL || test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; |
1da177e4c
|
553 |
} |
f5c2187cf
|
554 |
|
8e1f936b7
|
555 556 557 558 |
static struct shrinker rpc_cred_shrinker = { .shrink = rpcauth_cache_shrinker, .seeks = DEFAULT_SEEKS, }; |
f5c2187cf
|
559 560 561 562 |
void __init rpcauth_init_module(void) { rpc_init_authunix(); |
9a559efd4
|
563 |
rpc_init_generic_auth(); |
8e1f936b7
|
564 |
register_shrinker(&rpc_cred_shrinker); |
f5c2187cf
|
565 566 567 568 |
} void __exit rpcauth_remove_module(void) { |
8e1f936b7
|
569 |
unregister_shrinker(&rpc_cred_shrinker); |
f5c2187cf
|
570 |
} |