aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c74
1 files changed, 64 insertions, 10 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 237d935747a5..380152603d1e 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -345,7 +345,8 @@ struct rsc {
345 345
346static struct cache_head *rsc_table[RSC_HASHMAX]; 346static struct cache_head *rsc_table[RSC_HASHMAX];
347static struct cache_detail rsc_cache; 347static struct cache_detail rsc_cache;
348static struct rsc *rsc_lookup(struct rsc *item, int set); 348static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
349static struct rsc *rsc_lookup(struct rsc *item);
349 350
350static void rsc_free(struct rsc *rsci) 351static void rsc_free(struct rsc *rsci)
351{ 352{
@@ -372,15 +373,21 @@ rsc_hash(struct rsc *rsci)
372 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS); 373 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
373} 374}
374 375
375static inline int 376static int
376rsc_match(struct rsc *new, struct rsc *tmp) 377rsc_match(struct cache_head *a, struct cache_head *b)
377{ 378{
379 struct rsc *new = container_of(a, struct rsc, h);
380 struct rsc *tmp = container_of(b, struct rsc, h);
381
378 return netobj_equal(&new->handle, &tmp->handle); 382 return netobj_equal(&new->handle, &tmp->handle);
379} 383}
380 384
381static inline void 385static void
382rsc_init(struct rsc *new, struct rsc *tmp) 386rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
383{ 387{
388 struct rsc *new = container_of(cnew, struct rsc, h);
389 struct rsc *tmp = container_of(ctmp, struct rsc, h);
390
384 new->handle.len = tmp->handle.len; 391 new->handle.len = tmp->handle.len;
385 tmp->handle.len = 0; 392 tmp->handle.len = 0;
386 new->handle.data = tmp->handle.data; 393 new->handle.data = tmp->handle.data;
@@ -389,9 +396,12 @@ rsc_init(struct rsc *new, struct rsc *tmp)
389 new->cred.cr_group_info = NULL; 396 new->cred.cr_group_info = NULL;
390} 397}
391 398
392static inline void 399static void
393rsc_update(struct rsc *new, struct rsc *tmp) 400update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
394{ 401{
402 struct rsc *new = container_of(cnew, struct rsc, h);
403 struct rsc *tmp = container_of(ctmp, struct rsc, h);
404
395 new->mechctx = tmp->mechctx; 405 new->mechctx = tmp->mechctx;
396 tmp->mechctx = NULL; 406 tmp->mechctx = NULL;
397 memset(&new->seqdata, 0, sizeof(new->seqdata)); 407 memset(&new->seqdata, 0, sizeof(new->seqdata));
@@ -400,6 +410,16 @@ rsc_update(struct rsc *new, struct rsc *tmp)
400 tmp->cred.cr_group_info = NULL; 410 tmp->cred.cr_group_info = NULL;
401} 411}
402 412
413static struct cache_head *
414rsc_alloc(void)
415{
416 struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL);
417 if (rsci)
418 return &rsci->h;
419 else
420 return NULL;
421}
422
403static int rsc_parse(struct cache_detail *cd, 423static int rsc_parse(struct cache_detail *cd,
404 char *mesg, int mlen) 424 char *mesg, int mlen)
405{ 425{
@@ -425,6 +445,10 @@ static int rsc_parse(struct cache_detail *cd,
425 if (expiry == 0) 445 if (expiry == 0)
426 goto out; 446 goto out;
427 447
448 rscp = rsc_lookup(&rsci);
449 if (!rscp)
450 goto out;
451
428 /* uid, or NEGATIVE */ 452 /* uid, or NEGATIVE */
429 rv = get_int(&mesg, &rsci.cred.cr_uid); 453 rv = get_int(&mesg, &rsci.cred.cr_uid);
430 if (rv == -EINVAL) 454 if (rv == -EINVAL)
@@ -480,12 +504,14 @@ static int rsc_parse(struct cache_detail *cd,
480 gss_mech_put(gm); 504 gss_mech_put(gm);
481 } 505 }
482 rsci.h.expiry_time = expiry; 506 rsci.h.expiry_time = expiry;
483 rscp = rsc_lookup(&rsci, 1); 507 rscp = rsc_update(&rsci, rscp);
484 status = 0; 508 status = 0;
485out: 509out:
486 rsc_free(&rsci); 510 rsc_free(&rsci);
487 if (rscp) 511 if (rscp)
488 rsc_put(&rscp->h, &rsc_cache); 512 rsc_put(&rscp->h, &rsc_cache);
513 else
514 status = -ENOMEM;
489 return status; 515 return status;
490} 516}
491 517
@@ -496,9 +522,37 @@ static struct cache_detail rsc_cache = {
496 .name = "auth.rpcsec.context", 522 .name = "auth.rpcsec.context",
497 .cache_put = rsc_put, 523 .cache_put = rsc_put,
498 .cache_parse = rsc_parse, 524 .cache_parse = rsc_parse,
525 .match = rsc_match,
526 .init = rsc_init,
527 .update = update_rsc,
528 .alloc = rsc_alloc,
499}; 529};
500 530
501static DefineSimpleCacheLookup(rsc, rsc); 531static struct rsc *rsc_lookup(struct rsc *item)
532{
533 struct cache_head *ch;
534 int hash = rsc_hash(item);
535
536 ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
537 if (ch)
538 return container_of(ch, struct rsc, h);
539 else
540 return NULL;
541}
542
543static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
544{
545 struct cache_head *ch;
546 int hash = rsc_hash(new);
547
548 ch = sunrpc_cache_update(&rsc_cache, &new->h,
549 &old->h, hash);
550 if (ch)
551 return container_of(ch, struct rsc, h);
552 else
553 return NULL;
554}
555
502 556
503static struct rsc * 557static struct rsc *
504gss_svc_searchbyctx(struct xdr_netobj *handle) 558gss_svc_searchbyctx(struct xdr_netobj *handle)
@@ -509,7 +563,7 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
509 memset(&rsci, 0, sizeof(rsci)); 563 memset(&rsci, 0, sizeof(rsci));
510 if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) 564 if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
511 return NULL; 565 return NULL;
512 found = rsc_lookup(&rsci, 0); 566 found = rsc_lookup(&rsci);
513 rsc_free(&rsci); 567 rsc_free(&rsci);
514 if (!found) 568 if (!found)
515 return NULL; 569 return NULL;