NFSv4: Don't use cred->cr_ops->cr_name in nfs4_proc_setclientid()
[pandora-kernel.git] / net / sunrpc / auth_generic.c
1 /*
2  * Generic RPC credential
3  *
4  * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
5  */
6
7 #include <linux/err.h>
8 #include <linux/types.h>
9 #include <linux/module.h>
10 #include <linux/sched.h>
11 #include <linux/sunrpc/auth.h>
12 #include <linux/sunrpc/clnt.h>
13 #include <linux/sunrpc/debug.h>
14 #include <linux/sunrpc/sched.h>
15
16 #ifdef RPC_DEBUG
17 # define RPCDBG_FACILITY        RPCDBG_AUTH
18 #endif
19
20 struct generic_cred {
21         struct rpc_cred gc_base;
22         struct auth_cred acred;
23 };
24
25 static struct rpc_auth generic_auth;
26 static struct rpc_cred_cache generic_cred_cache;
27 static const struct rpc_credops generic_credops;
28
29 /*
30  * Public call interface
31  */
32 struct rpc_cred *rpc_lookup_cred(void)
33 {
34         return rpcauth_lookupcred(&generic_auth, 0);
35 }
36 EXPORT_SYMBOL_GPL(rpc_lookup_cred);
37
38 static void
39 generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred)
40 {
41         struct rpc_auth *auth = task->tk_client->cl_auth;
42         struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
43         struct rpc_cred *ret;
44
45         ret = auth->au_ops->lookup_cred(auth, acred, 0);
46         if (!IS_ERR(ret))
47                 task->tk_msg.rpc_cred = ret;
48         else
49                 task->tk_status = PTR_ERR(ret);
50 }
51
52 /*
53  * Lookup generic creds for current process
54  */
55 static struct rpc_cred *
56 generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
57 {
58         return rpcauth_lookup_credcache(&generic_auth, acred, flags);
59 }
60
61 static struct rpc_cred *
62 generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
63 {
64         struct generic_cred *gcred;
65
66         gcred = kmalloc(sizeof(*gcred), GFP_KERNEL);
67         if (gcred == NULL)
68                 return ERR_PTR(-ENOMEM);
69
70         rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops);
71         gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
72
73         gcred->acred.uid = acred->uid;
74         gcred->acred.gid = acred->gid;
75         gcred->acred.group_info = acred->group_info;
76         if (gcred->acred.group_info != NULL)
77                 get_group_info(gcred->acred.group_info);
78
79         dprintk("RPC:       allocated generic cred %p for uid %d gid %d\n",
80                         gcred, acred->uid, acred->gid);
81         return &gcred->gc_base;
82 }
83
84 static void
85 generic_free_cred(struct rpc_cred *cred)
86 {
87         struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
88
89         dprintk("RPC:       generic_free_cred %p\n", gcred);
90         if (gcred->acred.group_info != NULL)
91                 put_group_info(gcred->acred.group_info);
92         kfree(gcred);
93 }
94
95 static void
96 generic_free_cred_callback(struct rcu_head *head)
97 {
98         struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu);
99         generic_free_cred(cred);
100 }
101
102 static void
103 generic_destroy_cred(struct rpc_cred *cred)
104 {
105         call_rcu(&cred->cr_rcu, generic_free_cred_callback);
106 }
107
108 /*
109  * Match credentials against current process creds.
110  */
111 static int
112 generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
113 {
114         struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
115
116         if (gcred->acred.uid != acred->uid ||
117             gcred->acred.gid != acred->gid ||
118             gcred->acred.group_info != acred->group_info)
119                 return 0;
120         return 1;
121 }
122
123 void __init rpc_init_generic_auth(void)
124 {
125         spin_lock_init(&generic_cred_cache.lock);
126 }
127
128 void __exit rpc_destroy_generic_auth(void)
129 {
130         rpcauth_clear_credcache(&generic_cred_cache);
131 }
132
133 static struct rpc_cred_cache generic_cred_cache = {
134         {{ NULL, },},
135 };
136
137 static const struct rpc_authops generic_auth_ops = {
138         .owner = THIS_MODULE,
139         .au_name = "Generic",
140         .lookup_cred = generic_lookup_cred,
141         .crcreate = generic_create_cred,
142 };
143
144 static struct rpc_auth generic_auth = {
145         .au_ops = &generic_auth_ops,
146         .au_count = ATOMIC_INIT(0),
147         .au_credcache = &generic_cred_cache,
148 };
149
150 static const struct rpc_credops generic_credops = {
151         .cr_name = "Generic cred",
152         .crdestroy = generic_destroy_cred,
153         .crbind = generic_bind_cred,
154         .crmatch = generic_match,
155 };