1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/net/sunrpc/auth.c
5 * Generic RPC client authentication API.
7 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
10 #include <linux/types.h>
11 #include <linux/sched.h>
12 #include <linux/cred.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/errno.h>
16 #include <linux/hash.h>
17 #include <linux/sunrpc/clnt.h>
18 #include <linux/sunrpc/gss_api.h>
19 #include <linux/spinlock.h>
21 #include <trace/events/sunrpc.h>
23 #define RPC_CREDCACHE_DEFAULT_HASHBITS (4)
24 struct rpc_cred_cache
{
25 struct hlist_head
*hashtable
;
26 unsigned int hashbits
;
30 static unsigned int auth_hashbits
= RPC_CREDCACHE_DEFAULT_HASHBITS
;
32 static const struct rpc_authops __rcu
*auth_flavors
[RPC_AUTH_MAXFLAVOR
] = {
33 [RPC_AUTH_NULL
] = (const struct rpc_authops __force __rcu
*)&authnull_ops
,
34 [RPC_AUTH_UNIX
] = (const struct rpc_authops __force __rcu
*)&authunix_ops
,
35 [RPC_AUTH_TLS
] = (const struct rpc_authops __force __rcu
*)&authtls_ops
,
38 static LIST_HEAD(cred_unused
);
39 static unsigned long number_cred_unused
;
41 static struct cred machine_cred
= {
42 .usage
= ATOMIC_INIT(1),
46 * Return the machine_cred pointer to be used whenever
47 * the a generic machine credential is needed.
49 const struct cred
*rpc_machine_cred(void)
53 EXPORT_SYMBOL_GPL(rpc_machine_cred
);
55 #define MAX_HASHTABLE_BITS (14)
56 static int param_set_hashtbl_sz(const char *val
, const struct kernel_param
*kp
)
64 ret
= kstrtoul(val
, 0, &num
);
68 if (nbits
> MAX_HASHTABLE_BITS
|| nbits
< 2)
70 *(unsigned int *)kp
->arg
= nbits
;
76 static int param_get_hashtbl_sz(char *buffer
, const struct kernel_param
*kp
)
80 nbits
= *(unsigned int *)kp
->arg
;
81 return sprintf(buffer
, "%u\n", 1U << nbits
);
84 #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
86 static const struct kernel_param_ops param_ops_hashtbl_sz
= {
87 .set
= param_set_hashtbl_sz
,
88 .get
= param_get_hashtbl_sz
,
91 module_param_named(auth_hashtable_size
, auth_hashbits
, hashtbl_sz
, 0644);
92 MODULE_PARM_DESC(auth_hashtable_size
, "RPC credential cache hashtable size");
94 static unsigned long auth_max_cred_cachesize
= ULONG_MAX
;
95 module_param(auth_max_cred_cachesize
, ulong
, 0644);
96 MODULE_PARM_DESC(auth_max_cred_cachesize
, "RPC credential maximum total cache size");
99 pseudoflavor_to_flavor(u32 flavor
) {
100 if (flavor
> RPC_AUTH_MAXFLAVOR
)
106 rpcauth_register(const struct rpc_authops
*ops
)
108 const struct rpc_authops
*old
;
109 rpc_authflavor_t flavor
;
111 if ((flavor
= ops
->au_flavor
) >= RPC_AUTH_MAXFLAVOR
)
113 old
= cmpxchg((const struct rpc_authops
** __force
)&auth_flavors
[flavor
], NULL
, ops
);
114 if (old
== NULL
|| old
== ops
)
118 EXPORT_SYMBOL_GPL(rpcauth_register
);
121 rpcauth_unregister(const struct rpc_authops
*ops
)
123 const struct rpc_authops
*old
;
124 rpc_authflavor_t flavor
;
126 if ((flavor
= ops
->au_flavor
) >= RPC_AUTH_MAXFLAVOR
)
129 old
= cmpxchg((const struct rpc_authops
** __force
)&auth_flavors
[flavor
], ops
, NULL
);
130 if (old
== ops
|| old
== NULL
)
134 EXPORT_SYMBOL_GPL(rpcauth_unregister
);
136 static const struct rpc_authops
*
137 rpcauth_get_authops(rpc_authflavor_t flavor
)
139 const struct rpc_authops
*ops
;
141 if (flavor
>= RPC_AUTH_MAXFLAVOR
)
145 ops
= rcu_dereference(auth_flavors
[flavor
]);
148 request_module("rpc-auth-%u", flavor
);
150 ops
= rcu_dereference(auth_flavors
[flavor
]);
154 if (!try_module_get(ops
->owner
))
162 rpcauth_put_authops(const struct rpc_authops
*ops
)
164 module_put(ops
->owner
);
168 * rpcauth_get_pseudoflavor - check if security flavor is supported
169 * @flavor: a security flavor
170 * @info: a GSS mech OID, quality of protection, and service value
172 * Verifies that an appropriate kernel module is available or already loaded.
173 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
174 * not supported locally.
177 rpcauth_get_pseudoflavor(rpc_authflavor_t flavor
, struct rpcsec_gss_info
*info
)
179 const struct rpc_authops
*ops
= rpcauth_get_authops(flavor
);
180 rpc_authflavor_t pseudoflavor
;
183 return RPC_AUTH_MAXFLAVOR
;
184 pseudoflavor
= flavor
;
185 if (ops
->info2flavor
!= NULL
)
186 pseudoflavor
= ops
->info2flavor(info
);
188 rpcauth_put_authops(ops
);
191 EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor
);
194 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
195 * @pseudoflavor: GSS pseudoflavor to match
196 * @info: rpcsec_gss_info structure to fill in
198 * Returns zero and fills in "info" if pseudoflavor matches a
199 * supported mechanism.
202 rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor
, struct rpcsec_gss_info
*info
)
204 rpc_authflavor_t flavor
= pseudoflavor_to_flavor(pseudoflavor
);
205 const struct rpc_authops
*ops
;
208 ops
= rpcauth_get_authops(flavor
);
213 if (ops
->flavor2info
!= NULL
)
214 result
= ops
->flavor2info(pseudoflavor
, info
);
216 rpcauth_put_authops(ops
);
219 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo
);
222 rpcauth_create(const struct rpc_auth_create_args
*args
, struct rpc_clnt
*clnt
)
224 struct rpc_auth
*auth
= ERR_PTR(-EINVAL
);
225 const struct rpc_authops
*ops
;
226 u32 flavor
= pseudoflavor_to_flavor(args
->pseudoflavor
);
228 ops
= rpcauth_get_authops(flavor
);
232 auth
= ops
->create(args
, clnt
);
234 rpcauth_put_authops(ops
);
238 rpcauth_release(clnt
->cl_auth
);
239 clnt
->cl_auth
= auth
;
244 EXPORT_SYMBOL_GPL(rpcauth_create
);
247 rpcauth_release(struct rpc_auth
*auth
)
249 if (!refcount_dec_and_test(&auth
->au_count
))
251 auth
->au_ops
->destroy(auth
);
254 static DEFINE_SPINLOCK(rpc_credcache_lock
);
257 * On success, the caller is responsible for freeing the reference
258 * held by the hashtable
261 rpcauth_unhash_cred_locked(struct rpc_cred
*cred
)
263 if (!test_and_clear_bit(RPCAUTH_CRED_HASHED
, &cred
->cr_flags
))
265 hlist_del_rcu(&cred
->cr_hash
);
270 rpcauth_unhash_cred(struct rpc_cred
*cred
)
272 spinlock_t
*cache_lock
;
275 if (!test_bit(RPCAUTH_CRED_HASHED
, &cred
->cr_flags
))
277 cache_lock
= &cred
->cr_auth
->au_credcache
->lock
;
278 spin_lock(cache_lock
);
279 ret
= rpcauth_unhash_cred_locked(cred
);
280 spin_unlock(cache_lock
);
285 * Initialize RPC credential cache
288 rpcauth_init_credcache(struct rpc_auth
*auth
)
290 struct rpc_cred_cache
*new;
291 unsigned int hashsize
;
293 new = kmalloc(sizeof(*new), GFP_KERNEL
);
296 new->hashbits
= auth_hashbits
;
297 hashsize
= 1U << new->hashbits
;
298 new->hashtable
= kcalloc(hashsize
, sizeof(new->hashtable
[0]), GFP_KERNEL
);
301 spin_lock_init(&new->lock
);
302 auth
->au_credcache
= new;
309 EXPORT_SYMBOL_GPL(rpcauth_init_credcache
);
312 rpcauth_stringify_acceptor(struct rpc_cred
*cred
)
314 if (!cred
->cr_ops
->crstringify_acceptor
)
316 return cred
->cr_ops
->crstringify_acceptor(cred
);
318 EXPORT_SYMBOL_GPL(rpcauth_stringify_acceptor
);
321 * Destroy a list of credentials
324 void rpcauth_destroy_credlist(struct list_head
*head
)
326 struct rpc_cred
*cred
;
328 while (!list_empty(head
)) {
329 cred
= list_entry(head
->next
, struct rpc_cred
, cr_lru
);
330 list_del_init(&cred
->cr_lru
);
336 rpcauth_lru_add_locked(struct rpc_cred
*cred
)
338 if (!list_empty(&cred
->cr_lru
))
340 number_cred_unused
++;
341 list_add_tail(&cred
->cr_lru
, &cred_unused
);
345 rpcauth_lru_add(struct rpc_cred
*cred
)
347 if (!list_empty(&cred
->cr_lru
))
349 spin_lock(&rpc_credcache_lock
);
350 rpcauth_lru_add_locked(cred
);
351 spin_unlock(&rpc_credcache_lock
);
355 rpcauth_lru_remove_locked(struct rpc_cred
*cred
)
357 if (list_empty(&cred
->cr_lru
))
359 number_cred_unused
--;
360 list_del_init(&cred
->cr_lru
);
364 rpcauth_lru_remove(struct rpc_cred
*cred
)
366 if (list_empty(&cred
->cr_lru
))
368 spin_lock(&rpc_credcache_lock
);
369 rpcauth_lru_remove_locked(cred
);
370 spin_unlock(&rpc_credcache_lock
);
374 * Clear the RPC credential cache, and delete those credentials
375 * that are not referenced.
378 rpcauth_clear_credcache(struct rpc_cred_cache
*cache
)
381 struct hlist_head
*head
;
382 struct rpc_cred
*cred
;
383 unsigned int hashsize
= 1U << cache
->hashbits
;
386 spin_lock(&rpc_credcache_lock
);
387 spin_lock(&cache
->lock
);
388 for (i
= 0; i
< hashsize
; i
++) {
389 head
= &cache
->hashtable
[i
];
390 while (!hlist_empty(head
)) {
391 cred
= hlist_entry(head
->first
, struct rpc_cred
, cr_hash
);
392 rpcauth_unhash_cred_locked(cred
);
393 /* Note: We now hold a reference to cred */
394 rpcauth_lru_remove_locked(cred
);
395 list_add_tail(&cred
->cr_lru
, &free
);
398 spin_unlock(&cache
->lock
);
399 spin_unlock(&rpc_credcache_lock
);
400 rpcauth_destroy_credlist(&free
);
404 * Destroy the RPC credential cache
407 rpcauth_destroy_credcache(struct rpc_auth
*auth
)
409 struct rpc_cred_cache
*cache
= auth
->au_credcache
;
412 auth
->au_credcache
= NULL
;
413 rpcauth_clear_credcache(cache
);
414 kfree(cache
->hashtable
);
418 EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache
);
421 #define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ)
424 * Remove stale credentials. Avoid sleeping inside the loop.
427 rpcauth_prune_expired(struct list_head
*free
, int nr_to_scan
)
429 struct rpc_cred
*cred
, *next
;
430 unsigned long expired
= jiffies
- RPC_AUTH_EXPIRY_MORATORIUM
;
433 list_for_each_entry_safe(cred
, next
, &cred_unused
, cr_lru
) {
435 if (nr_to_scan
-- == 0)
437 if (refcount_read(&cred
->cr_count
) > 1) {
438 rpcauth_lru_remove_locked(cred
);
442 * Enforce a 60 second garbage collection moratorium
443 * Note that the cred_unused list must be time-ordered.
445 if (time_in_range(cred
->cr_expire
, expired
, jiffies
))
447 if (!rpcauth_unhash_cred(cred
))
450 rpcauth_lru_remove_locked(cred
);
452 list_add_tail(&cred
->cr_lru
, free
);
454 return freed
? freed
: SHRINK_STOP
;
458 rpcauth_cache_do_shrink(int nr_to_scan
)
463 spin_lock(&rpc_credcache_lock
);
464 freed
= rpcauth_prune_expired(&free
, nr_to_scan
);
465 spin_unlock(&rpc_credcache_lock
);
466 rpcauth_destroy_credlist(&free
);
472 * Run memory cache shrinker.
475 rpcauth_cache_shrink_scan(struct shrinker
*shrink
, struct shrink_control
*sc
)
478 if ((sc
->gfp_mask
& GFP_KERNEL
) != GFP_KERNEL
)
481 /* nothing left, don't come back */
482 if (list_empty(&cred_unused
))
485 return rpcauth_cache_do_shrink(sc
->nr_to_scan
);
489 rpcauth_cache_shrink_count(struct shrinker
*shrink
, struct shrink_control
*sc
)
492 return number_cred_unused
* sysctl_vfs_cache_pressure
/ 100;
496 rpcauth_cache_enforce_limit(void)
499 unsigned int nr_to_scan
;
501 if (number_cred_unused
<= auth_max_cred_cachesize
)
503 diff
= number_cred_unused
- auth_max_cred_cachesize
;
505 if (diff
< nr_to_scan
)
507 rpcauth_cache_do_shrink(nr_to_scan
);
511 * Look up a process' credentials in the authentication cache
514 rpcauth_lookup_credcache(struct rpc_auth
*auth
, struct auth_cred
* acred
,
515 int flags
, gfp_t gfp
)
518 struct rpc_cred_cache
*cache
= auth
->au_credcache
;
519 struct rpc_cred
*cred
= NULL
,
523 nr
= auth
->au_ops
->hash_cred(acred
, cache
->hashbits
);
526 hlist_for_each_entry_rcu(entry
, &cache
->hashtable
[nr
], cr_hash
) {
527 if (!entry
->cr_ops
->crmatch(acred
, entry
, flags
))
529 cred
= get_rpccred(entry
);
538 new = auth
->au_ops
->crcreate(auth
, acred
, flags
, gfp
);
544 spin_lock(&cache
->lock
);
545 hlist_for_each_entry(entry
, &cache
->hashtable
[nr
], cr_hash
) {
546 if (!entry
->cr_ops
->crmatch(acred
, entry
, flags
))
548 cred
= get_rpccred(entry
);
554 set_bit(RPCAUTH_CRED_HASHED
, &cred
->cr_flags
);
555 refcount_inc(&cred
->cr_count
);
556 hlist_add_head_rcu(&cred
->cr_hash
, &cache
->hashtable
[nr
]);
558 list_add_tail(&new->cr_lru
, &free
);
559 spin_unlock(&cache
->lock
);
560 rpcauth_cache_enforce_limit();
562 if (test_bit(RPCAUTH_CRED_NEW
, &cred
->cr_flags
) &&
563 cred
->cr_ops
->cr_init
!= NULL
&&
564 !(flags
& RPCAUTH_LOOKUP_NEW
)) {
565 int res
= cred
->cr_ops
->cr_init(auth
, cred
);
571 rpcauth_destroy_credlist(&free
);
575 EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache
);
578 rpcauth_lookupcred(struct rpc_auth
*auth
, int flags
)
580 struct auth_cred acred
;
581 struct rpc_cred
*ret
;
582 const struct cred
*cred
= current_cred();
584 memset(&acred
, 0, sizeof(acred
));
586 ret
= auth
->au_ops
->lookup_cred(auth
, &acred
, flags
);
589 EXPORT_SYMBOL_GPL(rpcauth_lookupcred
);
592 rpcauth_init_cred(struct rpc_cred
*cred
, const struct auth_cred
*acred
,
593 struct rpc_auth
*auth
, const struct rpc_credops
*ops
)
595 INIT_HLIST_NODE(&cred
->cr_hash
);
596 INIT_LIST_HEAD(&cred
->cr_lru
);
597 refcount_set(&cred
->cr_count
, 1);
598 cred
->cr_auth
= auth
;
601 cred
->cr_expire
= jiffies
;
602 cred
->cr_cred
= get_cred(acred
->cred
);
604 EXPORT_SYMBOL_GPL(rpcauth_init_cred
);
606 static struct rpc_cred
*
607 rpcauth_bind_root_cred(struct rpc_task
*task
, int lookupflags
)
609 struct rpc_auth
*auth
= task
->tk_client
->cl_auth
;
610 struct auth_cred acred
= {
611 .cred
= get_task_cred(&init_task
),
613 struct rpc_cred
*ret
;
615 if (RPC_IS_ASYNC(task
))
616 lookupflags
|= RPCAUTH_LOOKUP_ASYNC
;
617 ret
= auth
->au_ops
->lookup_cred(auth
, &acred
, lookupflags
);
618 put_cred(acred
.cred
);
622 static struct rpc_cred
*
623 rpcauth_bind_machine_cred(struct rpc_task
*task
, int lookupflags
)
625 struct rpc_auth
*auth
= task
->tk_client
->cl_auth
;
626 struct auth_cred acred
= {
627 .principal
= task
->tk_client
->cl_principal
,
628 .cred
= init_task
.cred
,
631 if (!acred
.principal
)
633 if (RPC_IS_ASYNC(task
))
634 lookupflags
|= RPCAUTH_LOOKUP_ASYNC
;
635 return auth
->au_ops
->lookup_cred(auth
, &acred
, lookupflags
);
638 static struct rpc_cred
*
639 rpcauth_bind_new_cred(struct rpc_task
*task
, int lookupflags
)
641 struct rpc_auth
*auth
= task
->tk_client
->cl_auth
;
643 return rpcauth_lookupcred(auth
, lookupflags
);
647 rpcauth_bindcred(struct rpc_task
*task
, const struct cred
*cred
, int flags
)
649 struct rpc_rqst
*req
= task
->tk_rqstp
;
650 struct rpc_cred
*new = NULL
;
652 struct rpc_auth
*auth
= task
->tk_client
->cl_auth
;
653 struct auth_cred acred
= {
657 if (flags
& RPC_TASK_ASYNC
)
658 lookupflags
|= RPCAUTH_LOOKUP_NEW
| RPCAUTH_LOOKUP_ASYNC
;
659 if (task
->tk_op_cred
)
660 /* Task must use exactly this rpc_cred */
661 new = get_rpccred(task
->tk_op_cred
);
662 else if (cred
!= NULL
&& cred
!= &machine_cred
)
663 new = auth
->au_ops
->lookup_cred(auth
, &acred
, lookupflags
);
664 else if (cred
== &machine_cred
)
665 new = rpcauth_bind_machine_cred(task
, lookupflags
);
667 /* If machine cred couldn't be bound, try a root cred */
670 else if (cred
== &machine_cred
)
671 new = rpcauth_bind_root_cred(task
, lookupflags
);
672 else if (flags
& RPC_TASK_NULLCREDS
)
673 new = authnull_ops
.lookup_cred(NULL
, NULL
, 0);
675 new = rpcauth_bind_new_cred(task
, lookupflags
);
678 put_rpccred(req
->rq_cred
);
684 put_rpccred(struct rpc_cred
*cred
)
689 if (refcount_dec_and_test(&cred
->cr_count
))
691 if (refcount_read(&cred
->cr_count
) != 1 ||
692 !test_bit(RPCAUTH_CRED_HASHED
, &cred
->cr_flags
))
694 if (test_bit(RPCAUTH_CRED_UPTODATE
, &cred
->cr_flags
) != 0) {
695 cred
->cr_expire
= jiffies
;
696 rpcauth_lru_add(cred
);
698 if (unlikely(!test_bit(RPCAUTH_CRED_HASHED
, &cred
->cr_flags
)))
699 rpcauth_lru_remove(cred
);
700 } else if (rpcauth_unhash_cred(cred
)) {
701 rpcauth_lru_remove(cred
);
702 if (refcount_dec_and_test(&cred
->cr_count
))
710 cred
->cr_ops
->crdestroy(cred
);
712 EXPORT_SYMBOL_GPL(put_rpccred
);
715 * rpcauth_marshcred - Append RPC credential to end of @xdr
716 * @task: controlling RPC task
717 * @xdr: xdr_stream containing initial portion of RPC Call header
719 * On success, an appropriate verifier is added to @xdr, @xdr is
720 * updated to point past the verifier, and zero is returned.
721 * Otherwise, @xdr is in an undefined state and a negative errno
724 int rpcauth_marshcred(struct rpc_task
*task
, struct xdr_stream
*xdr
)
726 const struct rpc_credops
*ops
= task
->tk_rqstp
->rq_cred
->cr_ops
;
728 return ops
->crmarshal(task
, xdr
);
732 * rpcauth_wrap_req_encode - XDR encode the RPC procedure
733 * @task: controlling RPC task
734 * @xdr: stream where on-the-wire bytes are to be marshalled
736 * On success, @xdr contains the encoded and wrapped message.
737 * Otherwise, @xdr is in an undefined state.
739 int rpcauth_wrap_req_encode(struct rpc_task
*task
, struct xdr_stream
*xdr
)
741 kxdreproc_t encode
= task
->tk_msg
.rpc_proc
->p_encode
;
743 encode(task
->tk_rqstp
, xdr
, task
->tk_msg
.rpc_argp
);
746 EXPORT_SYMBOL_GPL(rpcauth_wrap_req_encode
);
749 * rpcauth_wrap_req - XDR encode and wrap the RPC procedure
750 * @task: controlling RPC task
751 * @xdr: stream where on-the-wire bytes are to be marshalled
753 * On success, @xdr contains the encoded and wrapped message,
754 * and zero is returned. Otherwise, @xdr is in an undefined
755 * state and a negative errno is returned.
757 int rpcauth_wrap_req(struct rpc_task
*task
, struct xdr_stream
*xdr
)
759 const struct rpc_credops
*ops
= task
->tk_rqstp
->rq_cred
->cr_ops
;
761 return ops
->crwrap_req(task
, xdr
);
765 * rpcauth_checkverf - Validate verifier in RPC Reply header
766 * @task: controlling RPC task
767 * @xdr: xdr_stream containing RPC Reply header
770 * %0: Verifier is valid. @xdr now points past the verifier.
771 * %-EIO: Verifier is corrupted or message ended early.
772 * %-EACCES: Verifier is intact but not valid.
773 * %-EPROTONOSUPPORT: Server does not support the requested auth type.
775 * When a negative errno is returned, @xdr is left in an undefined
779 rpcauth_checkverf(struct rpc_task
*task
, struct xdr_stream
*xdr
)
781 const struct rpc_credops
*ops
= task
->tk_rqstp
->rq_cred
->cr_ops
;
783 return ops
->crvalidate(task
, xdr
);
787 * rpcauth_unwrap_resp_decode - Invoke XDR decode function
788 * @task: controlling RPC task
789 * @xdr: stream where the Reply message resides
791 * Returns zero on success; otherwise a negative errno is returned.
794 rpcauth_unwrap_resp_decode(struct rpc_task
*task
, struct xdr_stream
*xdr
)
796 kxdrdproc_t decode
= task
->tk_msg
.rpc_proc
->p_decode
;
798 return decode(task
->tk_rqstp
, xdr
, task
->tk_msg
.rpc_resp
);
800 EXPORT_SYMBOL_GPL(rpcauth_unwrap_resp_decode
);
803 * rpcauth_unwrap_resp - Invoke unwrap and decode function for the cred
804 * @task: controlling RPC task
805 * @xdr: stream where the Reply message resides
807 * Returns zero on success; otherwise a negative errno is returned.
810 rpcauth_unwrap_resp(struct rpc_task
*task
, struct xdr_stream
*xdr
)
812 const struct rpc_credops
*ops
= task
->tk_rqstp
->rq_cred
->cr_ops
;
814 return ops
->crunwrap_resp(task
, xdr
);
818 rpcauth_xmit_need_reencode(struct rpc_task
*task
)
820 struct rpc_cred
*cred
= task
->tk_rqstp
->rq_cred
;
822 if (!cred
|| !cred
->cr_ops
->crneed_reencode
)
824 return cred
->cr_ops
->crneed_reencode(task
);
828 rpcauth_refreshcred(struct rpc_task
*task
)
830 struct rpc_cred
*cred
;
833 cred
= task
->tk_rqstp
->rq_cred
;
835 err
= rpcauth_bindcred(task
, task
->tk_msg
.rpc_cred
, task
->tk_flags
);
838 cred
= task
->tk_rqstp
->rq_cred
;
841 err
= cred
->cr_ops
->crrefresh(task
);
844 task
->tk_status
= err
;
849 rpcauth_invalcred(struct rpc_task
*task
)
851 struct rpc_cred
*cred
= task
->tk_rqstp
->rq_cred
;
854 clear_bit(RPCAUTH_CRED_UPTODATE
, &cred
->cr_flags
);
858 rpcauth_uptodatecred(struct rpc_task
*task
)
860 struct rpc_cred
*cred
= task
->tk_rqstp
->rq_cred
;
862 return cred
== NULL
||
863 test_bit(RPCAUTH_CRED_UPTODATE
, &cred
->cr_flags
) != 0;
866 static struct shrinker
*rpc_cred_shrinker
;
868 int __init
rpcauth_init_module(void)
872 err
= rpc_init_authunix();
875 rpc_cred_shrinker
= shrinker_alloc(0, "sunrpc_cred");
876 if (!rpc_cred_shrinker
) {
881 rpc_cred_shrinker
->count_objects
= rpcauth_cache_shrink_count
;
882 rpc_cred_shrinker
->scan_objects
= rpcauth_cache_shrink_scan
;
884 shrinker_register(rpc_cred_shrinker
);
888 rpc_destroy_authunix();
893 void rpcauth_remove_module(void)
895 rpc_destroy_authunix();
896 shrinker_free(rpc_cred_shrinker
);