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