Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/net/sunrpc/auth.c
0004  *
0005  * Generic RPC client authentication API.
0006  *
0007  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
0008  */
0009 
0010 #include <linux/types.h>
0011 #include <linux/sched.h>
0012 #include <linux/cred.h>
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/errno.h>
0016 #include <linux/hash.h>
0017 #include <linux/sunrpc/clnt.h>
0018 #include <linux/sunrpc/gss_api.h>
0019 #include <linux/spinlock.h>
0020 
0021 #include <trace/events/sunrpc.h>
0022 
0023 #define RPC_CREDCACHE_DEFAULT_HASHBITS  (4)
0024 struct rpc_cred_cache {
0025     struct hlist_head   *hashtable;
0026     unsigned int        hashbits;
0027     spinlock_t      lock;
0028 };
0029 
0030 static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS;
0031 
0032 static const struct rpc_authops __rcu *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
0033     [RPC_AUTH_NULL] = (const struct rpc_authops __force __rcu *)&authnull_ops,
0034     [RPC_AUTH_UNIX] = (const struct rpc_authops __force __rcu *)&authunix_ops,
0035     NULL,           /* others can be loadable modules */
0036 };
0037 
0038 static LIST_HEAD(cred_unused);
0039 static unsigned long number_cred_unused;
0040 
0041 static struct cred machine_cred = {
0042     .usage = ATOMIC_INIT(1),
0043 #ifdef CONFIG_DEBUG_CREDENTIALS
0044     .magic = CRED_MAGIC,
0045 #endif
0046 };
0047 
0048 /*
0049  * Return the machine_cred pointer to be used whenever
0050  * the a generic machine credential is needed.
0051  */
0052 const struct cred *rpc_machine_cred(void)
0053 {
0054     return &machine_cred;
0055 }
0056 EXPORT_SYMBOL_GPL(rpc_machine_cred);
0057 
0058 #define MAX_HASHTABLE_BITS (14)
0059 static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
0060 {
0061     unsigned long num;
0062     unsigned int nbits;
0063     int ret;
0064 
0065     if (!val)
0066         goto out_inval;
0067     ret = kstrtoul(val, 0, &num);
0068     if (ret)
0069         goto out_inval;
0070     nbits = fls(num - 1);
0071     if (nbits > MAX_HASHTABLE_BITS || nbits < 2)
0072         goto out_inval;
0073     *(unsigned int *)kp->arg = nbits;
0074     return 0;
0075 out_inval:
0076     return -EINVAL;
0077 }
0078 
0079 static int param_get_hashtbl_sz(char *buffer, const struct kernel_param *kp)
0080 {
0081     unsigned int nbits;
0082 
0083     nbits = *(unsigned int *)kp->arg;
0084     return sprintf(buffer, "%u\n", 1U << nbits);
0085 }
0086 
0087 #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
0088 
0089 static const struct kernel_param_ops param_ops_hashtbl_sz = {
0090     .set = param_set_hashtbl_sz,
0091     .get = param_get_hashtbl_sz,
0092 };
0093 
0094 module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
0095 MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
0096 
0097 static unsigned long auth_max_cred_cachesize = ULONG_MAX;
0098 module_param(auth_max_cred_cachesize, ulong, 0644);
0099 MODULE_PARM_DESC(auth_max_cred_cachesize, "RPC credential maximum total cache size");
0100 
0101 static u32
0102 pseudoflavor_to_flavor(u32 flavor) {
0103     if (flavor > RPC_AUTH_MAXFLAVOR)
0104         return RPC_AUTH_GSS;
0105     return flavor;
0106 }
0107 
0108 int
0109 rpcauth_register(const struct rpc_authops *ops)
0110 {
0111     const struct rpc_authops *old;
0112     rpc_authflavor_t flavor;
0113 
0114     if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
0115         return -EINVAL;
0116     old = cmpxchg((const struct rpc_authops ** __force)&auth_flavors[flavor], NULL, ops);
0117     if (old == NULL || old == ops)
0118         return 0;
0119     return -EPERM;
0120 }
0121 EXPORT_SYMBOL_GPL(rpcauth_register);
0122 
0123 int
0124 rpcauth_unregister(const struct rpc_authops *ops)
0125 {
0126     const struct rpc_authops *old;
0127     rpc_authflavor_t flavor;
0128 
0129     if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
0130         return -EINVAL;
0131 
0132     old = cmpxchg((const struct rpc_authops ** __force)&auth_flavors[flavor], ops, NULL);
0133     if (old == ops || old == NULL)
0134         return 0;
0135     return -EPERM;
0136 }
0137 EXPORT_SYMBOL_GPL(rpcauth_unregister);
0138 
0139 static const struct rpc_authops *
0140 rpcauth_get_authops(rpc_authflavor_t flavor)
0141 {
0142     const struct rpc_authops *ops;
0143 
0144     if (flavor >= RPC_AUTH_MAXFLAVOR)
0145         return NULL;
0146 
0147     rcu_read_lock();
0148     ops = rcu_dereference(auth_flavors[flavor]);
0149     if (ops == NULL) {
0150         rcu_read_unlock();
0151         request_module("rpc-auth-%u", flavor);
0152         rcu_read_lock();
0153         ops = rcu_dereference(auth_flavors[flavor]);
0154         if (ops == NULL)
0155             goto out;
0156     }
0157     if (!try_module_get(ops->owner))
0158         ops = NULL;
0159 out:
0160     rcu_read_unlock();
0161     return ops;
0162 }
0163 
0164 static void
0165 rpcauth_put_authops(const struct rpc_authops *ops)
0166 {
0167     module_put(ops->owner);
0168 }
0169 
0170 /**
0171  * rpcauth_get_pseudoflavor - check if security flavor is supported
0172  * @flavor: a security flavor
0173  * @info: a GSS mech OID, quality of protection, and service value
0174  *
0175  * Verifies that an appropriate kernel module is available or already loaded.
0176  * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
0177  * not supported locally.
0178  */
0179 rpc_authflavor_t
0180 rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info)
0181 {
0182     const struct rpc_authops *ops = rpcauth_get_authops(flavor);
0183     rpc_authflavor_t pseudoflavor;
0184 
0185     if (!ops)
0186         return RPC_AUTH_MAXFLAVOR;
0187     pseudoflavor = flavor;
0188     if (ops->info2flavor != NULL)
0189         pseudoflavor = ops->info2flavor(info);
0190 
0191     rpcauth_put_authops(ops);
0192     return pseudoflavor;
0193 }
0194 EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor);
0195 
0196 /**
0197  * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
0198  * @pseudoflavor: GSS pseudoflavor to match
0199  * @info: rpcsec_gss_info structure to fill in
0200  *
0201  * Returns zero and fills in "info" if pseudoflavor matches a
0202  * supported mechanism.
0203  */
0204 int
0205 rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info)
0206 {
0207     rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor);
0208     const struct rpc_authops *ops;
0209     int result;
0210 
0211     ops = rpcauth_get_authops(flavor);
0212     if (ops == NULL)
0213         return -ENOENT;
0214 
0215     result = -ENOENT;
0216     if (ops->flavor2info != NULL)
0217         result = ops->flavor2info(pseudoflavor, info);
0218 
0219     rpcauth_put_authops(ops);
0220     return result;
0221 }
0222 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo);
0223 
0224 struct rpc_auth *
0225 rpcauth_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
0226 {
0227     struct rpc_auth *auth = ERR_PTR(-EINVAL);
0228     const struct rpc_authops *ops;
0229     u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor);
0230 
0231     ops = rpcauth_get_authops(flavor);
0232     if (ops == NULL)
0233         goto out;
0234 
0235     auth = ops->create(args, clnt);
0236 
0237     rpcauth_put_authops(ops);
0238     if (IS_ERR(auth))
0239         return auth;
0240     if (clnt->cl_auth)
0241         rpcauth_release(clnt->cl_auth);
0242     clnt->cl_auth = auth;
0243 
0244 out:
0245     return auth;
0246 }
0247 EXPORT_SYMBOL_GPL(rpcauth_create);
0248 
0249 void
0250 rpcauth_release(struct rpc_auth *auth)
0251 {
0252     if (!refcount_dec_and_test(&auth->au_count))
0253         return;
0254     auth->au_ops->destroy(auth);
0255 }
0256 
0257 static DEFINE_SPINLOCK(rpc_credcache_lock);
0258 
0259 /*
0260  * On success, the caller is responsible for freeing the reference
0261  * held by the hashtable
0262  */
0263 static bool
0264 rpcauth_unhash_cred_locked(struct rpc_cred *cred)
0265 {
0266     if (!test_and_clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags))
0267         return false;
0268     hlist_del_rcu(&cred->cr_hash);
0269     return true;
0270 }
0271 
0272 static bool
0273 rpcauth_unhash_cred(struct rpc_cred *cred)
0274 {
0275     spinlock_t *cache_lock;
0276     bool ret;
0277 
0278     if (!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags))
0279         return false;
0280     cache_lock = &cred->cr_auth->au_credcache->lock;
0281     spin_lock(cache_lock);
0282     ret = rpcauth_unhash_cred_locked(cred);
0283     spin_unlock(cache_lock);
0284     return ret;
0285 }
0286 
0287 /*
0288  * Initialize RPC credential cache
0289  */
0290 int
0291 rpcauth_init_credcache(struct rpc_auth *auth)
0292 {
0293     struct rpc_cred_cache *new;
0294     unsigned int hashsize;
0295 
0296     new = kmalloc(sizeof(*new), GFP_KERNEL);
0297     if (!new)
0298         goto out_nocache;
0299     new->hashbits = auth_hashbits;
0300     hashsize = 1U << new->hashbits;
0301     new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL);
0302     if (!new->hashtable)
0303         goto out_nohashtbl;
0304     spin_lock_init(&new->lock);
0305     auth->au_credcache = new;
0306     return 0;
0307 out_nohashtbl:
0308     kfree(new);
0309 out_nocache:
0310     return -ENOMEM;
0311 }
0312 EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
0313 
0314 char *
0315 rpcauth_stringify_acceptor(struct rpc_cred *cred)
0316 {
0317     if (!cred->cr_ops->crstringify_acceptor)
0318         return NULL;
0319     return cred->cr_ops->crstringify_acceptor(cred);
0320 }
0321 EXPORT_SYMBOL_GPL(rpcauth_stringify_acceptor);
0322 
0323 /*
0324  * Destroy a list of credentials
0325  */
0326 static inline
0327 void rpcauth_destroy_credlist(struct list_head *head)
0328 {
0329     struct rpc_cred *cred;
0330 
0331     while (!list_empty(head)) {
0332         cred = list_entry(head->next, struct rpc_cred, cr_lru);
0333         list_del_init(&cred->cr_lru);
0334         put_rpccred(cred);
0335     }
0336 }
0337 
0338 static void
0339 rpcauth_lru_add_locked(struct rpc_cred *cred)
0340 {
0341     if (!list_empty(&cred->cr_lru))
0342         return;
0343     number_cred_unused++;
0344     list_add_tail(&cred->cr_lru, &cred_unused);
0345 }
0346 
0347 static void
0348 rpcauth_lru_add(struct rpc_cred *cred)
0349 {
0350     if (!list_empty(&cred->cr_lru))
0351         return;
0352     spin_lock(&rpc_credcache_lock);
0353     rpcauth_lru_add_locked(cred);
0354     spin_unlock(&rpc_credcache_lock);
0355 }
0356 
0357 static void
0358 rpcauth_lru_remove_locked(struct rpc_cred *cred)
0359 {
0360     if (list_empty(&cred->cr_lru))
0361         return;
0362     number_cred_unused--;
0363     list_del_init(&cred->cr_lru);
0364 }
0365 
0366 static void
0367 rpcauth_lru_remove(struct rpc_cred *cred)
0368 {
0369     if (list_empty(&cred->cr_lru))
0370         return;
0371     spin_lock(&rpc_credcache_lock);
0372     rpcauth_lru_remove_locked(cred);
0373     spin_unlock(&rpc_credcache_lock);
0374 }
0375 
0376 /*
0377  * Clear the RPC credential cache, and delete those credentials
0378  * that are not referenced.
0379  */
0380 void
0381 rpcauth_clear_credcache(struct rpc_cred_cache *cache)
0382 {
0383     LIST_HEAD(free);
0384     struct hlist_head *head;
0385     struct rpc_cred *cred;
0386     unsigned int hashsize = 1U << cache->hashbits;
0387     int     i;
0388 
0389     spin_lock(&rpc_credcache_lock);
0390     spin_lock(&cache->lock);
0391     for (i = 0; i < hashsize; i++) {
0392         head = &cache->hashtable[i];
0393         while (!hlist_empty(head)) {
0394             cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
0395             rpcauth_unhash_cred_locked(cred);
0396             /* Note: We now hold a reference to cred */
0397             rpcauth_lru_remove_locked(cred);
0398             list_add_tail(&cred->cr_lru, &free);
0399         }
0400     }
0401     spin_unlock(&cache->lock);
0402     spin_unlock(&rpc_credcache_lock);
0403     rpcauth_destroy_credlist(&free);
0404 }
0405 
0406 /*
0407  * Destroy the RPC credential cache
0408  */
0409 void
0410 rpcauth_destroy_credcache(struct rpc_auth *auth)
0411 {
0412     struct rpc_cred_cache *cache = auth->au_credcache;
0413 
0414     if (cache) {
0415         auth->au_credcache = NULL;
0416         rpcauth_clear_credcache(cache);
0417         kfree(cache->hashtable);
0418         kfree(cache);
0419     }
0420 }
0421 EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache);
0422 
0423 
0424 #define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ)
0425 
0426 /*
0427  * Remove stale credentials. Avoid sleeping inside the loop.
0428  */
0429 static long
0430 rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
0431 {
0432     struct rpc_cred *cred, *next;
0433     unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM;
0434     long freed = 0;
0435 
0436     list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
0437 
0438         if (nr_to_scan-- == 0)
0439             break;
0440         if (refcount_read(&cred->cr_count) > 1) {
0441             rpcauth_lru_remove_locked(cred);
0442             continue;
0443         }
0444         /*
0445          * Enforce a 60 second garbage collection moratorium
0446          * Note that the cred_unused list must be time-ordered.
0447          */
0448         if (time_in_range(cred->cr_expire, expired, jiffies))
0449             continue;
0450         if (!rpcauth_unhash_cred(cred))
0451             continue;
0452 
0453         rpcauth_lru_remove_locked(cred);
0454         freed++;
0455         list_add_tail(&cred->cr_lru, free);
0456     }
0457     return freed ? freed : SHRINK_STOP;
0458 }
0459 
0460 static unsigned long
0461 rpcauth_cache_do_shrink(int nr_to_scan)
0462 {
0463     LIST_HEAD(free);
0464     unsigned long freed;
0465 
0466     spin_lock(&rpc_credcache_lock);
0467     freed = rpcauth_prune_expired(&free, nr_to_scan);
0468     spin_unlock(&rpc_credcache_lock);
0469     rpcauth_destroy_credlist(&free);
0470 
0471     return freed;
0472 }
0473 
0474 /*
0475  * Run memory cache shrinker.
0476  */
0477 static unsigned long
0478 rpcauth_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
0479 
0480 {
0481     if ((sc->gfp_mask & GFP_KERNEL) != GFP_KERNEL)
0482         return SHRINK_STOP;
0483 
0484     /* nothing left, don't come back */
0485     if (list_empty(&cred_unused))
0486         return SHRINK_STOP;
0487 
0488     return rpcauth_cache_do_shrink(sc->nr_to_scan);
0489 }
0490 
0491 static unsigned long
0492 rpcauth_cache_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
0493 
0494 {
0495     return number_cred_unused * sysctl_vfs_cache_pressure / 100;
0496 }
0497 
0498 static void
0499 rpcauth_cache_enforce_limit(void)
0500 {
0501     unsigned long diff;
0502     unsigned int nr_to_scan;
0503 
0504     if (number_cred_unused <= auth_max_cred_cachesize)
0505         return;
0506     diff = number_cred_unused - auth_max_cred_cachesize;
0507     nr_to_scan = 100;
0508     if (diff < nr_to_scan)
0509         nr_to_scan = diff;
0510     rpcauth_cache_do_shrink(nr_to_scan);
0511 }
0512 
0513 /*
0514  * Look up a process' credentials in the authentication cache
0515  */
0516 struct rpc_cred *
0517 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
0518         int flags, gfp_t gfp)
0519 {
0520     LIST_HEAD(free);
0521     struct rpc_cred_cache *cache = auth->au_credcache;
0522     struct rpc_cred *cred = NULL,
0523             *entry, *new;
0524     unsigned int nr;
0525 
0526     nr = auth->au_ops->hash_cred(acred, cache->hashbits);
0527 
0528     rcu_read_lock();
0529     hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) {
0530         if (!entry->cr_ops->crmatch(acred, entry, flags))
0531             continue;
0532         cred = get_rpccred(entry);
0533         if (cred)
0534             break;
0535     }
0536     rcu_read_unlock();
0537 
0538     if (cred != NULL)
0539         goto found;
0540 
0541     new = auth->au_ops->crcreate(auth, acred, flags, gfp);
0542     if (IS_ERR(new)) {
0543         cred = new;
0544         goto out;
0545     }
0546 
0547     spin_lock(&cache->lock);
0548     hlist_for_each_entry(entry, &cache->hashtable[nr], cr_hash) {
0549         if (!entry->cr_ops->crmatch(acred, entry, flags))
0550             continue;
0551         cred = get_rpccred(entry);
0552         if (cred)
0553             break;
0554     }
0555     if (cred == NULL) {
0556         cred = new;
0557         set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
0558         refcount_inc(&cred->cr_count);
0559         hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]);
0560     } else
0561         list_add_tail(&new->cr_lru, &free);
0562     spin_unlock(&cache->lock);
0563     rpcauth_cache_enforce_limit();
0564 found:
0565     if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
0566         cred->cr_ops->cr_init != NULL &&
0567         !(flags & RPCAUTH_LOOKUP_NEW)) {
0568         int res = cred->cr_ops->cr_init(auth, cred);
0569         if (res < 0) {
0570             put_rpccred(cred);
0571             cred = ERR_PTR(res);
0572         }
0573     }
0574     rpcauth_destroy_credlist(&free);
0575 out:
0576     return cred;
0577 }
0578 EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache);
0579 
0580 struct rpc_cred *
0581 rpcauth_lookupcred(struct rpc_auth *auth, int flags)
0582 {
0583     struct auth_cred acred;
0584     struct rpc_cred *ret;
0585     const struct cred *cred = current_cred();
0586 
0587     memset(&acred, 0, sizeof(acred));
0588     acred.cred = cred;
0589     ret = auth->au_ops->lookup_cred(auth, &acred, flags);
0590     return ret;
0591 }
0592 EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
0593 
0594 void
0595 rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
0596           struct rpc_auth *auth, const struct rpc_credops *ops)
0597 {
0598     INIT_HLIST_NODE(&cred->cr_hash);
0599     INIT_LIST_HEAD(&cred->cr_lru);
0600     refcount_set(&cred->cr_count, 1);
0601     cred->cr_auth = auth;
0602     cred->cr_flags = 0;
0603     cred->cr_ops = ops;
0604     cred->cr_expire = jiffies;
0605     cred->cr_cred = get_cred(acred->cred);
0606 }
0607 EXPORT_SYMBOL_GPL(rpcauth_init_cred);
0608 
0609 static struct rpc_cred *
0610 rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
0611 {
0612     struct rpc_auth *auth = task->tk_client->cl_auth;
0613     struct auth_cred acred = {
0614         .cred = get_task_cred(&init_task),
0615     };
0616     struct rpc_cred *ret;
0617 
0618     if (RPC_IS_ASYNC(task))
0619         lookupflags |= RPCAUTH_LOOKUP_ASYNC;
0620     ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
0621     put_cred(acred.cred);
0622     return ret;
0623 }
0624 
0625 static struct rpc_cred *
0626 rpcauth_bind_machine_cred(struct rpc_task *task, int lookupflags)
0627 {
0628     struct rpc_auth *auth = task->tk_client->cl_auth;
0629     struct auth_cred acred = {
0630         .principal = task->tk_client->cl_principal,
0631         .cred = init_task.cred,
0632     };
0633 
0634     if (!acred.principal)
0635         return NULL;
0636     if (RPC_IS_ASYNC(task))
0637         lookupflags |= RPCAUTH_LOOKUP_ASYNC;
0638     return auth->au_ops->lookup_cred(auth, &acred, lookupflags);
0639 }
0640 
0641 static struct rpc_cred *
0642 rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
0643 {
0644     struct rpc_auth *auth = task->tk_client->cl_auth;
0645 
0646     return rpcauth_lookupcred(auth, lookupflags);
0647 }
0648 
0649 static int
0650 rpcauth_bindcred(struct rpc_task *task, const struct cred *cred, int flags)
0651 {
0652     struct rpc_rqst *req = task->tk_rqstp;
0653     struct rpc_cred *new = NULL;
0654     int lookupflags = 0;
0655     struct rpc_auth *auth = task->tk_client->cl_auth;
0656     struct auth_cred acred = {
0657         .cred = cred,
0658     };
0659 
0660     if (flags & RPC_TASK_ASYNC)
0661         lookupflags |= RPCAUTH_LOOKUP_NEW | RPCAUTH_LOOKUP_ASYNC;
0662     if (task->tk_op_cred)
0663         /* Task must use exactly this rpc_cred */
0664         new = get_rpccred(task->tk_op_cred);
0665     else if (cred != NULL && cred != &machine_cred)
0666         new = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
0667     else if (cred == &machine_cred)
0668         new = rpcauth_bind_machine_cred(task, lookupflags);
0669 
0670     /* If machine cred couldn't be bound, try a root cred */
0671     if (new)
0672         ;
0673     else if (cred == &machine_cred)
0674         new = rpcauth_bind_root_cred(task, lookupflags);
0675     else if (flags & RPC_TASK_NULLCREDS)
0676         new = authnull_ops.lookup_cred(NULL, NULL, 0);
0677     else
0678         new = rpcauth_bind_new_cred(task, lookupflags);
0679     if (IS_ERR(new))
0680         return PTR_ERR(new);
0681     put_rpccred(req->rq_cred);
0682     req->rq_cred = new;
0683     return 0;
0684 }
0685 
0686 void
0687 put_rpccred(struct rpc_cred *cred)
0688 {
0689     if (cred == NULL)
0690         return;
0691     rcu_read_lock();
0692     if (refcount_dec_and_test(&cred->cr_count))
0693         goto destroy;
0694     if (refcount_read(&cred->cr_count) != 1 ||
0695         !test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags))
0696         goto out;
0697     if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) {
0698         cred->cr_expire = jiffies;
0699         rpcauth_lru_add(cred);
0700         /* Race breaker */
0701         if (unlikely(!test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags)))
0702             rpcauth_lru_remove(cred);
0703     } else if (rpcauth_unhash_cred(cred)) {
0704         rpcauth_lru_remove(cred);
0705         if (refcount_dec_and_test(&cred->cr_count))
0706             goto destroy;
0707     }
0708 out:
0709     rcu_read_unlock();
0710     return;
0711 destroy:
0712     rcu_read_unlock();
0713     cred->cr_ops->crdestroy(cred);
0714 }
0715 EXPORT_SYMBOL_GPL(put_rpccred);
0716 
0717 /**
0718  * rpcauth_marshcred - Append RPC credential to end of @xdr
0719  * @task: controlling RPC task
0720  * @xdr: xdr_stream containing initial portion of RPC Call header
0721  *
0722  * On success, an appropriate verifier is added to @xdr, @xdr is
0723  * updated to point past the verifier, and zero is returned.
0724  * Otherwise, @xdr is in an undefined state and a negative errno
0725  * is returned.
0726  */
0727 int rpcauth_marshcred(struct rpc_task *task, struct xdr_stream *xdr)
0728 {
0729     const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
0730 
0731     return ops->crmarshal(task, xdr);
0732 }
0733 
0734 /**
0735  * rpcauth_wrap_req_encode - XDR encode the RPC procedure
0736  * @task: controlling RPC task
0737  * @xdr: stream where on-the-wire bytes are to be marshalled
0738  *
0739  * On success, @xdr contains the encoded and wrapped message.
0740  * Otherwise, @xdr is in an undefined state.
0741  */
0742 int rpcauth_wrap_req_encode(struct rpc_task *task, struct xdr_stream *xdr)
0743 {
0744     kxdreproc_t encode = task->tk_msg.rpc_proc->p_encode;
0745 
0746     encode(task->tk_rqstp, xdr, task->tk_msg.rpc_argp);
0747     return 0;
0748 }
0749 EXPORT_SYMBOL_GPL(rpcauth_wrap_req_encode);
0750 
0751 /**
0752  * rpcauth_wrap_req - XDR encode and wrap the RPC procedure
0753  * @task: controlling RPC task
0754  * @xdr: stream where on-the-wire bytes are to be marshalled
0755  *
0756  * On success, @xdr contains the encoded and wrapped message,
0757  * and zero is returned. Otherwise, @xdr is in an undefined
0758  * state and a negative errno is returned.
0759  */
0760 int rpcauth_wrap_req(struct rpc_task *task, struct xdr_stream *xdr)
0761 {
0762     const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
0763 
0764     return ops->crwrap_req(task, xdr);
0765 }
0766 
0767 /**
0768  * rpcauth_checkverf - Validate verifier in RPC Reply header
0769  * @task: controlling RPC task
0770  * @xdr: xdr_stream containing RPC Reply header
0771  *
0772  * On success, @xdr is updated to point past the verifier and
0773  * zero is returned. Otherwise, @xdr is in an undefined state
0774  * and a negative errno is returned.
0775  */
0776 int
0777 rpcauth_checkverf(struct rpc_task *task, struct xdr_stream *xdr)
0778 {
0779     const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
0780 
0781     return ops->crvalidate(task, xdr);
0782 }
0783 
0784 /**
0785  * rpcauth_unwrap_resp_decode - Invoke XDR decode function
0786  * @task: controlling RPC task
0787  * @xdr: stream where the Reply message resides
0788  *
0789  * Returns zero on success; otherwise a negative errno is returned.
0790  */
0791 int
0792 rpcauth_unwrap_resp_decode(struct rpc_task *task, struct xdr_stream *xdr)
0793 {
0794     kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode;
0795 
0796     return decode(task->tk_rqstp, xdr, task->tk_msg.rpc_resp);
0797 }
0798 EXPORT_SYMBOL_GPL(rpcauth_unwrap_resp_decode);
0799 
0800 /**
0801  * rpcauth_unwrap_resp - Invoke unwrap and decode function for the cred
0802  * @task: controlling RPC task
0803  * @xdr: stream where the Reply message resides
0804  *
0805  * Returns zero on success; otherwise a negative errno is returned.
0806  */
0807 int
0808 rpcauth_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
0809 {
0810     const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
0811 
0812     return ops->crunwrap_resp(task, xdr);
0813 }
0814 
0815 bool
0816 rpcauth_xmit_need_reencode(struct rpc_task *task)
0817 {
0818     struct rpc_cred *cred = task->tk_rqstp->rq_cred;
0819 
0820     if (!cred || !cred->cr_ops->crneed_reencode)
0821         return false;
0822     return cred->cr_ops->crneed_reencode(task);
0823 }
0824 
0825 int
0826 rpcauth_refreshcred(struct rpc_task *task)
0827 {
0828     struct rpc_cred *cred;
0829     int err;
0830 
0831     cred = task->tk_rqstp->rq_cred;
0832     if (cred == NULL) {
0833         err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags);
0834         if (err < 0)
0835             goto out;
0836         cred = task->tk_rqstp->rq_cred;
0837     }
0838 
0839     err = cred->cr_ops->crrefresh(task);
0840 out:
0841     if (err < 0)
0842         task->tk_status = err;
0843     return err;
0844 }
0845 
0846 void
0847 rpcauth_invalcred(struct rpc_task *task)
0848 {
0849     struct rpc_cred *cred = task->tk_rqstp->rq_cred;
0850 
0851     if (cred)
0852         clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
0853 }
0854 
0855 int
0856 rpcauth_uptodatecred(struct rpc_task *task)
0857 {
0858     struct rpc_cred *cred = task->tk_rqstp->rq_cred;
0859 
0860     return cred == NULL ||
0861         test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
0862 }
0863 
0864 static struct shrinker rpc_cred_shrinker = {
0865     .count_objects = rpcauth_cache_shrink_count,
0866     .scan_objects = rpcauth_cache_shrink_scan,
0867     .seeks = DEFAULT_SEEKS,
0868 };
0869 
0870 int __init rpcauth_init_module(void)
0871 {
0872     int err;
0873 
0874     err = rpc_init_authunix();
0875     if (err < 0)
0876         goto out1;
0877     err = register_shrinker(&rpc_cred_shrinker, "sunrpc_cred");
0878     if (err < 0)
0879         goto out2;
0880     return 0;
0881 out2:
0882     rpc_destroy_authunix();
0883 out1:
0884     return err;
0885 }
0886 
0887 void rpcauth_remove_module(void)
0888 {
0889     rpc_destroy_authunix();
0890     unregister_shrinker(&rpc_cred_shrinker);
0891 }