diff options
Diffstat (limited to 'net/sunrpc/auth_unix.c')
-rw-r--r-- | net/sunrpc/auth_unix.c | 120 |
1 files changed, 70 insertions, 50 deletions
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 770e338a9b11..d4018e5a24c5 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c | |||
@@ -28,8 +28,6 @@ static mempool_t *unix_pool; | |||
28 | static struct rpc_auth * | 28 | static struct rpc_auth * |
29 | unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | 29 | unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) |
30 | { | 30 | { |
31 | dprintk("RPC: creating UNIX authenticator for client %p\n", | ||
32 | clnt); | ||
33 | refcount_inc(&unix_auth.au_count); | 31 | refcount_inc(&unix_auth.au_count); |
34 | return &unix_auth; | 32 | return &unix_auth; |
35 | } | 33 | } |
@@ -37,7 +35,6 @@ unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
37 | static void | 35 | static void |
38 | unx_destroy(struct rpc_auth *auth) | 36 | unx_destroy(struct rpc_auth *auth) |
39 | { | 37 | { |
40 | dprintk("RPC: destroying UNIX authenticator %p\n", auth); | ||
41 | } | 38 | } |
42 | 39 | ||
43 | /* | 40 | /* |
@@ -48,10 +45,6 @@ unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
48 | { | 45 | { |
49 | struct rpc_cred *ret = mempool_alloc(unix_pool, GFP_NOFS); | 46 | struct rpc_cred *ret = mempool_alloc(unix_pool, GFP_NOFS); |
50 | 47 | ||
51 | dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", | ||
52 | from_kuid(&init_user_ns, acred->cred->fsuid), | ||
53 | from_kgid(&init_user_ns, acred->cred->fsgid)); | ||
54 | |||
55 | rpcauth_init_cred(ret, acred, auth, &unix_credops); | 48 | rpcauth_init_cred(ret, acred, auth, &unix_credops); |
56 | ret->cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; | 49 | ret->cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; |
57 | return ret; | 50 | return ret; |
@@ -61,7 +54,7 @@ static void | |||
61 | unx_free_cred_callback(struct rcu_head *head) | 54 | unx_free_cred_callback(struct rcu_head *head) |
62 | { | 55 | { |
63 | struct rpc_cred *rpc_cred = container_of(head, struct rpc_cred, cr_rcu); | 56 | struct rpc_cred *rpc_cred = container_of(head, struct rpc_cred, cr_rcu); |
64 | dprintk("RPC: unx_free_cred %p\n", rpc_cred); | 57 | |
65 | put_cred(rpc_cred->cr_cred); | 58 | put_cred(rpc_cred->cr_cred); |
66 | mempool_free(rpc_cred, unix_pool); | 59 | mempool_free(rpc_cred, unix_pool); |
67 | } | 60 | } |
@@ -106,37 +99,55 @@ unx_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) | |||
106 | * Marshal credentials. | 99 | * Marshal credentials. |
107 | * Maybe we should keep a cached credential for performance reasons. | 100 | * Maybe we should keep a cached credential for performance reasons. |
108 | */ | 101 | */ |
109 | static __be32 * | 102 | static int |
110 | unx_marshal(struct rpc_task *task, __be32 *p) | 103 | unx_marshal(struct rpc_task *task, struct xdr_stream *xdr) |
111 | { | 104 | { |
112 | struct rpc_clnt *clnt = task->tk_client; | 105 | struct rpc_clnt *clnt = task->tk_client; |
113 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 106 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
114 | __be32 *base, *hold; | 107 | __be32 *p, *cred_len, *gidarr_len; |
115 | int i; | 108 | int i; |
116 | struct group_info *gi = cred->cr_cred->group_info; | 109 | struct group_info *gi = cred->cr_cred->group_info; |
117 | 110 | ||
118 | *p++ = htonl(RPC_AUTH_UNIX); | 111 | /* Credential */ |
119 | base = p++; | 112 | |
120 | *p++ = htonl(jiffies/HZ); | 113 | p = xdr_reserve_space(xdr, 3 * sizeof(*p)); |
121 | 114 | if (!p) | |
122 | /* | 115 | goto marshal_failed; |
123 | * Copy the UTS nodename captured when the client was created. | 116 | *p++ = rpc_auth_unix; |
124 | */ | 117 | cred_len = p++; |
125 | p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); | 118 | *p++ = xdr_zero; /* stamp */ |
126 | 119 | if (xdr_stream_encode_opaque(xdr, clnt->cl_nodename, | |
127 | *p++ = htonl((u32) from_kuid(&init_user_ns, cred->cr_cred->fsuid)); | 120 | clnt->cl_nodelen) < 0) |
128 | *p++ = htonl((u32) from_kgid(&init_user_ns, cred->cr_cred->fsgid)); | 121 | goto marshal_failed; |
129 | hold = p++; | 122 | p = xdr_reserve_space(xdr, 3 * sizeof(*p)); |
123 | if (!p) | ||
124 | goto marshal_failed; | ||
125 | *p++ = cpu_to_be32(from_kuid(&init_user_ns, cred->cr_cred->fsuid)); | ||
126 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, cred->cr_cred->fsgid)); | ||
127 | |||
128 | gidarr_len = p++; | ||
130 | if (gi) | 129 | if (gi) |
131 | for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++) | 130 | for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++) |
132 | *p++ = htonl((u32) from_kgid(&init_user_ns, gi->gid[i])); | 131 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, |
133 | *hold = htonl(p - hold - 1); /* gid array length */ | 132 | gi->gid[i])); |
134 | *base = htonl((p - base - 1) << 2); /* cred length */ | 133 | *gidarr_len = cpu_to_be32(p - gidarr_len - 1); |
134 | *cred_len = cpu_to_be32((p - cred_len - 1) << 2); | ||
135 | p = xdr_reserve_space(xdr, (p - gidarr_len - 1) << 2); | ||
136 | if (!p) | ||
137 | goto marshal_failed; | ||
138 | |||
139 | /* Verifier */ | ||
140 | |||
141 | p = xdr_reserve_space(xdr, 2 * sizeof(*p)); | ||
142 | if (!p) | ||
143 | goto marshal_failed; | ||
144 | *p++ = rpc_auth_null; | ||
145 | *p = xdr_zero; | ||
135 | 146 | ||
136 | *p++ = htonl(RPC_AUTH_NULL); | 147 | return 0; |
137 | *p++ = htonl(0); | ||
138 | 148 | ||
139 | return p; | 149 | marshal_failed: |
150 | return -EMSGSIZE; | ||
140 | } | 151 | } |
141 | 152 | ||
142 | /* | 153 | /* |
@@ -149,29 +160,35 @@ unx_refresh(struct rpc_task *task) | |||
149 | return 0; | 160 | return 0; |
150 | } | 161 | } |
151 | 162 | ||
152 | static __be32 * | 163 | static int |
153 | unx_validate(struct rpc_task *task, __be32 *p) | 164 | unx_validate(struct rpc_task *task, struct xdr_stream *xdr) |
154 | { | 165 | { |
155 | rpc_authflavor_t flavor; | 166 | struct rpc_auth *auth = task->tk_rqstp->rq_cred->cr_auth; |
156 | u32 size; | 167 | __be32 *p; |
157 | 168 | u32 size; | |
158 | flavor = ntohl(*p++); | 169 | |
159 | if (flavor != RPC_AUTH_NULL && | 170 | p = xdr_inline_decode(xdr, 2 * sizeof(*p)); |
160 | flavor != RPC_AUTH_UNIX && | 171 | if (!p) |
161 | flavor != RPC_AUTH_SHORT) { | 172 | return -EIO; |
162 | printk("RPC: bad verf flavor: %u\n", flavor); | 173 | switch (*p++) { |
163 | return ERR_PTR(-EIO); | 174 | case rpc_auth_null: |
164 | } | 175 | case rpc_auth_unix: |
165 | 176 | case rpc_auth_short: | |
166 | size = ntohl(*p++); | 177 | break; |
167 | if (size > RPC_MAX_AUTH_SIZE) { | 178 | default: |
168 | printk("RPC: giant verf size: %u\n", size); | 179 | return -EIO; |
169 | return ERR_PTR(-EIO); | ||
170 | } | 180 | } |
171 | task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2; | 181 | size = be32_to_cpup(p); |
172 | p += (size >> 2); | 182 | if (size > RPC_MAX_AUTH_SIZE) |
173 | 183 | return -EIO; | |
174 | return p; | 184 | p = xdr_inline_decode(xdr, size); |
185 | if (!p) | ||
186 | return -EIO; | ||
187 | |||
188 | auth->au_verfsize = XDR_QUADLEN(size) + 2; | ||
189 | auth->au_rslack = XDR_QUADLEN(size) + 2; | ||
190 | auth->au_ralign = XDR_QUADLEN(size) + 2; | ||
191 | return 0; | ||
175 | } | 192 | } |
176 | 193 | ||
177 | int __init rpc_init_authunix(void) | 194 | int __init rpc_init_authunix(void) |
@@ -198,6 +215,7 @@ static | |||
198 | struct rpc_auth unix_auth = { | 215 | struct rpc_auth unix_auth = { |
199 | .au_cslack = UNX_CALLSLACK, | 216 | .au_cslack = UNX_CALLSLACK, |
200 | .au_rslack = NUL_REPLYSLACK, | 217 | .au_rslack = NUL_REPLYSLACK, |
218 | .au_verfsize = NUL_REPLYSLACK, | ||
201 | .au_ops = &authunix_ops, | 219 | .au_ops = &authunix_ops, |
202 | .au_flavor = RPC_AUTH_UNIX, | 220 | .au_flavor = RPC_AUTH_UNIX, |
203 | .au_count = REFCOUNT_INIT(1), | 221 | .au_count = REFCOUNT_INIT(1), |
@@ -209,6 +227,8 @@ const struct rpc_credops unix_credops = { | |||
209 | .crdestroy = unx_destroy_cred, | 227 | .crdestroy = unx_destroy_cred, |
210 | .crmatch = unx_match, | 228 | .crmatch = unx_match, |
211 | .crmarshal = unx_marshal, | 229 | .crmarshal = unx_marshal, |
230 | .crwrap_req = rpcauth_wrap_req_encode, | ||
212 | .crrefresh = unx_refresh, | 231 | .crrefresh = unx_refresh, |
213 | .crvalidate = unx_validate, | 232 | .crvalidate = unx_validate, |
233 | .crunwrap_resp = rpcauth_unwrap_resp_decode, | ||
214 | }; | 234 | }; |