Blame view
net/sunrpc/auth_unix.c
5.53 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* * linux/net/sunrpc/auth_unix.c * * UNIX-style authentication; no AUTH_SHORT support * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> */ |
5a0e3ad6a include cleanup: ... |
8 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 |
#include <linux/types.h> #include <linux/sched.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 15 16 17 18 19 20 21 22 |
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/auth.h> #define NFS_NGROUPS 16 struct unx_cred { struct rpc_cred uc_base; gid_t uc_gid; gid_t uc_gids[NFS_NGROUPS]; }; #define uc_uid uc_base.cr_uid |
1da177e4c Linux-2.6.12-rc2 |
23 |
|
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 29 30 |
#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) #ifdef RPC_DEBUG # define RPCDBG_FACILITY RPCDBG_AUTH #endif static struct rpc_auth unix_auth; |
f1c0a8615 SUNRPC: Mark auth... |
31 |
static const struct rpc_credops unix_credops; |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 |
static struct rpc_auth * unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) { |
46121cf7d SUNRPC: fix print... |
36 37 38 |
dprintk("RPC: creating UNIX authenticator for client %p ", clnt); |
f5c2187cf SUNRPC: Convert t... |
39 |
atomic_inc(&unix_auth.au_count); |
1da177e4c Linux-2.6.12-rc2 |
40 41 42 43 44 45 |
return &unix_auth; } static void unx_destroy(struct rpc_auth *auth) { |
46121cf7d SUNRPC: fix print... |
46 47 |
dprintk("RPC: destroying UNIX authenticator %p ", auth); |
3ab9bb724 SUNRPC: Fix a mem... |
48 |
rpcauth_clear_credcache(auth->au_credcache); |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
} /* * Lookup AUTH_UNIX creds for current process */ static struct rpc_cred * unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) { return rpcauth_lookup_credcache(auth, acred, flags); } static struct rpc_cred * unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) { struct unx_cred *cred; |
af0938357 SUNRPC: Fix RPCAU... |
64 65 |
unsigned int groups = 0; unsigned int i; |
1da177e4c Linux-2.6.12-rc2 |
66 |
|
46121cf7d SUNRPC: fix print... |
67 68 69 |
dprintk("RPC: allocating UNIX cred for uid %d gid %d ", acred->uid, acred->gid); |
1da177e4c Linux-2.6.12-rc2 |
70 |
|
0f38b873a SUNRPC: Use GFP_N... |
71 |
if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) |
1da177e4c Linux-2.6.12-rc2 |
72 |
return ERR_PTR(-ENOMEM); |
5fe4755e2 SUNRPC: Clean up ... |
73 |
rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); |
fc432dd90 SUNRPC: Enforce a... |
74 |
cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; |
af0938357 SUNRPC: Fix RPCAU... |
75 76 77 78 79 80 81 82 83 84 85 |
if (acred->group_info != NULL) groups = acred->group_info->ngroups; if (groups > NFS_NGROUPS) groups = NFS_NGROUPS; cred->uc_gid = acred->gid; for (i = 0; i < groups; i++) cred->uc_gids[i] = GROUP_AT(acred->group_info, i); if (i < NFS_NGROUPS) cred->uc_gids[i] = NOGROUP; |
1da177e4c Linux-2.6.12-rc2 |
86 |
|
696e38df9 SUNRPC: replace c... |
87 |
return &cred->uc_base; |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 |
} static void |
31be5bf15 SUNRPC: Convert t... |
91 |
unx_free_cred(struct unx_cred *unx_cred) |
1da177e4c Linux-2.6.12-rc2 |
92 |
{ |
31be5bf15 SUNRPC: Convert t... |
93 94 95 96 |
dprintk("RPC: unx_free_cred %p ", unx_cred); kfree(unx_cred); } |
696e38df9 SUNRPC: replace c... |
97 |
|
31be5bf15 SUNRPC: Convert t... |
98 99 100 101 102 103 104 105 106 107 108 |
static void unx_free_cred_callback(struct rcu_head *head) { struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu); unx_free_cred(unx_cred); } static void unx_destroy_cred(struct rpc_cred *cred) { call_rcu(&cred->cr_rcu, unx_free_cred_callback); |
1da177e4c Linux-2.6.12-rc2 |
109 110 111 112 113 114 115 116 |
} /* * Match credentials against current process creds. * The root_override argument takes care of cases where the caller may * request root creds (e.g. for NFS swapping). */ static int |
8a3177604 SUNRPC: Fix a loc... |
117 |
unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) |
1da177e4c Linux-2.6.12-rc2 |
118 |
{ |
696e38df9 SUNRPC: replace c... |
119 |
struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); |
af0938357 SUNRPC: Fix RPCAU... |
120 121 |
unsigned int groups = 0; unsigned int i; |
1da177e4c Linux-2.6.12-rc2 |
122 |
|
1da177e4c Linux-2.6.12-rc2 |
123 |
|
af0938357 SUNRPC: Fix RPCAU... |
124 125 |
if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid) return 0; |
1da177e4c Linux-2.6.12-rc2 |
126 |
|
af0938357 SUNRPC: Fix RPCAU... |
127 |
if (acred->group_info != NULL) |
1da177e4c Linux-2.6.12-rc2 |
128 |
groups = acred->group_info->ngroups; |
af0938357 SUNRPC: Fix RPCAU... |
129 130 131 132 133 |
if (groups > NFS_NGROUPS) groups = NFS_NGROUPS; for (i = 0; i < groups ; i++) if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) return 0; |
dc6f55e9f NFS/sunrpc: don't... |
134 135 136 |
if (groups < NFS_NGROUPS && cred->uc_gids[groups] != NOGROUP) return 0; |
af0938357 SUNRPC: Fix RPCAU... |
137 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
138 139 140 141 142 143 |
} /* * Marshal credentials. * Maybe we should keep a cached credential for performance reasons. */ |
d8ed029d6 [SUNRPC]: trivial... |
144 145 |
static __be32 * unx_marshal(struct rpc_task *task, __be32 *p) |
1da177e4c Linux-2.6.12-rc2 |
146 147 |
{ struct rpc_clnt *clnt = task->tk_client; |
a17c2153d SUNRPC: Move the ... |
148 |
struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base); |
d8ed029d6 [SUNRPC]: trivial... |
149 |
__be32 *base, *hold; |
1da177e4c Linux-2.6.12-rc2 |
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
int i; *p++ = htonl(RPC_AUTH_UNIX); base = p++; *p++ = htonl(jiffies/HZ); /* * Copy the UTS nodename captured when the client was created. */ p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); *p++ = htonl((u32) cred->uc_uid); *p++ = htonl((u32) cred->uc_gid); hold = p++; for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) *p++ = htonl((u32) cred->uc_gids[i]); *hold = htonl(p - hold - 1); /* gid array length */ *base = htonl((p - base - 1) << 2); /* cred length */ *p++ = htonl(RPC_AUTH_NULL); *p++ = htonl(0); return p; } /* * Refresh credentials. This is a no-op for AUTH_UNIX */ static int unx_refresh(struct rpc_task *task) { |
a17c2153d SUNRPC: Move the ... |
181 |
set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags); |
1da177e4c Linux-2.6.12-rc2 |
182 183 |
return 0; } |
d8ed029d6 [SUNRPC]: trivial... |
184 185 |
static __be32 * unx_validate(struct rpc_task *task, __be32 *p) |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
{ rpc_authflavor_t flavor; u32 size; flavor = ntohl(*p++); if (flavor != RPC_AUTH_NULL && flavor != RPC_AUTH_UNIX && flavor != RPC_AUTH_SHORT) { printk("RPC: bad verf flavor: %u ", flavor); return NULL; } size = ntohl(*p++); if (size > RPC_MAX_AUTH_SIZE) { printk("RPC: giant verf size: %u ", size); return NULL; } |
a17c2153d SUNRPC: Move the ... |
205 |
task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2; |
1da177e4c Linux-2.6.12-rc2 |
206 207 208 209 |
p += (size >> 2); return p; } |
5d8d9a4d9 NFS: Ensure the A... |
210 |
int __init rpc_init_authunix(void) |
9499b4341 SUNRPC: Give cred... |
211 |
{ |
5d8d9a4d9 NFS: Ensure the A... |
212 213 214 215 216 217 |
return rpcauth_init_credcache(&unix_auth); } void rpc_destroy_authunix(void) { rpcauth_destroy_credcache(&unix_auth); |
9499b4341 SUNRPC: Give cred... |
218 |
} |
f1c0a8615 SUNRPC: Mark auth... |
219 |
const struct rpc_authops authunix_ops = { |
1da177e4c Linux-2.6.12-rc2 |
220 221 |
.owner = THIS_MODULE, .au_flavor = RPC_AUTH_UNIX, |
1da177e4c Linux-2.6.12-rc2 |
222 |
.au_name = "UNIX", |
1da177e4c Linux-2.6.12-rc2 |
223 224 225 226 227 228 229 |
.create = unx_create, .destroy = unx_destroy, .lookup_cred = unx_lookup_cred, .crcreate = unx_create_cred, }; static |
1da177e4c Linux-2.6.12-rc2 |
230 231 232 233 |
struct rpc_auth unix_auth = { .au_cslack = UNX_WRITESLACK, .au_rslack = 2, /* assume AUTH_NULL verf */ .au_ops = &authunix_ops, |
81039f1f2 NFS: Display the ... |
234 |
.au_flavor = RPC_AUTH_UNIX, |
1da177e4c Linux-2.6.12-rc2 |
235 |
.au_count = ATOMIC_INIT(0), |
1da177e4c Linux-2.6.12-rc2 |
236 237 238 |
}; static |
f1c0a8615 SUNRPC: Mark auth... |
239 |
const struct rpc_credops unix_credops = { |
1da177e4c Linux-2.6.12-rc2 |
240 241 |
.cr_name = "AUTH_UNIX", .crdestroy = unx_destroy_cred, |
5c691044e SUNRPC: Add an rp... |
242 |
.crbind = rpcauth_generic_bind_cred, |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 247 |
.crmatch = unx_match, .crmarshal = unx_marshal, .crrefresh = unx_refresh, .crvalidate = unx_validate, }; |