Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
[pandora-kernel.git] / net / sunrpc / auth_gss / auth_gss.c
1 /*
2  * linux/net/sunrpc/auth_gss/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 __be32 *
830 gss_marshal(struct rpc_task *task, __be32 *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         __be32          *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 __be32 *
898 gss_validate(struct rpc_task *task, __be32 *p)
899 {
900         struct rpc_cred *cred = task->tk_msg.rpc_cred;
901         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
902         __be32          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, __be32 *p, void *obj)
944 {
945         struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
946         struct xdr_buf  integ_buf;
947         __be32          *integ_len = NULL;
948         struct xdr_netobj mic;
949         u32             offset;
950         __be32          *q;
951         struct kvec     *iov;
952         u32             maj_stat = 0;
953         int             status = -EIO;
954
955         integ_len = p++;
956         offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
957         *p++ = htonl(rqstp->rq_seqno);
958
959         status = encode(rqstp, p, obj);
960         if (status)
961                 return status;
962
963         if (xdr_buf_subsegment(snd_buf, &integ_buf,
964                                 offset, snd_buf->len - offset))
965                 return status;
966         *integ_len = htonl(integ_buf.len);
967
968         /* guess whether we're in the head or the tail: */
969         if (snd_buf->page_len || snd_buf->tail[0].iov_len) 
970                 iov = snd_buf->tail;
971         else
972                 iov = snd_buf->head;
973         p = iov->iov_base + iov->iov_len;
974         mic.data = (u8 *)(p + 1);
975
976         maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
977         status = -EIO; /* XXX? */
978         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
979                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
980         else if (maj_stat)
981                 return status;
982         q = xdr_encode_opaque(p, NULL, mic.len);
983
984         offset = (u8 *)q - (u8 *)p;
985         iov->iov_len += offset;
986         snd_buf->len += offset;
987         return 0;
988 }
989
990 static void
991 priv_release_snd_buf(struct rpc_rqst *rqstp)
992 {
993         int i;
994
995         for (i=0; i < rqstp->rq_enc_pages_num; i++)
996                 __free_page(rqstp->rq_enc_pages[i]);
997         kfree(rqstp->rq_enc_pages);
998 }
999
1000 static int
1001 alloc_enc_pages(struct rpc_rqst *rqstp)
1002 {
1003         struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1004         int first, last, i;
1005
1006         if (snd_buf->page_len == 0) {
1007                 rqstp->rq_enc_pages_num = 0;
1008                 return 0;
1009         }
1010
1011         first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1012         last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
1013         rqstp->rq_enc_pages_num = last - first + 1 + 1;
1014         rqstp->rq_enc_pages
1015                 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
1016                                 GFP_NOFS);
1017         if (!rqstp->rq_enc_pages)
1018                 goto out;
1019         for (i=0; i < rqstp->rq_enc_pages_num; i++) {
1020                 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
1021                 if (rqstp->rq_enc_pages[i] == NULL)
1022                         goto out_free;
1023         }
1024         rqstp->rq_release_snd_buf = priv_release_snd_buf;
1025         return 0;
1026 out_free:
1027         for (i--; i >= 0; i--) {
1028                 __free_page(rqstp->rq_enc_pages[i]);
1029         }
1030 out:
1031         return -EAGAIN;
1032 }
1033
1034 static inline int
1035 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1036                 kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
1037 {
1038         struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
1039         u32             offset;
1040         u32             maj_stat;
1041         int             status;
1042         __be32          *opaque_len;
1043         struct page     **inpages;
1044         int             first;
1045         int             pad;
1046         struct kvec     *iov;
1047         char            *tmp;
1048
1049         opaque_len = p++;
1050         offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1051         *p++ = htonl(rqstp->rq_seqno);
1052
1053         status = encode(rqstp, p, obj);
1054         if (status)
1055                 return status;
1056
1057         status = alloc_enc_pages(rqstp);
1058         if (status)
1059                 return status;
1060         first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1061         inpages = snd_buf->pages + first;
1062         snd_buf->pages = rqstp->rq_enc_pages;
1063         snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
1064         /* Give the tail its own page, in case we need extra space in the
1065          * head when wrapping: */
1066         if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1067                 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
1068                 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
1069                 snd_buf->tail[0].iov_base = tmp;
1070         }
1071         maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
1072         /* RPC_SLACK_SPACE should prevent this ever happening: */
1073         BUG_ON(snd_buf->len > snd_buf->buflen);
1074         status = -EIO;
1075         /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1076          * done anyway, so it's safe to put the request on the wire: */
1077         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1078                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1079         else if (maj_stat)
1080                 return status;
1081
1082         *opaque_len = htonl(snd_buf->len - offset);
1083         /* guess whether we're in the head or the tail: */
1084         if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1085                 iov = snd_buf->tail;
1086         else
1087                 iov = snd_buf->head;
1088         p = iov->iov_base + iov->iov_len;
1089         pad = 3 - ((snd_buf->len - offset - 1) & 3);
1090         memset(p, 0, pad);
1091         iov->iov_len += pad;
1092         snd_buf->len += pad;
1093
1094         return 0;
1095 }
1096
1097 static int
1098 gss_wrap_req(struct rpc_task *task,
1099              kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
1100 {
1101         struct rpc_cred *cred = task->tk_msg.rpc_cred;
1102         struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1103                         gc_base);
1104         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1105         int             status = -EIO;
1106
1107         dprintk("RPC: %4u gss_wrap_req\n", task->tk_pid);
1108         if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
1109                 /* The spec seems a little ambiguous here, but I think that not
1110                  * wrapping context destruction requests makes the most sense.
1111                  */
1112                 status = encode(rqstp, p, obj);
1113                 goto out;
1114         }
1115         switch (gss_cred->gc_service) {
1116                 case RPC_GSS_SVC_NONE:
1117                         status = encode(rqstp, p, obj);
1118                         break;
1119                 case RPC_GSS_SVC_INTEGRITY:
1120                         status = gss_wrap_req_integ(cred, ctx, encode,
1121                                                                 rqstp, p, obj);
1122                         break;
1123                 case RPC_GSS_SVC_PRIVACY:
1124                         status = gss_wrap_req_priv(cred, ctx, encode,
1125                                         rqstp, p, obj);
1126                         break;
1127         }
1128 out:
1129         gss_put_ctx(ctx);
1130         dprintk("RPC: %4u gss_wrap_req returning %d\n", task->tk_pid, status);
1131         return status;
1132 }
1133
1134 static inline int
1135 gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1136                 struct rpc_rqst *rqstp, __be32 **p)
1137 {
1138         struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
1139         struct xdr_buf integ_buf;
1140         struct xdr_netobj mic;
1141         u32 data_offset, mic_offset;
1142         u32 integ_len;
1143         u32 maj_stat;
1144         int status = -EIO;
1145
1146         integ_len = ntohl(*(*p)++);
1147         if (integ_len & 3)
1148                 return status;
1149         data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1150         mic_offset = integ_len + data_offset;
1151         if (mic_offset > rcv_buf->len)
1152                 return status;
1153         if (ntohl(*(*p)++) != rqstp->rq_seqno)
1154                 return status;
1155
1156         if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1157                                 mic_offset - data_offset))
1158                 return status;
1159
1160         if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1161                 return status;
1162
1163         maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1164         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1165                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1166         if (maj_stat != GSS_S_COMPLETE)
1167                 return status;
1168         return 0;
1169 }
1170
1171 static inline int
1172 gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1173                 struct rpc_rqst *rqstp, __be32 **p)
1174 {
1175         struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
1176         u32 offset;
1177         u32 opaque_len;
1178         u32 maj_stat;
1179         int status = -EIO;
1180
1181         opaque_len = ntohl(*(*p)++);
1182         offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1183         if (offset + opaque_len > rcv_buf->len)
1184                 return status;
1185         /* remove padding: */
1186         rcv_buf->len = offset + opaque_len;
1187
1188         maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
1189         if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1190                 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
1191         if (maj_stat != GSS_S_COMPLETE)
1192                 return status;
1193         if (ntohl(*(*p)++) != rqstp->rq_seqno)
1194                 return status;
1195
1196         return 0;
1197 }
1198
1199
1200 static int
1201 gss_unwrap_resp(struct rpc_task *task,
1202                 kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
1203 {
1204         struct rpc_cred *cred = task->tk_msg.rpc_cred;
1205         struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1206                         gc_base);
1207         struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1208         __be32          *savedp = p;
1209         struct kvec     *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1210         int             savedlen = head->iov_len;
1211         int             status = -EIO;
1212
1213         if (ctx->gc_proc != RPC_GSS_PROC_DATA)
1214                 goto out_decode;
1215         switch (gss_cred->gc_service) {
1216                 case RPC_GSS_SVC_NONE:
1217                         break;
1218                 case RPC_GSS_SVC_INTEGRITY:
1219                         status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1220                         if (status)
1221                                 goto out;
1222                         break;
1223                 case RPC_GSS_SVC_PRIVACY:
1224                         status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1225                         if (status)
1226                                 goto out;
1227                         break;
1228         }
1229         /* take into account extra slack for integrity and privacy cases: */
1230         task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
1231                                                 + (savedlen - head->iov_len);
1232 out_decode:
1233         status = decode(rqstp, p, obj);
1234 out:
1235         gss_put_ctx(ctx);
1236         dprintk("RPC: %4u gss_unwrap_resp returning %d\n", task->tk_pid,
1237                         status);
1238         return status;
1239 }
1240   
1241 static struct rpc_authops authgss_ops = {
1242         .owner          = THIS_MODULE,
1243         .au_flavor      = RPC_AUTH_GSS,
1244 #ifdef RPC_DEBUG
1245         .au_name        = "RPCSEC_GSS",
1246 #endif
1247         .create         = gss_create,
1248         .destroy        = gss_destroy,
1249         .lookup_cred    = gss_lookup_cred,
1250         .crcreate       = gss_create_cred
1251 };
1252
1253 static struct rpc_credops gss_credops = {
1254         .cr_name        = "AUTH_GSS",
1255         .crdestroy      = gss_destroy_cred,
1256         .cr_init        = gss_cred_init,
1257         .crmatch        = gss_match,
1258         .crmarshal      = gss_marshal,
1259         .crrefresh      = gss_refresh,
1260         .crvalidate     = gss_validate,
1261         .crwrap_req     = gss_wrap_req,
1262         .crunwrap_resp  = gss_unwrap_resp,
1263 };
1264
1265 static struct rpc_pipe_ops gss_upcall_ops = {
1266         .upcall         = gss_pipe_upcall,
1267         .downcall       = gss_pipe_downcall,
1268         .destroy_msg    = gss_pipe_destroy_msg,
1269         .release_pipe   = gss_pipe_release,
1270 };
1271
1272 /*
1273  * Initialize RPCSEC_GSS module
1274  */
1275 static int __init init_rpcsec_gss(void)
1276 {
1277         int err = 0;
1278
1279         err = rpcauth_register(&authgss_ops);
1280         if (err)
1281                 goto out;
1282         err = gss_svc_init();
1283         if (err)
1284                 goto out_unregister;
1285         return 0;
1286 out_unregister:
1287         rpcauth_unregister(&authgss_ops);
1288 out:
1289         return err;
1290 }
1291
1292 static void __exit exit_rpcsec_gss(void)
1293 {
1294         gss_svc_shutdown();
1295         rpcauth_unregister(&authgss_ops);
1296 }
1297
1298 MODULE_LICENSE("GPL");
1299 module_init(init_rpcsec_gss)
1300 module_exit(exit_rpcsec_gss)