11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/net/sunrpc/auth.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Generic RPC client authentication API. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #include <linux/types.h> 101da177e4SLinus Torvalds #include <linux/sched.h> 111da177e4SLinus Torvalds #include <linux/module.h> 121da177e4SLinus Torvalds #include <linux/slab.h> 131da177e4SLinus Torvalds #include <linux/errno.h> 141da177e4SLinus Torvalds #include <linux/sunrpc/clnt.h> 151da177e4SLinus Torvalds #include <linux/spinlock.h> 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds #ifdef RPC_DEBUG 181da177e4SLinus Torvalds # define RPCDBG_FACILITY RPCDBG_AUTH 191da177e4SLinus Torvalds #endif 201da177e4SLinus Torvalds 21fc1b356fSTrond Myklebust static DEFINE_SPINLOCK(rpc_authflavor_lock); 221da177e4SLinus Torvalds static struct rpc_authops * auth_flavors[RPC_AUTH_MAXFLAVOR] = { 231da177e4SLinus Torvalds &authnull_ops, /* AUTH_NULL */ 241da177e4SLinus Torvalds &authunix_ops, /* AUTH_UNIX */ 251da177e4SLinus Torvalds NULL, /* others can be loadable modules */ 261da177e4SLinus Torvalds }; 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds static u32 291da177e4SLinus Torvalds pseudoflavor_to_flavor(u32 flavor) { 301da177e4SLinus Torvalds if (flavor >= RPC_AUTH_MAXFLAVOR) 311da177e4SLinus Torvalds return RPC_AUTH_GSS; 321da177e4SLinus Torvalds return flavor; 331da177e4SLinus Torvalds } 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds int 361da177e4SLinus Torvalds rpcauth_register(struct rpc_authops *ops) 371da177e4SLinus Torvalds { 381da177e4SLinus Torvalds rpc_authflavor_t flavor; 39fc1b356fSTrond Myklebust int ret = -EPERM; 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 421da177e4SLinus Torvalds return -EINVAL; 43fc1b356fSTrond Myklebust spin_lock(&rpc_authflavor_lock); 44fc1b356fSTrond Myklebust if (auth_flavors[flavor] == NULL) { 451da177e4SLinus Torvalds auth_flavors[flavor] = ops; 46fc1b356fSTrond Myklebust ret = 0; 47fc1b356fSTrond Myklebust } 48fc1b356fSTrond Myklebust spin_unlock(&rpc_authflavor_lock); 49fc1b356fSTrond Myklebust return ret; 501da177e4SLinus Torvalds } 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds int 531da177e4SLinus Torvalds rpcauth_unregister(struct rpc_authops *ops) 541da177e4SLinus Torvalds { 551da177e4SLinus Torvalds rpc_authflavor_t flavor; 56fc1b356fSTrond Myklebust int ret = -EPERM; 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 591da177e4SLinus Torvalds return -EINVAL; 60fc1b356fSTrond Myklebust spin_lock(&rpc_authflavor_lock); 61fc1b356fSTrond Myklebust if (auth_flavors[flavor] == ops) { 621da177e4SLinus Torvalds auth_flavors[flavor] = NULL; 63fc1b356fSTrond Myklebust ret = 0; 64fc1b356fSTrond Myklebust } 65fc1b356fSTrond Myklebust spin_unlock(&rpc_authflavor_lock); 66fc1b356fSTrond Myklebust return ret; 671da177e4SLinus Torvalds } 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds struct rpc_auth * 701da177e4SLinus Torvalds rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds struct rpc_auth *auth; 731da177e4SLinus Torvalds struct rpc_authops *ops; 741da177e4SLinus Torvalds u32 flavor = pseudoflavor_to_flavor(pseudoflavor); 751da177e4SLinus Torvalds 76f344f6dfSOlaf Kirch auth = ERR_PTR(-EINVAL); 77f344f6dfSOlaf Kirch if (flavor >= RPC_AUTH_MAXFLAVOR) 78f344f6dfSOlaf Kirch goto out; 79f344f6dfSOlaf Kirch 80f344f6dfSOlaf Kirch #ifdef CONFIG_KMOD 81f344f6dfSOlaf Kirch if ((ops = auth_flavors[flavor]) == NULL) 82f344f6dfSOlaf Kirch request_module("rpc-auth-%u", flavor); 83f344f6dfSOlaf Kirch #endif 84fc1b356fSTrond Myklebust spin_lock(&rpc_authflavor_lock); 85fc1b356fSTrond Myklebust ops = auth_flavors[flavor]; 86fc1b356fSTrond Myklebust if (ops == NULL || !try_module_get(ops->owner)) { 87fc1b356fSTrond Myklebust spin_unlock(&rpc_authflavor_lock); 88f344f6dfSOlaf Kirch goto out; 89fc1b356fSTrond Myklebust } 90fc1b356fSTrond Myklebust spin_unlock(&rpc_authflavor_lock); 911da177e4SLinus Torvalds auth = ops->create(clnt, pseudoflavor); 92fc1b356fSTrond Myklebust module_put(ops->owner); 936a19275aSJ. Bruce Fields if (IS_ERR(auth)) 946a19275aSJ. Bruce Fields return auth; 951da177e4SLinus Torvalds if (clnt->cl_auth) 96*de7a8ce3STrond Myklebust rpcauth_release(clnt->cl_auth); 971da177e4SLinus Torvalds clnt->cl_auth = auth; 98f344f6dfSOlaf Kirch 99f344f6dfSOlaf Kirch out: 1001da177e4SLinus Torvalds return auth; 1011da177e4SLinus Torvalds } 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds void 104*de7a8ce3STrond Myklebust rpcauth_release(struct rpc_auth *auth) 1051da177e4SLinus Torvalds { 1061da177e4SLinus Torvalds if (!atomic_dec_and_test(&auth->au_count)) 1071da177e4SLinus Torvalds return; 1081da177e4SLinus Torvalds auth->au_ops->destroy(auth); 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds static DEFINE_SPINLOCK(rpc_credcache_lock); 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds /* 1141da177e4SLinus Torvalds * Initialize RPC credential cache 1151da177e4SLinus Torvalds */ 1161da177e4SLinus Torvalds int 1171da177e4SLinus Torvalds rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) 1181da177e4SLinus Torvalds { 1191da177e4SLinus Torvalds struct rpc_cred_cache *new; 1201da177e4SLinus Torvalds int i; 1211da177e4SLinus Torvalds 1228b3a7005SKris Katterjohn new = kmalloc(sizeof(*new), GFP_KERNEL); 1231da177e4SLinus Torvalds if (!new) 1241da177e4SLinus Torvalds return -ENOMEM; 1251da177e4SLinus Torvalds for (i = 0; i < RPC_CREDCACHE_NR; i++) 1261da177e4SLinus Torvalds INIT_HLIST_HEAD(&new->hashtable[i]); 1271da177e4SLinus Torvalds new->expire = expire; 1281da177e4SLinus Torvalds new->nextgc = jiffies + (expire >> 1); 1291da177e4SLinus Torvalds auth->au_credcache = new; 1301da177e4SLinus Torvalds return 0; 1311da177e4SLinus Torvalds } 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds /* 1341da177e4SLinus Torvalds * Destroy a list of credentials 1351da177e4SLinus Torvalds */ 1361da177e4SLinus Torvalds static inline 1371da177e4SLinus Torvalds void rpcauth_destroy_credlist(struct hlist_head *head) 1381da177e4SLinus Torvalds { 1391da177e4SLinus Torvalds struct rpc_cred *cred; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds while (!hlist_empty(head)) { 1421da177e4SLinus Torvalds cred = hlist_entry(head->first, struct rpc_cred, cr_hash); 1431da177e4SLinus Torvalds hlist_del_init(&cred->cr_hash); 1441da177e4SLinus Torvalds put_rpccred(cred); 1451da177e4SLinus Torvalds } 1461da177e4SLinus Torvalds } 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds /* 1491da177e4SLinus Torvalds * Clear the RPC credential cache, and delete those credentials 1501da177e4SLinus Torvalds * that are not referenced. 1511da177e4SLinus Torvalds */ 1521da177e4SLinus Torvalds void 1533ab9bb72STrond Myklebust rpcauth_clear_credcache(struct rpc_cred_cache *cache) 1541da177e4SLinus Torvalds { 1551da177e4SLinus Torvalds HLIST_HEAD(free); 1561da177e4SLinus Torvalds struct hlist_node *pos, *next; 1571da177e4SLinus Torvalds struct rpc_cred *cred; 1581da177e4SLinus Torvalds int i; 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds spin_lock(&rpc_credcache_lock); 1611da177e4SLinus Torvalds for (i = 0; i < RPC_CREDCACHE_NR; i++) { 1621da177e4SLinus Torvalds hlist_for_each_safe(pos, next, &cache->hashtable[i]) { 1631da177e4SLinus Torvalds cred = hlist_entry(pos, struct rpc_cred, cr_hash); 1641da177e4SLinus Torvalds __hlist_del(&cred->cr_hash); 1651da177e4SLinus Torvalds hlist_add_head(&cred->cr_hash, &free); 1661da177e4SLinus Torvalds } 1671da177e4SLinus Torvalds } 1681da177e4SLinus Torvalds spin_unlock(&rpc_credcache_lock); 1691da177e4SLinus Torvalds rpcauth_destroy_credlist(&free); 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1723ab9bb72STrond Myklebust /* 1733ab9bb72STrond Myklebust * Destroy the RPC credential cache 1743ab9bb72STrond Myklebust */ 1753ab9bb72STrond Myklebust void 1763ab9bb72STrond Myklebust rpcauth_destroy_credcache(struct rpc_auth *auth) 1773ab9bb72STrond Myklebust { 1783ab9bb72STrond Myklebust struct rpc_cred_cache *cache = auth->au_credcache; 1793ab9bb72STrond Myklebust 1803ab9bb72STrond Myklebust if (cache) { 1813ab9bb72STrond Myklebust auth->au_credcache = NULL; 1823ab9bb72STrond Myklebust rpcauth_clear_credcache(cache); 1833ab9bb72STrond Myklebust kfree(cache); 1843ab9bb72STrond Myklebust } 1853ab9bb72STrond Myklebust } 1863ab9bb72STrond Myklebust 1871da177e4SLinus Torvalds static void 1881da177e4SLinus Torvalds rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free) 1891da177e4SLinus Torvalds { 1901da177e4SLinus Torvalds if (atomic_read(&cred->cr_count) != 1) 1911da177e4SLinus Torvalds return; 1921da177e4SLinus Torvalds if (time_after(jiffies, cred->cr_expire + auth->au_credcache->expire)) 1931da177e4SLinus Torvalds cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 1941da177e4SLinus Torvalds if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) { 1951da177e4SLinus Torvalds __hlist_del(&cred->cr_hash); 1961da177e4SLinus Torvalds hlist_add_head(&cred->cr_hash, free); 1971da177e4SLinus Torvalds } 1981da177e4SLinus Torvalds } 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds /* 2011da177e4SLinus Torvalds * Remove stale credentials. Avoid sleeping inside the loop. 2021da177e4SLinus Torvalds */ 2031da177e4SLinus Torvalds static void 2041da177e4SLinus Torvalds rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) 2051da177e4SLinus Torvalds { 2061da177e4SLinus Torvalds struct rpc_cred_cache *cache = auth->au_credcache; 2071da177e4SLinus Torvalds struct hlist_node *pos, *next; 2081da177e4SLinus Torvalds struct rpc_cred *cred; 2091da177e4SLinus Torvalds int i; 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); 2121da177e4SLinus Torvalds for (i = 0; i < RPC_CREDCACHE_NR; i++) { 2131da177e4SLinus Torvalds hlist_for_each_safe(pos, next, &cache->hashtable[i]) { 2141da177e4SLinus Torvalds cred = hlist_entry(pos, struct rpc_cred, cr_hash); 2151da177e4SLinus Torvalds rpcauth_prune_expired(auth, cred, free); 2161da177e4SLinus Torvalds } 2171da177e4SLinus Torvalds } 2181da177e4SLinus Torvalds cache->nextgc = jiffies + cache->expire; 2191da177e4SLinus Torvalds } 2201da177e4SLinus Torvalds 2211da177e4SLinus Torvalds /* 2221da177e4SLinus Torvalds * Look up a process' credentials in the authentication cache 2231da177e4SLinus Torvalds */ 2241da177e4SLinus Torvalds struct rpc_cred * 2251da177e4SLinus Torvalds rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 2268a317760STrond Myklebust int flags) 2271da177e4SLinus Torvalds { 2281da177e4SLinus Torvalds struct rpc_cred_cache *cache = auth->au_credcache; 2291da177e4SLinus Torvalds HLIST_HEAD(free); 2301da177e4SLinus Torvalds struct hlist_node *pos, *next; 2311da177e4SLinus Torvalds struct rpc_cred *new = NULL, 2321da177e4SLinus Torvalds *cred = NULL; 2331da177e4SLinus Torvalds int nr = 0; 2341da177e4SLinus Torvalds 2358a317760STrond Myklebust if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) 2361da177e4SLinus Torvalds nr = acred->uid & RPC_CREDCACHE_MASK; 2371da177e4SLinus Torvalds retry: 2381da177e4SLinus Torvalds spin_lock(&rpc_credcache_lock); 2391da177e4SLinus Torvalds if (time_before(cache->nextgc, jiffies)) 2401da177e4SLinus Torvalds rpcauth_gc_credcache(auth, &free); 2411da177e4SLinus Torvalds hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { 2421da177e4SLinus Torvalds struct rpc_cred *entry; 2431da177e4SLinus Torvalds entry = hlist_entry(pos, struct rpc_cred, cr_hash); 2448a317760STrond Myklebust if (entry->cr_ops->crmatch(acred, entry, flags)) { 2451da177e4SLinus Torvalds hlist_del(&entry->cr_hash); 2461da177e4SLinus Torvalds cred = entry; 2471da177e4SLinus Torvalds break; 2481da177e4SLinus Torvalds } 2491da177e4SLinus Torvalds rpcauth_prune_expired(auth, entry, &free); 2501da177e4SLinus Torvalds } 2511da177e4SLinus Torvalds if (new) { 2521da177e4SLinus Torvalds if (cred) 2531da177e4SLinus Torvalds hlist_add_head(&new->cr_hash, &free); 2541da177e4SLinus Torvalds else 2551da177e4SLinus Torvalds cred = new; 2561da177e4SLinus Torvalds } 2571da177e4SLinus Torvalds if (cred) { 2581da177e4SLinus Torvalds hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]); 2591da177e4SLinus Torvalds get_rpccred(cred); 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds spin_unlock(&rpc_credcache_lock); 2621da177e4SLinus Torvalds 2631da177e4SLinus Torvalds rpcauth_destroy_credlist(&free); 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds if (!cred) { 2668a317760STrond Myklebust new = auth->au_ops->crcreate(auth, acred, flags); 2671da177e4SLinus Torvalds if (!IS_ERR(new)) { 2681da177e4SLinus Torvalds #ifdef RPC_DEBUG 2691da177e4SLinus Torvalds new->cr_magic = RPCAUTH_CRED_MAGIC; 2701da177e4SLinus Torvalds #endif 2711da177e4SLinus Torvalds goto retry; 2721da177e4SLinus Torvalds } else 2731da177e4SLinus Torvalds cred = new; 274fba3bad4STrond Myklebust } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) 275fba3bad4STrond Myklebust && cred->cr_ops->cr_init != NULL 276fba3bad4STrond Myklebust && !(flags & RPCAUTH_LOOKUP_NEW)) { 277fba3bad4STrond Myklebust int res = cred->cr_ops->cr_init(auth, cred); 278fba3bad4STrond Myklebust if (res < 0) { 279fba3bad4STrond Myklebust put_rpccred(cred); 280fba3bad4STrond Myklebust cred = ERR_PTR(res); 281fba3bad4STrond Myklebust } 2821da177e4SLinus Torvalds } 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds return (struct rpc_cred *) cred; 2851da177e4SLinus Torvalds } 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds struct rpc_cred * 2888a317760STrond Myklebust rpcauth_lookupcred(struct rpc_auth *auth, int flags) 2891da177e4SLinus Torvalds { 2901da177e4SLinus Torvalds struct auth_cred acred = { 2911da177e4SLinus Torvalds .uid = current->fsuid, 2921da177e4SLinus Torvalds .gid = current->fsgid, 2931da177e4SLinus Torvalds .group_info = current->group_info, 2941da177e4SLinus Torvalds }; 2951da177e4SLinus Torvalds struct rpc_cred *ret; 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds dprintk("RPC: looking up %s cred\n", 2981da177e4SLinus Torvalds auth->au_ops->au_name); 2991da177e4SLinus Torvalds get_group_info(acred.group_info); 3008a317760STrond Myklebust ret = auth->au_ops->lookup_cred(auth, &acred, flags); 3011da177e4SLinus Torvalds put_group_info(acred.group_info); 3021da177e4SLinus Torvalds return ret; 3031da177e4SLinus Torvalds } 3041da177e4SLinus Torvalds 3051da177e4SLinus Torvalds struct rpc_cred * 3061da177e4SLinus Torvalds rpcauth_bindcred(struct rpc_task *task) 3071da177e4SLinus Torvalds { 3081da177e4SLinus Torvalds struct rpc_auth *auth = task->tk_auth; 3091da177e4SLinus Torvalds struct auth_cred acred = { 3101da177e4SLinus Torvalds .uid = current->fsuid, 3111da177e4SLinus Torvalds .gid = current->fsgid, 3121da177e4SLinus Torvalds .group_info = current->group_info, 3131da177e4SLinus Torvalds }; 3141da177e4SLinus Torvalds struct rpc_cred *ret; 3158a317760STrond Myklebust int flags = 0; 3161da177e4SLinus Torvalds 31746121cf7SChuck Lever dprintk("RPC: %5u looking up %s cred\n", 3181da177e4SLinus Torvalds task->tk_pid, task->tk_auth->au_ops->au_name); 3191da177e4SLinus Torvalds get_group_info(acred.group_info); 3208a317760STrond Myklebust if (task->tk_flags & RPC_TASK_ROOTCREDS) 3218a317760STrond Myklebust flags |= RPCAUTH_LOOKUP_ROOTCREDS; 3228a317760STrond Myklebust ret = auth->au_ops->lookup_cred(auth, &acred, flags); 3231da177e4SLinus Torvalds if (!IS_ERR(ret)) 3241da177e4SLinus Torvalds task->tk_msg.rpc_cred = ret; 3251da177e4SLinus Torvalds else 3261da177e4SLinus Torvalds task->tk_status = PTR_ERR(ret); 3271da177e4SLinus Torvalds put_group_info(acred.group_info); 3281da177e4SLinus Torvalds return ret; 3291da177e4SLinus Torvalds } 3301da177e4SLinus Torvalds 3311da177e4SLinus Torvalds void 3321da177e4SLinus Torvalds rpcauth_holdcred(struct rpc_task *task) 3331da177e4SLinus Torvalds { 33446121cf7SChuck Lever dprintk("RPC: %5u holding %s cred %p\n", 33546121cf7SChuck Lever task->tk_pid, task->tk_auth->au_ops->au_name, 33646121cf7SChuck Lever task->tk_msg.rpc_cred); 3371da177e4SLinus Torvalds if (task->tk_msg.rpc_cred) 3381da177e4SLinus Torvalds get_rpccred(task->tk_msg.rpc_cred); 3391da177e4SLinus Torvalds } 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds void 3421da177e4SLinus Torvalds put_rpccred(struct rpc_cred *cred) 3431da177e4SLinus Torvalds { 3441da177e4SLinus Torvalds cred->cr_expire = jiffies; 3451da177e4SLinus Torvalds if (!atomic_dec_and_test(&cred->cr_count)) 3461da177e4SLinus Torvalds return; 3471da177e4SLinus Torvalds cred->cr_ops->crdestroy(cred); 3481da177e4SLinus Torvalds } 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds void 3511da177e4SLinus Torvalds rpcauth_unbindcred(struct rpc_task *task) 3521da177e4SLinus Torvalds { 3531da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 3541da177e4SLinus Torvalds 35546121cf7SChuck Lever dprintk("RPC: %5u releasing %s cred %p\n", 3560bbacc40SChuck Lever task->tk_pid, task->tk_auth->au_ops->au_name, cred); 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds put_rpccred(cred); 3591da177e4SLinus Torvalds task->tk_msg.rpc_cred = NULL; 3601da177e4SLinus Torvalds } 3611da177e4SLinus Torvalds 362d8ed029dSAlexey Dobriyan __be32 * 363d8ed029dSAlexey Dobriyan rpcauth_marshcred(struct rpc_task *task, __be32 *p) 3641da177e4SLinus Torvalds { 3651da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 3661da177e4SLinus Torvalds 36746121cf7SChuck Lever dprintk("RPC: %5u marshaling %s cred %p\n", 3680bbacc40SChuck Lever task->tk_pid, task->tk_auth->au_ops->au_name, cred); 3690bbacc40SChuck Lever 3701da177e4SLinus Torvalds return cred->cr_ops->crmarshal(task, p); 3711da177e4SLinus Torvalds } 3721da177e4SLinus Torvalds 373d8ed029dSAlexey Dobriyan __be32 * 374d8ed029dSAlexey Dobriyan rpcauth_checkverf(struct rpc_task *task, __be32 *p) 3751da177e4SLinus Torvalds { 3761da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 3771da177e4SLinus Torvalds 37846121cf7SChuck Lever dprintk("RPC: %5u validating %s cred %p\n", 3790bbacc40SChuck Lever task->tk_pid, task->tk_auth->au_ops->au_name, cred); 3800bbacc40SChuck Lever 3811da177e4SLinus Torvalds return cred->cr_ops->crvalidate(task, p); 3821da177e4SLinus Torvalds } 3831da177e4SLinus Torvalds 3841da177e4SLinus Torvalds int 3851da177e4SLinus Torvalds rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, 386d8ed029dSAlexey Dobriyan __be32 *data, void *obj) 3871da177e4SLinus Torvalds { 3881da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 3891da177e4SLinus Torvalds 39046121cf7SChuck Lever dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 3911da177e4SLinus Torvalds task->tk_pid, cred->cr_ops->cr_name, cred); 3921da177e4SLinus Torvalds if (cred->cr_ops->crwrap_req) 3931da177e4SLinus Torvalds return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); 3941da177e4SLinus Torvalds /* By default, we encode the arguments normally. */ 3951da177e4SLinus Torvalds return encode(rqstp, data, obj); 3961da177e4SLinus Torvalds } 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds int 3991da177e4SLinus Torvalds rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, 400d8ed029dSAlexey Dobriyan __be32 *data, void *obj) 4011da177e4SLinus Torvalds { 4021da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 4031da177e4SLinus Torvalds 40446121cf7SChuck Lever dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 4051da177e4SLinus Torvalds task->tk_pid, cred->cr_ops->cr_name, cred); 4061da177e4SLinus Torvalds if (cred->cr_ops->crunwrap_resp) 4071da177e4SLinus Torvalds return cred->cr_ops->crunwrap_resp(task, decode, rqstp, 4081da177e4SLinus Torvalds data, obj); 4091da177e4SLinus Torvalds /* By default, we decode the arguments normally. */ 4101da177e4SLinus Torvalds return decode(rqstp, data, obj); 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds 4131da177e4SLinus Torvalds int 4141da177e4SLinus Torvalds rpcauth_refreshcred(struct rpc_task *task) 4151da177e4SLinus Torvalds { 4161da177e4SLinus Torvalds struct rpc_cred *cred = task->tk_msg.rpc_cred; 4171da177e4SLinus Torvalds int err; 4181da177e4SLinus Torvalds 41946121cf7SChuck Lever dprintk("RPC: %5u refreshing %s cred %p\n", 4200bbacc40SChuck Lever task->tk_pid, task->tk_auth->au_ops->au_name, cred); 4210bbacc40SChuck Lever 4221da177e4SLinus Torvalds err = cred->cr_ops->crrefresh(task); 4231da177e4SLinus Torvalds if (err < 0) 4241da177e4SLinus Torvalds task->tk_status = err; 4251da177e4SLinus Torvalds return err; 4261da177e4SLinus Torvalds } 4271da177e4SLinus Torvalds 4281da177e4SLinus Torvalds void 4291da177e4SLinus Torvalds rpcauth_invalcred(struct rpc_task *task) 4301da177e4SLinus Torvalds { 43146121cf7SChuck Lever dprintk("RPC: %5u invalidating %s cred %p\n", 4321da177e4SLinus Torvalds task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred); 4331da177e4SLinus Torvalds spin_lock(&rpc_credcache_lock); 4341da177e4SLinus Torvalds if (task->tk_msg.rpc_cred) 4351da177e4SLinus Torvalds task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 4361da177e4SLinus Torvalds spin_unlock(&rpc_credcache_lock); 4371da177e4SLinus Torvalds } 4381da177e4SLinus Torvalds 4391da177e4SLinus Torvalds int 4401da177e4SLinus Torvalds rpcauth_uptodatecred(struct rpc_task *task) 4411da177e4SLinus Torvalds { 4421da177e4SLinus Torvalds return !(task->tk_msg.rpc_cred) || 4431da177e4SLinus Torvalds (task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE); 4441da177e4SLinus Torvalds } 445