Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/sunrpc/auth_gss/svcauth_gss.c
15112 views
1
/*
2
* Neil Brown <[email protected]>
3
* J. Bruce Fields <[email protected]>
4
* Andy Adamson <[email protected]>
5
* Dug Song <[email protected]>
6
*
7
* RPCSEC_GSS server authentication.
8
* This implements RPCSEC_GSS as defined in rfc2203 (rpcsec_gss) and rfc2078
9
* (gssapi)
10
*
11
* The RPCSEC_GSS involves three stages:
12
* 1/ context creation
13
* 2/ data exchange
14
* 3/ context destruction
15
*
16
* Context creation is handled largely by upcalls to user-space.
17
* In particular, GSS_Accept_sec_context is handled by an upcall
18
* Data exchange is handled entirely within the kernel
19
* In particular, GSS_GetMIC, GSS_VerifyMIC, GSS_Seal, GSS_Unseal are in-kernel.
20
* Context destruction is handled in-kernel
21
* GSS_Delete_sec_context is in-kernel
22
*
23
* Context creation is initiated by a RPCSEC_GSS_INIT request arriving.
24
* The context handle and gss_token are used as a key into the rpcsec_init cache.
25
* The content of this cache includes some of the outputs of GSS_Accept_sec_context,
26
* being major_status, minor_status, context_handle, reply_token.
27
* These are sent back to the client.
28
* Sequence window management is handled by the kernel. The window size if currently
29
* a compile time constant.
30
*
31
* When user-space is happy that a context is established, it places an entry
32
* in the rpcsec_context cache. The key for this cache is the context_handle.
33
* The content includes:
34
* uid/gidlist - for determining access rights
35
* mechanism type
36
* mechanism specific information, such as a key
37
*
38
*/
39
40
#include <linux/slab.h>
41
#include <linux/types.h>
42
#include <linux/module.h>
43
#include <linux/pagemap.h>
44
45
#include <linux/sunrpc/auth_gss.h>
46
#include <linux/sunrpc/gss_err.h>
47
#include <linux/sunrpc/svcauth.h>
48
#include <linux/sunrpc/svcauth_gss.h>
49
#include <linux/sunrpc/cache.h>
50
51
#ifdef RPC_DEBUG
52
# define RPCDBG_FACILITY RPCDBG_AUTH
53
#endif
54
55
/* The rpcsec_init cache is used for mapping RPCSEC_GSS_{,CONT_}INIT requests
56
* into replies.
57
*
58
* Key is context handle (\x if empty) and gss_token.
59
* Content is major_status minor_status (integers) context_handle, reply_token.
60
*
61
*/
62
63
static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b)
64
{
65
return a->len == b->len && 0 == memcmp(a->data, b->data, a->len);
66
}
67
68
#define RSI_HASHBITS 6
69
#define RSI_HASHMAX (1<<RSI_HASHBITS)
70
71
struct rsi {
72
struct cache_head h;
73
struct xdr_netobj in_handle, in_token;
74
struct xdr_netobj out_handle, out_token;
75
int major_status, minor_status;
76
};
77
78
static struct cache_head *rsi_table[RSI_HASHMAX];
79
static struct cache_detail rsi_cache;
80
static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
81
static struct rsi *rsi_lookup(struct rsi *item);
82
83
static void rsi_free(struct rsi *rsii)
84
{
85
kfree(rsii->in_handle.data);
86
kfree(rsii->in_token.data);
87
kfree(rsii->out_handle.data);
88
kfree(rsii->out_token.data);
89
}
90
91
static void rsi_put(struct kref *ref)
92
{
93
struct rsi *rsii = container_of(ref, struct rsi, h.ref);
94
rsi_free(rsii);
95
kfree(rsii);
96
}
97
98
static inline int rsi_hash(struct rsi *item)
99
{
100
return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
101
^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS);
102
}
103
104
static int rsi_match(struct cache_head *a, struct cache_head *b)
105
{
106
struct rsi *item = container_of(a, struct rsi, h);
107
struct rsi *tmp = container_of(b, struct rsi, h);
108
return netobj_equal(&item->in_handle, &tmp->in_handle) &&
109
netobj_equal(&item->in_token, &tmp->in_token);
110
}
111
112
static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len)
113
{
114
dst->len = len;
115
dst->data = (len ? kmemdup(src, len, GFP_KERNEL) : NULL);
116
if (len && !dst->data)
117
return -ENOMEM;
118
return 0;
119
}
120
121
static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src)
122
{
123
return dup_to_netobj(dst, src->data, src->len);
124
}
125
126
static void rsi_init(struct cache_head *cnew, struct cache_head *citem)
127
{
128
struct rsi *new = container_of(cnew, struct rsi, h);
129
struct rsi *item = container_of(citem, struct rsi, h);
130
131
new->out_handle.data = NULL;
132
new->out_handle.len = 0;
133
new->out_token.data = NULL;
134
new->out_token.len = 0;
135
new->in_handle.len = item->in_handle.len;
136
item->in_handle.len = 0;
137
new->in_token.len = item->in_token.len;
138
item->in_token.len = 0;
139
new->in_handle.data = item->in_handle.data;
140
item->in_handle.data = NULL;
141
new->in_token.data = item->in_token.data;
142
item->in_token.data = NULL;
143
}
144
145
static void update_rsi(struct cache_head *cnew, struct cache_head *citem)
146
{
147
struct rsi *new = container_of(cnew, struct rsi, h);
148
struct rsi *item = container_of(citem, struct rsi, h);
149
150
BUG_ON(new->out_handle.data || new->out_token.data);
151
new->out_handle.len = item->out_handle.len;
152
item->out_handle.len = 0;
153
new->out_token.len = item->out_token.len;
154
item->out_token.len = 0;
155
new->out_handle.data = item->out_handle.data;
156
item->out_handle.data = NULL;
157
new->out_token.data = item->out_token.data;
158
item->out_token.data = NULL;
159
160
new->major_status = item->major_status;
161
new->minor_status = item->minor_status;
162
}
163
164
static struct cache_head *rsi_alloc(void)
165
{
166
struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL);
167
if (rsii)
168
return &rsii->h;
169
else
170
return NULL;
171
}
172
173
static void rsi_request(struct cache_detail *cd,
174
struct cache_head *h,
175
char **bpp, int *blen)
176
{
177
struct rsi *rsii = container_of(h, struct rsi, h);
178
179
qword_addhex(bpp, blen, rsii->in_handle.data, rsii->in_handle.len);
180
qword_addhex(bpp, blen, rsii->in_token.data, rsii->in_token.len);
181
(*bpp)[-1] = '\n';
182
}
183
184
static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
185
{
186
return sunrpc_cache_pipe_upcall(cd, h, rsi_request);
187
}
188
189
190
static int rsi_parse(struct cache_detail *cd,
191
char *mesg, int mlen)
192
{
193
/* context token expiry major minor context token */
194
char *buf = mesg;
195
char *ep;
196
int len;
197
struct rsi rsii, *rsip = NULL;
198
time_t expiry;
199
int status = -EINVAL;
200
201
memset(&rsii, 0, sizeof(rsii));
202
/* handle */
203
len = qword_get(&mesg, buf, mlen);
204
if (len < 0)
205
goto out;
206
status = -ENOMEM;
207
if (dup_to_netobj(&rsii.in_handle, buf, len))
208
goto out;
209
210
/* token */
211
len = qword_get(&mesg, buf, mlen);
212
status = -EINVAL;
213
if (len < 0)
214
goto out;
215
status = -ENOMEM;
216
if (dup_to_netobj(&rsii.in_token, buf, len))
217
goto out;
218
219
rsip = rsi_lookup(&rsii);
220
if (!rsip)
221
goto out;
222
223
rsii.h.flags = 0;
224
/* expiry */
225
expiry = get_expiry(&mesg);
226
status = -EINVAL;
227
if (expiry == 0)
228
goto out;
229
230
/* major/minor */
231
len = qword_get(&mesg, buf, mlen);
232
if (len <= 0)
233
goto out;
234
rsii.major_status = simple_strtoul(buf, &ep, 10);
235
if (*ep)
236
goto out;
237
len = qword_get(&mesg, buf, mlen);
238
if (len <= 0)
239
goto out;
240
rsii.minor_status = simple_strtoul(buf, &ep, 10);
241
if (*ep)
242
goto out;
243
244
/* out_handle */
245
len = qword_get(&mesg, buf, mlen);
246
if (len < 0)
247
goto out;
248
status = -ENOMEM;
249
if (dup_to_netobj(&rsii.out_handle, buf, len))
250
goto out;
251
252
/* out_token */
253
len = qword_get(&mesg, buf, mlen);
254
status = -EINVAL;
255
if (len < 0)
256
goto out;
257
status = -ENOMEM;
258
if (dup_to_netobj(&rsii.out_token, buf, len))
259
goto out;
260
rsii.h.expiry_time = expiry;
261
rsip = rsi_update(&rsii, rsip);
262
status = 0;
263
out:
264
rsi_free(&rsii);
265
if (rsip)
266
cache_put(&rsip->h, &rsi_cache);
267
else
268
status = -ENOMEM;
269
return status;
270
}
271
272
static struct cache_detail rsi_cache = {
273
.owner = THIS_MODULE,
274
.hash_size = RSI_HASHMAX,
275
.hash_table = rsi_table,
276
.name = "auth.rpcsec.init",
277
.cache_put = rsi_put,
278
.cache_upcall = rsi_upcall,
279
.cache_parse = rsi_parse,
280
.match = rsi_match,
281
.init = rsi_init,
282
.update = update_rsi,
283
.alloc = rsi_alloc,
284
};
285
286
static struct rsi *rsi_lookup(struct rsi *item)
287
{
288
struct cache_head *ch;
289
int hash = rsi_hash(item);
290
291
ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
292
if (ch)
293
return container_of(ch, struct rsi, h);
294
else
295
return NULL;
296
}
297
298
static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
299
{
300
struct cache_head *ch;
301
int hash = rsi_hash(new);
302
303
ch = sunrpc_cache_update(&rsi_cache, &new->h,
304
&old->h, hash);
305
if (ch)
306
return container_of(ch, struct rsi, h);
307
else
308
return NULL;
309
}
310
311
312
/*
313
* The rpcsec_context cache is used to store a context that is
314
* used in data exchange.
315
* The key is a context handle. The content is:
316
* uid, gidlist, mechanism, service-set, mech-specific-data
317
*/
318
319
#define RSC_HASHBITS 10
320
#define RSC_HASHMAX (1<<RSC_HASHBITS)
321
322
#define GSS_SEQ_WIN 128
323
324
struct gss_svc_seq_data {
325
/* highest seq number seen so far: */
326
int sd_max;
327
/* for i such that sd_max-GSS_SEQ_WIN < i <= sd_max, the i-th bit of
328
* sd_win is nonzero iff sequence number i has been seen already: */
329
unsigned long sd_win[GSS_SEQ_WIN/BITS_PER_LONG];
330
spinlock_t sd_lock;
331
};
332
333
struct rsc {
334
struct cache_head h;
335
struct xdr_netobj handle;
336
struct svc_cred cred;
337
struct gss_svc_seq_data seqdata;
338
struct gss_ctx *mechctx;
339
char *client_name;
340
};
341
342
static struct cache_head *rsc_table[RSC_HASHMAX];
343
static struct cache_detail rsc_cache;
344
static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
345
static struct rsc *rsc_lookup(struct rsc *item);
346
347
static void rsc_free(struct rsc *rsci)
348
{
349
kfree(rsci->handle.data);
350
if (rsci->mechctx)
351
gss_delete_sec_context(&rsci->mechctx);
352
if (rsci->cred.cr_group_info)
353
put_group_info(rsci->cred.cr_group_info);
354
kfree(rsci->client_name);
355
}
356
357
static void rsc_put(struct kref *ref)
358
{
359
struct rsc *rsci = container_of(ref, struct rsc, h.ref);
360
361
rsc_free(rsci);
362
kfree(rsci);
363
}
364
365
static inline int
366
rsc_hash(struct rsc *rsci)
367
{
368
return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
369
}
370
371
static int
372
rsc_match(struct cache_head *a, struct cache_head *b)
373
{
374
struct rsc *new = container_of(a, struct rsc, h);
375
struct rsc *tmp = container_of(b, struct rsc, h);
376
377
return netobj_equal(&new->handle, &tmp->handle);
378
}
379
380
static void
381
rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
382
{
383
struct rsc *new = container_of(cnew, struct rsc, h);
384
struct rsc *tmp = container_of(ctmp, struct rsc, h);
385
386
new->handle.len = tmp->handle.len;
387
tmp->handle.len = 0;
388
new->handle.data = tmp->handle.data;
389
tmp->handle.data = NULL;
390
new->mechctx = NULL;
391
new->cred.cr_group_info = NULL;
392
new->client_name = NULL;
393
}
394
395
static void
396
update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
397
{
398
struct rsc *new = container_of(cnew, struct rsc, h);
399
struct rsc *tmp = container_of(ctmp, struct rsc, h);
400
401
new->mechctx = tmp->mechctx;
402
tmp->mechctx = NULL;
403
memset(&new->seqdata, 0, sizeof(new->seqdata));
404
spin_lock_init(&new->seqdata.sd_lock);
405
new->cred = tmp->cred;
406
tmp->cred.cr_group_info = NULL;
407
new->client_name = tmp->client_name;
408
tmp->client_name = NULL;
409
}
410
411
static struct cache_head *
412
rsc_alloc(void)
413
{
414
struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL);
415
if (rsci)
416
return &rsci->h;
417
else
418
return NULL;
419
}
420
421
static int rsc_parse(struct cache_detail *cd,
422
char *mesg, int mlen)
423
{
424
/* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */
425
char *buf = mesg;
426
int len, rv;
427
struct rsc rsci, *rscp = NULL;
428
time_t expiry;
429
int status = -EINVAL;
430
struct gss_api_mech *gm = NULL;
431
432
memset(&rsci, 0, sizeof(rsci));
433
/* context handle */
434
len = qword_get(&mesg, buf, mlen);
435
if (len < 0) goto out;
436
status = -ENOMEM;
437
if (dup_to_netobj(&rsci.handle, buf, len))
438
goto out;
439
440
rsci.h.flags = 0;
441
/* expiry */
442
expiry = get_expiry(&mesg);
443
status = -EINVAL;
444
if (expiry == 0)
445
goto out;
446
447
rscp = rsc_lookup(&rsci);
448
if (!rscp)
449
goto out;
450
451
/* uid, or NEGATIVE */
452
rv = get_int(&mesg, &rsci.cred.cr_uid);
453
if (rv == -EINVAL)
454
goto out;
455
if (rv == -ENOENT)
456
set_bit(CACHE_NEGATIVE, &rsci.h.flags);
457
else {
458
int N, i;
459
460
/* gid */
461
if (get_int(&mesg, &rsci.cred.cr_gid))
462
goto out;
463
464
/* number of additional gid's */
465
if (get_int(&mesg, &N))
466
goto out;
467
status = -ENOMEM;
468
rsci.cred.cr_group_info = groups_alloc(N);
469
if (rsci.cred.cr_group_info == NULL)
470
goto out;
471
472
/* gid's */
473
status = -EINVAL;
474
for (i=0; i<N; i++) {
475
gid_t gid;
476
if (get_int(&mesg, &gid))
477
goto out;
478
GROUP_AT(rsci.cred.cr_group_info, i) = gid;
479
}
480
481
/* mech name */
482
len = qword_get(&mesg, buf, mlen);
483
if (len < 0)
484
goto out;
485
gm = gss_mech_get_by_name(buf);
486
status = -EOPNOTSUPP;
487
if (!gm)
488
goto out;
489
490
status = -EINVAL;
491
/* mech-specific data: */
492
len = qword_get(&mesg, buf, mlen);
493
if (len < 0)
494
goto out;
495
status = gss_import_sec_context(buf, len, gm, &rsci.mechctx, GFP_KERNEL);
496
if (status)
497
goto out;
498
499
/* get client name */
500
len = qword_get(&mesg, buf, mlen);
501
if (len > 0) {
502
rsci.client_name = kstrdup(buf, GFP_KERNEL);
503
if (!rsci.client_name)
504
goto out;
505
}
506
507
}
508
rsci.h.expiry_time = expiry;
509
rscp = rsc_update(&rsci, rscp);
510
status = 0;
511
out:
512
gss_mech_put(gm);
513
rsc_free(&rsci);
514
if (rscp)
515
cache_put(&rscp->h, &rsc_cache);
516
else
517
status = -ENOMEM;
518
return status;
519
}
520
521
static struct cache_detail rsc_cache = {
522
.owner = THIS_MODULE,
523
.hash_size = RSC_HASHMAX,
524
.hash_table = rsc_table,
525
.name = "auth.rpcsec.context",
526
.cache_put = rsc_put,
527
.cache_parse = rsc_parse,
528
.match = rsc_match,
529
.init = rsc_init,
530
.update = update_rsc,
531
.alloc = rsc_alloc,
532
};
533
534
static struct rsc *rsc_lookup(struct rsc *item)
535
{
536
struct cache_head *ch;
537
int hash = rsc_hash(item);
538
539
ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
540
if (ch)
541
return container_of(ch, struct rsc, h);
542
else
543
return NULL;
544
}
545
546
static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
547
{
548
struct cache_head *ch;
549
int hash = rsc_hash(new);
550
551
ch = sunrpc_cache_update(&rsc_cache, &new->h,
552
&old->h, hash);
553
if (ch)
554
return container_of(ch, struct rsc, h);
555
else
556
return NULL;
557
}
558
559
560
static struct rsc *
561
gss_svc_searchbyctx(struct xdr_netobj *handle)
562
{
563
struct rsc rsci;
564
struct rsc *found;
565
566
memset(&rsci, 0, sizeof(rsci));
567
if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
568
return NULL;
569
found = rsc_lookup(&rsci);
570
rsc_free(&rsci);
571
if (!found)
572
return NULL;
573
if (cache_check(&rsc_cache, &found->h, NULL))
574
return NULL;
575
return found;
576
}
577
578
/* Implements sequence number algorithm as specified in RFC 2203. */
579
static int
580
gss_check_seq_num(struct rsc *rsci, int seq_num)
581
{
582
struct gss_svc_seq_data *sd = &rsci->seqdata;
583
584
spin_lock(&sd->sd_lock);
585
if (seq_num > sd->sd_max) {
586
if (seq_num >= sd->sd_max + GSS_SEQ_WIN) {
587
memset(sd->sd_win,0,sizeof(sd->sd_win));
588
sd->sd_max = seq_num;
589
} else while (sd->sd_max < seq_num) {
590
sd->sd_max++;
591
__clear_bit(sd->sd_max % GSS_SEQ_WIN, sd->sd_win);
592
}
593
__set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win);
594
goto ok;
595
} else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) {
596
goto drop;
597
}
598
/* sd_max - GSS_SEQ_WIN < seq_num <= sd_max */
599
if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win))
600
goto drop;
601
ok:
602
spin_unlock(&sd->sd_lock);
603
return 1;
604
drop:
605
spin_unlock(&sd->sd_lock);
606
return 0;
607
}
608
609
static inline u32 round_up_to_quad(u32 i)
610
{
611
return (i + 3 ) & ~3;
612
}
613
614
static inline int
615
svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
616
{
617
int l;
618
619
if (argv->iov_len < 4)
620
return -1;
621
o->len = svc_getnl(argv);
622
l = round_up_to_quad(o->len);
623
if (argv->iov_len < l)
624
return -1;
625
o->data = argv->iov_base;
626
argv->iov_base += l;
627
argv->iov_len -= l;
628
return 0;
629
}
630
631
static inline int
632
svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
633
{
634
u8 *p;
635
636
if (resv->iov_len + 4 > PAGE_SIZE)
637
return -1;
638
svc_putnl(resv, o->len);
639
p = resv->iov_base + resv->iov_len;
640
resv->iov_len += round_up_to_quad(o->len);
641
if (resv->iov_len > PAGE_SIZE)
642
return -1;
643
memcpy(p, o->data, o->len);
644
memset(p + o->len, 0, round_up_to_quad(o->len) - o->len);
645
return 0;
646
}
647
648
/*
649
* Verify the checksum on the header and return SVC_OK on success.
650
* Otherwise, return SVC_DROP (in the case of a bad sequence number)
651
* or return SVC_DENIED and indicate error in authp.
652
*/
653
static int
654
gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
655
__be32 *rpcstart, struct rpc_gss_wire_cred *gc, __be32 *authp)
656
{
657
struct gss_ctx *ctx_id = rsci->mechctx;
658
struct xdr_buf rpchdr;
659
struct xdr_netobj checksum;
660
u32 flavor = 0;
661
struct kvec *argv = &rqstp->rq_arg.head[0];
662
struct kvec iov;
663
664
/* data to compute the checksum over: */
665
iov.iov_base = rpcstart;
666
iov.iov_len = (u8 *)argv->iov_base - (u8 *)rpcstart;
667
xdr_buf_from_iov(&iov, &rpchdr);
668
669
*authp = rpc_autherr_badverf;
670
if (argv->iov_len < 4)
671
return SVC_DENIED;
672
flavor = svc_getnl(argv);
673
if (flavor != RPC_AUTH_GSS)
674
return SVC_DENIED;
675
if (svc_safe_getnetobj(argv, &checksum))
676
return SVC_DENIED;
677
678
if (rqstp->rq_deferred) /* skip verification of revisited request */
679
return SVC_OK;
680
if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
681
*authp = rpcsec_gsserr_credproblem;
682
return SVC_DENIED;
683
}
684
685
if (gc->gc_seq > MAXSEQ) {
686
dprintk("RPC: svcauth_gss: discarding request with "
687
"large sequence number %d\n", gc->gc_seq);
688
*authp = rpcsec_gsserr_ctxproblem;
689
return SVC_DENIED;
690
}
691
if (!gss_check_seq_num(rsci, gc->gc_seq)) {
692
dprintk("RPC: svcauth_gss: discarding request with "
693
"old sequence number %d\n", gc->gc_seq);
694
return SVC_DROP;
695
}
696
return SVC_OK;
697
}
698
699
static int
700
gss_write_null_verf(struct svc_rqst *rqstp)
701
{
702
__be32 *p;
703
704
svc_putnl(rqstp->rq_res.head, RPC_AUTH_NULL);
705
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
706
/* don't really need to check if head->iov_len > PAGE_SIZE ... */
707
*p++ = 0;
708
if (!xdr_ressize_check(rqstp, p))
709
return -1;
710
return 0;
711
}
712
713
static int
714
gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
715
{
716
__be32 xdr_seq;
717
u32 maj_stat;
718
struct xdr_buf verf_data;
719
struct xdr_netobj mic;
720
__be32 *p;
721
struct kvec iov;
722
723
svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
724
xdr_seq = htonl(seq);
725
726
iov.iov_base = &xdr_seq;
727
iov.iov_len = sizeof(xdr_seq);
728
xdr_buf_from_iov(&iov, &verf_data);
729
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
730
mic.data = (u8 *)(p + 1);
731
maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
732
if (maj_stat != GSS_S_COMPLETE)
733
return -1;
734
*p++ = htonl(mic.len);
735
memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len);
736
p += XDR_QUADLEN(mic.len);
737
if (!xdr_ressize_check(rqstp, p))
738
return -1;
739
return 0;
740
}
741
742
struct gss_domain {
743
struct auth_domain h;
744
u32 pseudoflavor;
745
};
746
747
static struct auth_domain *
748
find_gss_auth_domain(struct gss_ctx *ctx, u32 svc)
749
{
750
char *name;
751
752
name = gss_service_to_auth_domain_name(ctx->mech_type, svc);
753
if (!name)
754
return NULL;
755
return auth_domain_find(name);
756
}
757
758
static struct auth_ops svcauthops_gss;
759
760
u32 svcauth_gss_flavor(struct auth_domain *dom)
761
{
762
struct gss_domain *gd = container_of(dom, struct gss_domain, h);
763
764
return gd->pseudoflavor;
765
}
766
767
EXPORT_SYMBOL_GPL(svcauth_gss_flavor);
768
769
int
770
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
771
{
772
struct gss_domain *new;
773
struct auth_domain *test;
774
int stat = -ENOMEM;
775
776
new = kmalloc(sizeof(*new), GFP_KERNEL);
777
if (!new)
778
goto out;
779
kref_init(&new->h.ref);
780
new->h.name = kstrdup(name, GFP_KERNEL);
781
if (!new->h.name)
782
goto out_free_dom;
783
new->h.flavour = &svcauthops_gss;
784
new->pseudoflavor = pseudoflavor;
785
786
stat = 0;
787
test = auth_domain_lookup(name, &new->h);
788
if (test != &new->h) { /* Duplicate registration */
789
auth_domain_put(test);
790
kfree(new->h.name);
791
goto out_free_dom;
792
}
793
return 0;
794
795
out_free_dom:
796
kfree(new);
797
out:
798
return stat;
799
}
800
801
EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor);
802
803
static inline int
804
read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
805
{
806
__be32 raw;
807
int status;
808
809
status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
810
if (status)
811
return status;
812
*obj = ntohl(raw);
813
return 0;
814
}
815
816
/* It would be nice if this bit of code could be shared with the client.
817
* Obstacles:
818
* The client shouldn't malloc(), would have to pass in own memory.
819
* The server uses base of head iovec as read pointer, while the
820
* client uses separate pointer. */
821
static int
822
unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
823
{
824
int stat = -EINVAL;
825
u32 integ_len, maj_stat;
826
struct xdr_netobj mic;
827
struct xdr_buf integ_buf;
828
829
integ_len = svc_getnl(&buf->head[0]);
830
if (integ_len & 3)
831
return stat;
832
if (integ_len > buf->len)
833
return stat;
834
if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
835
BUG();
836
/* copy out mic... */
837
if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
838
BUG();
839
if (mic.len > RPC_MAX_AUTH_SIZE)
840
return stat;
841
mic.data = kmalloc(mic.len, GFP_KERNEL);
842
if (!mic.data)
843
return stat;
844
if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
845
goto out;
846
maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
847
if (maj_stat != GSS_S_COMPLETE)
848
goto out;
849
if (svc_getnl(&buf->head[0]) != seq)
850
goto out;
851
stat = 0;
852
out:
853
kfree(mic.data);
854
return stat;
855
}
856
857
static inline int
858
total_buf_len(struct xdr_buf *buf)
859
{
860
return buf->head[0].iov_len + buf->page_len + buf->tail[0].iov_len;
861
}
862
863
static void
864
fix_priv_head(struct xdr_buf *buf, int pad)
865
{
866
if (buf->page_len == 0) {
867
/* We need to adjust head and buf->len in tandem in this
868
* case to make svc_defer() work--it finds the original
869
* buffer start using buf->len - buf->head[0].iov_len. */
870
buf->head[0].iov_len -= pad;
871
}
872
}
873
874
static int
875
unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
876
{
877
u32 priv_len, maj_stat;
878
int pad, saved_len, remaining_len, offset;
879
880
rqstp->rq_splice_ok = 0;
881
882
priv_len = svc_getnl(&buf->head[0]);
883
if (rqstp->rq_deferred) {
884
/* Already decrypted last time through! The sequence number
885
* check at out_seq is unnecessary but harmless: */
886
goto out_seq;
887
}
888
/* buf->len is the number of bytes from the original start of the
889
* request to the end, where head[0].iov_len is just the bytes
890
* not yet read from the head, so these two values are different: */
891
remaining_len = total_buf_len(buf);
892
if (priv_len > remaining_len)
893
return -EINVAL;
894
pad = remaining_len - priv_len;
895
buf->len -= pad;
896
fix_priv_head(buf, pad);
897
898
/* Maybe it would be better to give gss_unwrap a length parameter: */
899
saved_len = buf->len;
900
buf->len = priv_len;
901
maj_stat = gss_unwrap(ctx, 0, buf);
902
pad = priv_len - buf->len;
903
buf->len = saved_len;
904
buf->len -= pad;
905
/* The upper layers assume the buffer is aligned on 4-byte boundaries.
906
* In the krb5p case, at least, the data ends up offset, so we need to
907
* move it around. */
908
/* XXX: This is very inefficient. It would be better to either do
909
* this while we encrypt, or maybe in the receive code, if we can peak
910
* ahead and work out the service and mechanism there. */
911
offset = buf->head[0].iov_len % 4;
912
if (offset) {
913
buf->buflen = RPCSVC_MAXPAYLOAD;
914
xdr_shift_buf(buf, offset);
915
fix_priv_head(buf, pad);
916
}
917
if (maj_stat != GSS_S_COMPLETE)
918
return -EINVAL;
919
out_seq:
920
if (svc_getnl(&buf->head[0]) != seq)
921
return -EINVAL;
922
return 0;
923
}
924
925
struct gss_svc_data {
926
/* decoded gss client cred: */
927
struct rpc_gss_wire_cred clcred;
928
/* save a pointer to the beginning of the encoded verifier,
929
* for use in encryption/checksumming in svcauth_gss_release: */
930
__be32 *verf_start;
931
struct rsc *rsci;
932
};
933
934
char *svc_gss_principal(struct svc_rqst *rqstp)
935
{
936
struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data;
937
938
if (gd && gd->rsci)
939
return gd->rsci->client_name;
940
return NULL;
941
}
942
EXPORT_SYMBOL_GPL(svc_gss_principal);
943
944
static int
945
svcauth_gss_set_client(struct svc_rqst *rqstp)
946
{
947
struct gss_svc_data *svcdata = rqstp->rq_auth_data;
948
struct rsc *rsci = svcdata->rsci;
949
struct rpc_gss_wire_cred *gc = &svcdata->clcred;
950
int stat;
951
952
/*
953
* A gss export can be specified either by:
954
* export *(sec=krb5,rw)
955
* or by
956
* export gss/krb5(rw)
957
* The latter is deprecated; but for backwards compatibility reasons
958
* the nfsd code will still fall back on trying it if the former
959
* doesn't work; so we try to make both available to nfsd, below.
960
*/
961
rqstp->rq_gssclient = find_gss_auth_domain(rsci->mechctx, gc->gc_svc);
962
if (rqstp->rq_gssclient == NULL)
963
return SVC_DENIED;
964
stat = svcauth_unix_set_client(rqstp);
965
if (stat == SVC_DROP || stat == SVC_CLOSE)
966
return stat;
967
return SVC_OK;
968
}
969
970
static inline int
971
gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
972
{
973
struct rsc *rsci;
974
int rc;
975
976
if (rsip->major_status != GSS_S_COMPLETE)
977
return gss_write_null_verf(rqstp);
978
rsci = gss_svc_searchbyctx(&rsip->out_handle);
979
if (rsci == NULL) {
980
rsip->major_status = GSS_S_NO_CONTEXT;
981
return gss_write_null_verf(rqstp);
982
}
983
rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
984
cache_put(&rsci->h, &rsc_cache);
985
return rc;
986
}
987
988
/*
989
* Having read the cred already and found we're in the context
990
* initiation case, read the verifier and initiate (or check the results
991
* of) upcalls to userspace for help with context initiation. If
992
* the upcall results are available, write the verifier and result.
993
* Otherwise, drop the request pending an answer to the upcall.
994
*/
995
static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
996
struct rpc_gss_wire_cred *gc, __be32 *authp)
997
{
998
struct kvec *argv = &rqstp->rq_arg.head[0];
999
struct kvec *resv = &rqstp->rq_res.head[0];
1000
struct xdr_netobj tmpobj;
1001
struct rsi *rsip, rsikey;
1002
int ret;
1003
1004
/* Read the verifier; should be NULL: */
1005
*authp = rpc_autherr_badverf;
1006
if (argv->iov_len < 2 * 4)
1007
return SVC_DENIED;
1008
if (svc_getnl(argv) != RPC_AUTH_NULL)
1009
return SVC_DENIED;
1010
if (svc_getnl(argv) != 0)
1011
return SVC_DENIED;
1012
1013
/* Martial context handle and token for upcall: */
1014
*authp = rpc_autherr_badcred;
1015
if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0)
1016
return SVC_DENIED;
1017
memset(&rsikey, 0, sizeof(rsikey));
1018
if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx))
1019
return SVC_CLOSE;
1020
*authp = rpc_autherr_badverf;
1021
if (svc_safe_getnetobj(argv, &tmpobj)) {
1022
kfree(rsikey.in_handle.data);
1023
return SVC_DENIED;
1024
}
1025
if (dup_netobj(&rsikey.in_token, &tmpobj)) {
1026
kfree(rsikey.in_handle.data);
1027
return SVC_CLOSE;
1028
}
1029
1030
/* Perform upcall, or find upcall result: */
1031
rsip = rsi_lookup(&rsikey);
1032
rsi_free(&rsikey);
1033
if (!rsip)
1034
return SVC_CLOSE;
1035
if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
1036
/* No upcall result: */
1037
return SVC_CLOSE;
1038
1039
ret = SVC_CLOSE;
1040
/* Got an answer to the upcall; use it: */
1041
if (gss_write_init_verf(rqstp, rsip))
1042
goto out;
1043
if (resv->iov_len + 4 > PAGE_SIZE)
1044
goto out;
1045
svc_putnl(resv, RPC_SUCCESS);
1046
if (svc_safe_putnetobj(resv, &rsip->out_handle))
1047
goto out;
1048
if (resv->iov_len + 3 * 4 > PAGE_SIZE)
1049
goto out;
1050
svc_putnl(resv, rsip->major_status);
1051
svc_putnl(resv, rsip->minor_status);
1052
svc_putnl(resv, GSS_SEQ_WIN);
1053
if (svc_safe_putnetobj(resv, &rsip->out_token))
1054
goto out;
1055
1056
ret = SVC_COMPLETE;
1057
out:
1058
cache_put(&rsip->h, &rsi_cache);
1059
return ret;
1060
}
1061
1062
/*
1063
* Accept an rpcsec packet.
1064
* If context establishment, punt to user space
1065
* If data exchange, verify/decrypt
1066
* If context destruction, handle here
1067
* In the context establishment and destruction case we encode
1068
* response here and return SVC_COMPLETE.
1069
*/
1070
static int
1071
svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1072
{
1073
struct kvec *argv = &rqstp->rq_arg.head[0];
1074
struct kvec *resv = &rqstp->rq_res.head[0];
1075
u32 crlen;
1076
struct gss_svc_data *svcdata = rqstp->rq_auth_data;
1077
struct rpc_gss_wire_cred *gc;
1078
struct rsc *rsci = NULL;
1079
__be32 *rpcstart;
1080
__be32 *reject_stat = resv->iov_base + resv->iov_len;
1081
int ret;
1082
1083
dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
1084
argv->iov_len);
1085
1086
*authp = rpc_autherr_badcred;
1087
if (!svcdata)
1088
svcdata = kmalloc(sizeof(*svcdata), GFP_KERNEL);
1089
if (!svcdata)
1090
goto auth_err;
1091
rqstp->rq_auth_data = svcdata;
1092
svcdata->verf_start = NULL;
1093
svcdata->rsci = NULL;
1094
gc = &svcdata->clcred;
1095
1096
/* start of rpc packet is 7 u32's back from here:
1097
* xid direction rpcversion prog vers proc flavour
1098
*/
1099
rpcstart = argv->iov_base;
1100
rpcstart -= 7;
1101
1102
/* credential is:
1103
* version(==1), proc(0,1,2,3), seq, service (1,2,3), handle
1104
* at least 5 u32s, and is preceded by length, so that makes 6.
1105
*/
1106
1107
if (argv->iov_len < 5 * 4)
1108
goto auth_err;
1109
crlen = svc_getnl(argv);
1110
if (svc_getnl(argv) != RPC_GSS_VERSION)
1111
goto auth_err;
1112
gc->gc_proc = svc_getnl(argv);
1113
gc->gc_seq = svc_getnl(argv);
1114
gc->gc_svc = svc_getnl(argv);
1115
if (svc_safe_getnetobj(argv, &gc->gc_ctx))
1116
goto auth_err;
1117
if (crlen != round_up_to_quad(gc->gc_ctx.len) + 5 * 4)
1118
goto auth_err;
1119
1120
if ((gc->gc_proc != RPC_GSS_PROC_DATA) && (rqstp->rq_proc != 0))
1121
goto auth_err;
1122
1123
*authp = rpc_autherr_badverf;
1124
switch (gc->gc_proc) {
1125
case RPC_GSS_PROC_INIT:
1126
case RPC_GSS_PROC_CONTINUE_INIT:
1127
return svcauth_gss_handle_init(rqstp, gc, authp);
1128
case RPC_GSS_PROC_DATA:
1129
case RPC_GSS_PROC_DESTROY:
1130
/* Look up the context, and check the verifier: */
1131
*authp = rpcsec_gsserr_credproblem;
1132
rsci = gss_svc_searchbyctx(&gc->gc_ctx);
1133
if (!rsci)
1134
goto auth_err;
1135
switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
1136
case SVC_OK:
1137
break;
1138
case SVC_DENIED:
1139
goto auth_err;
1140
case SVC_DROP:
1141
goto drop;
1142
}
1143
break;
1144
default:
1145
*authp = rpc_autherr_rejectedcred;
1146
goto auth_err;
1147
}
1148
1149
/* now act upon the command: */
1150
switch (gc->gc_proc) {
1151
case RPC_GSS_PROC_DESTROY:
1152
if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
1153
goto auth_err;
1154
rsci->h.expiry_time = get_seconds();
1155
set_bit(CACHE_NEGATIVE, &rsci->h.flags);
1156
if (resv->iov_len + 4 > PAGE_SIZE)
1157
goto drop;
1158
svc_putnl(resv, RPC_SUCCESS);
1159
goto complete;
1160
case RPC_GSS_PROC_DATA:
1161
*authp = rpcsec_gsserr_ctxproblem;
1162
svcdata->verf_start = resv->iov_base + resv->iov_len;
1163
if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
1164
goto auth_err;
1165
rqstp->rq_cred = rsci->cred;
1166
get_group_info(rsci->cred.cr_group_info);
1167
*authp = rpc_autherr_badcred;
1168
switch (gc->gc_svc) {
1169
case RPC_GSS_SVC_NONE:
1170
break;
1171
case RPC_GSS_SVC_INTEGRITY:
1172
/* placeholders for length and seq. number: */
1173
svc_putnl(resv, 0);
1174
svc_putnl(resv, 0);
1175
if (unwrap_integ_data(&rqstp->rq_arg,
1176
gc->gc_seq, rsci->mechctx))
1177
goto garbage_args;
1178
break;
1179
case RPC_GSS_SVC_PRIVACY:
1180
/* placeholders for length and seq. number: */
1181
svc_putnl(resv, 0);
1182
svc_putnl(resv, 0);
1183
if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
1184
gc->gc_seq, rsci->mechctx))
1185
goto garbage_args;
1186
break;
1187
default:
1188
goto auth_err;
1189
}
1190
svcdata->rsci = rsci;
1191
cache_get(&rsci->h);
1192
rqstp->rq_flavor = gss_svc_to_pseudoflavor(
1193
rsci->mechctx->mech_type, gc->gc_svc);
1194
ret = SVC_OK;
1195
goto out;
1196
}
1197
garbage_args:
1198
ret = SVC_GARBAGE;
1199
goto out;
1200
auth_err:
1201
/* Restore write pointer to its original value: */
1202
xdr_ressize_check(rqstp, reject_stat);
1203
ret = SVC_DENIED;
1204
goto out;
1205
complete:
1206
ret = SVC_COMPLETE;
1207
goto out;
1208
drop:
1209
ret = SVC_DROP;
1210
out:
1211
if (rsci)
1212
cache_put(&rsci->h, &rsc_cache);
1213
return ret;
1214
}
1215
1216
static __be32 *
1217
svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd)
1218
{
1219
__be32 *p;
1220
u32 verf_len;
1221
1222
p = gsd->verf_start;
1223
gsd->verf_start = NULL;
1224
1225
/* If the reply stat is nonzero, don't wrap: */
1226
if (*(p-1) != rpc_success)
1227
return NULL;
1228
/* Skip the verifier: */
1229
p += 1;
1230
verf_len = ntohl(*p++);
1231
p += XDR_QUADLEN(verf_len);
1232
/* move accept_stat to right place: */
1233
memcpy(p, p + 2, 4);
1234
/* Also don't wrap if the accept stat is nonzero: */
1235
if (*p != rpc_success) {
1236
resbuf->head[0].iov_len -= 2 * 4;
1237
return NULL;
1238
}
1239
p++;
1240
return p;
1241
}
1242
1243
static inline int
1244
svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
1245
{
1246
struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1247
struct rpc_gss_wire_cred *gc = &gsd->clcred;
1248
struct xdr_buf *resbuf = &rqstp->rq_res;
1249
struct xdr_buf integ_buf;
1250
struct xdr_netobj mic;
1251
struct kvec *resv;
1252
__be32 *p;
1253
int integ_offset, integ_len;
1254
int stat = -EINVAL;
1255
1256
p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
1257
if (p == NULL)
1258
goto out;
1259
integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
1260
integ_len = resbuf->len - integ_offset;
1261
BUG_ON(integ_len % 4);
1262
*p++ = htonl(integ_len);
1263
*p++ = htonl(gc->gc_seq);
1264
if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset,
1265
integ_len))
1266
BUG();
1267
if (resbuf->tail[0].iov_base == NULL) {
1268
if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1269
goto out_err;
1270
resbuf->tail[0].iov_base = resbuf->head[0].iov_base
1271
+ resbuf->head[0].iov_len;
1272
resbuf->tail[0].iov_len = 0;
1273
resv = &resbuf->tail[0];
1274
} else {
1275
resv = &resbuf->tail[0];
1276
}
1277
mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
1278
if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
1279
goto out_err;
1280
svc_putnl(resv, mic.len);
1281
memset(mic.data + mic.len, 0,
1282
round_up_to_quad(mic.len) - mic.len);
1283
resv->iov_len += XDR_QUADLEN(mic.len) << 2;
1284
/* not strictly required: */
1285
resbuf->len += XDR_QUADLEN(mic.len) << 2;
1286
BUG_ON(resv->iov_len > PAGE_SIZE);
1287
out:
1288
stat = 0;
1289
out_err:
1290
return stat;
1291
}
1292
1293
static inline int
1294
svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
1295
{
1296
struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1297
struct rpc_gss_wire_cred *gc = &gsd->clcred;
1298
struct xdr_buf *resbuf = &rqstp->rq_res;
1299
struct page **inpages = NULL;
1300
__be32 *p, *len;
1301
int offset;
1302
int pad;
1303
1304
p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
1305
if (p == NULL)
1306
return 0;
1307
len = p++;
1308
offset = (u8 *)p - (u8 *)resbuf->head[0].iov_base;
1309
*p++ = htonl(gc->gc_seq);
1310
inpages = resbuf->pages;
1311
/* XXX: Would be better to write some xdr helper functions for
1312
* nfs{2,3,4}xdr.c that place the data right, instead of copying: */
1313
1314
/*
1315
* If there is currently tail data, make sure there is
1316
* room for the head, tail, and 2 * RPC_MAX_AUTH_SIZE in
1317
* the page, and move the current tail data such that
1318
* there is RPC_MAX_AUTH_SIZE slack space available in
1319
* both the head and tail.
1320
*/
1321
if (resbuf->tail[0].iov_base) {
1322
BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
1323
+ PAGE_SIZE);
1324
BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
1325
if (resbuf->tail[0].iov_len + resbuf->head[0].iov_len
1326
+ 2 * RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1327
return -ENOMEM;
1328
memmove(resbuf->tail[0].iov_base + RPC_MAX_AUTH_SIZE,
1329
resbuf->tail[0].iov_base,
1330
resbuf->tail[0].iov_len);
1331
resbuf->tail[0].iov_base += RPC_MAX_AUTH_SIZE;
1332
}
1333
/*
1334
* If there is no current tail data, make sure there is
1335
* room for the head data, and 2 * RPC_MAX_AUTH_SIZE in the
1336
* allotted page, and set up tail information such that there
1337
* is RPC_MAX_AUTH_SIZE slack space available in both the
1338
* head and tail.
1339
*/
1340
if (resbuf->tail[0].iov_base == NULL) {
1341
if (resbuf->head[0].iov_len + 2*RPC_MAX_AUTH_SIZE > PAGE_SIZE)
1342
return -ENOMEM;
1343
resbuf->tail[0].iov_base = resbuf->head[0].iov_base
1344
+ resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE;
1345
resbuf->tail[0].iov_len = 0;
1346
}
1347
if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages))
1348
return -ENOMEM;
1349
*len = htonl(resbuf->len - offset);
1350
pad = 3 - ((resbuf->len - offset - 1)&3);
1351
p = (__be32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
1352
memset(p, 0, pad);
1353
resbuf->tail[0].iov_len += pad;
1354
resbuf->len += pad;
1355
return 0;
1356
}
1357
1358
static int
1359
svcauth_gss_release(struct svc_rqst *rqstp)
1360
{
1361
struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1362
struct rpc_gss_wire_cred *gc = &gsd->clcred;
1363
struct xdr_buf *resbuf = &rqstp->rq_res;
1364
int stat = -EINVAL;
1365
1366
if (gc->gc_proc != RPC_GSS_PROC_DATA)
1367
goto out;
1368
/* Release can be called twice, but we only wrap once. */
1369
if (gsd->verf_start == NULL)
1370
goto out;
1371
/* normally not set till svc_send, but we need it here: */
1372
/* XXX: what for? Do we mess it up the moment we call svc_putu32
1373
* or whatever? */
1374
resbuf->len = total_buf_len(resbuf);
1375
switch (gc->gc_svc) {
1376
case RPC_GSS_SVC_NONE:
1377
break;
1378
case RPC_GSS_SVC_INTEGRITY:
1379
stat = svcauth_gss_wrap_resp_integ(rqstp);
1380
if (stat)
1381
goto out_err;
1382
break;
1383
case RPC_GSS_SVC_PRIVACY:
1384
stat = svcauth_gss_wrap_resp_priv(rqstp);
1385
if (stat)
1386
goto out_err;
1387
break;
1388
/*
1389
* For any other gc_svc value, svcauth_gss_accept() already set
1390
* the auth_error appropriately; just fall through:
1391
*/
1392
}
1393
1394
out:
1395
stat = 0;
1396
out_err:
1397
if (rqstp->rq_client)
1398
auth_domain_put(rqstp->rq_client);
1399
rqstp->rq_client = NULL;
1400
if (rqstp->rq_gssclient)
1401
auth_domain_put(rqstp->rq_gssclient);
1402
rqstp->rq_gssclient = NULL;
1403
if (rqstp->rq_cred.cr_group_info)
1404
put_group_info(rqstp->rq_cred.cr_group_info);
1405
rqstp->rq_cred.cr_group_info = NULL;
1406
if (gsd->rsci)
1407
cache_put(&gsd->rsci->h, &rsc_cache);
1408
gsd->rsci = NULL;
1409
1410
return stat;
1411
}
1412
1413
static void
1414
svcauth_gss_domain_release(struct auth_domain *dom)
1415
{
1416
struct gss_domain *gd = container_of(dom, struct gss_domain, h);
1417
1418
kfree(dom->name);
1419
kfree(gd);
1420
}
1421
1422
static struct auth_ops svcauthops_gss = {
1423
.name = "rpcsec_gss",
1424
.owner = THIS_MODULE,
1425
.flavour = RPC_AUTH_GSS,
1426
.accept = svcauth_gss_accept,
1427
.release = svcauth_gss_release,
1428
.domain_release = svcauth_gss_domain_release,
1429
.set_client = svcauth_gss_set_client,
1430
};
1431
1432
int
1433
gss_svc_init(void)
1434
{
1435
int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
1436
if (rv)
1437
return rv;
1438
rv = cache_register(&rsc_cache);
1439
if (rv)
1440
goto out1;
1441
rv = cache_register(&rsi_cache);
1442
if (rv)
1443
goto out2;
1444
return 0;
1445
out2:
1446
cache_unregister(&rsc_cache);
1447
out1:
1448
svc_auth_unregister(RPC_AUTH_GSS);
1449
return rv;
1450
}
1451
1452
void
1453
gss_svc_shutdown(void)
1454
{
1455
cache_unregister(&rsc_cache);
1456
cache_unregister(&rsi_cache);
1457
svc_auth_unregister(RPC_AUTH_GSS);
1458
}
1459
1460