]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - net/sunrpc/auth_gss/auth_gss.c
RPCSEC_GSS: Share rpc_pipes when an rpc_clnt owns multiple rpcsec auth caches
[mirror_ubuntu-focal-kernel.git] / net / sunrpc / auth_gss / auth_gss.c
CommitLineData
1da177e4 1/*
f30c2269 2 * linux/net/sunrpc/auth_gss/auth_gss.c
1da177e4
LT
3 *
4 * RPCSEC_GSS client authentication.
cca5172a 5 *
1da177e4
LT
6 * Copyright (c) 2000 The Regents of the University of Michigan.
7 * All rights reserved.
8 *
9 * Dug Song <dugsong@monkey.org>
10 * Andy Adamson <andros@umich.edu>
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1da177e4
LT
36 */
37
38
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/types.h>
42#include <linux/slab.h>
1da177e4 43#include <linux/sched.h>
2d2da60c 44#include <linux/pagemap.h>
1da177e4
LT
45#include <linux/sunrpc/clnt.h>
46#include <linux/sunrpc/auth.h>
47#include <linux/sunrpc/auth_gss.h>
48#include <linux/sunrpc/svcauth_gss.h>
49#include <linux/sunrpc/gss_err.h>
50#include <linux/workqueue.h>
51#include <linux/sunrpc/rpc_pipe_fs.h>
52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h>
54
abfdbd53
TM
55#include "../netns.h"
56
f1c0a861 57static const struct rpc_authops authgss_ops;
1da177e4 58
f1c0a861 59static const struct rpc_credops gss_credops;
0df7fb74 60static const struct rpc_credops gss_nullops;
1da177e4 61
126e216a
TM
62#define GSS_RETRY_EXPIRED 5
63static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
64
1da177e4
LT
65#ifdef RPC_DEBUG
66# define RPCDBG_FACILITY RPCDBG_AUTH
67#endif
68
725f2865 69#define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2)
1da177e4
LT
70/* length of a krb5 verifier (48), plus data added before arguments when
71 * using integrity (two 4-byte integers): */
adeb8133 72#define GSS_VERF_SLACK 100
1da177e4 73
19172284
TM
74struct gss_pipe {
75 struct rpc_pipe_dir_object pdo;
76 struct rpc_pipe *pipe;
77 struct rpc_clnt *clnt;
78 const char *name;
414a6295 79 struct kref kref;
19172284
TM
80};
81
1da177e4 82struct gss_auth {
0285ed1f 83 struct kref kref;
1da177e4
LT
84 struct rpc_auth rpc_auth;
85 struct gss_api_mech *mech;
86 enum rpc_gss_svc service;
1da177e4 87 struct rpc_clnt *client;
e726340a 88 struct net *net;
34769fc4
BF
89 /*
90 * There are two upcall pipes; dentry[1], named "gssd", is used
91 * for the new text-based upcall; dentry[0] is named after the
92 * mechanism (for example, "krb5") and exists for
93 * backwards-compatibility with older gssd's.
94 */
19172284 95 struct gss_pipe *gss_pipe[2];
bd4a3eb1 96 const char *target_name;
1da177e4
LT
97};
98
79a3f20b 99/* pipe_version >= 0 if and only if someone has a pipe open. */
79a3f20b
BF
100static DEFINE_SPINLOCK(pipe_version_lock);
101static struct rpc_wait_queue pipe_version_rpc_waitqueue;
102static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
cf81939d 103
5d28dc82 104static void gss_free_ctx(struct gss_cl_ctx *);
b693ba4a
TM
105static const struct rpc_pipe_ops gss_upcall_ops_v0;
106static const struct rpc_pipe_ops gss_upcall_ops_v1;
1da177e4 107
1da177e4
LT
108static inline struct gss_cl_ctx *
109gss_get_ctx(struct gss_cl_ctx *ctx)
110{
111 atomic_inc(&ctx->count);
112 return ctx;
113}
114
115static inline void
116gss_put_ctx(struct gss_cl_ctx *ctx)
117{
118 if (atomic_dec_and_test(&ctx->count))
5d28dc82 119 gss_free_ctx(ctx);
1da177e4
LT
120}
121
5d28dc82
TM
122/* gss_cred_set_ctx:
123 * called by gss_upcall_callback and gss_create_upcall in order
124 * to set the gss context. The actual exchange of an old context
9beae467 125 * and a new one is protected by the pipe->lock.
5d28dc82 126 */
1da177e4
LT
127static void
128gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
129{
130 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
5d28dc82 131
cd019f75
TM
132 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
133 return;
7b6962b0 134 gss_get_ctx(ctx);
cf778b00 135 rcu_assign_pointer(gss_cred->gc_ctx, ctx);
fc432dd9 136 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
cd019f75 137 smp_mb__before_clear_bit();
fc432dd9 138 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
1da177e4
LT
139}
140
141static const void *
142simple_get_bytes(const void *p, const void *end, void *res, size_t len)
143{
144 const void *q = (const void *)((const char *)p + len);
145 if (unlikely(q > end || q < p))
146 return ERR_PTR(-EFAULT);
147 memcpy(res, p, len);
148 return q;
149}
150
151static inline const void *
152simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
153{
154 const void *q;
155 unsigned int len;
156
157 p = simple_get_bytes(p, end, &len, sizeof(len));
158 if (IS_ERR(p))
159 return p;
160 q = (const void *)((const char *)p + len);
161 if (unlikely(q > end || q < p))
162 return ERR_PTR(-EFAULT);
0f38b873 163 dest->data = kmemdup(p, len, GFP_NOFS);
1da177e4
LT
164 if (unlikely(dest->data == NULL))
165 return ERR_PTR(-ENOMEM);
166 dest->len = len;
1da177e4
LT
167 return q;
168}
169
170static struct gss_cl_ctx *
171gss_cred_get_ctx(struct rpc_cred *cred)
172{
173 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
174 struct gss_cl_ctx *ctx = NULL;
175
5d28dc82 176 rcu_read_lock();
1da177e4
LT
177 if (gss_cred->gc_ctx)
178 ctx = gss_get_ctx(gss_cred->gc_ctx);
5d28dc82 179 rcu_read_unlock();
1da177e4
LT
180 return ctx;
181}
182
183static struct gss_cl_ctx *
184gss_alloc_context(void)
185{
186 struct gss_cl_ctx *ctx;
187
0f38b873 188 ctx = kzalloc(sizeof(*ctx), GFP_NOFS);
1da177e4 189 if (ctx != NULL) {
1da177e4
LT
190 ctx->gc_proc = RPC_GSS_PROC_DATA;
191 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */
192 spin_lock_init(&ctx->gc_seq_lock);
193 atomic_set(&ctx->count,1);
194 }
195 return ctx;
196}
197
198#define GSSD_MIN_TIMEOUT (60 * 60)
199static const void *
200gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct gss_api_mech *gm)
201{
202 const void *q;
203 unsigned int seclen;
204 unsigned int timeout;
620038f6 205 unsigned long now = jiffies;
1da177e4
LT
206 u32 window_size;
207 int ret;
208
620038f6
AA
209 /* First unsigned int gives the remaining lifetime in seconds of the
210 * credential - e.g. the remaining TGT lifetime for Kerberos or
211 * the -t value passed to GSSD.
212 */
1da177e4
LT
213 p = simple_get_bytes(p, end, &timeout, sizeof(timeout));
214 if (IS_ERR(p))
215 goto err;
216 if (timeout == 0)
217 timeout = GSSD_MIN_TIMEOUT;
620038f6
AA
218 ctx->gc_expiry = now + ((unsigned long)timeout * HZ);
219 /* Sequence number window. Determines the maximum number of
220 * simultaneous requests
221 */
1da177e4
LT
222 p = simple_get_bytes(p, end, &window_size, sizeof(window_size));
223 if (IS_ERR(p))
224 goto err;
225 ctx->gc_win = window_size;
226 /* gssd signals an error by passing ctx->gc_win = 0: */
227 if (ctx->gc_win == 0) {
dc5ddce9
JL
228 /*
229 * in which case, p points to an error code. Anything other
230 * than -EKEYEXPIRED gets converted to -EACCES.
231 */
232 p = simple_get_bytes(p, end, &ret, sizeof(ret));
233 if (!IS_ERR(p))
234 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) :
235 ERR_PTR(-EACCES);
1da177e4
LT
236 goto err;
237 }
238 /* copy the opaque wire context */
239 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx);
240 if (IS_ERR(p))
241 goto err;
242 /* import the opaque security context */
243 p = simple_get_bytes(p, end, &seclen, sizeof(seclen));
244 if (IS_ERR(p))
245 goto err;
246 q = (const void *)((const char *)p + seclen);
247 if (unlikely(q > end || q < p)) {
248 p = ERR_PTR(-EFAULT);
249 goto err;
250 }
400f26b5 251 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS);
1da177e4
LT
252 if (ret < 0) {
253 p = ERR_PTR(ret);
254 goto err;
255 }
620038f6
AA
256 dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u\n",
257 __func__, ctx->gc_expiry, now, timeout);
1da177e4
LT
258 return q;
259err:
173db309 260 dprintk("RPC: %s returns error %ld\n", __func__, -PTR_ERR(p));
1da177e4
LT
261 return p;
262}
263
34769fc4 264#define UPCALL_BUF_LEN 128
1da177e4
LT
265
266struct gss_upcall_msg {
267 atomic_t count;
7eaf040b 268 kuid_t uid;
1da177e4
LT
269 struct rpc_pipe_msg msg;
270 struct list_head list;
271 struct gss_auth *auth;
9beae467 272 struct rpc_pipe *pipe;
1da177e4
LT
273 struct rpc_wait_queue rpc_waitqueue;
274 wait_queue_head_t waitqueue;
275 struct gss_cl_ctx *ctx;
34769fc4 276 char databuf[UPCALL_BUF_LEN];
1da177e4
LT
277};
278
2aed8b47 279static int get_pipe_version(struct net *net)
79a3f20b 280{
2aed8b47 281 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
79a3f20b
BF
282 int ret;
283
284 spin_lock(&pipe_version_lock);
2aed8b47
TM
285 if (sn->pipe_version >= 0) {
286 atomic_inc(&sn->pipe_users);
287 ret = sn->pipe_version;
79a3f20b
BF
288 } else
289 ret = -EAGAIN;
290 spin_unlock(&pipe_version_lock);
291 return ret;
292}
293
2aed8b47 294static void put_pipe_version(struct net *net)
79a3f20b 295{
2aed8b47
TM
296 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
297
298 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) {
299 sn->pipe_version = -1;
79a3f20b
BF
300 spin_unlock(&pipe_version_lock);
301 }
302}
303
1da177e4
LT
304static void
305gss_release_msg(struct gss_upcall_msg *gss_msg)
306{
e726340a 307 struct net *net = gss_msg->auth->net;
1da177e4
LT
308 if (!atomic_dec_and_test(&gss_msg->count))
309 return;
2aed8b47 310 put_pipe_version(net);
1da177e4
LT
311 BUG_ON(!list_empty(&gss_msg->list));
312 if (gss_msg->ctx != NULL)
313 gss_put_ctx(gss_msg->ctx);
f6a1cc89 314 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
1da177e4
LT
315 kfree(gss_msg);
316}
317
318static struct gss_upcall_msg *
7eaf040b 319__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
1da177e4
LT
320{
321 struct gss_upcall_msg *pos;
9beae467 322 list_for_each_entry(pos, &pipe->in_downcall, list) {
0b4d51b0 323 if (!uid_eq(pos->uid, uid))
1da177e4
LT
324 continue;
325 atomic_inc(&pos->count);
632f0d05 326 dprintk("RPC: %s found msg %p\n", __func__, pos);
1da177e4
LT
327 return pos;
328 }
632f0d05 329 dprintk("RPC: %s found nothing\n", __func__);
1da177e4
LT
330 return NULL;
331}
332
720b8f2d 333/* Try to add an upcall to the pipefs queue.
1da177e4
LT
334 * If an upcall owned by our uid already exists, then we return a reference
335 * to that upcall instead of adding the new upcall.
336 */
337static inline struct gss_upcall_msg *
053e324f 338gss_add_msg(struct gss_upcall_msg *gss_msg)
1da177e4 339{
9beae467 340 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4
LT
341 struct gss_upcall_msg *old;
342
9beae467
SK
343 spin_lock(&pipe->lock);
344 old = __gss_find_upcall(pipe, gss_msg->uid);
1da177e4
LT
345 if (old == NULL) {
346 atomic_inc(&gss_msg->count);
9beae467 347 list_add(&gss_msg->list, &pipe->in_downcall);
1da177e4
LT
348 } else
349 gss_msg = old;
9beae467 350 spin_unlock(&pipe->lock);
1da177e4
LT
351 return gss_msg;
352}
353
354static void
355__gss_unhash_msg(struct gss_upcall_msg *gss_msg)
356{
1da177e4
LT
357 list_del_init(&gss_msg->list);
358 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
359 wake_up_all(&gss_msg->waitqueue);
360 atomic_dec(&gss_msg->count);
361}
362
363static void
364gss_unhash_msg(struct gss_upcall_msg *gss_msg)
365{
9beae467 366 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4 367
3b68aaea
TM
368 if (list_empty(&gss_msg->list))
369 return;
9beae467 370 spin_lock(&pipe->lock);
3b68aaea
TM
371 if (!list_empty(&gss_msg->list))
372 __gss_unhash_msg(gss_msg);
9beae467 373 spin_unlock(&pipe->lock);
1da177e4
LT
374}
375
126e216a
TM
376static void
377gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss_msg)
378{
379 switch (gss_msg->msg.errno) {
380 case 0:
381 if (gss_msg->ctx == NULL)
382 break;
383 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
384 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx);
385 break;
386 case -EKEYEXPIRED:
387 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
388 }
389 gss_cred->gc_upcall_timestamp = jiffies;
390 gss_cred->gc_upcall = NULL;
391 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
392}
393
1da177e4
LT
394static void
395gss_upcall_callback(struct rpc_task *task)
396{
a17c2153 397 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
1da177e4
LT
398 struct gss_cred, gc_base);
399 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
9beae467 400 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4 401
9beae467 402 spin_lock(&pipe->lock);
126e216a 403 gss_handle_downcall_result(gss_cred, gss_msg);
9beae467 404 spin_unlock(&pipe->lock);
126e216a 405 task->tk_status = gss_msg->msg.errno;
1da177e4
LT
406 gss_release_msg(gss_msg);
407}
408
34769fc4
BF
409static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
410{
90602c7b
EB
411 uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
412 memcpy(gss_msg->databuf, &uid, sizeof(uid));
413 gss_msg->msg.data = gss_msg->databuf;
414 gss_msg->msg.len = sizeof(uid);
415 BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
34769fc4
BF
416}
417
8b1c7bf5 418static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
bd4a3eb1
TM
419 const char *service_name,
420 const char *target_name)
34769fc4 421{
683ac665 422 struct gss_api_mech *mech = gss_msg->auth->mech;
8b1c7bf5
OK
423 char *p = gss_msg->databuf;
424 int len = 0;
425
426 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
683ac665 427 mech->gm_name,
90602c7b 428 from_kuid(&init_user_ns, gss_msg->uid));
8b1c7bf5 429 p += gss_msg->msg.len;
bd4a3eb1
TM
430 if (target_name) {
431 len = sprintf(p, "target=%s ", target_name);
8b1c7bf5
OK
432 p += len;
433 gss_msg->msg.len += len;
434 }
68c97153
TM
435 if (service_name != NULL) {
436 len = sprintf(p, "service=%s ", service_name);
2efef708
OK
437 p += len;
438 gss_msg->msg.len += len;
439 }
683ac665 440 if (mech->gm_upcall_enctypes) {
f8628220 441 len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes);
683ac665
TM
442 p += len;
443 gss_msg->msg.len += len;
444 }
8b1c7bf5
OK
445 len = sprintf(p, "\n");
446 gss_msg->msg.len += len;
447
34769fc4
BF
448 gss_msg->msg.data = gss_msg->databuf;
449 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
450}
451
68c97153 452static struct gss_upcall_msg *
e726340a 453gss_alloc_msg(struct gss_auth *gss_auth,
7eaf040b 454 kuid_t uid, const char *service_name)
1da177e4
LT
455{
456 struct gss_upcall_msg *gss_msg;
79a3f20b 457 int vers;
1da177e4 458
0f38b873 459 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
db75b3d6
BF
460 if (gss_msg == NULL)
461 return ERR_PTR(-ENOMEM);
e726340a 462 vers = get_pipe_version(gss_auth->net);
79a3f20b
BF
463 if (vers < 0) {
464 kfree(gss_msg);
465 return ERR_PTR(vers);
466 }
19172284 467 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe;
db75b3d6
BF
468 INIT_LIST_HEAD(&gss_msg->list);
469 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
470 init_waitqueue_head(&gss_msg->waitqueue);
471 atomic_set(&gss_msg->count, 1);
db75b3d6
BF
472 gss_msg->uid = uid;
473 gss_msg->auth = gss_auth;
bd4a3eb1
TM
474 switch (vers) {
475 case 0:
476 gss_encode_v0_msg(gss_msg);
477 default:
478 gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
479 };
1da177e4
LT
480 return gss_msg;
481}
482
483static struct gss_upcall_msg *
e726340a 484gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
1da177e4 485{
7c67db3a
TM
486 struct gss_cred *gss_cred = container_of(cred,
487 struct gss_cred, gc_base);
1da177e4 488 struct gss_upcall_msg *gss_new, *gss_msg;
7eaf040b 489 kuid_t uid = cred->cr_uid;
1da177e4 490
e726340a 491 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal);
db75b3d6
BF
492 if (IS_ERR(gss_new))
493 return gss_new;
053e324f 494 gss_msg = gss_add_msg(gss_new);
1da177e4 495 if (gss_msg == gss_new) {
9beae467 496 int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
1da177e4
LT
497 if (res) {
498 gss_unhash_msg(gss_new);
499 gss_msg = ERR_PTR(res);
500 }
501 } else
502 gss_release_msg(gss_new);
503 return gss_msg;
504}
505
b03568c3
BF
506static void warn_gssd(void)
507{
508 static unsigned long ratelimit;
509 unsigned long now = jiffies;
510
511 if (time_after(now, ratelimit)) {
512 printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
513 "Please check user daemon is running.\n");
514 ratelimit = now + 15*HZ;
515 }
516}
517
1da177e4
LT
518static inline int
519gss_refresh_upcall(struct rpc_task *task)
520{
a17c2153 521 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
4a8c1344 522 struct gss_auth *gss_auth = container_of(cred->cr_auth,
1da177e4
LT
523 struct gss_auth, rpc_auth);
524 struct gss_cred *gss_cred = container_of(cred,
525 struct gss_cred, gc_base);
526 struct gss_upcall_msg *gss_msg;
9beae467 527 struct rpc_pipe *pipe;
1da177e4
LT
528 int err = 0;
529
632f0d05 530 dprintk("RPC: %5u %s for uid %u\n",
cdba321e 531 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
e726340a 532 gss_msg = gss_setup_upcall(gss_auth, cred);
480e3243 533 if (PTR_ERR(gss_msg) == -EAGAIN) {
79a3f20b
BF
534 /* XXX: warning on the first, under the assumption we
535 * shouldn't normally hit this case on a refresh. */
536 warn_gssd();
537 task->tk_timeout = 15*HZ;
538 rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
d1a8016a 539 return -EAGAIN;
79a3f20b 540 }
1da177e4
LT
541 if (IS_ERR(gss_msg)) {
542 err = PTR_ERR(gss_msg);
543 goto out;
544 }
9beae467
SK
545 pipe = gss_msg->pipe;
546 spin_lock(&pipe->lock);
1da177e4 547 if (gss_cred->gc_upcall != NULL)
5d00837b 548 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
126e216a 549 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
1da177e4
LT
550 task->tk_timeout = 0;
551 gss_cred->gc_upcall = gss_msg;
552 /* gss_upcall_callback will release the reference to gss_upcall_msg */
553 atomic_inc(&gss_msg->count);
5d00837b 554 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
126e216a
TM
555 } else {
556 gss_handle_downcall_result(gss_cred, gss_msg);
1da177e4 557 err = gss_msg->msg.errno;
126e216a 558 }
9beae467 559 spin_unlock(&pipe->lock);
1da177e4
LT
560 gss_release_msg(gss_msg);
561out:
632f0d05 562 dprintk("RPC: %5u %s for uid %u result %d\n",
cdba321e
EB
563 task->tk_pid, __func__,
564 from_kuid(&init_user_ns, cred->cr_uid), err);
1da177e4
LT
565 return err;
566}
567
568static inline int
569gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
570{
e726340a 571 struct net *net = gss_auth->net;
abfdbd53 572 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
9beae467 573 struct rpc_pipe *pipe;
1da177e4
LT
574 struct rpc_cred *cred = &gss_cred->gc_base;
575 struct gss_upcall_msg *gss_msg;
abfdbd53 576 unsigned long timeout;
1da177e4 577 DEFINE_WAIT(wait);
d36ccb9c 578 int err;
1da177e4 579
cdba321e
EB
580 dprintk("RPC: %s for uid %u\n",
581 __func__, from_kuid(&init_user_ns, cred->cr_uid));
79a3f20b 582retry:
d36ccb9c 583 err = 0;
abfdbd53
TM
584 /* Default timeout is 15s unless we know that gssd is not running */
585 timeout = 15 * HZ;
586 if (!sn->gssd_running)
587 timeout = HZ >> 2;
e726340a 588 gss_msg = gss_setup_upcall(gss_auth, cred);
79a3f20b
BF
589 if (PTR_ERR(gss_msg) == -EAGAIN) {
590 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
2aed8b47
TM
591 sn->pipe_version >= 0, timeout);
592 if (sn->pipe_version < 0) {
abfdbd53
TM
593 if (err == 0)
594 sn->gssd_running = 0;
d1a8016a
BS
595 warn_gssd();
596 err = -EACCES;
597 }
d36ccb9c 598 if (err < 0)
79a3f20b 599 goto out;
79a3f20b
BF
600 goto retry;
601 }
1da177e4
LT
602 if (IS_ERR(gss_msg)) {
603 err = PTR_ERR(gss_msg);
604 goto out;
605 }
9beae467 606 pipe = gss_msg->pipe;
1da177e4 607 for (;;) {
5afa9133 608 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE);
9beae467 609 spin_lock(&pipe->lock);
1da177e4 610 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
1da177e4
LT
611 break;
612 }
9beae467 613 spin_unlock(&pipe->lock);
5afa9133 614 if (fatal_signal_pending(current)) {
1da177e4
LT
615 err = -ERESTARTSYS;
616 goto out_intr;
617 }
618 schedule();
619 }
620 if (gss_msg->ctx)
7b6962b0 621 gss_cred_set_ctx(cred, gss_msg->ctx);
1da177e4
LT
622 else
623 err = gss_msg->msg.errno;
9beae467 624 spin_unlock(&pipe->lock);
1da177e4
LT
625out_intr:
626 finish_wait(&gss_msg->waitqueue, &wait);
627 gss_release_msg(gss_msg);
628out:
632f0d05 629 dprintk("RPC: %s for uid %u result %d\n",
cdba321e 630 __func__, from_kuid(&init_user_ns, cred->cr_uid), err);
1da177e4
LT
631 return err;
632}
633
1da177e4
LT
634#define MSG_BUF_MAXSIZE 1024
635
636static ssize_t
637gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
638{
639 const void *p, *end;
640 void *buf;
1da177e4 641 struct gss_upcall_msg *gss_msg;
496ad9aa 642 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe;
1da177e4 643 struct gss_cl_ctx *ctx;
90602c7b
EB
644 uid_t id;
645 kuid_t uid;
3b68aaea 646 ssize_t err = -EFBIG;
1da177e4
LT
647
648 if (mlen > MSG_BUF_MAXSIZE)
649 goto out;
650 err = -ENOMEM;
0f38b873 651 buf = kmalloc(mlen, GFP_NOFS);
1da177e4
LT
652 if (!buf)
653 goto out;
654
1da177e4
LT
655 err = -EFAULT;
656 if (copy_from_user(buf, src, mlen))
657 goto err;
658
659 end = (const void *)((char *)buf + mlen);
90602c7b 660 p = simple_get_bytes(buf, end, &id, sizeof(id));
1da177e4
LT
661 if (IS_ERR(p)) {
662 err = PTR_ERR(p);
663 goto err;
664 }
665
90602c7b
EB
666 uid = make_kuid(&init_user_ns, id);
667 if (!uid_valid(uid)) {
668 err = -EINVAL;
669 goto err;
670 }
671
1da177e4
LT
672 err = -ENOMEM;
673 ctx = gss_alloc_context();
674 if (ctx == NULL)
675 goto err;
3b68aaea
TM
676
677 err = -ENOENT;
678 /* Find a matching upcall */
9beae467
SK
679 spin_lock(&pipe->lock);
680 gss_msg = __gss_find_upcall(pipe, uid);
3b68aaea 681 if (gss_msg == NULL) {
9beae467 682 spin_unlock(&pipe->lock);
3b68aaea
TM
683 goto err_put_ctx;
684 }
685 list_del_init(&gss_msg->list);
9beae467 686 spin_unlock(&pipe->lock);
3b68aaea 687
6e84c7b6 688 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
1da177e4
LT
689 if (IS_ERR(p)) {
690 err = PTR_ERR(p);
486bad2e
JL
691 switch (err) {
692 case -EACCES:
dc5ddce9 693 case -EKEYEXPIRED:
486bad2e
JL
694 gss_msg->msg.errno = err;
695 err = mlen;
696 break;
697 case -EFAULT:
698 case -ENOMEM:
699 case -EINVAL:
700 case -ENOSYS:
701 gss_msg->msg.errno = -EAGAIN;
702 break;
703 default:
704 printk(KERN_CRIT "%s: bad return from "
6c853099 705 "gss_fill_context: %zd\n", __func__, err);
486bad2e
JL
706 BUG();
707 }
3b68aaea 708 goto err_release_msg;
1da177e4 709 }
3b68aaea
TM
710 gss_msg->ctx = gss_get_ctx(ctx);
711 err = mlen;
712
713err_release_msg:
9beae467 714 spin_lock(&pipe->lock);
3b68aaea 715 __gss_unhash_msg(gss_msg);
9beae467 716 spin_unlock(&pipe->lock);
3b68aaea 717 gss_release_msg(gss_msg);
1da177e4
LT
718err_put_ctx:
719 gss_put_ctx(ctx);
720err:
721 kfree(buf);
722out:
632f0d05 723 dprintk("RPC: %s returning %Zd\n", __func__, err);
1da177e4
LT
724 return err;
725}
726
34769fc4 727static int gss_pipe_open(struct inode *inode, int new_version)
cf81939d 728{
2aed8b47
TM
729 struct net *net = inode->i_sb->s_fs_info;
730 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
34769fc4
BF
731 int ret = 0;
732
79a3f20b 733 spin_lock(&pipe_version_lock);
2aed8b47 734 if (sn->pipe_version < 0) {
34769fc4 735 /* First open of any gss pipe determines the version: */
2aed8b47 736 sn->pipe_version = new_version;
79a3f20b
BF
737 rpc_wake_up(&pipe_version_rpc_waitqueue);
738 wake_up(&pipe_version_waitqueue);
2aed8b47 739 } else if (sn->pipe_version != new_version) {
34769fc4
BF
740 /* Trying to open a pipe of a different version */
741 ret = -EBUSY;
742 goto out;
79a3f20b 743 }
2aed8b47 744 atomic_inc(&sn->pipe_users);
34769fc4 745out:
79a3f20b 746 spin_unlock(&pipe_version_lock);
34769fc4
BF
747 return ret;
748
749}
750
751static int gss_pipe_open_v0(struct inode *inode)
752{
753 return gss_pipe_open(inode, 0);
754}
755
756static int gss_pipe_open_v1(struct inode *inode)
757{
758 return gss_pipe_open(inode, 1);
cf81939d
BF
759}
760
1da177e4
LT
761static void
762gss_pipe_release(struct inode *inode)
763{
2aed8b47 764 struct net *net = inode->i_sb->s_fs_info;
9beae467 765 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
6e84c7b6 766 struct gss_upcall_msg *gss_msg;
1da177e4 767
5a67657a 768restart:
9beae467
SK
769 spin_lock(&pipe->lock);
770 list_for_each_entry(gss_msg, &pipe->in_downcall, list) {
1da177e4 771
5a67657a
TM
772 if (!list_empty(&gss_msg->msg.list))
773 continue;
1da177e4
LT
774 gss_msg->msg.errno = -EPIPE;
775 atomic_inc(&gss_msg->count);
776 __gss_unhash_msg(gss_msg);
9beae467 777 spin_unlock(&pipe->lock);
1da177e4 778 gss_release_msg(gss_msg);
5a67657a 779 goto restart;
1da177e4 780 }
9beae467 781 spin_unlock(&pipe->lock);
cf81939d 782
2aed8b47 783 put_pipe_version(net);
1da177e4
LT
784}
785
786static void
787gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
788{
789 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
1da177e4
LT
790
791 if (msg->errno < 0) {
632f0d05
CL
792 dprintk("RPC: %s releasing msg %p\n",
793 __func__, gss_msg);
1da177e4
LT
794 atomic_inc(&gss_msg->count);
795 gss_unhash_msg(gss_msg);
b03568c3
BF
796 if (msg->errno == -ETIMEDOUT)
797 warn_gssd();
1da177e4
LT
798 gss_release_msg(gss_msg);
799 }
800}
801
19172284
TM
802static void gss_pipe_dentry_destroy(struct dentry *dir,
803 struct rpc_pipe_dir_object *pdo)
ccdc28f8 804{
19172284
TM
805 struct gss_pipe *gss_pipe = pdo->pdo_data;
806 struct rpc_pipe *pipe = gss_pipe->pipe;
ccdc28f8 807
19172284
TM
808 if (pipe->dentry != NULL) {
809 rpc_unlink(pipe->dentry);
810 pipe->dentry = NULL;
6b2fddd3 811 }
ccdc28f8
SK
812}
813
19172284
TM
814static int gss_pipe_dentry_create(struct dentry *dir,
815 struct rpc_pipe_dir_object *pdo)
ccdc28f8 816{
19172284 817 struct gss_pipe *p = pdo->pdo_data;
6b2fddd3 818 struct dentry *dentry;
ccdc28f8 819
19172284
TM
820 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
821 if (IS_ERR(dentry))
822 return PTR_ERR(dentry);
823 p->pipe->dentry = dentry;
824 return 0;
825}
826
827static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = {
828 .create = gss_pipe_dentry_create,
829 .destroy = gss_pipe_dentry_destroy,
830};
831
832static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt,
833 const char *name,
834 const struct rpc_pipe_ops *upcall_ops)
835{
19172284
TM
836 struct gss_pipe *p;
837 int err = -ENOMEM;
ccdc28f8 838
19172284
TM
839 p = kmalloc(sizeof(*p), GFP_KERNEL);
840 if (p == NULL)
6b2fddd3 841 goto err;
19172284
TM
842 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
843 if (IS_ERR(p->pipe)) {
844 err = PTR_ERR(p->pipe);
845 goto err_free_gss_pipe;
6b2fddd3 846 }
19172284
TM
847 p->name = name;
848 p->clnt = clnt;
414a6295 849 kref_init(&p->kref);
19172284
TM
850 rpc_init_pipe_dir_object(&p->pdo,
851 &gss_pipe_dir_object_ops,
852 p);
414a6295 853 return p;
19172284
TM
854err_free_gss_pipe:
855 kfree(p);
6b2fddd3 856err:
19172284 857 return ERR_PTR(err);
ccdc28f8
SK
858}
859
414a6295
TM
860struct gss_alloc_pdo {
861 struct rpc_clnt *clnt;
862 const char *name;
863 const struct rpc_pipe_ops *upcall_ops;
864};
865
866static int gss_pipe_match_pdo(struct rpc_pipe_dir_object *pdo, void *data)
867{
868 struct gss_pipe *gss_pipe;
869 struct gss_alloc_pdo *args = data;
870
871 if (pdo->pdo_ops != &gss_pipe_dir_object_ops)
872 return 0;
873 gss_pipe = container_of(pdo, struct gss_pipe, pdo);
874 if (strcmp(gss_pipe->name, args->name) != 0)
875 return 0;
876 if (!kref_get_unless_zero(&gss_pipe->kref))
877 return 0;
878 return 1;
879}
880
881static struct rpc_pipe_dir_object *gss_pipe_alloc_pdo(void *data)
882{
883 struct gss_pipe *gss_pipe;
884 struct gss_alloc_pdo *args = data;
885
886 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops);
887 if (!IS_ERR(gss_pipe))
888 return &gss_pipe->pdo;
889 return NULL;
890}
891
892static struct gss_pipe *gss_pipe_get(struct rpc_clnt *clnt,
893 const char *name,
894 const struct rpc_pipe_ops *upcall_ops)
895{
896 struct net *net = rpc_net_ns(clnt);
897 struct rpc_pipe_dir_object *pdo;
898 struct gss_alloc_pdo args = {
899 .clnt = clnt,
900 .name = name,
901 .upcall_ops = upcall_ops,
902 };
903
904 pdo = rpc_find_or_alloc_pipe_dir_object(net,
905 &clnt->cl_pipedir_objects,
906 gss_pipe_match_pdo,
907 gss_pipe_alloc_pdo,
908 &args);
909 if (pdo != NULL)
910 return container_of(pdo, struct gss_pipe, pdo);
911 return ERR_PTR(-ENOMEM);
912}
913
19172284 914static void __gss_pipe_free(struct gss_pipe *p)
ccdc28f8 915{
19172284
TM
916 struct rpc_clnt *clnt = p->clnt;
917 struct net *net = rpc_net_ns(clnt);
ccdc28f8 918
19172284
TM
919 rpc_remove_pipe_dir_object(net,
920 &clnt->cl_pipedir_objects,
921 &p->pdo);
922 rpc_destroy_pipe_data(p->pipe);
923 kfree(p);
ccdc28f8
SK
924}
925
414a6295
TM
926static void __gss_pipe_release(struct kref *kref)
927{
928 struct gss_pipe *p = container_of(kref, struct gss_pipe, kref);
929
930 __gss_pipe_free(p);
931}
932
19172284 933static void gss_pipe_free(struct gss_pipe *p)
ccdc28f8 934{
19172284 935 if (p != NULL)
414a6295 936 kref_put(&p->kref, __gss_pipe_release);
ccdc28f8
SK
937}
938
cca5172a
YH
939/*
940 * NOTE: we have the opportunity to use different
1da177e4
LT
941 * parameters based on the input flavor (which must be a pseudoflavor)
942 */
943static struct rpc_auth *
c2190661 944gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1da177e4 945{
c2190661 946 rpc_authflavor_t flavor = args->pseudoflavor;
1da177e4 947 struct gss_auth *gss_auth;
19172284 948 struct gss_pipe *gss_pipe;
1da177e4 949 struct rpc_auth * auth;
6a19275a 950 int err = -ENOMEM; /* XXX? */
1da177e4 951
8885cb36 952 dprintk("RPC: creating GSS authenticator for client %p\n", clnt);
1da177e4
LT
953
954 if (!try_module_get(THIS_MODULE))
6a19275a 955 return ERR_PTR(err);
1da177e4
LT
956 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
957 goto out_dec;
bd4a3eb1 958 gss_auth->target_name = NULL;
c2190661
TM
959 if (args->target_name) {
960 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL);
bd4a3eb1
TM
961 if (gss_auth->target_name == NULL)
962 goto err_free;
963 }
1da177e4 964 gss_auth->client = clnt;
e726340a 965 gss_auth->net = get_net(rpc_net_ns(clnt));
6a19275a 966 err = -EINVAL;
1da177e4
LT
967 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
968 if (!gss_auth->mech) {
9b1d75b7 969 dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
e726340a 970 goto err_put_net;
1da177e4
LT
971 }
972 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
438b6fde
BF
973 if (gss_auth->service == 0)
974 goto err_put_mech;
1da177e4
LT
975 auth = &gss_auth->rpc_auth;
976 auth->au_cslack = GSS_CRED_SLACK >> 2;
977 auth->au_rslack = GSS_VERF_SLACK >> 2;
978 auth->au_ops = &authgss_ops;
979 auth->au_flavor = flavor;
980 atomic_set(&auth->au_count, 1);
0285ed1f 981 kref_init(&gss_auth->kref);
1da177e4 982
19172284
TM
983 err = rpcauth_init_credcache(auth);
984 if (err)
985 goto err_put_mech;
34769fc4
BF
986 /*
987 * Note: if we created the old pipe first, then someone who
988 * examined the directory at the right moment might conclude
989 * that we supported only the old pipe. So we instead create
990 * the new pipe first.
991 */
414a6295 992 gss_pipe = gss_pipe_get(clnt, "gssd", &gss_upcall_ops_v1);
19172284
TM
993 if (IS_ERR(gss_pipe)) {
994 err = PTR_ERR(gss_pipe);
995 goto err_destroy_credcache;
6a19275a 996 }
19172284 997 gss_auth->gss_pipe[1] = gss_pipe;
1da177e4 998
414a6295 999 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name,
19172284
TM
1000 &gss_upcall_ops_v0);
1001 if (IS_ERR(gss_pipe)) {
1002 err = PTR_ERR(gss_pipe);
c239d83b
SK
1003 goto err_destroy_pipe_1;
1004 }
19172284 1005 gss_auth->gss_pipe[0] = gss_pipe;
07a2bf1d 1006
1da177e4 1007 return auth;
c239d83b 1008err_destroy_pipe_1:
414a6295 1009 gss_pipe_free(gss_auth->gss_pipe[1]);
19172284
TM
1010err_destroy_credcache:
1011 rpcauth_destroy_credcache(auth);
1da177e4
LT
1012err_put_mech:
1013 gss_mech_put(gss_auth->mech);
e726340a
TM
1014err_put_net:
1015 put_net(gss_auth->net);
1da177e4 1016err_free:
bd4a3eb1 1017 kfree(gss_auth->target_name);
1da177e4
LT
1018 kfree(gss_auth);
1019out_dec:
1020 module_put(THIS_MODULE);
6a19275a 1021 return ERR_PTR(err);
1da177e4
LT
1022}
1023
0285ed1f
TM
1024static void
1025gss_free(struct gss_auth *gss_auth)
1026{
19172284
TM
1027 gss_pipe_free(gss_auth->gss_pipe[0]);
1028 gss_pipe_free(gss_auth->gss_pipe[1]);
0285ed1f 1029 gss_mech_put(gss_auth->mech);
e726340a 1030 put_net(gss_auth->net);
bd4a3eb1 1031 kfree(gss_auth->target_name);
0285ed1f
TM
1032
1033 kfree(gss_auth);
1034 module_put(THIS_MODULE);
1035}
1036
1037static void
1038gss_free_callback(struct kref *kref)
1039{
1040 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
1041
1042 gss_free(gss_auth);
1043}
1044
1da177e4
LT
1045static void
1046gss_destroy(struct rpc_auth *auth)
1047{
19172284
TM
1048 struct gss_auth *gss_auth = container_of(auth,
1049 struct gss_auth, rpc_auth);
1da177e4 1050
8885cb36
CL
1051 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
1052 auth, auth->au_flavor);
1da177e4 1053
19172284
TM
1054 gss_pipe_free(gss_auth->gss_pipe[0]);
1055 gss_auth->gss_pipe[0] = NULL;
1056 gss_pipe_free(gss_auth->gss_pipe[1]);
1057 gss_auth->gss_pipe[1] = NULL;
3ab9bb72
TM
1058 rpcauth_destroy_credcache(auth);
1059
0285ed1f 1060 kref_put(&gss_auth->kref, gss_free_callback);
1da177e4
LT
1061}
1062
0df7fb74
TM
1063/*
1064 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
1065 * to the server with the GSS control procedure field set to
1066 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
1067 * all RPCSEC_GSS state associated with that context.
1068 */
1069static int
1070gss_destroying_context(struct rpc_cred *cred)
1071{
1072 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
1073 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
1074 struct rpc_task *task;
1075
1076 if (gss_cred->gc_ctx == NULL ||
6dcd3926 1077 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
0df7fb74
TM
1078 return 0;
1079
1080 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
1081 cred->cr_ops = &gss_nullops;
1082
1083 /* Take a reference to ensure the cred will be destroyed either
1084 * by the RPC call or by the put_rpccred() below */
1085 get_rpccred(cred);
1086
080a1f14 1087 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
0df7fb74
TM
1088 if (!IS_ERR(task))
1089 rpc_put_task(task);
1090
1091 put_rpccred(cred);
1092 return 1;
1093}
1094
1095/* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
1da177e4
LT
1096 * to create a new cred or context, so they check that things have been
1097 * allocated before freeing them. */
1098static void
5d28dc82 1099gss_do_free_ctx(struct gss_cl_ctx *ctx)
1da177e4 1100{
632f0d05 1101 dprintk("RPC: %s\n", __func__);
1da177e4 1102
0d8a3746 1103 gss_delete_sec_context(&ctx->gc_gss_ctx);
1da177e4
LT
1104 kfree(ctx->gc_wire_ctx.data);
1105 kfree(ctx);
1106}
1107
5d28dc82
TM
1108static void
1109gss_free_ctx_callback(struct rcu_head *head)
1110{
1111 struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu);
1112 gss_do_free_ctx(ctx);
1113}
1114
1115static void
1116gss_free_ctx(struct gss_cl_ctx *ctx)
1117{
1118 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
1119}
1120
1da177e4 1121static void
31be5bf1 1122gss_free_cred(struct gss_cred *gss_cred)
1da177e4 1123{
632f0d05 1124 dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
31be5bf1
TM
1125 kfree(gss_cred);
1126}
1da177e4 1127
31be5bf1
TM
1128static void
1129gss_free_cred_callback(struct rcu_head *head)
1130{
1131 struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
1132 gss_free_cred(gss_cred);
1133}
1da177e4 1134
31be5bf1 1135static void
6dcd3926 1136gss_destroy_nullcred(struct rpc_cred *cred)
31be5bf1 1137{
5d28dc82 1138 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
0285ed1f 1139 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
5d28dc82
TM
1140 struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
1141
a9b3cd7f 1142 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
31be5bf1 1143 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
5d28dc82
TM
1144 if (ctx)
1145 gss_put_ctx(ctx);
0285ed1f 1146 kref_put(&gss_auth->kref, gss_free_callback);
1da177e4
LT
1147}
1148
6dcd3926
JL
1149static void
1150gss_destroy_cred(struct rpc_cred *cred)
1151{
1152
1153 if (gss_destroying_context(cred))
1154 return;
1155 gss_destroy_nullcred(cred);
1156}
1157
1da177e4
LT
1158/*
1159 * Lookup RPCSEC_GSS cred for the current process
1160 */
1161static struct rpc_cred *
8a317760 1162gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1da177e4 1163{
8a317760 1164 return rpcauth_lookup_credcache(auth, acred, flags);
1da177e4
LT
1165}
1166
1167static struct rpc_cred *
8a317760 1168gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1da177e4
LT
1169{
1170 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1171 struct gss_cred *cred = NULL;
1172 int err = -ENOMEM;
1173
632f0d05 1174 dprintk("RPC: %s for uid %d, flavor %d\n",
cdba321e
EB
1175 __func__, from_kuid(&init_user_ns, acred->uid),
1176 auth->au_flavor);
1da177e4 1177
0f38b873 1178 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
1da177e4
LT
1179 goto out_err;
1180
5fe4755e 1181 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
1da177e4
LT
1182 /*
1183 * Note: in order to force a call to call_refresh(), we deliberately
1184 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
1185 */
fc432dd9 1186 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
1da177e4 1187 cred->gc_service = gss_auth->service;
68c97153
TM
1188 cred->gc_principal = NULL;
1189 if (acred->machine_cred)
1190 cred->gc_principal = acred->principal;
0285ed1f 1191 kref_get(&gss_auth->kref);
1da177e4
LT
1192 return &cred->gc_base;
1193
1194out_err:
632f0d05 1195 dprintk("RPC: %s failed with error %d\n", __func__, err);
1da177e4
LT
1196 return ERR_PTR(err);
1197}
1198
fba3bad4
TM
1199static int
1200gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
1201{
1202 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1203 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
1204 int err;
1205
1206 do {
1207 err = gss_create_upcall(gss_auth, gss_cred);
1208 } while (err == -EAGAIN);
1209 return err;
1210}
1211
1da177e4 1212static int
8a317760 1213gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
1da177e4
LT
1214{
1215 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1216
cd019f75 1217 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
8a317760 1218 goto out;
1da177e4 1219 /* Don't match with creds that have expired. */
cd019f75
TM
1220 if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
1221 return 0;
1222 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags))
1da177e4 1223 return 0;
8a317760 1224out:
68c97153
TM
1225 if (acred->principal != NULL) {
1226 if (gss_cred->gc_principal == NULL)
1227 return 0;
1228 return strcmp(acred->principal, gss_cred->gc_principal) == 0;
1229 }
1230 if (gss_cred->gc_principal != NULL)
7c67db3a 1231 return 0;
0b4d51b0 1232 return uid_eq(rc->cr_uid, acred->uid);
1da177e4
LT
1233}
1234
1235/*
1236* Marshal credentials.
1237* Maybe we should keep a cached credential for performance reasons.
1238*/
d8ed029d
AD
1239static __be32 *
1240gss_marshal(struct rpc_task *task, __be32 *p)
1da177e4 1241{
a17c2153
TM
1242 struct rpc_rqst *req = task->tk_rqstp;
1243 struct rpc_cred *cred = req->rq_cred;
1da177e4
LT
1244 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1245 gc_base);
1246 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1247 __be32 *cred_len;
1da177e4
LT
1248 u32 maj_stat = 0;
1249 struct xdr_netobj mic;
1250 struct kvec iov;
1251 struct xdr_buf verf_buf;
1252
632f0d05 1253 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1254
1255 *p++ = htonl(RPC_AUTH_GSS);
1256 cred_len = p++;
1257
1258 spin_lock(&ctx->gc_seq_lock);
1259 req->rq_seqno = ctx->gc_seq++;
1260 spin_unlock(&ctx->gc_seq_lock);
1261
1262 *p++ = htonl((u32) RPC_GSS_VERSION);
1263 *p++ = htonl((u32) ctx->gc_proc);
1264 *p++ = htonl((u32) req->rq_seqno);
1265 *p++ = htonl((u32) gss_cred->gc_service);
1266 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
1267 *cred_len = htonl((p - (cred_len + 1)) << 2);
1268
1269 /* We compute the checksum for the verifier over the xdr-encoded bytes
1270 * starting with the xid and ending at the end of the credential: */
a4f0835c 1271 iov.iov_base = xprt_skip_transport_header(req->rq_xprt,
808012fb 1272 req->rq_snd_buf.head[0].iov_base);
1da177e4
LT
1273 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
1274 xdr_buf_from_iov(&iov, &verf_buf);
1275
1276 /* set verifier flavor*/
1277 *p++ = htonl(RPC_AUTH_GSS);
1278
1279 mic.data = (u8 *)(p + 1);
00fd6e14 1280 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1da177e4 1281 if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
fc432dd9 1282 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1283 } else if (maj_stat != 0) {
1284 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1285 goto out_put_ctx;
1286 }
1287 p = xdr_encode_opaque(p, NULL, mic.len);
1288 gss_put_ctx(ctx);
1289 return p;
1290out_put_ctx:
1291 gss_put_ctx(ctx);
1292 return NULL;
1293}
1294
cd019f75
TM
1295static int gss_renew_cred(struct rpc_task *task)
1296{
a17c2153 1297 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
cd019f75
TM
1298 struct gss_cred *gss_cred = container_of(oldcred,
1299 struct gss_cred,
1300 gc_base);
1301 struct rpc_auth *auth = oldcred->cr_auth;
1302 struct auth_cred acred = {
1303 .uid = oldcred->cr_uid,
68c97153
TM
1304 .principal = gss_cred->gc_principal,
1305 .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
cd019f75
TM
1306 };
1307 struct rpc_cred *new;
1308
1309 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
1310 if (IS_ERR(new))
1311 return PTR_ERR(new);
a17c2153 1312 task->tk_rqstp->rq_cred = new;
cd019f75
TM
1313 put_rpccred(oldcred);
1314 return 0;
1315}
1316
126e216a
TM
1317static int gss_cred_is_negative_entry(struct rpc_cred *cred)
1318{
1319 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
1320 unsigned long now = jiffies;
1321 unsigned long begin, expire;
1322 struct gss_cred *gss_cred;
1323
1324 gss_cred = container_of(cred, struct gss_cred, gc_base);
1325 begin = gss_cred->gc_upcall_timestamp;
1326 expire = begin + gss_expired_cred_retry_delay * HZ;
1327
1328 if (time_in_range_open(now, begin, expire))
1329 return 1;
1330 }
1331 return 0;
1332}
1333
1da177e4
LT
1334/*
1335* Refresh credentials. XXX - finish
1336*/
1337static int
1338gss_refresh(struct rpc_task *task)
1339{
a17c2153 1340 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
cd019f75
TM
1341 int ret = 0;
1342
126e216a
TM
1343 if (gss_cred_is_negative_entry(cred))
1344 return -EKEYEXPIRED;
1345
cd019f75
TM
1346 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
1347 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
1348 ret = gss_renew_cred(task);
1349 if (ret < 0)
1350 goto out;
a17c2153 1351 cred = task->tk_rqstp->rq_cred;
cd019f75 1352 }
1da177e4 1353
cd019f75
TM
1354 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
1355 ret = gss_refresh_upcall(task);
1356out:
1357 return ret;
1da177e4
LT
1358}
1359
0df7fb74
TM
1360/* Dummy refresh routine: used only when destroying the context */
1361static int
1362gss_refresh_null(struct rpc_task *task)
1363{
1364 return -EACCES;
1365}
1366
d8ed029d
AD
1367static __be32 *
1368gss_validate(struct rpc_task *task, __be32 *p)
1da177e4 1369{
a17c2153 1370 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4 1371 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1372 __be32 seq;
1da177e4
LT
1373 struct kvec iov;
1374 struct xdr_buf verf_buf;
1375 struct xdr_netobj mic;
1376 u32 flav,len;
1377 u32 maj_stat;
1378
632f0d05 1379 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1380
1381 flav = ntohl(*p++);
1382 if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
cca5172a 1383 goto out_bad;
1da177e4
LT
1384 if (flav != RPC_AUTH_GSS)
1385 goto out_bad;
1386 seq = htonl(task->tk_rqstp->rq_seqno);
1387 iov.iov_base = &seq;
1388 iov.iov_len = sizeof(seq);
1389 xdr_buf_from_iov(&iov, &verf_buf);
1390 mic.data = (u8 *)p;
1391 mic.len = len;
1392
00fd6e14 1393 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1da177e4 1394 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1395 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
0df7fb74 1396 if (maj_stat) {
632f0d05
CL
1397 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
1398 task->tk_pid, __func__, maj_stat);
1da177e4 1399 goto out_bad;
0df7fb74 1400 }
24b2605b
BF
1401 /* We leave it to unwrap to calculate au_rslack. For now we just
1402 * calculate the length of the verifier: */
1be27f36 1403 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1da177e4 1404 gss_put_ctx(ctx);
632f0d05
CL
1405 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1406 task->tk_pid, __func__);
1da177e4
LT
1407 return p + XDR_QUADLEN(len);
1408out_bad:
1409 gss_put_ctx(ctx);
632f0d05 1410 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
1da177e4
LT
1411 return NULL;
1412}
1413
9f06c719
CL
1414static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
1415 __be32 *p, void *obj)
1416{
1417 struct xdr_stream xdr;
1418
1419 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p);
1420 encode(rqstp, &xdr, obj);
1421}
1422
1da177e4
LT
1423static inline int
1424gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
9f06c719
CL
1425 kxdreproc_t encode, struct rpc_rqst *rqstp,
1426 __be32 *p, void *obj)
1da177e4
LT
1427{
1428 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1429 struct xdr_buf integ_buf;
d8ed029d 1430 __be32 *integ_len = NULL;
1da177e4 1431 struct xdr_netobj mic;
d8ed029d
AD
1432 u32 offset;
1433 __be32 *q;
1da177e4
LT
1434 struct kvec *iov;
1435 u32 maj_stat = 0;
1436 int status = -EIO;
1437
1438 integ_len = p++;
1439 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1440 *p++ = htonl(rqstp->rq_seqno);
1441
9f06c719 1442 gss_wrap_req_encode(encode, rqstp, p, obj);
1da177e4
LT
1443
1444 if (xdr_buf_subsegment(snd_buf, &integ_buf,
1445 offset, snd_buf->len - offset))
1446 return status;
1447 *integ_len = htonl(integ_buf.len);
1448
1449 /* guess whether we're in the head or the tail: */
cca5172a 1450 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1da177e4
LT
1451 iov = snd_buf->tail;
1452 else
1453 iov = snd_buf->head;
1454 p = iov->iov_base + iov->iov_len;
1455 mic.data = (u8 *)(p + 1);
1456
00fd6e14 1457 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1da177e4
LT
1458 status = -EIO; /* XXX? */
1459 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1460 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1461 else if (maj_stat)
1462 return status;
1463 q = xdr_encode_opaque(p, NULL, mic.len);
1464
1465 offset = (u8 *)q - (u8 *)p;
1466 iov->iov_len += offset;
1467 snd_buf->len += offset;
1468 return 0;
1469}
1470
2d2da60c
BF
1471static void
1472priv_release_snd_buf(struct rpc_rqst *rqstp)
1473{
1474 int i;
1475
1476 for (i=0; i < rqstp->rq_enc_pages_num; i++)
1477 __free_page(rqstp->rq_enc_pages[i]);
1478 kfree(rqstp->rq_enc_pages);
1479}
1480
1481static int
1482alloc_enc_pages(struct rpc_rqst *rqstp)
1483{
1484 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1485 int first, last, i;
1486
1487 if (snd_buf->page_len == 0) {
1488 rqstp->rq_enc_pages_num = 0;
1489 return 0;
1490 }
1491
1492 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1493 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
1494 rqstp->rq_enc_pages_num = last - first + 1 + 1;
1495 rqstp->rq_enc_pages
1496 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
1497 GFP_NOFS);
1498 if (!rqstp->rq_enc_pages)
1499 goto out;
1500 for (i=0; i < rqstp->rq_enc_pages_num; i++) {
1501 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
1502 if (rqstp->rq_enc_pages[i] == NULL)
1503 goto out_free;
1504 }
1505 rqstp->rq_release_snd_buf = priv_release_snd_buf;
1506 return 0;
1507out_free:
cdead7cf
TM
1508 rqstp->rq_enc_pages_num = i;
1509 priv_release_snd_buf(rqstp);
2d2da60c
BF
1510out:
1511 return -EAGAIN;
1512}
1513
1514static inline int
1515gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
9f06c719
CL
1516 kxdreproc_t encode, struct rpc_rqst *rqstp,
1517 __be32 *p, void *obj)
2d2da60c
BF
1518{
1519 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1520 u32 offset;
1521 u32 maj_stat;
1522 int status;
d8ed029d 1523 __be32 *opaque_len;
2d2da60c
BF
1524 struct page **inpages;
1525 int first;
1526 int pad;
1527 struct kvec *iov;
1528 char *tmp;
1529
1530 opaque_len = p++;
1531 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1532 *p++ = htonl(rqstp->rq_seqno);
1533
9f06c719 1534 gss_wrap_req_encode(encode, rqstp, p, obj);
2d2da60c
BF
1535
1536 status = alloc_enc_pages(rqstp);
1537 if (status)
1538 return status;
1539 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1540 inpages = snd_buf->pages + first;
1541 snd_buf->pages = rqstp->rq_enc_pages;
1542 snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
7561042f
KC
1543 /*
1544 * Give the tail its own page, in case we need extra space in the
1545 * head when wrapping:
1546 *
1547 * call_allocate() allocates twice the slack space required
1548 * by the authentication flavor to rq_callsize.
1549 * For GSS, slack is GSS_CRED_SLACK.
1550 */
2d2da60c
BF
1551 if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1552 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
1553 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
1554 snd_buf->tail[0].iov_base = tmp;
1555 }
00fd6e14 1556 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
7561042f 1557 /* slack space should prevent this ever happening: */
2d2da60c 1558 BUG_ON(snd_buf->len > snd_buf->buflen);
cca5172a 1559 status = -EIO;
2d2da60c
BF
1560 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1561 * done anyway, so it's safe to put the request on the wire: */
1562 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1563 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
2d2da60c
BF
1564 else if (maj_stat)
1565 return status;
1566
1567 *opaque_len = htonl(snd_buf->len - offset);
1568 /* guess whether we're in the head or the tail: */
1569 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1570 iov = snd_buf->tail;
1571 else
1572 iov = snd_buf->head;
1573 p = iov->iov_base + iov->iov_len;
1574 pad = 3 - ((snd_buf->len - offset - 1) & 3);
1575 memset(p, 0, pad);
1576 iov->iov_len += pad;
1577 snd_buf->len += pad;
1578
1579 return 0;
1580}
1581
1da177e4
LT
1582static int
1583gss_wrap_req(struct rpc_task *task,
9f06c719 1584 kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
1da177e4 1585{
a17c2153 1586 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4
LT
1587 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1588 gc_base);
1589 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1590 int status = -EIO;
1591
632f0d05 1592 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1593 if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
1594 /* The spec seems a little ambiguous here, but I think that not
1595 * wrapping context destruction requests makes the most sense.
1596 */
9f06c719
CL
1597 gss_wrap_req_encode(encode, rqstp, p, obj);
1598 status = 0;
1da177e4
LT
1599 goto out;
1600 }
1601 switch (gss_cred->gc_service) {
89f0e4fe
JP
1602 case RPC_GSS_SVC_NONE:
1603 gss_wrap_req_encode(encode, rqstp, p, obj);
1604 status = 0;
1605 break;
1606 case RPC_GSS_SVC_INTEGRITY:
1607 status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj);
1608 break;
1609 case RPC_GSS_SVC_PRIVACY:
1610 status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj);
1611 break;
1da177e4
LT
1612 }
1613out:
1614 gss_put_ctx(ctx);
632f0d05 1615 dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
1da177e4
LT
1616 return status;
1617}
1618
1619static inline int
1620gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
d8ed029d 1621 struct rpc_rqst *rqstp, __be32 **p)
1da177e4
LT
1622{
1623 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1624 struct xdr_buf integ_buf;
1625 struct xdr_netobj mic;
1626 u32 data_offset, mic_offset;
1627 u32 integ_len;
1628 u32 maj_stat;
1629 int status = -EIO;
1630
1631 integ_len = ntohl(*(*p)++);
1632 if (integ_len & 3)
1633 return status;
1634 data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1635 mic_offset = integ_len + data_offset;
1636 if (mic_offset > rcv_buf->len)
1637 return status;
1638 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1639 return status;
1640
1641 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1642 mic_offset - data_offset))
1643 return status;
1644
1645 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1646 return status;
1647
00fd6e14 1648 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1da177e4 1649 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1650 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1651 if (maj_stat != GSS_S_COMPLETE)
1652 return status;
1653 return 0;
1654}
1655
2d2da60c
BF
1656static inline int
1657gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
d8ed029d 1658 struct rpc_rqst *rqstp, __be32 **p)
2d2da60c
BF
1659{
1660 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1661 u32 offset;
1662 u32 opaque_len;
1663 u32 maj_stat;
1664 int status = -EIO;
1665
1666 opaque_len = ntohl(*(*p)++);
1667 offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1668 if (offset + opaque_len > rcv_buf->len)
1669 return status;
1670 /* remove padding: */
1671 rcv_buf->len = offset + opaque_len;
1672
00fd6e14 1673 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
2d2da60c 1674 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1675 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
2d2da60c
BF
1676 if (maj_stat != GSS_S_COMPLETE)
1677 return status;
1678 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1679 return status;
1680
1681 return 0;
1682}
1683
bf269551
CL
1684static int
1685gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
1686 __be32 *p, void *obj)
1687{
1688 struct xdr_stream xdr;
1689
1690 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
1691 return decode(rqstp, &xdr, obj);
1692}
2d2da60c 1693
1da177e4
LT
1694static int
1695gss_unwrap_resp(struct rpc_task *task,
bf269551 1696 kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
1da177e4 1697{
a17c2153 1698 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4
LT
1699 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1700 gc_base);
1701 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1702 __be32 *savedp = p;
2d2da60c
BF
1703 struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1704 int savedlen = head->iov_len;
1da177e4
LT
1705 int status = -EIO;
1706
1707 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
1708 goto out_decode;
1709 switch (gss_cred->gc_service) {
89f0e4fe
JP
1710 case RPC_GSS_SVC_NONE:
1711 break;
1712 case RPC_GSS_SVC_INTEGRITY:
1713 status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1714 if (status)
1715 goto out;
1716 break;
1717 case RPC_GSS_SVC_PRIVACY:
1718 status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1719 if (status)
1720 goto out;
1721 break;
1da177e4 1722 }
24b2605b 1723 /* take into account extra slack for integrity and privacy cases: */
1be27f36 1724 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
2d2da60c 1725 + (savedlen - head->iov_len);
1da177e4 1726out_decode:
bf269551 1727 status = gss_unwrap_req_decode(decode, rqstp, p, obj);
1da177e4
LT
1728out:
1729 gss_put_ctx(ctx);
632f0d05
CL
1730 dprintk("RPC: %5u %s returning %d\n",
1731 task->tk_pid, __func__, status);
1da177e4
LT
1732 return status;
1733}
cca5172a 1734
f1c0a861 1735static const struct rpc_authops authgss_ops = {
1da177e4
LT
1736 .owner = THIS_MODULE,
1737 .au_flavor = RPC_AUTH_GSS,
1da177e4 1738 .au_name = "RPCSEC_GSS",
1da177e4
LT
1739 .create = gss_create,
1740 .destroy = gss_destroy,
1741 .lookup_cred = gss_lookup_cred,
80df9d20 1742 .crcreate = gss_create_cred,
6a1a1e34 1743 .list_pseudoflavors = gss_mech_list_pseudoflavors,
9568c5e9 1744 .info2flavor = gss_mech_info2flavor,
a77c806f 1745 .flavor2info = gss_mech_flavor2info,
1da177e4
LT
1746};
1747
f1c0a861 1748static const struct rpc_credops gss_credops = {
1da177e4
LT
1749 .cr_name = "AUTH_GSS",
1750 .crdestroy = gss_destroy_cred,
fba3bad4 1751 .cr_init = gss_cred_init,
5c691044 1752 .crbind = rpcauth_generic_bind_cred,
1da177e4
LT
1753 .crmatch = gss_match,
1754 .crmarshal = gss_marshal,
1755 .crrefresh = gss_refresh,
1756 .crvalidate = gss_validate,
1757 .crwrap_req = gss_wrap_req,
1758 .crunwrap_resp = gss_unwrap_resp,
1759};
1760
0df7fb74
TM
1761static const struct rpc_credops gss_nullops = {
1762 .cr_name = "AUTH_GSS",
6dcd3926 1763 .crdestroy = gss_destroy_nullcred,
5c691044 1764 .crbind = rpcauth_generic_bind_cred,
0df7fb74
TM
1765 .crmatch = gss_match,
1766 .crmarshal = gss_marshal,
1767 .crrefresh = gss_refresh_null,
1768 .crvalidate = gss_validate,
1769 .crwrap_req = gss_wrap_req,
1770 .crunwrap_resp = gss_unwrap_resp,
1771};
1772
b693ba4a 1773static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
c1225158 1774 .upcall = rpc_pipe_generic_upcall,
34769fc4
BF
1775 .downcall = gss_pipe_downcall,
1776 .destroy_msg = gss_pipe_destroy_msg,
1777 .open_pipe = gss_pipe_open_v0,
1778 .release_pipe = gss_pipe_release,
1779};
1780
b693ba4a 1781static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
c1225158 1782 .upcall = rpc_pipe_generic_upcall,
1da177e4
LT
1783 .downcall = gss_pipe_downcall,
1784 .destroy_msg = gss_pipe_destroy_msg,
34769fc4 1785 .open_pipe = gss_pipe_open_v1,
1da177e4
LT
1786 .release_pipe = gss_pipe_release,
1787};
1788
a1db410d
SK
1789static __net_init int rpcsec_gss_init_net(struct net *net)
1790{
1791 return gss_svc_init_net(net);
1792}
1793
1794static __net_exit void rpcsec_gss_exit_net(struct net *net)
1795{
1796 gss_svc_shutdown_net(net);
1797}
1798
1799static struct pernet_operations rpcsec_gss_net_ops = {
1800 .init = rpcsec_gss_init_net,
1801 .exit = rpcsec_gss_exit_net,
1802};
1803
1da177e4
LT
1804/*
1805 * Initialize RPCSEC_GSS module
1806 */
1807static int __init init_rpcsec_gss(void)
1808{
1809 int err = 0;
1810
1811 err = rpcauth_register(&authgss_ops);
1812 if (err)
1813 goto out;
1814 err = gss_svc_init();
1815 if (err)
1816 goto out_unregister;
a1db410d
SK
1817 err = register_pernet_subsys(&rpcsec_gss_net_ops);
1818 if (err)
1819 goto out_svc_exit;
79a3f20b 1820 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
1da177e4 1821 return 0;
a1db410d
SK
1822out_svc_exit:
1823 gss_svc_shutdown();
1da177e4
LT
1824out_unregister:
1825 rpcauth_unregister(&authgss_ops);
1826out:
1827 return err;
1828}
1829
1830static void __exit exit_rpcsec_gss(void)
1831{
a1db410d 1832 unregister_pernet_subsys(&rpcsec_gss_net_ops);
1da177e4
LT
1833 gss_svc_shutdown();
1834 rpcauth_unregister(&authgss_ops);
bf12691d 1835 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1da177e4
LT
1836}
1837
71afa85e 1838MODULE_ALIAS("rpc-auth-6");
1da177e4 1839MODULE_LICENSE("GPL");
126e216a
TM
1840module_param_named(expired_cred_retry_delay,
1841 gss_expired_cred_retry_delay,
1842 uint, 0644);
1843MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until "
1844 "the RPC engine retries an expired credential");
1845
1da177e4
LT
1846module_init(init_rpcsec_gss)
1847module_exit(exit_rpcsec_gss)