1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include <linux/slab.h>
41#include <linux/types.h>
42#include <linux/module.h>
43#include <linux/pagemap.h>
44#include <linux/user_namespace.h>
45
46#include <linux/sunrpc/auth_gss.h>
47#include <linux/sunrpc/gss_err.h>
48#include <linux/sunrpc/svcauth.h>
49#include <linux/sunrpc/svcauth_gss.h>
50#include <linux/sunrpc/cache.h>
51#include "gss_rpc_upcall.h"
52
53
54#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
55# define RPCDBG_FACILITY RPCDBG_AUTH
56#endif
57
58
59
60
61
62
63
64
65
66static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b)
67{
68 return a->len == b->len && 0 == memcmp(a->data, b->data, a->len);
69}
70
71#define RSI_HASHBITS 6
72#define RSI_HASHMAX (1<<RSI_HASHBITS)
73
74struct rsi {
75 struct cache_head h;
76 struct xdr_netobj in_handle, in_token;
77 struct xdr_netobj out_handle, out_token;
78 int major_status, minor_status;
79};
80
81static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
82static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item);
83
84static void rsi_free(struct rsi *rsii)
85{
86 kfree(rsii->in_handle.data);
87 kfree(rsii->in_token.data);
88 kfree(rsii->out_handle.data);
89 kfree(rsii->out_token.data);
90}
91
92static void rsi_put(struct kref *ref)
93{
94 struct rsi *rsii = container_of(ref, struct rsi, h.ref);
95 rsi_free(rsii);
96 kfree(rsii);
97}
98
99static inline int rsi_hash(struct rsi *item)
100{
101 return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
102 ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS);
103}
104
105static int rsi_match(struct cache_head *a, struct cache_head *b)
106{
107 struct rsi *item = container_of(a, struct rsi, h);
108 struct rsi *tmp = container_of(b, struct rsi, h);
109 return netobj_equal(&item->in_handle, &tmp->in_handle) &&
110 netobj_equal(&item->in_token, &tmp->in_token);
111}
112
113static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len)
114{
115 dst->len = len;
116 dst->data = (len ? kmemdup(src, len, GFP_KERNEL) : NULL);
117 if (len && !dst->data)
118 return -ENOMEM;
119 return 0;
120}
121
122static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src)
123{
124 return dup_to_netobj(dst, src->data, src->len);
125}
126
127static void rsi_init(struct cache_head *cnew, struct cache_head *citem)
128{
129 struct rsi *new = container_of(cnew, struct rsi, h);
130 struct rsi *item = container_of(citem, struct rsi, h);
131
132 new->out_handle.data = NULL;
133 new->out_handle.len = 0;
134 new->out_token.data = NULL;
135 new->out_token.len = 0;
136 new->in_handle.len = item->in_handle.len;
137 item->in_handle.len = 0;
138 new->in_token.len = item->in_token.len;
139 item->in_token.len = 0;
140 new->in_handle.data = item->in_handle.data;
141 item->in_handle.data = NULL;
142 new->in_token.data = item->in_token.data;
143 item->in_token.data = NULL;
144}
145
146static void update_rsi(struct cache_head *cnew, struct cache_head *citem)
147{
148 struct rsi *new = container_of(cnew, struct rsi, h);
149 struct rsi *item = container_of(citem, struct rsi, h);
150
151 BUG_ON(new->out_handle.data || new->out_token.data);
152 new->out_handle.len = item->out_handle.len;
153 item->out_handle.len = 0;
154 new->out_token.len = item->out_token.len;
155 item->out_token.len = 0;
156 new->out_handle.data = item->out_handle.data;
157 item->out_handle.data = NULL;
158 new->out_token.data = item->out_token.data;
159 item->out_token.data = NULL;
160
161 new->major_status = item->major_status;
162 new->minor_status = item->minor_status;
163}
164
165static struct cache_head *rsi_alloc(void)
166{
167 struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL);
168 if (rsii)
169 return &rsii->h;
170 else
171 return NULL;
172}
173
174static void rsi_request(struct cache_detail *cd,
175 struct cache_head *h,
176 char **bpp, int *blen)
177{
178 struct rsi *rsii = container_of(h, struct rsi, h);
179
180 qword_addhex(bpp, blen, rsii->in_handle.data, rsii->in_handle.len);
181 qword_addhex(bpp, blen, rsii->in_token.data, rsii->in_token.len);
182 (*bpp)[-1] = '\n';
183}
184
185static int rsi_parse(struct cache_detail *cd,
186 char *mesg, int mlen)
187{
188
189 char *buf = mesg;
190 char *ep;
191 int len;
192 struct rsi rsii, *rsip = NULL;
193 time_t expiry;
194 int status = -EINVAL;
195
196 memset(&rsii, 0, sizeof(rsii));
197
198 len = qword_get(&mesg, buf, mlen);
199 if (len < 0)
200 goto out;
201 status = -ENOMEM;
202 if (dup_to_netobj(&rsii.in_handle, buf, len))
203 goto out;
204
205
206 len = qword_get(&mesg, buf, mlen);
207 status = -EINVAL;
208 if (len < 0)
209 goto out;
210 status = -ENOMEM;
211 if (dup_to_netobj(&rsii.in_token, buf, len))
212 goto out;
213
214 rsip = rsi_lookup(cd, &rsii);
215 if (!rsip)
216 goto out;
217
218 rsii.h.flags = 0;
219
220 expiry = get_expiry(&mesg);
221 status = -EINVAL;
222 if (expiry == 0)
223 goto out;
224
225
226 len = qword_get(&mesg, buf, mlen);
227 if (len <= 0)
228 goto out;
229 rsii.major_status = simple_strtoul(buf, &ep, 10);
230 if (*ep)
231 goto out;
232 len = qword_get(&mesg, buf, mlen);
233 if (len <= 0)
234 goto out;
235 rsii.minor_status = simple_strtoul(buf, &ep, 10);
236 if (*ep)
237 goto out;
238
239
240 len = qword_get(&mesg, buf, mlen);
241 if (len < 0)
242 goto out;
243 status = -ENOMEM;
244 if (dup_to_netobj(&rsii.out_handle, buf, len))
245 goto out;
246
247
248 len = qword_get(&mesg, buf, mlen);
249 status = -EINVAL;
250 if (len < 0)
251 goto out;
252 status = -ENOMEM;
253 if (dup_to_netobj(&rsii.out_token, buf, len))
254 goto out;
255 rsii.h.expiry_time = expiry;
256 rsip = rsi_update(cd, &rsii, rsip);
257 status = 0;
258out:
259 rsi_free(&rsii);
260 if (rsip)
261 cache_put(&rsip->h, cd);
262 else
263 status = -ENOMEM;
264 return status;
265}
266
267static struct cache_detail rsi_cache_template = {
268 .owner = THIS_MODULE,
269 .hash_size = RSI_HASHMAX,
270 .name = "auth.rpcsec.init",
271 .cache_put = rsi_put,
272 .cache_request = rsi_request,
273 .cache_parse = rsi_parse,
274 .match = rsi_match,
275 .init = rsi_init,
276 .update = update_rsi,
277 .alloc = rsi_alloc,
278};
279
280static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
281{
282 struct cache_head *ch;
283 int hash = rsi_hash(item);
284
285 ch = sunrpc_cache_lookup(cd, &item->h, hash);
286 if (ch)
287 return container_of(ch, struct rsi, h);
288 else
289 return NULL;
290}
291
292static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old)
293{
294 struct cache_head *ch;
295 int hash = rsi_hash(new);
296
297 ch = sunrpc_cache_update(cd, &new->h,
298 &old->h, hash);
299 if (ch)
300 return container_of(ch, struct rsi, h);
301 else
302 return NULL;
303}
304
305
306
307
308
309
310
311
312
313#define RSC_HASHBITS 10
314#define RSC_HASHMAX (1<<RSC_HASHBITS)
315
316#define GSS_SEQ_WIN 128
317
318struct gss_svc_seq_data {
319
320 int sd_max;
321
322
323 unsigned long sd_win[GSS_SEQ_WIN/BITS_PER_LONG];
324 spinlock_t sd_lock;
325};
326
327struct rsc {
328 struct cache_head h;
329 struct xdr_netobj handle;
330 struct svc_cred cred;
331 struct gss_svc_seq_data seqdata;
332 struct gss_ctx *mechctx;
333};
334
335static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
336static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item);
337
338static void rsc_free(struct rsc *rsci)
339{
340 kfree(rsci->handle.data);
341 if (rsci->mechctx)
342 gss_delete_sec_context(&rsci->mechctx);
343 free_svc_cred(&rsci->cred);
344}
345
346static void rsc_put(struct kref *ref)
347{
348 struct rsc *rsci = container_of(ref, struct rsc, h.ref);
349
350 rsc_free(rsci);
351 kfree(rsci);
352}
353
354static inline int
355rsc_hash(struct rsc *rsci)
356{
357 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
358}
359
360static int
361rsc_match(struct cache_head *a, struct cache_head *b)
362{
363 struct rsc *new = container_of(a, struct rsc, h);
364 struct rsc *tmp = container_of(b, struct rsc, h);
365
366 return netobj_equal(&new->handle, &tmp->handle);
367}
368
369static void
370rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
371{
372 struct rsc *new = container_of(cnew, struct rsc, h);
373 struct rsc *tmp = container_of(ctmp, struct rsc, h);
374
375 new->handle.len = tmp->handle.len;
376 tmp->handle.len = 0;
377 new->handle.data = tmp->handle.data;
378 tmp->handle.data = NULL;
379 new->mechctx = NULL;
380 init_svc_cred(&new->cred);
381}
382
383static void
384update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
385{
386 struct rsc *new = container_of(cnew, struct rsc, h);
387 struct rsc *tmp = container_of(ctmp, struct rsc, h);
388
389 new->mechctx = tmp->mechctx;
390 tmp->mechctx = NULL;
391 memset(&new->seqdata, 0, sizeof(new->seqdata));
392 spin_lock_init(&new->seqdata.sd_lock);
393 new->cred = tmp->cred;
394 init_svc_cred(&tmp->cred);
395}
396
397static struct cache_head *
398rsc_alloc(void)
399{
400 struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL);
401 if (rsci)
402 return &rsci->h;
403 else
404 return NULL;
405}
406
407static int rsc_parse(struct cache_detail *cd,
408 char *mesg, int mlen)
409{
410
411 char *buf = mesg;
412 int id;
413 int len, rv;
414 struct rsc rsci, *rscp = NULL;
415 time_t expiry;
416 int status = -EINVAL;
417 struct gss_api_mech *gm = NULL;
418
419 memset(&rsci, 0, sizeof(rsci));
420
421 len = qword_get(&mesg, buf, mlen);
422 if (len < 0) goto out;
423 status = -ENOMEM;
424 if (dup_to_netobj(&rsci.handle, buf, len))
425 goto out;
426
427 rsci.h.flags = 0;
428
429 expiry = get_expiry(&mesg);
430 status = -EINVAL;
431 if (expiry == 0)
432 goto out;
433
434 rscp = rsc_lookup(cd, &rsci);
435 if (!rscp)
436 goto out;
437
438
439 rv = get_int(&mesg, &id);
440 if (rv == -EINVAL)
441 goto out;
442 if (rv == -ENOENT)
443 set_bit(CACHE_NEGATIVE, &rsci.h.flags);
444 else {
445 int N, i;
446
447
448
449
450
451
452
453
454
455
456 rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
457
458
459 if (get_int(&mesg, &id))
460 goto out;
461 rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
462
463
464 if (get_int(&mesg, &N))
465 goto out;
466 status = -ENOMEM;
467 rsci.cred.cr_group_info = groups_alloc(N);
468 if (rsci.cred.cr_group_info == NULL)
469 goto out;
470
471
472 status = -EINVAL;
473 for (i=0; i<N; i++) {
474 kgid_t kgid;
475 if (get_int(&mesg, &id))
476 goto out;
477 kgid = make_kgid(&init_user_ns, id);
478 if (!gid_valid(kgid))
479 goto out;
480 GROUP_AT(rsci.cred.cr_group_info, i) = kgid;
481 }
482 groups_sort(rsci.cred.cr_group_info);
483
484
485 len = qword_get(&mesg, buf, mlen);
486 if (len < 0)
487 goto out;
488 gm = rsci.cred.cr_gss_mech = gss_mech_get_by_name(buf);
489 status = -EOPNOTSUPP;
490 if (!gm)
491 goto out;
492
493 status = -EINVAL;
494
495 len = qword_get(&mesg, buf, mlen);
496 if (len < 0)
497 goto out;
498 status = gss_import_sec_context(buf, len, gm, &rsci.mechctx,
499 NULL, GFP_KERNEL);
500 if (status)
501 goto out;
502
503
504 len = qword_get(&mesg, buf, mlen);
505 if (len > 0) {
506 rsci.cred.cr_principal = kstrdup(buf, GFP_KERNEL);
507 if (!rsci.cred.cr_principal) {
508 status = -ENOMEM;
509 goto out;
510 }
511 }
512
513 }
514 rsci.h.expiry_time = expiry;
515 rscp = rsc_update(cd, &rsci, rscp);
516 status = 0;
517out:
518 rsc_free(&rsci);
519 if (rscp)
520 cache_put(&rscp->h, cd);
521 else
522 status = -ENOMEM;
523 return status;
524}
525
526static struct cache_detail rsc_cache_template = {
527 .owner = THIS_MODULE,
528 .hash_size = RSC_HASHMAX,
529 .name = "auth.rpcsec.context",
530 .cache_put = rsc_put,
531 .cache_parse = rsc_parse,
532 .match = rsc_match,
533 .init = rsc_init,
534 .update = update_rsc,
535 .alloc = rsc_alloc,
536};
537
538static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
539{
540 struct cache_head *ch;
541 int hash = rsc_hash(item);
542
543 ch = sunrpc_cache_lookup(cd, &item->h, hash);
544 if (ch)
545 return container_of(ch, struct rsc, h);
546 else
547 return NULL;
548}
549
550static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old)
551{
552 struct cache_head *ch;
553 int hash = rsc_hash(new);
554
555 ch = sunrpc_cache_update(cd, &new->h,
556 &old->h, hash);
557 if (ch)
558 return container_of(ch, struct rsc, h);
559 else
560 return NULL;
561}
562
563
564static struct rsc *
565gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle)
566{
567 struct rsc rsci;
568 struct rsc *found;
569
570 memset(&rsci, 0, sizeof(rsci));
571 if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
572 return NULL;
573 found = rsc_lookup(cd, &rsci);
574 rsc_free(&rsci);
575 if (!found)
576 return NULL;
577 if (cache_check(cd, &found->h, NULL))
578 return NULL;
579 return found;
580}
581
582
583static int
584gss_check_seq_num(struct rsc *rsci, int seq_num)
585{
586 struct gss_svc_seq_data *sd = &rsci->seqdata;
587
588 spin_lock(&sd->sd_lock);
589 if (seq_num > sd->sd_max) {
590 if (seq_num >= sd->sd_max + GSS_SEQ_WIN) {
591 memset(sd->sd_win,0,sizeof(sd->sd_win));
592 sd->sd_max = seq_num;
593 } else while (sd->sd_max < seq_num) {
594 sd->sd_max++;
595 __clear_bit(sd->sd_max % GSS_SEQ_WIN, sd->sd_win);
596 }
597 __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win);
598 goto ok;
599 } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) {
600 goto drop;
601 }
602
603 if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win))
604 goto drop;
605ok:
606 spin_unlock(&sd->sd_lock);
607 return 1;
608drop:
609 spin_unlock(&sd->sd_lock);
610 return 0;
611}
612
613static inline u32 round_up_to_quad(u32 i)
614{
615 return (i + 3 ) & ~3;
616}
617
618static inline int
619svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
620{
621 int l;
622
623 if (argv->iov_len < 4)
624 return -1;
625 o->len = svc_getnl(argv);
626 l = round_up_to_quad(o->len);
627 if (argv->iov_len < l)
628 return -1;
629 o->data = argv->iov_base;
630 argv->iov_base += l;
631 argv->iov_len -= l;
632 return 0;
633}
634
635static inline int
636svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
637{
638 u8 *p;
639
640 if (resv->iov_len + 4 > PAGE_SIZE)
641 return -1;
642 svc_putnl(resv, o->len);
643 p = resv->iov_base + resv->iov_len;
644 resv->iov_len += round_up_to_quad(o->len);
645 if (resv->iov_len > PAGE_SIZE)
646 return -1;
647 memcpy(p, o->data, o->len);
648 memset(p + o->len, 0, round_up_to_quad(o->len) - o->len);
649 return 0;
650}
651
652
653
654
655
656
657static int
658gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
659 __be32 *rpcstart, struct rpc_gss_wire_cred *gc, __be32 *authp)
660{
661 struct gss_ctx *ctx_id = rsci->mechctx;
662 struct xdr_buf rpchdr;
663 struct xdr_netobj checksum;
664 u32 flavor = 0;
665 struct kvec *argv = &rqstp->rq_arg.head[0];
666 struct kvec iov;
667
668
669 iov.iov_base = rpcstart;
670 iov.iov_len = (u8 *)argv->iov_base - (u8 *)rpcstart;
671 xdr_buf_from_iov(&iov, &rpchdr);
672
673 *authp = rpc_autherr_badverf;
674 if (argv->iov_len < 4)
675 return SVC_DENIED;
676 flavor = svc_getnl(argv);
677 if (flavor != RPC_AUTH_GSS)
678 return SVC_DENIED;
679 if (svc_safe_getnetobj(argv, &checksum))
680 return SVC_DENIED;
681
682 if (rqstp->rq_deferred)
683 return SVC_OK;
684 if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
685 *authp = rpcsec_gsserr_credproblem;
686 return SVC_DENIED;
687 }
688
689 if (gc->gc_seq > MAXSEQ) {
690 dprintk("RPC: svcauth_gss: discarding request with "
691 "large sequence number %d\n", gc->gc_seq);
692 *authp = rpcsec_gsserr_ctxproblem;
693 return SVC_DENIED;
694 }
695 if (!gss_check_seq_num(rsci, gc->gc_seq)) {
696 dprintk("RPC: svcauth_gss: discarding request with "
697 "old sequence number %d\n", gc->gc_seq);
698 return SVC_DROP;
699 }
700 return SVC_OK;
701}
702
703static int
704gss_write_null_verf(struct svc_rqst *rqstp)
705{
706 __be32 *p;
707
708 svc_putnl(rqstp->rq_res.head, RPC_AUTH_NULL);
709 p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
710
711 *p++ = 0;
712 if (!xdr_ressize_check(rqstp, p))
713 return -1;
714 return 0;
715}
716
717static int
718gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
719{
720 __be32 *xdr_seq;
721 u32 maj_stat;
722 struct xdr_buf verf_data;
723 struct xdr_netobj mic;
724 __be32 *p;
725 struct kvec iov;
726 int err = -1;
727
728 svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
729 xdr_seq = kmalloc(4, GFP_KERNEL);
730 if (!xdr_seq)
731 return -1;
732 *xdr_seq = htonl(seq);
733
734 iov.iov_base = xdr_seq;
735 iov.iov_len = 4;
736 xdr_buf_from_iov(&iov, &verf_data);
737 p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
738 mic.data = (u8 *)(p + 1);
739 maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
740 if (maj_stat != GSS_S_COMPLETE)
741 goto out;
742 *p++ = htonl(mic.len);
743 memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len);
744 p += XDR_QUADLEN(mic.len);
745 if (!xdr_ressize_check(rqstp, p))
746 goto out;
747 err = 0;
748out:
749 kfree(xdr_seq);
750 return err;
751}
752
753struct gss_domain {
754 struct auth_domain h;
755 u32 pseudoflavor;
756};
757
758static struct auth_domain *
759find_gss_auth_domain(struct gss_ctx *ctx, u32 svc)
760{
761 char *name;
762
763 name = gss_service_to_auth_domain_name(ctx->mech_type, svc);
764 if (!name)
765 return NULL;
766 return auth_domain_find(name);
767}
768
769static struct auth_ops svcauthops_gss;
770
771u32 svcauth_gss_flavor(struct auth_domain *dom)
772{
773 struct gss_domain *gd = container_of(dom, struct gss_domain, h);
774
775 return gd->pseudoflavor;
776}
777
778EXPORT_SYMBOL_GPL(svcauth_gss_flavor);
779
780int
781svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
782{
783 struct gss_domain *new;
784 struct auth_domain *test;
785 int stat = -ENOMEM;
786
787 new = kmalloc(sizeof(*new), GFP_KERNEL);
788 if (!new)
789 goto out;
790 kref_init(&new->h.ref);
791 new->h.name = kstrdup(name, GFP_KERNEL);
792 if (!new->h.name)
793 goto out_free_dom;
794 new->h.flavour = &svcauthops_gss;
795 new->pseudoflavor = pseudoflavor;
796
797 stat = 0;
798 test = auth_domain_lookup(name, &new->h);
799 if (test != &new->h) {
800 auth_domain_put(test);
801 kfree(new->h.name);
802 goto out_free_dom;
803 }
804 return 0;
805
806out_free_dom:
807 kfree(new);
808out:
809 return stat;
810}
811
812EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor);
813
814static inline int
815read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
816{
817 __be32 raw;
818 int status;
819
820 status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
821 if (status)
822 return status;
823 *obj = ntohl(raw);
824 return 0;
825}
826
827
828
829
830
831
832static int
833unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
834{
835 int stat = -EINVAL;
836 u32 integ_len, maj_stat;
837 struct xdr_netobj mic;
838 struct xdr_buf integ_buf;
839
840
841 if (rqstp->rq_deferred)
842 return 0;
843
844 integ_len = svc_getnl(&buf->head[0]);
845 if (integ_len & 3)
846 return stat;
847 if (integ_len > buf->len)
848 return stat;
849 if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
850 BUG();
851
852 if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
853 BUG();
854 if (mic.len > RPC_MAX_AUTH_SIZE)
855 return stat;
856 mic.data = kmalloc(mic.len, GFP_KERNEL);
857 if (!mic.data)
858 return stat;
859 if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
860 goto out;
861 maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
862 if (maj_stat != GSS_S_COMPLETE)
863 goto out;
864 if (svc_getnl(&buf->head[0]) != seq)
865 goto out;
866
867 xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
868 stat = 0;
869out:
870 kfree(mic.data);
871 return stat;
872}
873
874static inline int
875total_buf_len(struct xdr_buf *buf)
876{
877 return buf->head[0].iov_len + buf->page_len + buf->tail[0].iov_len;
878}
879
880static void
881fix_priv_head(struct xdr_buf *buf, int pad)
882{
883 if (buf->page_len == 0) {
884
885
886
887 buf->head[0].iov_len -= pad;
888 }
889}
890
891static int
892unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
893{
894 u32 priv_len, maj_stat;
895 int pad, saved_len, remaining_len, offset;
896
897 clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
898
899 priv_len = svc_getnl(&buf->head[0]);
900 if (rqstp->rq_deferred) {
901
902
903 goto out_seq;
904 }
905
906
907
908 remaining_len = total_buf_len(buf);
909 if (priv_len > remaining_len)
910 return -EINVAL;
911 pad = remaining_len - priv_len;
912 buf->len -= pad;
913 fix_priv_head(buf, pad);
914
915
916 saved_len = buf->len;
917 buf->len = priv_len;
918 maj_stat = gss_unwrap(ctx, 0, buf);
919 pad = priv_len - buf->len;
920 buf->len = saved_len;
921 buf->len -= pad;
922
923
924
925
926
927
928 offset = buf->head[0].iov_len % 4;
929 if (offset) {
930 buf->buflen = RPCSVC_MAXPAYLOAD;
931 xdr_shift_buf(buf, offset);
932 fix_priv_head(buf, pad);
933 }
934 if (maj_stat != GSS_S_COMPLETE)
935 return -EINVAL;
936out_seq:
937 if (svc_getnl(&buf->head[0]) != seq)
938 return -EINVAL;
939 return 0;
940}
941
942struct gss_svc_data {
943
944 struct rpc_gss_wire_cred clcred;
945
946
947 __be32 *verf_start;
948 struct rsc *rsci;
949};
950
951static int
952svcauth_gss_set_client(struct svc_rqst *rqstp)
953{
954 struct gss_svc_data *svcdata = rqstp->rq_auth_data;
955 struct rsc *rsci = svcdata->rsci;
956 struct rpc_gss_wire_cred *gc = &svcdata->clcred;
957 int stat;
958
959
960
961
962
963
964
965
966
967
968 rqstp->rq_gssclient = find_gss_auth_domain(rsci->mechctx, gc->gc_svc);
969 if (rqstp->rq_gssclient == NULL)
970 return SVC_DENIED;
971 stat = svcauth_unix_set_client(rqstp);
972 if (stat == SVC_DROP || stat == SVC_CLOSE)
973 return stat;
974 return SVC_OK;
975}
976
977static inline int
978gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp,
979 struct xdr_netobj *out_handle, int *major_status)
980{
981 struct rsc *rsci;
982 int rc;
983
984 if (*major_status != GSS_S_COMPLETE)
985 return gss_write_null_verf(rqstp);
986 rsci = gss_svc_searchbyctx(cd, out_handle);
987 if (rsci == NULL) {
988 *major_status = GSS_S_NO_CONTEXT;
989 return gss_write_null_verf(rqstp);
990 }
991 rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
992 cache_put(&rsci->h, cd);
993 return rc;
994}
995
996static inline int
997gss_read_common_verf(struct rpc_gss_wire_cred *gc,
998 struct kvec *argv, __be32 *authp,
999 struct xdr_netobj *in_handle)
1000{
1001
1002 *authp = rpc_autherr_badverf;
1003 if (argv->iov_len < 2 * 4)
1004 return SVC_DENIED;
1005 if (svc_getnl(argv) != RPC_AUTH_NULL)
1006 return SVC_DENIED;
1007 if (svc_getnl(argv) != 0)
1008 return SVC_DENIED;
1009
1010 *authp = rpc_autherr_badcred;
1011 if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0)
1012 return SVC_DENIED;
1013 if (dup_netobj(in_handle, &gc->gc_ctx))
1014 return SVC_CLOSE;
1015 *authp = rpc_autherr_badverf;
1016
1017 return 0;
1018}
1019
1020static inline int
1021gss_read_verf(struct rpc_gss_wire_cred *gc,
1022 struct kvec *argv, __be32 *authp,
1023 struct xdr_netobj *in_handle,
1024 struct xdr_netobj *in_token)
1025{
1026 struct xdr_netobj tmpobj;
1027 int res;
1028
1029 res = gss_read_common_verf(gc, argv, authp, in_handle);
1030 if (res)
1031 return res;
1032
1033 if (svc_safe_getnetobj(argv, &tmpobj)) {
1034 kfree(in_handle->data);
1035 return SVC_DENIED;
1036 }
1037 if (dup_netobj(in_token, &tmpobj)) {
1038 kfree(in_handle->data);
1039 return SVC_CLOSE;
1040 }
1041
1042 return 0;
1043}
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054static inline int
1055gss_read_proxy_verf(struct svc_rqst *rqstp,
1056 struct rpc_gss_wire_cred *gc, __be32 *authp,
1057 struct xdr_netobj *in_handle,
1058 struct gssp_in_token *in_token)
1059{
1060 struct kvec *argv = &rqstp->rq_arg.head[0];
1061 u32 inlen;
1062 int res;
1063
1064 res = gss_read_common_verf(gc, argv, authp, in_handle);
1065 if (res)
1066 return res;
1067
1068 inlen = svc_getnl(argv);
1069 if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
1070 return SVC_DENIED;
1071
1072 in_token->pages = rqstp->rq_pages;
1073 in_token->page_base = (ulong)argv->iov_base & ~PAGE_MASK;
1074 in_token->page_len = inlen;
1075
1076 return 0;
1077}
1078
1079static inline int
1080gss_write_resv(struct kvec *resv, size_t size_limit,
1081 struct xdr_netobj *out_handle, struct xdr_netobj *out_token,
1082 int major_status, int minor_status)
1083{
1084 if (resv->iov_len + 4 > size_limit)
1085 return -1;
1086 svc_putnl(resv, RPC_SUCCESS);
1087 if (svc_safe_putnetobj(resv, out_handle))
1088 return -1;
1089 if (resv->iov_len + 3 * 4 > size_limit)
1090 return -1;
1091 svc_putnl(resv, major_status);
1092 svc_putnl(resv, minor_status);
1093 svc_putnl(resv, GSS_SEQ_WIN);
1094 if (svc_safe_putnetobj(resv, out_token))
1095 return -1;
1096 return 0;
1097}
1098
1099
1100
1101
1102
1103
1104
1105
1106static int svcauth_gss_legacy_init(struct svc_rqst *rqstp,
1107 struct rpc_gss_wire_cred *gc, __be32 *authp)
1108{
1109 struct kvec *argv = &rqstp->rq_arg.head[0];
1110 struct kvec *resv = &rqstp->rq_res.head[0];
1111 struct rsi *rsip, rsikey;
1112 int ret;
1113 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1114
1115 memset(&rsikey, 0, sizeof(rsikey));
1116 ret = gss_read_verf(gc, argv, authp,
1117 &rsikey.in_handle, &rsikey.in_token);
1118 if (ret)
1119 return ret;
1120
1121
1122 rsip = rsi_lookup(sn->rsi_cache, &rsikey);
1123 rsi_free(&rsikey);
1124 if (!rsip)
1125 return SVC_CLOSE;
1126 if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
1127
1128 return SVC_CLOSE;
1129
1130 ret = SVC_CLOSE;
1131
1132 if (gss_write_init_verf(sn->rsc_cache, rqstp,
1133 &rsip->out_handle, &rsip->major_status))
1134 goto out;
1135 if (gss_write_resv(resv, PAGE_SIZE,
1136 &rsip->out_handle, &rsip->out_token,
1137 rsip->major_status, rsip->minor_status))
1138 goto out;
1139
1140 ret = SVC_COMPLETE;
1141out:
1142 cache_put(&rsip->h, sn->rsi_cache);
1143 return ret;
1144}
1145
1146static int gss_proxy_save_rsc(struct cache_detail *cd,
1147 struct gssp_upcall_data *ud,
1148 uint64_t *handle)
1149{
1150 struct rsc rsci, *rscp = NULL;
1151 static atomic64_t ctxhctr;
1152 long long ctxh;
1153 struct gss_api_mech *gm = NULL;
1154 time_t expiry;
1155 int status = -EINVAL;
1156
1157 memset(&rsci, 0, sizeof(rsci));
1158
1159 status = -ENOMEM;
1160
1161
1162 ctxh = atomic64_inc_return(&ctxhctr);
1163
1164
1165 *handle = ctxh;
1166
1167
1168 if (dup_to_netobj(&rsci.handle, (char *)handle, sizeof(uint64_t)))
1169 goto out;
1170 rscp = rsc_lookup(cd, &rsci);
1171 if (!rscp)
1172 goto out;
1173
1174
1175 if (!ud->found_creds) {
1176
1177
1178 dprintk("RPC: No creds found!\n");
1179 goto out;
1180 } else {
1181
1182
1183 rsci.cred = ud->creds;
1184 memset(&ud->creds, 0, sizeof(struct svc_cred));
1185
1186 status = -EOPNOTSUPP;
1187
1188 gm = gss_mech_get_by_OID(&ud->mech_oid);
1189 if (!gm)
1190 goto out;
1191 rsci.cred.cr_gss_mech = gm;
1192
1193 status = -EINVAL;
1194
1195 status = gss_import_sec_context(ud->out_handle.data,
1196 ud->out_handle.len,
1197 gm, &rsci.mechctx,
1198 &expiry, GFP_KERNEL);
1199 if (status)
1200 goto out;
1201 }
1202
1203 rsci.h.expiry_time = expiry;
1204 rscp = rsc_update(cd, &rsci, rscp);
1205 status = 0;
1206out:
1207 rsc_free(&rsci);
1208 if (rscp)
1209 cache_put(&rscp->h, cd);
1210 else
1211 status = -ENOMEM;
1212 return status;
1213}
1214
1215static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
1216 struct rpc_gss_wire_cred *gc, __be32 *authp)
1217{
1218 struct kvec *resv = &rqstp->rq_res.head[0];
1219 struct xdr_netobj cli_handle;
1220 struct gssp_upcall_data ud;
1221 uint64_t handle;
1222 int status;
1223 int ret;
1224 struct net *net = rqstp->rq_xprt->xpt_net;
1225 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1226
1227 memset(&ud, 0, sizeof(ud));
1228 ret = gss_read_proxy_verf(rqstp, gc, authp,
1229 &ud.in_handle, &ud.in_token);
1230 if (ret)
1231 return ret;
1232
1233 ret = SVC_CLOSE;
1234
1235
1236 status = gssp_accept_sec_context_upcall(net, &ud);
1237 if (status)
1238 goto out;
1239
1240 dprintk("RPC: svcauth_gss: gss major status = %d\n",
1241 ud.major_status);
1242
1243 switch (ud.major_status) {
1244 case GSS_S_CONTINUE_NEEDED:
1245 cli_handle = ud.out_handle;
1246 break;
1247 case GSS_S_COMPLETE:
1248 status = gss_proxy_save_rsc(sn->rsc_cache, &ud, &handle);
1249 if (status)
1250 goto out;
1251 cli_handle.data = (u8 *)&handle;
1252 cli_handle.len = sizeof(handle);
1253 break;
1254 default:
1255 ret = SVC_CLOSE;
1256 goto out;
1257 }
1258
1259
1260 if (gss_write_init_verf(sn->rsc_cache, rqstp,
1261 &cli_handle, &ud.major_status))
1262 goto out;
1263 if (gss_write_resv(resv, PAGE_SIZE,
1264 &cli_handle, &ud.out_token,
1265 ud.major_status, ud.minor_status))
1266 goto out;
1267
1268 ret = SVC_COMPLETE;
1269out:
1270 gssp_free_upcall_data(&ud);
1271 return ret;
1272}
1273
1274
1275
1276
1277
1278
1279static int set_gss_proxy(struct net *net, int type)
1280{
1281 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1282 int ret;
1283
1284 WARN_ON_ONCE(type != 0 && type != 1);
1285 ret = cmpxchg(&sn->use_gss_proxy, -1, type);
1286 if (ret != -1 && ret != type)
1287 return -EBUSY;
1288 return 0;
1289}
1290
1291static bool use_gss_proxy(struct net *net)
1292{
1293 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1294
1295
1296 if (sn->use_gss_proxy == -1)
1297 set_gss_proxy(net, 0);
1298 return sn->use_gss_proxy;
1299}
1300
1301#ifdef CONFIG_PROC_FS
1302
1303static ssize_t write_gssp(struct file *file, const char __user *buf,
1304 size_t count, loff_t *ppos)
1305{
1306 struct net *net = PDE_DATA(file->f_path.dentry->d_inode);
1307 char tbuf[20];
1308 unsigned long i;
1309 int res;
1310
1311 if (*ppos || count > sizeof(tbuf)-1)
1312 return -EINVAL;
1313 if (copy_from_user(tbuf, buf, count))
1314 return -EFAULT;
1315
1316 tbuf[count] = 0;
1317 res = kstrtoul(tbuf, 0, &i);
1318 if (res)
1319 return res;
1320 if (i != 1)
1321 return -EINVAL;
1322 res = set_gssp_clnt(net);
1323 if (res)
1324 return res;
1325 res = set_gss_proxy(net, 1);
1326 if (res)
1327 return res;
1328 return count;
1329}
1330
1331static ssize_t read_gssp(struct file *file, char __user *buf,
1332 size_t count, loff_t *ppos)
1333{
1334 struct net *net = PDE_DATA(file->f_path.dentry->d_inode);
1335 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1336 unsigned long p = *ppos;
1337 char tbuf[10];
1338 size_t len;
1339
1340 snprintf(tbuf, sizeof(tbuf), "%d\n", sn->use_gss_proxy);
1341 len = strlen(tbuf);
1342 if (p >= len)
1343 return 0;
1344 len -= p;
1345 if (len > count)
1346 len = count;
1347 if (copy_to_user(buf, (void *)(tbuf+p), len))
1348 return -EFAULT;
1349 *ppos += len;
1350 return len;
1351}
1352
1353static const struct file_operations use_gss_proxy_ops = {
1354 .open = nonseekable_open,
1355 .write = write_gssp,
1356 .read = read_gssp,
1357};
1358
1359static int create_use_gss_proxy_proc_entry(struct net *net)
1360{
1361 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1362 struct proc_dir_entry **p = &sn->use_gssp_proc;
1363
1364 sn->use_gss_proxy = -1;
1365 *p = proc_create_data("use-gss-proxy", S_IFREG|S_IRUSR|S_IWUSR,
1366 sn->proc_net_rpc,
1367 &use_gss_proxy_ops, net);
1368 if (!*p)
1369 return -ENOMEM;
1370 init_gssp_clnt(sn);
1371 return 0;
1372}
1373
1374static void destroy_use_gss_proxy_proc_entry(struct net *net)
1375{
1376 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1377
1378 if (sn->use_gssp_proc) {
1379 remove_proc_entry("use-gss-proxy", sn->proc_net_rpc);
1380 clear_gssp_clnt(sn);
1381 }
1382}
1383#else
1384
1385static int create_use_gss_proxy_proc_entry(struct net *net)
1386{
1387 return 0;
1388}
1389
1390static void destroy_use_gss_proxy_proc_entry(struct net *net) {}
1391
1392#endif
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402static int
1403svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1404{
1405 struct kvec *argv = &rqstp->rq_arg.head[0];
1406 struct kvec *resv = &rqstp->rq_res.head[0];
1407 u32 crlen;
1408 struct gss_svc_data *svcdata = rqstp->rq_auth_data;
1409 struct rpc_gss_wire_cred *gc;
1410 struct rsc *rsci = NULL;
1411 __be32 *rpcstart;
1412 __be32 *reject_stat = resv->iov_base + resv->iov_len;
1413 int ret;
1414 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1415
1416 dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
1417 argv->iov_len);
1418
1419 *authp = rpc_autherr_badcred;
1420 if (!svcdata)
1421 svcdata = kmalloc(sizeof(*svcdata), GFP_KERNEL);
1422 if (!svcdata)
1423 goto auth_err;
1424 rqstp->rq_auth_data = svcdata;
1425 svcdata->verf_start = NULL;
1426 svcdata->rsci = NULL;
1427 gc = &svcdata->clcred;
1428
1429
1430
1431
1432 rpcstart = argv->iov_base;
1433 rpcstart -= 7;
1434
1435
1436
1437
1438
1439
1440 if (argv->iov_len < 5 * 4)
1441 goto auth_err;
1442 crlen = svc_getnl(argv);
1443 if (svc_getnl(argv) != RPC_GSS_VERSION)
1444 goto auth_err;
1445 gc->gc_proc = svc_getnl(argv);
1446 gc->gc_seq = svc_getnl(argv);
1447 gc->gc_svc = svc_getnl(argv);
1448 if (svc_safe_getnetobj(argv, &gc->gc_ctx))
1449 goto auth_err;
1450 if (crlen != round_up_to_quad(gc->gc_ctx.len) + 5 * 4)
1451 goto auth_err;
1452
1453 if ((gc->gc_proc != RPC_GSS_PROC_DATA) && (rqstp->rq_proc != 0))
1454 goto auth_err;
1455
1456 *authp = rpc_autherr_badverf;
1457 switch (gc->gc_proc) {
1458 case RPC_GSS_PROC_INIT:
1459 case RPC_GSS_PROC_CONTINUE_INIT:
1460 if (use_gss_proxy(SVC_NET(rqstp)))
1461 return svcauth_gss_proxy_init(rqstp, gc, authp);
1462 else
1463 return svcauth_gss_legacy_init(rqstp, gc, authp);
1464 case RPC_GSS_PROC_DATA:
1465 case RPC_GSS_PROC_DESTROY:
1466
1467 *authp = rpcsec_gsserr_credproblem;
1468 rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx);
1469 if (!rsci)
1470 goto auth_err;
1471 switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
1472 case SVC_OK:
1473 break;
1474 case SVC_DENIED:
1475 goto auth_err;
1476 case SVC_DROP:
1477 goto drop;
1478 }
1479 break;
1480 default:
1481 *authp = rpc_autherr_rejectedcred;
1482 goto auth_err;
1483 }
1484
1485
1486 switch (gc->gc_proc) {
1487 case RPC_GSS_PROC_DESTROY:
1488 if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
1489 goto auth_err;
1490 rsci->h.expiry_time = seconds_since_boot();
1491 set_bit(CACHE_NEGATIVE, &rsci->h.flags);
1492 if (resv->iov_len + 4 > PAGE_SIZE)
1493 goto drop;
1494 svc_putnl(resv, RPC_SUCCESS);
1495 goto complete;
1496 case RPC_GSS_PROC_DATA:
1497 *authp = rpcsec_gsserr_ctxproblem;
1498 svcdata->verf_start = resv->iov_base + resv->iov_len;
1499 if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
1500 goto auth_err;
1501 rqstp->rq_cred = rsci->cred;
1502 get_group_info(rsci->cred.cr_group_info);
1503 *authp = rpc_autherr_badcred;
1504 switch (gc->gc_svc) {
1505 case RPC_GSS_SVC_NONE:
1506 break;
1507 case RPC_GSS_SVC_INTEGRITY:
1508
1509 svc_putnl(resv, 0);
1510 svc_putnl(resv, 0);
1511 if (unwrap_integ_data(rqstp, &rqstp->rq_arg,
1512 gc->gc_seq, rsci->mechctx))
1513 goto garbage_args;
1514 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE;
1515 break;
1516 case RPC_GSS_SVC_PRIVACY:
1517
1518 svc_putnl(resv, 0);
1519 svc_putnl(resv, 0);
1520 if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
1521 gc->gc_seq, rsci->mechctx))
1522 goto garbage_args;
1523 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2;
1524 break;
1525 default:
1526 goto auth_err;
1527 }
1528 svcdata->rsci = rsci;
1529 cache_get(&rsci->h);
1530 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor(
1531 rsci->mechctx->mech_type,
1532 GSS_C_QOP_DEFAULT,
1533 gc->gc_svc);
1534 ret = SVC_OK;
1535 goto out;
1536 }
1537garbage_args:
1538 ret = SVC_GARBAGE;
1539 goto out;
1540auth_err:
1541
1542 xdr_ressize_check(rqstp, reject_stat);
1543 ret = SVC_DENIED;
1544 goto out;
1545complete:
1546 ret = SVC_COMPLETE;
1547 goto out;
1548drop:
1549 ret = SVC_DROP;
1550out:
1551 if (rsci)
1552 cache_put(&rsci->h, sn->rsc_cache);
1553 return ret;
1554}
1555
1556static __be32 *
1557svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd)
1558{
1559 __be32 *p;
1560 u32 verf_len;
1561
1562 p = gsd->verf_start;
1563 gsd->verf_start = NULL;
1564
1565
1566 if (*(p-1) != rpc_success)
1567 return NULL;
1568
1569 p += 1;
1570 verf_len = ntohl(*p++);
1571 p += XDR_QUADLEN(verf_len);
1572
1573 memcpy(p, p + 2, 4);
1574
1575 if (*p != rpc_success) {
1576 resbuf->head[0].iov_len -= 2 * 4;
1577 return NULL;
1578 }
1579 p++;
1580 return p;
1581}
1582
1583static inline int
1584svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
1585{
1586 struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1587 struct rpc_gss_wire_cred *gc = &gsd->clcred;
1588 struct xdr_buf *resbuf = &rqstp->rq_res;
1589 struct xdr_buf integ_buf;
1590 struct xdr_netobj mic;
1591 struct kvec *resv;
1592 __be32 *p;
1593 int integ_offset, integ_len;
1594 int stat = -EINVAL;
1595
1596 p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
1597 if (p == NULL)
1598 goto out;
1599 integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
1600 integ_len = resbuf->len - integ_offset;
1601 BUG_ON(integ_len % 4);
1602 *p++ = htonl(integ_len);
1603 *p++ = htonl(gc->gc_seq);
1604 if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset,
1605 integ_len))
1606 BUG();
1607 if (resbuf->tail[0].iov_base == NULL) {
1608 if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1609 goto out_err;
1610 resbuf->tail[0].iov_base = resbuf->head[0].iov_base
1611 + resbuf->head[0].iov_len;
1612 resbuf->tail[0].iov_len = 0;
1613 resv = &resbuf->tail[0];
1614 } else {
1615 resv = &resbuf->tail[0];
1616 }
1617 mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
1618 if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
1619 goto out_err;
1620 svc_putnl(resv, mic.len);
1621 memset(mic.data + mic.len, 0,
1622 round_up_to_quad(mic.len) - mic.len);
1623 resv->iov_len += XDR_QUADLEN(mic.len) << 2;
1624
1625 resbuf->len += XDR_QUADLEN(mic.len) << 2;
1626 BUG_ON(resv->iov_len > PAGE_SIZE);
1627out:
1628 stat = 0;
1629out_err:
1630 return stat;
1631}
1632
1633static inline int
1634svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
1635{
1636 struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1637 struct rpc_gss_wire_cred *gc = &gsd->clcred;
1638 struct xdr_buf *resbuf = &rqstp->rq_res;
1639 struct page **inpages = NULL;
1640 __be32 *p, *len;
1641 int offset;
1642 int pad;
1643
1644 p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
1645 if (p == NULL)
1646 return 0;
1647 len = p++;
1648 offset = (u8 *)p - (u8 *)resbuf->head[0].iov_base;
1649 *p++ = htonl(gc->gc_seq);
1650 inpages = resbuf->pages;
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661 if (resbuf->tail[0].iov_base) {
1662 BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
1663 + PAGE_SIZE);
1664 BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
1665 if (resbuf->tail[0].iov_len + resbuf->head[0].iov_len
1666 + 2 * RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1667 return -ENOMEM;
1668 memmove(resbuf->tail[0].iov_base + RPC_MAX_AUTH_SIZE,
1669 resbuf->tail[0].iov_base,
1670 resbuf->tail[0].iov_len);
1671 resbuf->tail[0].iov_base += RPC_MAX_AUTH_SIZE;
1672 }
1673
1674
1675
1676
1677
1678
1679
1680 if (resbuf->tail[0].iov_base == NULL) {
1681 if (resbuf->head[0].iov_len + 2*RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1682 return -ENOMEM;
1683 resbuf->tail[0].iov_base = resbuf->head[0].iov_base
1684 + resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE;
1685 resbuf->tail[0].iov_len = 0;
1686 }
1687 if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages))
1688 return -ENOMEM;
1689 *len = htonl(resbuf->len - offset);
1690 pad = 3 - ((resbuf->len - offset - 1)&3);
1691 p = (__be32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
1692 memset(p, 0, pad);
1693 resbuf->tail[0].iov_len += pad;
1694 resbuf->len += pad;
1695 return 0;
1696}
1697
1698static int
1699svcauth_gss_release(struct svc_rqst *rqstp)
1700{
1701 struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1702 struct rpc_gss_wire_cred *gc = &gsd->clcred;
1703 struct xdr_buf *resbuf = &rqstp->rq_res;
1704 int stat = -EINVAL;
1705 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1706
1707 if (gc->gc_proc != RPC_GSS_PROC_DATA)
1708 goto out;
1709
1710 if (gsd->verf_start == NULL)
1711 goto out;
1712
1713
1714
1715 resbuf->len = total_buf_len(resbuf);
1716 switch (gc->gc_svc) {
1717 case RPC_GSS_SVC_NONE:
1718 break;
1719 case RPC_GSS_SVC_INTEGRITY:
1720 stat = svcauth_gss_wrap_resp_integ(rqstp);
1721 if (stat)
1722 goto out_err;
1723 break;
1724 case RPC_GSS_SVC_PRIVACY:
1725 stat = svcauth_gss_wrap_resp_priv(rqstp);
1726 if (stat)
1727 goto out_err;
1728 break;
1729
1730
1731
1732
1733 }
1734
1735out:
1736 stat = 0;
1737out_err:
1738 if (rqstp->rq_client)
1739 auth_domain_put(rqstp->rq_client);
1740 rqstp->rq_client = NULL;
1741 if (rqstp->rq_gssclient)
1742 auth_domain_put(rqstp->rq_gssclient);
1743 rqstp->rq_gssclient = NULL;
1744 if (rqstp->rq_cred.cr_group_info)
1745 put_group_info(rqstp->rq_cred.cr_group_info);
1746 rqstp->rq_cred.cr_group_info = NULL;
1747 if (gsd->rsci)
1748 cache_put(&gsd->rsci->h, sn->rsc_cache);
1749 gsd->rsci = NULL;
1750
1751 return stat;
1752}
1753
1754static void
1755svcauth_gss_domain_release(struct auth_domain *dom)
1756{
1757 struct gss_domain *gd = container_of(dom, struct gss_domain, h);
1758
1759 kfree(dom->name);
1760 kfree(gd);
1761}
1762
1763static struct auth_ops svcauthops_gss = {
1764 .name = "rpcsec_gss",
1765 .owner = THIS_MODULE,
1766 .flavour = RPC_AUTH_GSS,
1767 .accept = svcauth_gss_accept,
1768 .release = svcauth_gss_release,
1769 .domain_release = svcauth_gss_domain_release,
1770 .set_client = svcauth_gss_set_client,
1771};
1772
1773static int rsi_cache_create_net(struct net *net)
1774{
1775 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1776 struct cache_detail *cd;
1777 int err;
1778
1779 cd = cache_create_net(&rsi_cache_template, net);
1780 if (IS_ERR(cd))
1781 return PTR_ERR(cd);
1782 err = cache_register_net(cd, net);
1783 if (err) {
1784 cache_destroy_net(cd, net);
1785 return err;
1786 }
1787 sn->rsi_cache = cd;
1788 return 0;
1789}
1790
1791static void rsi_cache_destroy_net(struct net *net)
1792{
1793 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1794 struct cache_detail *cd = sn->rsi_cache;
1795
1796 sn->rsi_cache = NULL;
1797 cache_purge(cd);
1798 cache_unregister_net(cd, net);
1799 cache_destroy_net(cd, net);
1800}
1801
1802static int rsc_cache_create_net(struct net *net)
1803{
1804 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1805 struct cache_detail *cd;
1806 int err;
1807
1808 cd = cache_create_net(&rsc_cache_template, net);
1809 if (IS_ERR(cd))
1810 return PTR_ERR(cd);
1811 err = cache_register_net(cd, net);
1812 if (err) {
1813 cache_destroy_net(cd, net);
1814 return err;
1815 }
1816 sn->rsc_cache = cd;
1817 return 0;
1818}
1819
1820static void rsc_cache_destroy_net(struct net *net)
1821{
1822 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1823 struct cache_detail *cd = sn->rsc_cache;
1824
1825 sn->rsc_cache = NULL;
1826 cache_purge(cd);
1827 cache_unregister_net(cd, net);
1828 cache_destroy_net(cd, net);
1829}
1830
1831int
1832gss_svc_init_net(struct net *net)
1833{
1834 int rv;
1835
1836 rv = rsc_cache_create_net(net);
1837 if (rv)
1838 return rv;
1839 rv = rsi_cache_create_net(net);
1840 if (rv)
1841 goto out1;
1842 rv = create_use_gss_proxy_proc_entry(net);
1843 if (rv)
1844 goto out2;
1845 return 0;
1846out2:
1847 destroy_use_gss_proxy_proc_entry(net);
1848out1:
1849 rsc_cache_destroy_net(net);
1850 return rv;
1851}
1852
1853void
1854gss_svc_shutdown_net(struct net *net)
1855{
1856 destroy_use_gss_proxy_proc_entry(net);
1857 rsi_cache_destroy_net(net);
1858 rsc_cache_destroy_net(net);
1859}
1860
1861int
1862gss_svc_init(void)
1863{
1864 return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
1865}
1866
1867void
1868gss_svc_shutdown(void)
1869{
1870 svc_auth_unregister(RPC_AUTH_GSS);
1871}
1872