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

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Generic RPC client authentication API.
62 if (!val) in param_set_hashtbl_sz()
65 if (ret) in param_set_hashtbl_sz()
67 nbits = fls(num - 1); in param_set_hashtbl_sz()
68 if (nbits > MAX_HASHTABLE_BITS || nbits < 2) in param_set_hashtbl_sz()
70 *(unsigned int *)kp->arg = nbits; in param_set_hashtbl_sz()
73 return -EINVAL; in param_set_hashtbl_sz()
80 nbits = *(unsigned int *)kp->arg; in param_get_hashtbl_sz()
92 MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
96 MODULE_PARM_DESC(auth_max_cred_cachesize, "RPC credential maximum total cache size");
100 if (flavor > RPC_AUTH_MAXFLAVOR) in pseudoflavor_to_flavor()
111 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) in rpcauth_register()
112 return -EINVAL; in rpcauth_register()
114 if (old == NULL || old == ops) in rpcauth_register()
116 return -EPERM; in rpcauth_register()
126 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) in rpcauth_unregister()
127 return -EINVAL; in rpcauth_unregister()
130 if (old == ops || old == NULL) in rpcauth_unregister()
132 return -EPERM; in rpcauth_unregister()
141 if (flavor >= RPC_AUTH_MAXFLAVOR) in rpcauth_get_authops()
146 if (ops == NULL) { in rpcauth_get_authops()
148 request_module("rpc-auth-%u", flavor); in rpcauth_get_authops()
151 if (ops == NULL) in rpcauth_get_authops()
154 if (!try_module_get(ops->owner)) in rpcauth_get_authops()
164 module_put(ops->owner); in rpcauth_put_authops()
168 * rpcauth_get_pseudoflavor - check if security flavor is supported
173 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
182 if (!ops) in rpcauth_get_pseudoflavor()
185 if (ops->info2flavor != NULL) in rpcauth_get_pseudoflavor()
186 pseudoflavor = ops->info2flavor(info); in rpcauth_get_pseudoflavor()
194 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
198 * Returns zero and fills in "info" if pseudoflavor matches a
209 if (ops == NULL) in rpcauth_get_gssinfo()
210 return -ENOENT; in rpcauth_get_gssinfo()
212 result = -ENOENT; in rpcauth_get_gssinfo()
213 if (ops->flavor2info != NULL) in rpcauth_get_gssinfo()
214 result = ops->flavor2info(pseudoflavor, info); in rpcauth_get_gssinfo()
224 struct rpc_auth *auth = ERR_PTR(-EINVAL); in rpcauth_create()
226 u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor); in rpcauth_create()
229 if (ops == NULL) in rpcauth_create()
232 auth = ops->create(args, clnt); in rpcauth_create()
235 if (IS_ERR(auth)) in rpcauth_create()
237 if (clnt->cl_auth) in rpcauth_create()
238 rpcauth_release(clnt->cl_auth); in rpcauth_create()
239 clnt->cl_auth = auth; in rpcauth_create()
249 if (!refcount_dec_and_test(&auth->au_count)) in rpcauth_release()
251 auth->au_ops->destroy(auth); in rpcauth_release()
263 if (!test_and_clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in rpcauth_unhash_cred_locked()
265 hlist_del_rcu(&cred->cr_hash); in rpcauth_unhash_cred_locked()
275 if (!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in rpcauth_unhash_cred()
277 cache_lock = &cred->cr_auth->au_credcache->lock; in rpcauth_unhash_cred()
285 * Initialize RPC credential cache
294 if (!new) in rpcauth_init_credcache()
296 new->hashbits = auth_hashbits; in rpcauth_init_credcache()
297 hashsize = 1U << new->hashbits; in rpcauth_init_credcache()
298 new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL); in rpcauth_init_credcache()
299 if (!new->hashtable) in rpcauth_init_credcache()
301 spin_lock_init(&new->lock); in rpcauth_init_credcache()
302 auth->au_credcache = new; in rpcauth_init_credcache()
307 return -ENOMEM; in rpcauth_init_credcache()
314 if (!cred->cr_ops->crstringify_acceptor) in rpcauth_stringify_acceptor()
316 return cred->cr_ops->crstringify_acceptor(cred); in rpcauth_stringify_acceptor()
329 cred = list_entry(head->next, struct rpc_cred, cr_lru); in rpcauth_destroy_credlist()
330 list_del_init(&cred->cr_lru); in rpcauth_destroy_credlist()
338 if (!list_empty(&cred->cr_lru)) in rpcauth_lru_add_locked()
341 list_add_tail(&cred->cr_lru, &cred_unused); in rpcauth_lru_add_locked()
347 if (!list_empty(&cred->cr_lru)) in rpcauth_lru_add()
357 if (list_empty(&cred->cr_lru)) in rpcauth_lru_remove_locked()
359 number_cred_unused--; in rpcauth_lru_remove_locked()
360 list_del_init(&cred->cr_lru); in rpcauth_lru_remove_locked()
366 if (list_empty(&cred->cr_lru)) in rpcauth_lru_remove()
374 * Clear the RPC credential cache, and delete those credentials
383 unsigned int hashsize = 1U << cache->hashbits; in rpcauth_clear_credcache()
387 spin_lock(&cache->lock); in rpcauth_clear_credcache()
389 head = &cache->hashtable[i]; in rpcauth_clear_credcache()
391 cred = hlist_entry(head->first, struct rpc_cred, cr_hash); in rpcauth_clear_credcache()
395 list_add_tail(&cred->cr_lru, &free); in rpcauth_clear_credcache()
398 spin_unlock(&cache->lock); in rpcauth_clear_credcache()
404 * Destroy the RPC credential cache
409 struct rpc_cred_cache *cache = auth->au_credcache; in rpcauth_destroy_credcache()
411 if (cache) { in rpcauth_destroy_credcache()
412 auth->au_credcache = NULL; in rpcauth_destroy_credcache()
414 kfree(cache->hashtable); in rpcauth_destroy_credcache()
430 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; in rpcauth_prune_expired()
435 if (nr_to_scan-- == 0) in rpcauth_prune_expired()
437 if (refcount_read(&cred->cr_count) > 1) { in rpcauth_prune_expired()
443 * Note that the cred_unused list must be time-ordered. in rpcauth_prune_expired()
445 if (time_in_range(cred->cr_expire, expired, jiffies)) in rpcauth_prune_expired()
447 if (!rpcauth_unhash_cred(cred)) in rpcauth_prune_expired()
452 list_add_tail(&cred->cr_lru, free); in rpcauth_prune_expired()
478 if ((sc->gfp_mask & GFP_KERNEL) != GFP_KERNEL) in rpcauth_cache_shrink_scan()
482 if (list_empty(&cred_unused)) in rpcauth_cache_shrink_scan()
485 return rpcauth_cache_do_shrink(sc->nr_to_scan); in rpcauth_cache_shrink_scan()
501 if (number_cred_unused <= auth_max_cred_cachesize) in rpcauth_cache_enforce_limit()
503 diff = number_cred_unused - auth_max_cred_cachesize; in rpcauth_cache_enforce_limit()
505 if (diff < nr_to_scan) in rpcauth_cache_enforce_limit()
518 struct rpc_cred_cache *cache = auth->au_credcache; in rpcauth_lookup_credcache()
523 nr = auth->au_ops->hash_cred(acred, cache->hashbits); in rpcauth_lookup_credcache()
526 hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) { in rpcauth_lookup_credcache()
527 if (!entry->cr_ops->crmatch(acred, entry, flags)) in rpcauth_lookup_credcache()
530 if (cred) in rpcauth_lookup_credcache()
535 if (cred != NULL) in rpcauth_lookup_credcache()
538 new = auth->au_ops->crcreate(auth, acred, flags, gfp); in rpcauth_lookup_credcache()
539 if (IS_ERR(new)) { in rpcauth_lookup_credcache()
544 spin_lock(&cache->lock); in rpcauth_lookup_credcache()
545 hlist_for_each_entry(entry, &cache->hashtable[nr], cr_hash) { in rpcauth_lookup_credcache()
546 if (!entry->cr_ops->crmatch(acred, entry, flags)) in rpcauth_lookup_credcache()
549 if (cred) in rpcauth_lookup_credcache()
552 if (cred == NULL) { in rpcauth_lookup_credcache()
554 set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); in rpcauth_lookup_credcache()
555 refcount_inc(&cred->cr_count); in rpcauth_lookup_credcache()
556 hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); in rpcauth_lookup_credcache()
558 list_add_tail(&new->cr_lru, &free); in rpcauth_lookup_credcache()
559 spin_unlock(&cache->lock); in rpcauth_lookup_credcache()
562 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && in rpcauth_lookup_credcache()
563 cred->cr_ops->cr_init != NULL && in rpcauth_lookup_credcache()
565 int res = cred->cr_ops->cr_init(auth, cred); in rpcauth_lookup_credcache()
566 if (res < 0) { in rpcauth_lookup_credcache()
586 ret = auth->au_ops->lookup_cred(auth, &acred, flags); in rpcauth_lookupcred()
595 INIT_HLIST_NODE(&cred->cr_hash); in rpcauth_init_cred()
596 INIT_LIST_HEAD(&cred->cr_lru); in rpcauth_init_cred()
597 refcount_set(&cred->cr_count, 1); in rpcauth_init_cred()
598 cred->cr_auth = auth; in rpcauth_init_cred()
599 cred->cr_flags = 0; in rpcauth_init_cred()
600 cred->cr_ops = ops; in rpcauth_init_cred()
601 cred->cr_expire = jiffies; in rpcauth_init_cred()
602 cred->cr_cred = get_cred(acred->cred); in rpcauth_init_cred()
609 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_root_cred()
615 if (RPC_IS_ASYNC(task)) in rpcauth_bind_root_cred()
617 ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bind_root_cred()
625 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_machine_cred()
627 .principal = task->tk_client->cl_principal, in rpcauth_bind_machine_cred()
631 if (!acred.principal) in rpcauth_bind_machine_cred()
633 if (RPC_IS_ASYNC(task)) in rpcauth_bind_machine_cred()
635 return auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bind_machine_cred()
641 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bind_new_cred()
649 struct rpc_rqst *req = task->tk_rqstp; in rpcauth_bindcred()
652 struct rpc_auth *auth = task->tk_client->cl_auth; in rpcauth_bindcred()
657 if (flags & RPC_TASK_ASYNC) in rpcauth_bindcred()
659 if (task->tk_op_cred) in rpcauth_bindcred()
661 new = get_rpccred(task->tk_op_cred); in rpcauth_bindcred()
662 else if (cred != NULL && cred != &machine_cred) in rpcauth_bindcred()
663 new = auth->au_ops->lookup_cred(auth, &acred, lookupflags); in rpcauth_bindcred()
664 else if (cred == &machine_cred) in rpcauth_bindcred()
667 /* If machine cred couldn't be bound, try a root cred */ in rpcauth_bindcred()
668 if (new) in rpcauth_bindcred()
670 else if (cred == &machine_cred) in rpcauth_bindcred()
672 else if (flags & RPC_TASK_NULLCREDS) in rpcauth_bindcred()
676 if (IS_ERR(new)) in rpcauth_bindcred()
678 put_rpccred(req->rq_cred); in rpcauth_bindcred()
679 req->rq_cred = new; in rpcauth_bindcred()
686 if (cred == NULL) in put_rpccred()
689 if (refcount_dec_and_test(&cred->cr_count)) in put_rpccred()
691 if (refcount_read(&cred->cr_count) != 1 || in put_rpccred()
692 !test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)) in put_rpccred()
694 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) { in put_rpccred()
695 cred->cr_expire = jiffies; in put_rpccred()
698 if (unlikely(!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags))) in put_rpccred()
700 } else if (rpcauth_unhash_cred(cred)) { in put_rpccred()
702 if (refcount_dec_and_test(&cred->cr_count)) in put_rpccred()
710 cred->cr_ops->crdestroy(cred); in 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
726 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_marshcred()
728 return ops->crmarshal(task, xdr); in rpcauth_marshcred()
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
741 kxdreproc_t encode = task->tk_msg.rpc_proc->p_encode; in rpcauth_wrap_req_encode()
743 encode(task->tk_rqstp, xdr, task->tk_msg.rpc_argp); in 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
759 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_wrap_req()
761 return ops->crwrap_req(task, xdr); in rpcauth_wrap_req()
765 * rpcauth_checkverf - Validate verifier in RPC Reply header
766 * @task: controlling RPC task
767 * @xdr: xdr_stream containing RPC Reply header
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.
781 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_checkverf()
783 return ops->crvalidate(task, xdr); in rpcauth_checkverf()
787 * rpcauth_unwrap_resp_decode - Invoke XDR decode function
788 * @task: controlling RPC task
796 kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; in rpcauth_unwrap_resp_decode()
798 return decode(task->tk_rqstp, xdr, task->tk_msg.rpc_resp); in rpcauth_unwrap_resp_decode()
803 * rpcauth_unwrap_resp - Invoke unwrap and decode function for the cred
804 * @task: controlling RPC task
812 const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops; in rpcauth_unwrap_resp()
814 return ops->crunwrap_resp(task, xdr); in rpcauth_unwrap_resp()
820 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_xmit_need_reencode()
822 if (!cred || !cred->cr_ops->crneed_reencode) in rpcauth_xmit_need_reencode()
824 return cred->cr_ops->crneed_reencode(task); in rpcauth_xmit_need_reencode()
833 cred = task->tk_rqstp->rq_cred; in rpcauth_refreshcred()
834 if (cred == NULL) { in rpcauth_refreshcred()
835 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags); in rpcauth_refreshcred()
836 if (err < 0) in rpcauth_refreshcred()
838 cred = task->tk_rqstp->rq_cred; in rpcauth_refreshcred()
841 err = cred->cr_ops->crrefresh(task); in rpcauth_refreshcred()
843 if (err < 0) in rpcauth_refreshcred()
844 task->tk_status = err; in rpcauth_refreshcred()
851 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_invalcred()
853 if (cred) in rpcauth_invalcred()
854 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in rpcauth_invalcred()
860 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in rpcauth_uptodatecred()
863 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; in rpcauth_uptodatecred()
873 if (err < 0) in rpcauth_init_module()
876 if (!rpc_cred_shrinker) { in rpcauth_init_module()
877 err = -ENOMEM; in rpcauth_init_module()
881 rpc_cred_shrinker->count_objects = rpcauth_cache_shrink_count; in rpcauth_init_module()
882 rpc_cred_shrinker->scan_objects = rpcauth_cache_shrink_scan; in rpcauth_init_module()