SUNRPC: Make rpc_mkpipe() take the parent dentry as an argument
[linux-2.6] / net / sunrpc / auth_gss / auth_gss.c
1 /*
2  * linux/net/sunrpc/auth_gss.c
3  *
4  * RPCSEC_GSS client authentication.
5  * 
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.
36  *
37  * $Id$
38  */
39
40
41 #include <linux/module.h>
42 #include <linux/init.h>
43 #include <linux/types.h>
44 #include <linux/slab.h>
45 #include <linux/sched.h>
46 #include <linux/pagemap.h>
47 #include <linux/sunrpc/clnt.h>
48 #include <linux/sunrpc/auth.h>
49 #include <linux/sunrpc/auth_gss.h>
50 #include <linux/sunrpc/svcauth_gss.h>
51 #include <linux/sunrpc/gss_err.h>
52 #include <linux/workqueue.h>
53 #include <linux/sunrpc/rpc_pipe_fs.h>
54 #include <linux/sunrpc/gss_api.h>
55 #include <asm/uaccess.h>
56
57 static struct rpc_authops authgss_ops;
58
59 static struct rpc_credops gss_credops;
60
61 #ifdef RPC_DEBUG
62 # define RPCDBG_FACILITY        RPCDBG_AUTH
63 #endif
64
65 #define NFS_NGROUPS     16
66
67 #define GSS_CRED_EXPIRE         (60 * HZ)       /* XXX: reasonable? */
68 #define GSS_CRED_SLACK          1024            /* XXX: unused */
69 /* length of a krb5 verifier (48), plus data added before arguments when
70  * using integrity (two 4-byte integers): */
71 #define GSS_VERF_SLACK          56
72
73 /* XXX this define must match the gssd define
74 * as it is passed to gssd to signal the use of
75 * machine creds should be part of the shared rpc interface */
76
77 #define CA_RUN_AS_MACHINE  0x00000200 
78
79 /* dump the buffer in `emacs-hexl' style */
80 #define isprint(c)      ((c > 0x1f) && (c < 0x7f))
81
82 static DEFINE_RWLOCK(gss_ctx_lock);
83
84 struct gss_auth {
85         struct rpc_auth rpc_auth;
86         struct gss_api_mech *mech;
87         enum rpc_gss_svc service;
88         struct list_head upcalls;
89         struct rpc_clnt *client;
90         struct dentry *dentry;
91         spinlock_t lock;
92 };
93
94 static void gss_destroy_ctx(struct gss_cl_ctx *);
95 static struct rpc_pipe_ops gss_upcall_ops;
96
97 void
98 print_hexl(u32 *p, u_int length, u_int offset)
99 {
100         u_int i, j, jm;
101         u8 c, *cp;
102         
103         dprintk("RPC: print_hexl: length %d\n",length);
104         dprintk("\n");
105         cp = (u8 *) p;
106         
107         for (i = 0; i < length; i += 0x10) {
108                 dprintk("  %04x: ", (u_int)(i + offset));
109                 jm = length - i;
110                 jm = jm > 16 ? 16 : jm;
111                 
112                 for (j = 0; j < jm; j++) {
113                         if ((j % 2) == 1)
114                                 dprintk("%02x ", (u_int)cp[i+j]);
115                         else
116                                 dprintk("%02x", (u_int)cp[i+j]);
117                 }
118                 for (; j < 16; j++) {
119                         if ((j % 2) == 1)
120                                 dprintk("   ");
121                         else
122                                 dprintk("  ");
123                 }
124                 dprintk(" ");
125                 
126                 for (j = 0; j < jm; j++) {
127                         c = cp[i+j];
128                         c = isprint(c) ? c : '.';
129                         dprintk("%c", c);
130                 }
131                 dprintk("\n");
132         }
133 }
134
135 EXPORT_SYMBOL(print_hexl);
136
137 static inline struct gss_cl_ctx *
138 gss_get_ctx(struct gss_cl_ctx *ctx)
139 {
140         atomic_inc(&ctx->count);
141         return ctx;
142 }
143
144 static inline void
145 gss_put_ctx(struct gss_cl_ctx *ctx)
146 {
147         if (atomic_dec_and_test(&ctx->count))
148                 gss_destroy_ctx(ctx);
149 }
150
151 static void
152 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
153 {
154         struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
155         struct gss_cl_ctx *old;
156         write_lock(&gss_ctx_lock);
157         old = gss_cred->gc_ctx;
158         gss_cred->gc_ctx = ctx;
159         cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
160         cred->cr_flags &= ~RPCAUTH_CRED_NEW;
161         write_unlock(&gss_ctx_lock);
162         if (old)
163                 gss_put_ctx(old);
164 }
165
166 static int
167 gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
168 {
169         struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
170         int res = 0;
171
172         read_lock(&gss_ctx_lock);
173         if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx)
174                 res = 1;
175         read_unlock(&gss_ctx_lock);
176         return res;
177 }
178
179 static const void *
180 simple_get_bytes(const void *p, const void *end, void *res, size_t len)
181 {
182         const void *q = (const void *)((const char *)p + len);
183         if (unlikely(q > end || q < p))
184                 return ERR_PTR(-EFAULT);
185         memcpy(res, p, len);
186         return q;
187 }
188
189 static inline const void *
190 simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
191 {
192         const void *q;
193         unsigned int len;
194
195         p = simple_get_bytes(p, end, &len, sizeof(len));
196         if (IS_ERR(p))
197                 return p;
198         q = (const void *)((const char *)p + len);
199         if (unlikely(q > end || q < p))
200                 return ERR_PTR(-EFAULT);
201         dest->data = kmalloc(len, GFP_KERNEL);
202         if (unlikely(dest->data == NULL))
203                 return ERR_PTR(-ENOMEM);
204         dest->len = len;
205         memcpy(dest->data, p, len);
206         return q;
207 }
208
209 static struct gss_cl_ctx *
210 gss_cred_get_ctx(struct rpc_cred *cred)
211 {
212         struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
213         struct gss_cl_ctx *ctx = NULL;
214
215         read_lock(&gss_ctx_lock);
216         if (gss_cred->gc_ctx)
217                 ctx = gss_get_ctx(gss_cred->gc_ctx);
218         read_unlock(&gss_ctx_lock);
219         return ctx;
220 }
221
222 static struct gss_cl_ctx *
223 gss_alloc_context(void)
224 {
225         struct gss_cl_ctx *ctx;
226
227         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
228         if (ctx != NULL) {
229                 ctx->gc_proc = RPC_GSS_PROC_DATA;
230                 ctx->gc_seq = 1;        /* NetApp 6.4R1 doesn't accept seq. no. 0 */
231                 spin_lock_init(&ctx->gc_seq_lock);
232                 atomic_set(&ctx->count,1);
233         }
234         return ctx;
235 }
236
237 #define GSSD_MIN_TIMEOUT (60 * 60)
238 static const void *
239 gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct gss_api_mech *gm)
240 {
241         const void *q;
242         unsigned int seclen;
243         unsigned int timeout;
244         u32 window_size;
245         int ret;
246
247         /* First unsigned int gives the lifetime (in seconds) of the cred */
248         p = simple_get_bytes(p, end, &timeout, sizeof(timeout));
249         if (IS_ERR(p))
250                 goto err;
251         if (timeout == 0)
252                 timeout = GSSD_MIN_TIMEOUT;
253         ctx->gc_expiry = jiffies + (unsigned long)timeout * HZ * 3 / 4;
254         /* Sequence number window. Determines the maximum number of simultaneous requests */
255         p = simple_get_bytes(p, end, &window_size, sizeof(window_size));
256         if (IS_ERR(p))
257                 goto err;
258         ctx->gc_win = window_size;
259         /* gssd signals an error by passing ctx->gc_win = 0: */
260         if (ctx->gc_win == 0) {
261                 /* in which case, p points to  an error code which we ignore */
262                 p = ERR_PTR(-EACCES);
263                 goto err;
264         }
265         /* copy the opaque wire context */
266         p = simple_get_netobj(p, end, &ctx->gc_wire_ctx);
267         if (IS_ERR(p))
268                 goto err;
269         /* import the opaque security context */
270         p  = simple_get_bytes(p, end, &seclen, sizeof(seclen));
271         if (IS_ERR(p))
272                 goto err;
273         q = (const void *)((const char *)p + seclen);
274         if (unlikely(q > end || q < p)) {
275                 p = ERR_PTR(-EFAULT);
276                 goto err;
277         }
278         ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx);
279         if (ret < 0) {
280                 p = ERR_PTR(ret);
281                 goto err;
282         }
283         return q;
284 err:
285         dprintk("RPC:      gss_fill_context returning %ld\n", -PTR_ERR(p));
286         return p;
287 }
288
289
290 struct gss_upcall_msg {
291         atomic_t count;
292         uid_t   uid;
293         struct rpc_pipe_msg msg;
294         struct list_head list;
295         struct gss_auth *auth;
296         struct rpc_wait_queue rpc_waitqueue;
297         wait_queue_head_t waitqueue;
298         struct gss_cl_ctx *ctx;
299 };
300
301 static void
302 gss_release_msg(struct gss_upcall_msg *gss_msg)
303 {
304         if (!atomic_dec_and_test(&gss_msg->count))
305                 return;
306         BUG_ON(!list_empty(&gss_msg->list));
307         if (gss_msg->ctx != NULL)
308                 gss_put_ctx(gss_msg->ctx);
309         kfree(gss_msg);
310 }
311
312 static struct gss_upcall_msg *
313 __gss_find_upcall(struct gss_auth *gss_auth, uid_t uid)
314 {
315         struct gss_upcall_msg *pos;
316         list_for_each_entry(pos, &gss_auth->upcalls, list) {
317                 if (pos->uid != uid)
318                         continue;
319                 atomic_inc(&pos->count);
320                 dprintk("RPC:      gss_find_upcall found msg %p\n", pos);
321                 return pos;
322         }
323         dprintk("RPC:      gss_find_upcall found nothing\n");
324         return NULL;
325 }
326
327 /* Try to add a upcall to the pipefs queue.
328  * If an upcall owned by our uid already exists, then we return a reference
329  * to that upcall instead of adding the new upcall.
330  */
331 static inline struct gss_upcall_msg *
332 gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg)
333 {
334         struct gss_upcall_msg *old;
335
336         spin_lock(&gss_auth->lock);
337         old = __gss_find_upcall(gss_auth, gss_msg->uid);
338         if (old == NULL) {
339                 atomic_inc(&gss_msg->count);
340                 list_add(&gss_msg->list, &gss_auth->upcalls);
341         } else
342                 gss_msg = old;
343         spin_unlock(&gss_auth->lock);
344         return gss_msg;
345 }
346
347 static void
348 __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
349 {
350         if (list_empty(&gss_msg->list))
351                 return;
352         list_del_init(&gss_msg->list);
353         rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
354         wake_up_all(&gss_msg->waitqueue);
355         atomic_dec(&gss_msg->count);
356 }
357
358 static void
359 gss_unhash_msg(struct gss_upcall_msg *gss_msg)
360 {
361         struct gss_auth *gss_auth = gss_msg->auth;
362
363         spin_lock(&gss_auth->lock);
364         __gss_unhash_msg(gss_msg);
365         spin_unlock(&gss_auth->lock);
366 }
367
368 static void
369 gss_upcall_callback(struct rpc_task *task)
370 {
371         struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred,
372                         struct gss_cred, gc_base);
373         struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
374
375         BUG_ON(gss_msg == NULL);
376         if (gss_msg->ctx)
377                 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx));
378         else
379                 task->tk_status = gss_msg->msg.errno;
380         spin_lock(&gss_msg->auth->lock);
381         gss_cred->gc_upcall = NULL;
382         rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
383         spin_unlock(&gss_msg->auth->lock);
384         gss_release_msg(gss_msg);
385 }
386
387 static inline struct gss_upcall_msg *
388 gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
389 {
390         struct gss_upcall_msg *gss_msg;
391
392         gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL);
393         if (gss_msg != NULL) {
394                 INIT_LIST_HEAD(&gss_msg->list);
395                 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
396                 init_waitqueue_head(&gss_msg->waitqueue);
397                 atomic_set(&gss_msg->count, 1);
398                 gss_msg->msg.data = &gss_msg->uid;
399                 gss_msg->msg.len = sizeof(gss_msg->uid);
400                 gss_msg->uid = uid;
401                 gss_msg->auth = gss_auth;
402         }
403         return gss_msg;
404 }
405
406 static struct gss_upcall_msg *
407 gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cred *cred)
408 {
409         struct gss_upcall_msg *gss_new, *gss_msg;
410
411         gss_new = gss_alloc_msg(gss_auth, cred->cr_uid);
412         if (gss_new == NULL)
413                 return ERR_PTR(-ENOMEM);
414         gss_msg = gss_add_msg(gss_auth, gss_new);
415         if (gss_msg == gss_new) {
416                 int res = rpc_queue_upcall(gss_auth->dentry->d_inode, &gss_new->msg);
417                 if (res) {
418                         gss_unhash_msg(gss_new);
419                         gss_msg = ERR_PTR(res);
420                 }
421         } else
422                 gss_release_msg(gss_new);
423         return gss_msg;
424 }
425
426 static inline int
427 gss_refresh_upcall(struct rpc_task *task)
428 {
429         struct rpc_cred *cred = task->tk_msg.rpc_cred;
430         struct gss_auth *gss_auth = container_of(task->tk_client->cl_auth,
431                         struct gss_auth, rpc_auth);
432         struct gss_cred *gss_cred = container_of(cred,
433                         struct gss_cred, gc_base);
434         struct gss_upcall_msg *gss_msg;
435         int err = 0;
436
437         dprintk("RPC: %4u gss_refresh_upcall for uid %u\n", task->tk_pid, cred->cr_uid);
438         gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
439         if (IS_ERR(gss_msg)) {
440                 err = PTR_ERR(gss_msg);
441                 goto out;
442         }
443         spin_lock(&gss_auth->lock);
444         if (gss_cred->gc_upcall != NULL)
445                 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL);
446         else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
447                 task->tk_timeout = 0;
448                 gss_cred->gc_upcall = gss_msg;
449                 /* gss_upcall_callback will release the reference to gss_upcall_msg */
450                 atomic_inc(&gss_msg->count);
451                 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL);
452         } else
453                 err = gss_msg->msg.errno;
454         spin_unlock(&gss_auth->lock);
455         gss_release_msg(gss_msg);
456 out:
457         dprintk("RPC: %4u gss_refresh_upcall for uid %u result %d\n", task->tk_pid,
458                         cred->cr_uid, err);
459         return err;
460 }
461
462 static inline int
463 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
464 {
465         struct rpc_cred *cred = &gss_cred->gc_base;
466         struct gss_upcall_msg *gss_msg;
467         DEFINE_WAIT(wait);
468         int err = 0;
469
470         dprintk("RPC: gss_upcall for uid %u\n", cred->cr_uid);
471         gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
472         if (IS_ERR(gss_msg)) {
473                 err = PTR_ERR(gss_msg);
474                 goto out;
475         }
476         for (;;) {
477                 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE);
478                 spin_lock(&gss_auth->lock);
479                 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
480                         spin_unlock(&gss_auth->lock);
481                         break;
482                 }
483                 spin_unlock(&gss_auth->lock);
484                 if (signalled()) {
485                         err = -ERESTARTSYS;
486                         goto out_intr;
487                 }
488                 schedule();
489         }
490         if (gss_msg->ctx)
491                 gss_cred_set_ctx(cred, gss_get_ctx(gss_msg->ctx));
492         else
493                 err = gss_msg->msg.errno;
494 out_intr:
495         finish_wait(&gss_msg->waitqueue, &wait);
496         gss_release_msg(gss_msg);
497 out:
498         dprintk("RPC: gss_create_upcall for uid %u result %d\n", cred->cr_uid, err);
499         return err;
500 }
501
502 static ssize_t
503 gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
504                 char __user *dst, size_t buflen)
505 {
506         char *data = (char *)msg->data + msg->copied;
507         ssize_t mlen = msg->len;
508         ssize_t left;
509
510         if (mlen > buflen)
511                 mlen = buflen;
512         left = copy_to_user(dst, data, mlen);
513         if (left < 0) {
514                 msg->errno = left;
515                 return left;
516         }
517         mlen -= left;
518         msg->copied += mlen;
519         msg->errno = 0;
520         return mlen;
521 }
522
523 #define MSG_BUF_MAXSIZE 1024
524
525 static ssize_t
526 gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
527 {
528         const void *p, *end;
529         void *buf;
530         struct rpc_clnt *clnt;
531         struct gss_auth *gss_auth;
532         struct rpc_cred *cred;
533         struct gss_upcall_msg *gss_msg;
534         struct gss_cl_ctx *ctx;
535         uid_t uid;
536         int err = -EFBIG;
537
538         if (mlen > MSG_BUF_MAXSIZE)
539                 goto out;
540         err = -ENOMEM;
541         buf = kmalloc(mlen, GFP_KERNEL);
542         if (!buf)
543                 goto out;
544
545         clnt = RPC_I(filp->f_dentry->d_inode)->private;
546         err = -EFAULT;
547         if (copy_from_user(buf, src, mlen))
548                 goto err;
549
550         end = (const void *)((char *)buf + mlen);
551         p = simple_get_bytes(buf, end, &uid, sizeof(uid));
552         if (IS_ERR(p)) {
553                 err = PTR_ERR(p);
554                 goto err;
555         }
556
557         err = -ENOMEM;
558         ctx = gss_alloc_context();
559         if (ctx == NULL)
560                 goto err;
561         err = 0;
562         gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth);
563         p = gss_fill_context(p, end, ctx, gss_auth->mech);
564         if (IS_ERR(p)) {
565                 err = PTR_ERR(p);
566                 if (err != -EACCES)
567                         goto err_put_ctx;
568         }
569         spin_lock(&gss_auth->lock);
570         gss_msg = __gss_find_upcall(gss_auth, uid);
571         if (gss_msg) {
572                 if (err == 0 && gss_msg->ctx == NULL)
573                         gss_msg->ctx = gss_get_ctx(ctx);
574                 gss_msg->msg.errno = err;
575                 __gss_unhash_msg(gss_msg);
576                 spin_unlock(&gss_auth->lock);
577                 gss_release_msg(gss_msg);
578         } else {
579                 struct auth_cred acred = { .uid = uid };
580                 spin_unlock(&gss_auth->lock);
581                 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
582                 if (IS_ERR(cred)) {
583                         err = PTR_ERR(cred);
584                         goto err_put_ctx;
585                 }
586                 gss_cred_set_ctx(cred, gss_get_ctx(ctx));
587         }
588         gss_put_ctx(ctx);
589         kfree(buf);
590         dprintk("RPC:      gss_pipe_downcall returning length %Zu\n", mlen);
591         return mlen;
592 err_put_ctx:
593         gss_put_ctx(ctx);
594 err:
595         kfree(buf);
596 out:
597         dprintk("RPC:      gss_pipe_downcall returning %d\n", err);
598         return err;
599 }
600
601 static void
602 gss_pipe_release(struct inode *inode)
603 {
604         struct rpc_inode *rpci = RPC_I(inode);
605         struct rpc_clnt *clnt;
606         struct rpc_auth *auth;
607         struct gss_auth *gss_auth;
608
609         clnt = rpci->private;
610         auth = clnt->cl_auth;
611         gss_auth = container_of(auth, struct gss_auth, rpc_auth);
612         spin_lock(&gss_auth->lock);
613         while (!list_empty(&gss_auth->upcalls)) {
614                 struct gss_upcall_msg *gss_msg;
615
616                 gss_msg = list_entry(gss_auth->upcalls.next,
617                                 struct gss_upcall_msg, list);
618                 gss_msg->msg.errno = -EPIPE;
619                 atomic_inc(&gss_msg->count);
620                 __gss_unhash_msg(gss_msg);
621                 spin_unlock(&gss_auth->lock);
622                 gss_release_msg(gss_msg);
623                 spin_lock(&gss_auth->lock);
624         }
625         spin_unlock(&gss_auth->lock);
626 }
627
628 static void
629 gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
630 {
631         struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
632         static unsigned long ratelimit;
633
634         if (msg->errno < 0) {
635                 dprintk("RPC:      gss_pipe_destroy_msg releasing msg %p\n",
636                                 gss_msg);
637                 atomic_inc(&gss_msg->count);
638                 gss_unhash_msg(gss_msg);
639                 if (msg->errno == -ETIMEDOUT) {
640                         unsigned long now = jiffies;
641                         if (time_after(now, ratelimit)) {
642                                 printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
643                                                     "Please check user daemon is running!\n");
644                                 ratelimit = now + 15*HZ;
645                         }
646                 }
647                 gss_release_msg(gss_msg);
648         }
649 }
650
651 /* 
652  * NOTE: we have the opportunity to use different 
653  * parameters based on the input flavor (which must be a pseudoflavor)
654  */
655 static struct rpc_auth *
656 gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
657 {
658         struct gss_auth *gss_auth;
659         struct rpc_auth * auth;
660         int err = -ENOMEM; /* XXX? */
661
662         dprintk("RPC:      creating GSS authenticator for client %p\n",clnt);
663
664         if (!try_module_get(THIS_MODULE))
665                 return ERR_PTR(err);
666         if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
667                 goto out_dec;
668         gss_auth->client = clnt;
669         err = -EINVAL;
670         gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
671         if (!gss_auth->mech) {
672                 printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
673                                 __FUNCTION__, flavor);
674                 goto err_free;
675         }
676         gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
677         if (gss_auth->service == 0)
678                 goto err_put_mech;
679         INIT_LIST_HEAD(&gss_auth->upcalls);
680         spin_lock_init(&gss_auth->lock);
681         auth = &gss_auth->rpc_auth;
682         auth->au_cslack = GSS_CRED_SLACK >> 2;
683         auth->au_rslack = GSS_VERF_SLACK >> 2;
684         auth->au_ops = &authgss_ops;
685         auth->au_flavor = flavor;
686         atomic_set(&auth->au_count, 1);
687
688         err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
689         if (err)
690                 goto err_put_mech;
691
692         gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
693                         clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
694         if (IS_ERR(gss_auth->dentry)) {
695                 err = PTR_ERR(gss_auth->dentry);
696                 goto err_put_mech;
697         }
698
699         return auth;
700 err_put_mech:
701         gss_mech_put(gss_auth->mech);
702 err_free:
703         kfree(gss_auth);
704 out_dec:
705         module_put(THIS_MODULE);
706         return ERR_PTR(err);
707 }
708
709 static void
710 gss_destroy(struct rpc_auth *auth)
711 {
712         struct gss_auth *gss_auth;
713
714         dprintk("RPC:      destroying GSS authenticator %p flavor %d\n",
715                 auth, auth->au_flavor);
716
717         gss_auth = container_of(auth, struct gss_auth, rpc_auth);
718         rpc_unlink(gss_auth->dentry);
719         gss_auth->dentry = NULL;
720         gss_mech_put(gss_auth->mech);
721
722         rpcauth_free_credcache(auth);
723         kfree(gss_auth);
724         module_put(THIS_MODULE);
725 }
726
727 /* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure
728  * to create a new cred or context, so they check that things have been
729  * allocated before freeing them. */
730 static void
731 gss_destroy_ctx(struct gss_cl_ctx *ctx)
732 {
733         dprintk("RPC:      gss_destroy_ctx\n");
734
735         if (ctx->gc_gss_ctx)
736                 gss_delete_sec_context(&ctx->gc_gss_ctx);
737
738         kfree(ctx->gc_wire_ctx.data);
739         kfree(ctx);
740 }
741
742 static void
743 gss_destroy_cred(struct rpc_cred *rc)
744 {
745         struct gss_cred *cred = container_of(rc, struct gss_cred, gc_base);
746
747         dprintk("RPC:      gss_destroy_cred \n");
748
749         if (cred->gc_ctx)
750                 gss_put_ctx(cred->gc_ctx);
751         kfree(cred);
752 }
753
754 /*
755  * Lookup RPCSEC_GSS cred for the current process
756  */
757 static struct rpc_cred *
758 gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
759 {
760         return rpcauth_lookup_credcache(auth, acred, flags);
761 }
762
763 static struct rpc_cred *
764 gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
765 {
766         struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
767         struct gss_cred *cred = NULL;
768         int err = -ENOMEM;
769
770         dprintk("RPC:      gss_create_cred for uid %d, flavor %d\n",
771                 acred->uid, auth->au_flavor);
772
773         if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL)))
774                 goto out_err;
775
776         atomic_set(&cred->gc_count, 1);
777         cred->gc_uid = acred->uid;
778         /*
779          * Note: in order to force a call to call_refresh(), we deliberately
780          * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
781          */
782         cred->gc_flags = 0;
783         cred->gc_base.cr_ops = &gss_credops;
784         cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
785         cred->gc_service = gss_auth->service;
786         return &cred->gc_base;
787
788 out_err:
789         dprintk("RPC:      gss_create_cred failed with error %d\n", err);
790         return ERR_PTR(err);
791 }
792
793 static int
794 gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
795 {
796         struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
797         struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
798         int err;
799
800         do {
801                 err = gss_create_upcall(gss_auth, gss_cred);
802         } while (err == -EAGAIN);
803         return err;
804 }
805
806 static int
807 gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
808 {
809         struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
810
811         /*
812          * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
813          * we don't really care if the credential has expired or not,
814          * since the caller should be prepared to reinitialise it.
815          */
816         if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
817                 goto out;
818         /* Don't match with creds that have expired. */
819         if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
820                 return 0;
821 out:
822         return (rc->cr_uid == acred->uid);
823 }
824
825 /*
826 * Marshal credentials.
827 * Maybe we should keep a cached credential for performance reasons.
828 */
829 static u32 *
830 gss_marshal(struct rpc_task *task, u32 *p)
831 {
832         struct rpc_cred *cred = task->tk_msg.rpc_cred;
833         struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
834                                                  gc_base);
835         struct gss_cl_ctx       *ctx = gss_cred_get_ctx(cred);
836         u32             *cred_len;
837         struct rpc_rqst *req = task->tk_rqstp;
838         u32             maj_stat = 0;
839         struct xdr_netobj mic;
840         struct kvec     iov;
841         struct xdr_buf  verf_buf;
842
843         dprintk("RPC: %4u gss_marshal\n", task->tk_pid);
844
845         *p++ = htonl(RPC_AUTH_GSS);
846         cred_len = p++;
847
848         spin_lock(&ctx->gc_seq_lock);
849         req->rq_seqno = ctx->gc_seq++;
850         spin_unlock(&ctx->gc_seq_lock);
851
852         *p++ = htonl((u32) RPC_GSS_VERSION);
853         *p++ = htonl((u32) ctx->gc_proc);
854         *p++ = htonl((u32) req->rq_seqno);
855         *p++ = htonl((u32) gss_cred->gc_service);
856         p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
857         *cred_len = htonl((p - (cred_len + 1)) << 2);
858
859         /* We compute the checksum for the verifier over the xdr-encoded bytes
860          * starting with the xid and ending at the end of the credential: */
861         iov.iov_base = xprt_skip_transport_header(task->tk_xprt,
862                                         req->rq_snd_buf.head[0].iov_base);
863         iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
864         xdr_buf_from_iov(&iov, &verf_buf);
865
866         /* set verifier flavor*/
867         *p++ = htonl(RPC_AUTH_GSS);
868
869         mic.data = (u8 *)(p + 1);
870         maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
871         if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
872                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
873         } else if (maj_stat != 0) {
874                 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
875                 goto out_put_ctx;
876         }
877         p = xdr_encode_opaque(p, NULL, mic.len);
878         gss_put_ctx(ctx);
879         return p;
880 out_put_ctx:
881         gss_put_ctx(ctx);
882         return NULL;
883 }
884
885 /*
886 * Refresh credentials. XXX - finish
887 */
888 static int
889 gss_refresh(struct rpc_task *task)
890 {
891
892         if (!gss_cred_is_uptodate_ctx(task->tk_msg.rpc_cred))
893                 return gss_refresh_upcall(task);
894         return 0;
895 }
896
897 static u32 *
898 gss_validate(struct rpc_task *task, u32 *p)
899 {
900         struct rpc_cred *cred = task->tk_msg.rpc_cred;
901         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
902         u32             seq;
903         struct kvec     iov;
904         struct xdr_buf  verf_buf;
905         struct xdr_netobj mic;
906         u32             flav,len;
907         u32             maj_stat;
908
909         dprintk("RPC: %4u gss_validate\n", task->tk_pid);
910
911         flav = ntohl(*p++);
912         if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
913                 goto out_bad;
914         if (flav != RPC_AUTH_GSS)
915                 goto out_bad;
916         seq = htonl(task->tk_rqstp->rq_seqno);
917         iov.iov_base = &seq;
918         iov.iov_len = sizeof(seq);
919         xdr_buf_from_iov(&iov, &verf_buf);
920         mic.data = (u8 *)p;
921         mic.len = len;
922
923         maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
924         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
925                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
926         if (maj_stat)
927                 goto out_bad;
928         /* We leave it to unwrap to calculate au_rslack. For now we just
929          * calculate the length of the verifier: */
930         task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
931         gss_put_ctx(ctx);
932         dprintk("RPC: %4u GSS gss_validate: gss_verify_mic succeeded.\n",
933                         task->tk_pid);
934         return p + XDR_QUADLEN(len);
935 out_bad:
936         gss_put_ctx(ctx);
937         dprintk("RPC: %4u gss_validate failed.\n", task->tk_pid);
938         return NULL;
939 }
940
941 static inline int
942 gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
943                 kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
944 {
945         struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
946         struct xdr_buf  integ_buf;
947         u32             *integ_len = NULL;
948         struct xdr_netobj mic;
949         u32             offset, *q;
950         struct kvec     *iov;
951         u32             maj_stat = 0;
952         int             status = -EIO;
953
954         integ_len = p++;
955         offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
956         *p++ = htonl(rqstp->rq_seqno);
957
958         status = encode(rqstp, p, obj);
959         if (status)
960                 return status;
961
962         if (xdr_buf_subsegment(snd_buf, &integ_buf,
963                                 offset, snd_buf->len - offset))
964                 return status;
965         *integ_len = htonl(integ_buf.len);
966
967         /* guess whether we're in the head or the tail: */
968         if (snd_buf->page_len || snd_buf->tail[0].iov_len) 
969                 iov = snd_buf->tail;
970         else
971                 iov = snd_buf->head;
972         p = iov->iov_base + iov->iov_len;
973         mic.data = (u8 *)(p + 1);
974
975         maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
976         status = -EIO; /* XXX? */
977         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
978                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
979         else if (maj_stat)
980                 return status;
981         q = xdr_encode_opaque(p, NULL, mic.len);
982
983         offset = (u8 *)q - (u8 *)p;
984         iov->iov_len += offset;
985         snd_buf->len += offset;
986         return 0;
987 }
988
989 static void
990 priv_release_snd_buf(struct rpc_rqst *rqstp)
991 {
992         int i;
993
994         for (i=0; i < rqstp->rq_enc_pages_num; i++)
995                 __free_page(rqstp->rq_enc_pages[i]);
996         kfree(rqstp->rq_enc_pages);
997 }
998
999 static int
1000 alloc_enc_pages(struct rpc_rqst *rqstp)
1001 {
1002         struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1003         int first, last, i;
1004
1005         if (snd_buf->page_len == 0) {
1006                 rqstp->rq_enc_pages_num = 0;
1007                 return 0;
1008         }
1009
1010         first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1011         last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
1012         rqstp->rq_enc_pages_num = last - first + 1 + 1;
1013         rqstp->rq_enc_pages
1014                 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
1015                                 GFP_NOFS);
1016         if (!rqstp->rq_enc_pages)
1017                 goto out;
1018         for (i=0; i < rqstp->rq_enc_pages_num; i++) {
1019                 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
1020                 if (rqstp->rq_enc_pages[i] == NULL)
1021                         goto out_free;
1022         }
1023         rqstp->rq_release_snd_buf = priv_release_snd_buf;
1024         return 0;
1025 out_free:
1026         for (i--; i >= 0; i--) {
1027                 __free_page(rqstp->rq_enc_pages[i]);
1028         }
1029 out:
1030         return -EAGAIN;
1031 }
1032
1033 static inline int
1034 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1035                 kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
1036 {
1037         struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
1038         u32             offset;
1039         u32             maj_stat;
1040         int             status;
1041         u32             *opaque_len;
1042         struct page     **inpages;
1043         int             first;
1044         int             pad;
1045         struct kvec     *iov;
1046         char            *tmp;
1047
1048         opaque_len = p++;
1049         offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1050         *p++ = htonl(rqstp->rq_seqno);
1051
1052         status = encode(rqstp, p, obj);
1053         if (status)
1054                 return status;
1055
1056         status = alloc_enc_pages(rqstp);
1057         if (status)
1058                 return status;
1059         first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1060         inpages = snd_buf->pages + first;
1061         snd_buf->pages = rqstp->rq_enc_pages;
1062         snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
1063         /* Give the tail its own page, in case we need extra space in the
1064          * head when wrapping: */
1065         if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1066                 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
1067                 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
1068                 snd_buf->tail[0].iov_base = tmp;
1069         }
1070         maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
1071         /* RPC_SLACK_SPACE should prevent this ever happening: */
1072         BUG_ON(snd_buf->len > snd_buf->buflen);
1073         status = -EIO;
1074         /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1075          * done anyway, so it's safe to put the request on the wire: */
1076         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1077                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1078         else if (maj_stat)
1079                 return status;
1080
1081         *opaque_len = htonl(snd_buf->len - offset);
1082         /* guess whether we're in the head or the tail: */
1083         if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1084                 iov = snd_buf->tail;
1085         else
1086                 iov = snd_buf->head;
1087         p = iov->iov_base + iov->iov_len;
1088         pad = 3 - ((snd_buf->len - offset - 1) & 3);
1089         memset(p, 0, pad);
1090         iov->iov_len += pad;
1091         snd_buf->len += pad;
1092
1093         return 0;
1094 }
1095
1096 static int
1097 gss_wrap_req(struct rpc_task *task,
1098              kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
1099 {
1100         struct rpc_cred *cred = task->tk_msg.rpc_cred;
1101         struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1102                         gc_base);
1103         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1104         int             status = -EIO;
1105
1106         dprintk("RPC: %4u gss_wrap_req\n", task->tk_pid);
1107         if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
1108                 /* The spec seems a little ambiguous here, but I think that not
1109                  * wrapping context destruction requests makes the most sense.
1110                  */
1111                 status = encode(rqstp, p, obj);
1112                 goto out;
1113         }
1114         switch (gss_cred->gc_service) {
1115                 case RPC_GSS_SVC_NONE:
1116                         status = encode(rqstp, p, obj);
1117                         break;
1118                 case RPC_GSS_SVC_INTEGRITY:
1119                         status = gss_wrap_req_integ(cred, ctx, encode,
1120                                                                 rqstp, p, obj);
1121                         break;
1122                 case RPC_GSS_SVC_PRIVACY:
1123                         status = gss_wrap_req_priv(cred, ctx, encode,
1124                                         rqstp, p, obj);
1125                         break;
1126         }
1127 out:
1128         gss_put_ctx(ctx);
1129         dprintk("RPC: %4u gss_wrap_req returning %d\n", task->tk_pid, status);
1130         return status;
1131 }
1132
1133 static inline int
1134 gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1135                 struct rpc_rqst *rqstp, u32 **p)
1136 {
1137         struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
1138         struct xdr_buf integ_buf;
1139         struct xdr_netobj mic;
1140         u32 data_offset, mic_offset;
1141         u32 integ_len;
1142         u32 maj_stat;
1143         int status = -EIO;
1144
1145         integ_len = ntohl(*(*p)++);
1146         if (integ_len & 3)
1147                 return status;
1148         data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1149         mic_offset = integ_len + data_offset;
1150         if (mic_offset > rcv_buf->len)
1151                 return status;
1152         if (ntohl(*(*p)++) != rqstp->rq_seqno)
1153                 return status;
1154
1155         if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1156                                 mic_offset - data_offset))
1157                 return status;
1158
1159         if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1160                 return status;
1161
1162         maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1163         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1164                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1165         if (maj_stat != GSS_S_COMPLETE)
1166                 return status;
1167         return 0;
1168 }
1169
1170 static inline int
1171 gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1172                 struct rpc_rqst *rqstp, u32 **p)
1173 {
1174         struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
1175         u32 offset;
1176         u32 opaque_len;
1177         u32 maj_stat;
1178         int status = -EIO;
1179
1180         opaque_len = ntohl(*(*p)++);
1181         offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1182         if (offset + opaque_len > rcv_buf->len)
1183                 return status;
1184         /* remove padding: */
1185         rcv_buf->len = offset + opaque_len;
1186
1187         maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
1188         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1189                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1190         if (maj_stat != GSS_S_COMPLETE)
1191                 return status;
1192         if (ntohl(*(*p)++) != rqstp->rq_seqno)
1193                 return status;
1194
1195         return 0;
1196 }
1197
1198
1199 static int
1200 gss_unwrap_resp(struct rpc_task *task,
1201                 kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
1202 {
1203         struct rpc_cred *cred = task->tk_msg.rpc_cred;
1204         struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1205                         gc_base);
1206         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1207         u32             *savedp = p;
1208         struct kvec     *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1209         int             savedlen = head->iov_len;
1210         int             status = -EIO;
1211
1212         if (ctx->gc_proc != RPC_GSS_PROC_DATA)
1213                 goto out_decode;
1214         switch (gss_cred->gc_service) {
1215                 case RPC_GSS_SVC_NONE:
1216                         break;
1217                 case RPC_GSS_SVC_INTEGRITY:
1218                         status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1219                         if (status)
1220                                 goto out;
1221                         break;
1222                 case RPC_GSS_SVC_PRIVACY:
1223                         status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1224                         if (status)
1225                                 goto out;
1226                         break;
1227         }
1228         /* take into account extra slack for integrity and privacy cases: */
1229         task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
1230                                                 + (savedlen - head->iov_len);
1231 out_decode:
1232         status = decode(rqstp, p, obj);
1233 out:
1234         gss_put_ctx(ctx);
1235         dprintk("RPC: %4u gss_unwrap_resp returning %d\n", task->tk_pid,
1236                         status);
1237         return status;
1238 }
1239   
1240 static struct rpc_authops authgss_ops = {
1241         .owner          = THIS_MODULE,
1242         .au_flavor      = RPC_AUTH_GSS,
1243 #ifdef RPC_DEBUG
1244         .au_name        = "RPCSEC_GSS",
1245 #endif
1246         .create         = gss_create,
1247         .destroy        = gss_destroy,
1248         .lookup_cred    = gss_lookup_cred,
1249         .crcreate       = gss_create_cred
1250 };
1251
1252 static struct rpc_credops gss_credops = {
1253         .cr_name        = "AUTH_GSS",
1254         .crdestroy      = gss_destroy_cred,
1255         .cr_init        = gss_cred_init,
1256         .crmatch        = gss_match,
1257         .crmarshal      = gss_marshal,
1258         .crrefresh      = gss_refresh,
1259         .crvalidate     = gss_validate,
1260         .crwrap_req     = gss_wrap_req,
1261         .crunwrap_resp  = gss_unwrap_resp,
1262 };
1263
1264 static struct rpc_pipe_ops gss_upcall_ops = {
1265         .upcall         = gss_pipe_upcall,
1266         .downcall       = gss_pipe_downcall,
1267         .destroy_msg    = gss_pipe_destroy_msg,
1268         .release_pipe   = gss_pipe_release,
1269 };
1270
1271 /*
1272  * Initialize RPCSEC_GSS module
1273  */
1274 static int __init init_rpcsec_gss(void)
1275 {
1276         int err = 0;
1277
1278         err = rpcauth_register(&authgss_ops);
1279         if (err)
1280                 goto out;
1281         err = gss_svc_init();
1282         if (err)
1283                 goto out_unregister;
1284         return 0;
1285 out_unregister:
1286         rpcauth_unregister(&authgss_ops);
1287 out:
1288         return err;
1289 }
1290
1291 static void __exit exit_rpcsec_gss(void)
1292 {
1293         gss_svc_shutdown();
1294         rpcauth_unregister(&authgss_ops);
1295 }
1296
1297 MODULE_LICENSE("GPL");
1298 module_init(init_rpcsec_gss)
1299 module_exit(exit_rpcsec_gss)