Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * linux/net/sunrpc/svcauth.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * The generic interface for RPC authentication on the server side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * CHANGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * 19-Apr-2000 Chris Evans      - Security fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/sunrpc/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/sunrpc/xdr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/sunrpc/svcsock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/sunrpc/svcauth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <trace/events/sunrpc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "sunrpc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define RPCDBG_FACILITY	RPCDBG_AUTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * Table of authenticators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) extern struct auth_ops svcauth_null;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) extern struct auth_ops svcauth_unix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	[RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	[RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static struct auth_ops *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) svc_get_auth_ops(rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct auth_ops		*aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (flavor >= RPC_AUTH_MAXFLAVOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	aops = rcu_dereference(authtab[flavor]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (aops != NULL && !try_module_get(aops->owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		aops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) svc_put_auth_ops(struct auth_ops *aops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	module_put(aops->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	rpc_authflavor_t	flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct auth_ops		*aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	*authp = rpc_auth_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	flavor = svc_getnl(&rqstp->rq_arg.head[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	dprintk("svc: svc_authenticate (%d)\n", flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	aops = svc_get_auth_ops(flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (aops == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		*authp = rpc_autherr_badcred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return SVC_DENIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	rqstp->rq_auth_slack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	init_svc_cred(&rqstp->rq_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	rqstp->rq_authop = aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return aops->accept(rqstp, authp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) EXPORT_SYMBOL_GPL(svc_authenticate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) int svc_set_client(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	rqstp->rq_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return rqstp->rq_authop->set_client(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) EXPORT_SYMBOL_GPL(svc_set_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /* A request, which was authenticated, has now executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * Time to finalise the credentials and verifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * and release and resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) int svc_authorise(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct auth_ops *aops = rqstp->rq_authop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	int rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	rqstp->rq_authop = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (aops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		rv = aops->release(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		svc_put_auth_ops(aops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct auth_ops *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	int rv = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (flavor < RPC_AUTH_MAXFLAVOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		if (old == NULL || old == aops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) EXPORT_SYMBOL_GPL(svc_auth_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) svc_auth_unregister(rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (flavor < RPC_AUTH_MAXFLAVOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		rcu_assign_pointer(authtab[flavor], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXPORT_SYMBOL_GPL(svc_auth_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /**************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * 'auth_domains' are stored in a hash table indexed by name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * When the last reference to an 'auth_domain' is dropped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * the object is unhashed and freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * If auth_domain_lookup fails to find an entry, it will return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * it's second argument 'new'.  If this is non-null, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * have been atomically linked into the table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define	DN_HASHBITS	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define	DN_HASHMAX	(1<<DN_HASHBITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static struct hlist_head	auth_domain_table[DN_HASHMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static DEFINE_SPINLOCK(auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void auth_domain_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	__releases(&auth_domain_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct auth_domain *dom = container_of(kref, struct auth_domain, ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	hlist_del_rcu(&dom->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	dom->flavour->domain_release(dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	spin_unlock(&auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) void auth_domain_put(struct auth_domain *dom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	kref_put_lock(&dom->ref, auth_domain_release, &auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EXPORT_SYMBOL_GPL(auth_domain_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct auth_domain *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) auth_domain_lookup(char *name, struct auth_domain *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	struct auth_domain *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	spin_lock(&auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	hlist_for_each_entry(hp, head, hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		if (strcmp(hp->name, name)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			kref_get(&hp->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			spin_unlock(&auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			return hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		hlist_add_head_rcu(&new->hash, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	spin_unlock(&auth_domain_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EXPORT_SYMBOL_GPL(auth_domain_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct auth_domain *auth_domain_find(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct auth_domain *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	hlist_for_each_entry_rcu(hp, head, hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		if (strcmp(hp->name, name)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			if (!kref_get_unless_zero(&hp->ref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				hp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			return hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EXPORT_SYMBOL_GPL(auth_domain_find);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * auth_domain_cleanup - check that the auth_domain table is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * On module unload the auth_domain_table must be empty.  To make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * easier to catch bugs which don't clean up domains properly, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * warn if anything remains in the table at cleanup time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * Note that we cannot proactively remove the domains at this stage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * The ->release() function might be in a module that has already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * unloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) void auth_domain_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct auth_domain *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	for (h = 0; h < DN_HASHMAX; h++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		hlist_for_each_entry(hp, &auth_domain_table[h], hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			pr_warn("svc: domain %s still present at module unload.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 				hp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }