Lines Matching +full:rpc +full:- +full:if

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Generic RPC client authentication API.
65 if (!val) in param_set_hashtbl_sz()
68 if (ret) in param_set_hashtbl_sz()
70 nbits = fls(num - 1); in param_set_hashtbl_sz()
71 if (nbits > MAX_HASHTABLE_BITS || nbits < 2) in param_set_hashtbl_sz()
73 *(unsigned int *)kp->arg = nbits; in param_set_hashtbl_sz()
76 return -EINVAL; in param_set_hashtbl_sz()
83 nbits = *(unsigned int *)kp->arg; in param_get_hashtbl_sz()
95 MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
99 MODULE_PARM_DESC(auth_max_cred_cachesize, "RPC credential maximum total cache size");
103 if (flavor > RPC_AUTH_MAXFLAVOR) in pseudoflavor_to_flavor()
114 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) in rpcauth_register()
115 return -EINVAL; in rpcauth_register()
117 if (old == NULL || old == ops) in rpcauth_register()
119 return -EPERM; in rpcauth_register()
129 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) in rpcauth_unregister()
130 return -EINVAL; in rpcauth_unregister()
133 if (old == ops || old == NULL) in rpcauth_unregister()
135 return -EPERM; in rpcauth_unregister()
144 if (flavor >= RPC_AUTH_MAXFLAVOR) in rpcauth_get_authops()
149 if (ops == NULL) { in rpcauth_get_authops()
151 request_module("rpc-auth-%u", flavor); in rpcauth_get_authops()
154 if (ops == NULL) in rpcauth_get_authops()
157 if (!try_module_get(ops->owner)) in rpcauth_get_authops()
167 module_put(ops->owner); in rpcauth_put_authops()
171 * rpcauth_get_pseudoflavor - check if security flavor is supported
176 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
185 if (!ops) in rpcauth_get_pseudoflavor()
188 if (ops->info2flavor != NULL) in rpcauth_get_pseudoflavor()
189 pseudoflavor = ops->info2flavor(info); in rpcauth_get_pseudoflavor()
197 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
201 * Returns zero and fills in "info" if pseudoflavor matches a
212 if (ops == NULL) in rpcauth_get_gssinfo()
213 return -ENOENT; in rpcauth_get_gssinfo()
215 result = -ENOENT; in rpcauth_get_gssinfo()
216 if (ops->flavor2info != NULL) in rpcauth_get_gssinfo()
217 result = ops->flavor2info(pseudoflavor, info); in rpcauth_get_gssinfo()
227 struct rpc_auth *auth = ERR_PTR(-EINVAL); in rpcauth_create()
229 u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor); in rpcauth_create()
232 if (ops == NULL) in rpcauth_create()
235 auth = ops->create(args, clnt); in rpcauth_create()
238 if (IS_ERR(auth)) in rpcauth_create()
240 if (clnt->cl_auth) in rpcauth_create()
241 rpcauth_release(clnt->cl_auth); in rpcauth_create()
242 clnt->cl_auth = auth; in rpcauth_create()
252 if (!refcount_dec_and_test(&auth->au_count)) in rpcauth_release()
254 auth->au_ops->destroy(auth); in rpcauth_release()
266 if (!test_and_clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in rpcauth_unhash_cred_locked()
268 hlist_del_rcu(&cred->cr_hash); in rpcauth_unhash_cred_locked()
278 if (!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in rpcauth_unhash_cred()
280 cache_lock = &cred->cr_auth->au_credcache->lock; in rpcauth_unhash_cred()
288 * Initialize RPC credential cache
297 if (!new) in rpcauth_init_credcache()
299 new->hashbits = auth_hashbits; in rpcauth_init_credcache()
300 hashsize = 1U << new->hashbits; in rpcauth_init_credcache()
301 new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL); in rpcauth_init_credcache()
302 if (!new->hashtable) in rpcauth_init_credcache()
304 spin_lock_init(&new->lock); in rpcauth_init_credcache()
305 auth->au_credcache = new; in rpcauth_init_credcache()
310 return -ENOMEM; in rpcauth_init_credcache()
317 if (!cred->cr_ops->crstringify_acceptor) in rpcauth_stringify_acceptor()
319 return cred->cr_ops->crstringify_acceptor(cred); in rpcauth_stringify_acceptor()
332 cred = list_entry(head->next, struct rpc_cred, cr_lru); in rpcauth_destroy_credlist()
333 list_del_init(&cred->cr_lru); in rpcauth_destroy_credlist()
341 if (!list_empty(&cred->cr_lru)) in rpcauth_lru_add_locked()
344 list_add_tail(&cred->cr_lru, &cred_unused); in rpcauth_lru_add_locked()
350 if (!list_empty(&cred->cr_lru)) in rpcauth_lru_add()
360 if (list_empty(&cred->cr_lru)) in rpcauth_lru_remove_locked()
362 number_cred_unused--; in rpcauth_lru_remove_locked()
363 list_del_init(&cred->cr_lru); in rpcauth_lru_remove_locked()
369 if (list_empty(&cred->cr_lru)) in rpcauth_lru_remove()
377 * Clear the RPC credential cache, and delete those credentials
386 unsigned int hashsize = 1U << cache->hashbits; in rpcauth_clear_credcache()
390 spin_lock(&cache->lock); in rpcauth_clear_credcache()
392 head = &cache->hashtable[i]; in rpcauth_clear_credcache()
394 cred = hlist_entry(head->first, struct rpc_cred, cr_hash); in rpcauth_clear_credcache()
398 list_add_tail(&cred->cr_lru, &free); in rpcauth_clear_credcache()
401 spin_unlock(&cache->lock); in rpcauth_clear_credcache()
407 * Destroy the RPC credential cache
412 struct rpc_cred_cache *cache = auth->au_credcache; in rpcauth_destroy_credcache()
414 if (cache) { in rpcauth_destroy_credcache()
415 auth->au_credcache = NULL; in rpcauth_destroy_credcache()
417 kfree(cache->hashtable); in rpcauth_destroy_credcache()
433 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; in rpcauth_prune_expired()
438 if (nr_to_scan-- == 0) in rpcauth_prune_expired()
440 if (refcount_read(&cred->cr_count) > 1) { in rpcauth_prune_expired()
446 * Note that the cred_unused list must be time-ordered. in rpcauth_prune_expired()
448 if (!time_in_range(cred->cr_expire, expired, jiffies)) in rpcauth_prune_expired()
450 if (!rpcauth_unhash_cred(cred)) in rpcauth_prune_expired()
455 list_add_tail(&cred->cr_lru, free); in rpcauth_prune_expired()
481 if ((sc->gfp_mask & GFP_KERNEL) != GFP_KERNEL) in rpcauth_cache_shrink_scan()
485 if (list_empty(&cred_unused)) in rpcauth_cache_shrink_scan()
488 return rpcauth_cache_do_shrink(sc->nr_to_scan); in rpcauth_cache_shrink_scan()
504 if (number_cred_unused <= auth_max_cred_cachesize) in rpcauth_cache_enforce_limit()
506 diff = number_cred_unused - auth_max_cred_cachesize; in rpcauth_cache_enforce_limit()
508 if (diff < nr_to_scan) in rpcauth_cache_enforce_limit()
521 struct rpc_cred_cache *cache = auth->au_credcache; in rpcauth_lookup_credcache()
526 nr = auth->au_ops->hash_cred(acred, cache->hashbits); in rpcauth_lookup_credcache()
529 hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) { in rpcauth_lookup_credcache()
530 if (!entry->cr_ops->crmatch(acred, entry, flags)) in rpcauth_lookup_credcache()
533 if (cred) in rpcauth_lookup_credcache()
538 if (cred != NULL) in rpcauth_lookup_credcache()
541 new = auth->au_ops->crcreate(auth, acred, flags, gfp); in rpcauth_lookup_credcache()
542 if (IS_ERR(new)) { in rpcauth_lookup_credcache()
547 spin_lock(&cache->lock); in rpcauth_lookup_credcache()
548 hlist_for_each_entry(entry, &cache->hashtable[nr], cr_hash) { in rpcauth_lookup_credcache()
549 if (!entry->cr_ops->crmatch(acred, entry, flags)) in rpcauth_lookup_credcache()
552 if (cred) in rpcauth_lookup_credcache()
555 if (cred == NULL) { in rpcauth_lookup_credcache()
557 set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); in rpcauth_lookup_credcache()
558 refcount_inc(&cred->cr_count); in rpcauth_lookup_credcache()
559 hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); in rpcauth_lookup_credcache()
561 list_add_tail(&new->cr_lru, &free); in rpcauth_lookup_credcache()
562 spin_unlock(&cache->lock); in rpcauth_lookup_credcache()
565 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && in rpcauth_lookup_credcache()
566 cred->cr_ops->cr_init != NULL && in rpcauth_lookup_credcache()
568 int res = cred->cr_ops->cr_init(auth, cred); in rpcauth_lookup_credcache()
569 if (res < 0) { in rpcauth_lookup_credcache()
589 ret = auth->au_ops->lookup_cred(auth, &acred, flags); in rpcauth_lookupcred()
598 INIT_HLIST_NODE(&cred->cr_hash); in rpcauth_init_cred()
599 INIT_LIST_HEAD(&cred->cr_lru); in rpcauth_init_cred()
600 refcount_set(&cred->cr_count, 1); in rpcauth_init_cred()
601 cred->cr_auth = auth; in rpcauth_init_cred()
602 cred->cr_flags = 0; in rpcauth_init_cred()
603 cred->cr_ops = ops; in rpcauth_init_cred()
604 cred->cr_expire = jiffies; in rpcauth_init_cred()
605 cred->cr_cred = get_cred(acred->cred); in rpcauth_init_cred()
612 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_root_cred()
618 ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bind_root_cred()
626 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_machine_cred()
628 .principal = task->tk_client->cl_principal, in rpcauth_bind_machine_cred()
632 if (!acred.principal) in rpcauth_bind_machine_cred()
634 return auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bind_machine_cred()
640 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_new_cred()
648 struct rpc_rqst *req = task->tk_rqstp; in rpcauth_bindcred()
651 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bindcred()
656 if (flags & RPC_TASK_ASYNC) in rpcauth_bindcred()
658 if (task->tk_op_cred) in rpcauth_bindcred()
660 new = get_rpccred(task->tk_op_cred); in rpcauth_bindcred()
661 else if (cred != NULL && cred != &machine_cred) in rpcauth_bindcred()
662 new = auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bindcred()
663 else if (cred == &machine_cred) in rpcauth_bindcred()
666 /* If machine cred couldn't be bound, try a root cred */ in rpcauth_bindcred()
667 if (new) in rpcauth_bindcred()
669 else if (cred == &machine_cred || (flags & RPC_TASK_ROOTCREDS)) in rpcauth_bindcred()
671 else if (flags & RPC_TASK_NULLCREDS) in rpcauth_bindcred()
675 if (IS_ERR(new)) in rpcauth_bindcred()
677 put_rpccred(req->rq_cred); in rpcauth_bindcred()
678 req->rq_cred = new; in rpcauth_bindcred()
685 if (cred == NULL) in put_rpccred()
688 if (refcount_dec_and_test(&cred->cr_count)) in put_rpccred()
690 if (refcount_read(&cred->cr_count) != 1 || in put_rpccred()
691 !test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in put_rpccred()
693 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) { in put_rpccred()
694 cred->cr_expire = jiffies; in put_rpccred()
697 if (unlikely(!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags))) in put_rpccred()
699 } else if (rpcauth_unhash_cred(cred)) { in put_rpccred()
701 if (refcount_dec_and_test(&cred->cr_count)) in put_rpccred()
709 cred->cr_ops->crdestroy(cred); in put_rpccred()
714 * rpcauth_marshcred - Append RPC credential to end of @xdr
715 * @task: controlling RPC task
716 * @xdr: xdr_stream containing initial portion of RPC Call header
725 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_marshcred()
727 return ops->crmarshal(task, xdr); in rpcauth_marshcred()
731 * rpcauth_wrap_req_encode - XDR encode the RPC procedure
732 * @task: controlling RPC task
733 * @xdr: stream where on-the-wire bytes are to be marshalled
740 kxdreproc_t encode = task->tk_msg.rpc_proc->p_encode; in rpcauth_wrap_req_encode()
742 encode(task->tk_rqstp, xdr, task->tk_msg.rpc_argp); in rpcauth_wrap_req_encode()
748 * rpcauth_wrap_req - XDR encode and wrap the RPC procedure
749 * @task: controlling RPC task
750 * @xdr: stream where on-the-wire bytes are to be marshalled
758 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_wrap_req()
760 return ops->crwrap_req(task, xdr); in rpcauth_wrap_req()
764 * rpcauth_checkverf - Validate verifier in RPC Reply header
765 * @task: controlling RPC task
766 * @xdr: xdr_stream containing RPC Reply header
775 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_checkverf()
777 return ops->crvalidate(task, xdr); in rpcauth_checkverf()
781 * rpcauth_unwrap_resp_decode - Invoke XDR decode function
782 * @task: controlling RPC task
790 kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; in rpcauth_unwrap_resp_decode()
792 return decode(task->tk_rqstp, xdr, task->tk_msg.rpc_resp); in rpcauth_unwrap_resp_decode()
797 * rpcauth_unwrap_resp - Invoke unwrap and decode function for the cred
798 * @task: controlling RPC task
806 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_unwrap_resp()
808 return ops->crunwrap_resp(task, xdr); in rpcauth_unwrap_resp()
814 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_xmit_need_reencode()
816 if (!cred || !cred->cr_ops->crneed_reencode) in rpcauth_xmit_need_reencode()
818 return cred->cr_ops->crneed_reencode(task); in rpcauth_xmit_need_reencode()
827 cred = task->tk_rqstp->rq_cred; in rpcauth_refreshcred()
828 if (cred == NULL) { in rpcauth_refreshcred()
829 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags); in rpcauth_refreshcred()
830 if (err < 0) in rpcauth_refreshcred()
832 cred = task->tk_rqstp->rq_cred; in rpcauth_refreshcred()
835 err = cred->cr_ops->crrefresh(task); in rpcauth_refreshcred()
837 if (err < 0) in rpcauth_refreshcred()
838 task->tk_status = err; in rpcauth_refreshcred()
845 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_invalcred()
847 if (cred) in rpcauth_invalcred()
848 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in rpcauth_invalcred()
854 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_uptodatecred()
857 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; in rpcauth_uptodatecred()
871 if (err < 0) in rpcauth_init_module()
874 if (err < 0) in rpcauth_init_module()