2 * Generic RPC credential
4 * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
8 #include <linux/slab.h>
9 #include <linux/types.h>
10 #include <linux/module.h>
11 #include <linux/sched.h>
12 #include <linux/sunrpc/auth.h>
13 #include <linux/sunrpc/clnt.h>
14 #include <linux/sunrpc/debug.h>
15 #include <linux/sunrpc/sched.h>
18 # define RPCDBG_FACILITY RPCDBG_AUTH
21 #define RPC_MACHINE_CRED_USERID ((uid_t)0)
22 #define RPC_MACHINE_CRED_GROUPID ((gid_t)0)
25 struct rpc_cred gc_base
;
26 struct auth_cred acred
;
29 static struct rpc_auth generic_auth
;
30 static struct rpc_cred_cache generic_cred_cache
;
31 static const struct rpc_credops generic_credops
;
34 * Public call interface
36 struct rpc_cred
*rpc_lookup_cred(void)
38 return rpcauth_lookupcred(&generic_auth
, 0);
40 EXPORT_SYMBOL_GPL(rpc_lookup_cred
);
43 * Public call interface for looking up machine creds.
45 struct rpc_cred
*rpc_lookup_machine_cred(void)
47 struct auth_cred acred
= {
48 .uid
= RPC_MACHINE_CRED_USERID
,
49 .gid
= RPC_MACHINE_CRED_GROUPID
,
53 dprintk("RPC: looking up machine cred\n");
54 return generic_auth
.au_ops
->lookup_cred(&generic_auth
, &acred
, 0);
56 EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred
);
59 generic_bind_cred(struct rpc_task
*task
, struct rpc_cred
*cred
, int lookupflags
)
61 struct rpc_auth
*auth
= task
->tk_client
->cl_auth
;
62 struct auth_cred
*acred
= &container_of(cred
, struct generic_cred
, gc_base
)->acred
;
65 ret
= auth
->au_ops
->lookup_cred(auth
, acred
, lookupflags
);
67 task
->tk_msg
.rpc_cred
= ret
;
69 task
->tk_status
= PTR_ERR(ret
);
73 * Lookup generic creds for current process
75 static struct rpc_cred
*
76 generic_lookup_cred(struct rpc_auth
*auth
, struct auth_cred
*acred
, int flags
)
78 return rpcauth_lookup_credcache(&generic_auth
, acred
, flags
);
81 static struct rpc_cred
*
82 generic_create_cred(struct rpc_auth
*auth
, struct auth_cred
*acred
, int flags
)
84 struct generic_cred
*gcred
;
86 gcred
= kmalloc(sizeof(*gcred
), GFP_KERNEL
);
88 return ERR_PTR(-ENOMEM
);
90 rpcauth_init_cred(&gcred
->gc_base
, acred
, &generic_auth
, &generic_credops
);
91 gcred
->gc_base
.cr_flags
= 1UL << RPCAUTH_CRED_UPTODATE
;
93 gcred
->acred
.uid
= acred
->uid
;
94 gcred
->acred
.gid
= acred
->gid
;
95 gcred
->acred
.group_info
= acred
->group_info
;
96 if (gcred
->acred
.group_info
!= NULL
)
97 get_group_info(gcred
->acred
.group_info
);
98 gcred
->acred
.machine_cred
= acred
->machine_cred
;
100 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n",
101 gcred
->acred
.machine_cred
? "machine" : "generic",
102 gcred
, acred
->uid
, acred
->gid
);
103 return &gcred
->gc_base
;
107 generic_free_cred(struct rpc_cred
*cred
)
109 struct generic_cred
*gcred
= container_of(cred
, struct generic_cred
, gc_base
);
111 dprintk("RPC: generic_free_cred %p\n", gcred
);
112 if (gcred
->acred
.group_info
!= NULL
)
113 put_group_info(gcred
->acred
.group_info
);
118 generic_free_cred_callback(struct rcu_head
*head
)
120 struct rpc_cred
*cred
= container_of(head
, struct rpc_cred
, cr_rcu
);
121 generic_free_cred(cred
);
125 generic_destroy_cred(struct rpc_cred
*cred
)
127 call_rcu(&cred
->cr_rcu
, generic_free_cred_callback
);
131 * Match credentials against current process creds.
134 generic_match(struct auth_cred
*acred
, struct rpc_cred
*cred
, int flags
)
136 struct generic_cred
*gcred
= container_of(cred
, struct generic_cred
, gc_base
);
139 if (gcred
->acred
.uid
!= acred
->uid
||
140 gcred
->acred
.gid
!= acred
->gid
||
141 gcred
->acred
.machine_cred
!= acred
->machine_cred
)
144 /* Optimisation in the case where pointers are identical... */
145 if (gcred
->acred
.group_info
== acred
->group_info
)
149 if (gcred
->acred
.group_info
->ngroups
!= acred
->group_info
->ngroups
)
151 for (i
= 0; i
< gcred
->acred
.group_info
->ngroups
; i
++) {
152 if (GROUP_AT(gcred
->acred
.group_info
, i
) !=
153 GROUP_AT(acred
->group_info
, i
))
162 void __init
rpc_init_generic_auth(void)
164 spin_lock_init(&generic_cred_cache
.lock
);
167 void __exit
rpc_destroy_generic_auth(void)
169 rpcauth_clear_credcache(&generic_cred_cache
);
172 static struct rpc_cred_cache generic_cred_cache
= {
176 static const struct rpc_authops generic_auth_ops
= {
177 .owner
= THIS_MODULE
,
178 .au_name
= "Generic",
179 .lookup_cred
= generic_lookup_cred
,
180 .crcreate
= generic_create_cred
,
183 static struct rpc_auth generic_auth
= {
184 .au_ops
= &generic_auth_ops
,
185 .au_count
= ATOMIC_INIT(0),
186 .au_credcache
= &generic_cred_cache
,
189 static const struct rpc_credops generic_credops
= {
190 .cr_name
= "Generic cred",
191 .crdestroy
= generic_destroy_cred
,
192 .crbind
= generic_bind_cred
,
193 .crmatch
= generic_match
,