diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 11:53:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 11:53:47 -0400 |
commit | f63d395d47f37a4fe771e6d4b1db9d2cdae5ffc5 (patch) | |
tree | 3448a14ae965802adb963762cadeb9989ce4caa2 /net/sunrpc/auth_gss | |
parent | 643ac9fc5429e85b8b7f534544b80bcc4f34c367 (diff) | |
parent | 5a7c9eec9fde1da0e3adf0a4ddb64ff2a324a492 (diff) |
Merge tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates for Linux 3.4 from Trond Myklebust:
"New features include:
- Add NFS client support for containers.
This should enable most of the necessary functionality, including
lockd support, and support for rpc.statd, NFSv4 idmapper and
RPCSEC_GSS upcalls into the correct network namespace from which
the mount system call was issued.
- NFSv4 idmapper scalability improvements
Base the idmapper cache on the keyring interface to allow
concurrent access to idmapper entries. Start the process of
migrating users from the single-threaded daemon-based approach to
the multi-threaded request-key based approach.
- NFSv4.1 implementation id.
Allows the NFSv4.1 client and server to mutually identify each
other for logging and debugging purposes.
- Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
having to use the more counterintuitive 'vers=4,minorversion=1'.
- SUNRPC tracepoints.
Start the process of adding tracepoints in order to improve
debugging of the RPC layer.
- pNFS object layout support for autologin.
Important bugfixes include:
- Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to
fail to wake up all tasks when applied to priority waitqueues.
- Ensure that we handle read delegations correctly, when we try to
truncate a file.
- A number of fixes for NFSv4 state manager loops (mostly to do with
delegation recovery)."
* tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (224 commits)
NFS: fix sb->s_id in nfs debug prints
xprtrdma: Remove assumption that each segment is <= PAGE_SIZE
xprtrdma: The transport should not bug-check when a dup reply is received
pnfs-obj: autologin: Add support for protocol autologin
NFS: Remove nfs4_setup_sequence from generic rename code
NFS: Remove nfs4_setup_sequence from generic unlink code
NFS: Remove nfs4_setup_sequence from generic read code
NFS: Remove nfs4_setup_sequence from generic write code
NFS: Fix more NFS debug related build warnings
SUNRPC/LOCKD: Fix build warnings when CONFIG_SUNRPC_DEBUG is undefined
nfs: non void functions must return a value
SUNRPC: Kill compiler warning when RPC_DEBUG is unset
SUNRPC/NFS: Add Kbuild dependencies for NFS_DEBUG/RPC_DEBUG
NFS: Use cond_resched_lock() to reduce latencies in the commit scans
NFSv4: It is not safe to dereference lsp->ls_state in release_lockowner
NFS: ncommit count is being double decremented
SUNRPC: We must not use list_for_each_entry_safe() in rpc_wake_up()
Try using machine credentials for RENEW calls
NFSv4.1: Fix a few issues in filelayout_commit_pagelist
NFSv4.1: Clean ups and bugfixes for the pNFS read/writeback/commit code
...
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 216 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_crypto.c | 7 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_mech.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_seal.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 165 |
5 files changed, 276 insertions, 116 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index affa631ac1ab..d3ad81f8da5b 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -81,7 +81,7 @@ struct gss_auth { | |||
81 | * mechanism (for example, "krb5") and exists for | 81 | * mechanism (for example, "krb5") and exists for |
82 | * backwards-compatibility with older gssd's. | 82 | * backwards-compatibility with older gssd's. |
83 | */ | 83 | */ |
84 | struct dentry *dentry[2]; | 84 | struct rpc_pipe *pipe[2]; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* pipe_version >= 0 if and only if someone has a pipe open. */ | 87 | /* pipe_version >= 0 if and only if someone has a pipe open. */ |
@@ -112,7 +112,7 @@ gss_put_ctx(struct gss_cl_ctx *ctx) | |||
112 | /* gss_cred_set_ctx: | 112 | /* gss_cred_set_ctx: |
113 | * called by gss_upcall_callback and gss_create_upcall in order | 113 | * called by gss_upcall_callback and gss_create_upcall in order |
114 | * to set the gss context. The actual exchange of an old context | 114 | * to set the gss context. The actual exchange of an old context |
115 | * and a new one is protected by the inode->i_lock. | 115 | * and a new one is protected by the pipe->lock. |
116 | */ | 116 | */ |
117 | static void | 117 | static void |
118 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) | 118 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) |
@@ -251,7 +251,7 @@ struct gss_upcall_msg { | |||
251 | struct rpc_pipe_msg msg; | 251 | struct rpc_pipe_msg msg; |
252 | struct list_head list; | 252 | struct list_head list; |
253 | struct gss_auth *auth; | 253 | struct gss_auth *auth; |
254 | struct rpc_inode *inode; | 254 | struct rpc_pipe *pipe; |
255 | struct rpc_wait_queue rpc_waitqueue; | 255 | struct rpc_wait_queue rpc_waitqueue; |
256 | wait_queue_head_t waitqueue; | 256 | wait_queue_head_t waitqueue; |
257 | struct gss_cl_ctx *ctx; | 257 | struct gss_cl_ctx *ctx; |
@@ -294,10 +294,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
294 | } | 294 | } |
295 | 295 | ||
296 | static struct gss_upcall_msg * | 296 | static struct gss_upcall_msg * |
297 | __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | 297 | __gss_find_upcall(struct rpc_pipe *pipe, uid_t uid) |
298 | { | 298 | { |
299 | struct gss_upcall_msg *pos; | 299 | struct gss_upcall_msg *pos; |
300 | list_for_each_entry(pos, &rpci->in_downcall, list) { | 300 | list_for_each_entry(pos, &pipe->in_downcall, list) { |
301 | if (pos->uid != uid) | 301 | if (pos->uid != uid) |
302 | continue; | 302 | continue; |
303 | atomic_inc(&pos->count); | 303 | atomic_inc(&pos->count); |
@@ -315,18 +315,17 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | |||
315 | static inline struct gss_upcall_msg * | 315 | static inline struct gss_upcall_msg * |
316 | gss_add_msg(struct gss_upcall_msg *gss_msg) | 316 | gss_add_msg(struct gss_upcall_msg *gss_msg) |
317 | { | 317 | { |
318 | struct rpc_inode *rpci = gss_msg->inode; | 318 | struct rpc_pipe *pipe = gss_msg->pipe; |
319 | struct inode *inode = &rpci->vfs_inode; | ||
320 | struct gss_upcall_msg *old; | 319 | struct gss_upcall_msg *old; |
321 | 320 | ||
322 | spin_lock(&inode->i_lock); | 321 | spin_lock(&pipe->lock); |
323 | old = __gss_find_upcall(rpci, gss_msg->uid); | 322 | old = __gss_find_upcall(pipe, gss_msg->uid); |
324 | if (old == NULL) { | 323 | if (old == NULL) { |
325 | atomic_inc(&gss_msg->count); | 324 | atomic_inc(&gss_msg->count); |
326 | list_add(&gss_msg->list, &rpci->in_downcall); | 325 | list_add(&gss_msg->list, &pipe->in_downcall); |
327 | } else | 326 | } else |
328 | gss_msg = old; | 327 | gss_msg = old; |
329 | spin_unlock(&inode->i_lock); | 328 | spin_unlock(&pipe->lock); |
330 | return gss_msg; | 329 | return gss_msg; |
331 | } | 330 | } |
332 | 331 | ||
@@ -342,14 +341,14 @@ __gss_unhash_msg(struct gss_upcall_msg *gss_msg) | |||
342 | static void | 341 | static void |
343 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) | 342 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) |
344 | { | 343 | { |
345 | struct inode *inode = &gss_msg->inode->vfs_inode; | 344 | struct rpc_pipe *pipe = gss_msg->pipe; |
346 | 345 | ||
347 | if (list_empty(&gss_msg->list)) | 346 | if (list_empty(&gss_msg->list)) |
348 | return; | 347 | return; |
349 | spin_lock(&inode->i_lock); | 348 | spin_lock(&pipe->lock); |
350 | if (!list_empty(&gss_msg->list)) | 349 | if (!list_empty(&gss_msg->list)) |
351 | __gss_unhash_msg(gss_msg); | 350 | __gss_unhash_msg(gss_msg); |
352 | spin_unlock(&inode->i_lock); | 351 | spin_unlock(&pipe->lock); |
353 | } | 352 | } |
354 | 353 | ||
355 | static void | 354 | static void |
@@ -376,11 +375,11 @@ gss_upcall_callback(struct rpc_task *task) | |||
376 | struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, | 375 | struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, |
377 | struct gss_cred, gc_base); | 376 | struct gss_cred, gc_base); |
378 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; | 377 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; |
379 | struct inode *inode = &gss_msg->inode->vfs_inode; | 378 | struct rpc_pipe *pipe = gss_msg->pipe; |
380 | 379 | ||
381 | spin_lock(&inode->i_lock); | 380 | spin_lock(&pipe->lock); |
382 | gss_handle_downcall_result(gss_cred, gss_msg); | 381 | gss_handle_downcall_result(gss_cred, gss_msg); |
383 | spin_unlock(&inode->i_lock); | 382 | spin_unlock(&pipe->lock); |
384 | task->tk_status = gss_msg->msg.errno; | 383 | task->tk_status = gss_msg->msg.errno; |
385 | gss_release_msg(gss_msg); | 384 | gss_release_msg(gss_msg); |
386 | } | 385 | } |
@@ -450,7 +449,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, | |||
450 | kfree(gss_msg); | 449 | kfree(gss_msg); |
451 | return ERR_PTR(vers); | 450 | return ERR_PTR(vers); |
452 | } | 451 | } |
453 | gss_msg->inode = RPC_I(gss_auth->dentry[vers]->d_inode); | 452 | gss_msg->pipe = gss_auth->pipe[vers]; |
454 | INIT_LIST_HEAD(&gss_msg->list); | 453 | INIT_LIST_HEAD(&gss_msg->list); |
455 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 454 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); |
456 | init_waitqueue_head(&gss_msg->waitqueue); | 455 | init_waitqueue_head(&gss_msg->waitqueue); |
@@ -474,8 +473,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
474 | return gss_new; | 473 | return gss_new; |
475 | gss_msg = gss_add_msg(gss_new); | 474 | gss_msg = gss_add_msg(gss_new); |
476 | if (gss_msg == gss_new) { | 475 | if (gss_msg == gss_new) { |
477 | struct inode *inode = &gss_new->inode->vfs_inode; | 476 | int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); |
478 | int res = rpc_queue_upcall(inode, &gss_new->msg); | ||
479 | if (res) { | 477 | if (res) { |
480 | gss_unhash_msg(gss_new); | 478 | gss_unhash_msg(gss_new); |
481 | gss_msg = ERR_PTR(res); | 479 | gss_msg = ERR_PTR(res); |
@@ -506,7 +504,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
506 | struct gss_cred *gss_cred = container_of(cred, | 504 | struct gss_cred *gss_cred = container_of(cred, |
507 | struct gss_cred, gc_base); | 505 | struct gss_cred, gc_base); |
508 | struct gss_upcall_msg *gss_msg; | 506 | struct gss_upcall_msg *gss_msg; |
509 | struct inode *inode; | 507 | struct rpc_pipe *pipe; |
510 | int err = 0; | 508 | int err = 0; |
511 | 509 | ||
512 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, | 510 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, |
@@ -524,8 +522,8 @@ gss_refresh_upcall(struct rpc_task *task) | |||
524 | err = PTR_ERR(gss_msg); | 522 | err = PTR_ERR(gss_msg); |
525 | goto out; | 523 | goto out; |
526 | } | 524 | } |
527 | inode = &gss_msg->inode->vfs_inode; | 525 | pipe = gss_msg->pipe; |
528 | spin_lock(&inode->i_lock); | 526 | spin_lock(&pipe->lock); |
529 | if (gss_cred->gc_upcall != NULL) | 527 | if (gss_cred->gc_upcall != NULL) |
530 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); | 528 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); |
531 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { | 529 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { |
@@ -538,7 +536,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
538 | gss_handle_downcall_result(gss_cred, gss_msg); | 536 | gss_handle_downcall_result(gss_cred, gss_msg); |
539 | err = gss_msg->msg.errno; | 537 | err = gss_msg->msg.errno; |
540 | } | 538 | } |
541 | spin_unlock(&inode->i_lock); | 539 | spin_unlock(&pipe->lock); |
542 | gss_release_msg(gss_msg); | 540 | gss_release_msg(gss_msg); |
543 | out: | 541 | out: |
544 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", | 542 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", |
@@ -549,7 +547,7 @@ out: | |||
549 | static inline int | 547 | static inline int |
550 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | 548 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) |
551 | { | 549 | { |
552 | struct inode *inode; | 550 | struct rpc_pipe *pipe; |
553 | struct rpc_cred *cred = &gss_cred->gc_base; | 551 | struct rpc_cred *cred = &gss_cred->gc_base; |
554 | struct gss_upcall_msg *gss_msg; | 552 | struct gss_upcall_msg *gss_msg; |
555 | DEFINE_WAIT(wait); | 553 | DEFINE_WAIT(wait); |
@@ -573,14 +571,14 @@ retry: | |||
573 | err = PTR_ERR(gss_msg); | 571 | err = PTR_ERR(gss_msg); |
574 | goto out; | 572 | goto out; |
575 | } | 573 | } |
576 | inode = &gss_msg->inode->vfs_inode; | 574 | pipe = gss_msg->pipe; |
577 | for (;;) { | 575 | for (;;) { |
578 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); | 576 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); |
579 | spin_lock(&inode->i_lock); | 577 | spin_lock(&pipe->lock); |
580 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { | 578 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { |
581 | break; | 579 | break; |
582 | } | 580 | } |
583 | spin_unlock(&inode->i_lock); | 581 | spin_unlock(&pipe->lock); |
584 | if (fatal_signal_pending(current)) { | 582 | if (fatal_signal_pending(current)) { |
585 | err = -ERESTARTSYS; | 583 | err = -ERESTARTSYS; |
586 | goto out_intr; | 584 | goto out_intr; |
@@ -591,7 +589,7 @@ retry: | |||
591 | gss_cred_set_ctx(cred, gss_msg->ctx); | 589 | gss_cred_set_ctx(cred, gss_msg->ctx); |
592 | else | 590 | else |
593 | err = gss_msg->msg.errno; | 591 | err = gss_msg->msg.errno; |
594 | spin_unlock(&inode->i_lock); | 592 | spin_unlock(&pipe->lock); |
595 | out_intr: | 593 | out_intr: |
596 | finish_wait(&gss_msg->waitqueue, &wait); | 594 | finish_wait(&gss_msg->waitqueue, &wait); |
597 | gss_release_msg(gss_msg); | 595 | gss_release_msg(gss_msg); |
@@ -609,7 +607,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
609 | const void *p, *end; | 607 | const void *p, *end; |
610 | void *buf; | 608 | void *buf; |
611 | struct gss_upcall_msg *gss_msg; | 609 | struct gss_upcall_msg *gss_msg; |
612 | struct inode *inode = filp->f_path.dentry->d_inode; | 610 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; |
613 | struct gss_cl_ctx *ctx; | 611 | struct gss_cl_ctx *ctx; |
614 | uid_t uid; | 612 | uid_t uid; |
615 | ssize_t err = -EFBIG; | 613 | ssize_t err = -EFBIG; |
@@ -639,14 +637,14 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
639 | 637 | ||
640 | err = -ENOENT; | 638 | err = -ENOENT; |
641 | /* Find a matching upcall */ | 639 | /* Find a matching upcall */ |
642 | spin_lock(&inode->i_lock); | 640 | spin_lock(&pipe->lock); |
643 | gss_msg = __gss_find_upcall(RPC_I(inode), uid); | 641 | gss_msg = __gss_find_upcall(pipe, uid); |
644 | if (gss_msg == NULL) { | 642 | if (gss_msg == NULL) { |
645 | spin_unlock(&inode->i_lock); | 643 | spin_unlock(&pipe->lock); |
646 | goto err_put_ctx; | 644 | goto err_put_ctx; |
647 | } | 645 | } |
648 | list_del_init(&gss_msg->list); | 646 | list_del_init(&gss_msg->list); |
649 | spin_unlock(&inode->i_lock); | 647 | spin_unlock(&pipe->lock); |
650 | 648 | ||
651 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); | 649 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); |
652 | if (IS_ERR(p)) { | 650 | if (IS_ERR(p)) { |
@@ -674,9 +672,9 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
674 | err = mlen; | 672 | err = mlen; |
675 | 673 | ||
676 | err_release_msg: | 674 | err_release_msg: |
677 | spin_lock(&inode->i_lock); | 675 | spin_lock(&pipe->lock); |
678 | __gss_unhash_msg(gss_msg); | 676 | __gss_unhash_msg(gss_msg); |
679 | spin_unlock(&inode->i_lock); | 677 | spin_unlock(&pipe->lock); |
680 | gss_release_msg(gss_msg); | 678 | gss_release_msg(gss_msg); |
681 | err_put_ctx: | 679 | err_put_ctx: |
682 | gss_put_ctx(ctx); | 680 | gss_put_ctx(ctx); |
@@ -722,23 +720,23 @@ static int gss_pipe_open_v1(struct inode *inode) | |||
722 | static void | 720 | static void |
723 | gss_pipe_release(struct inode *inode) | 721 | gss_pipe_release(struct inode *inode) |
724 | { | 722 | { |
725 | struct rpc_inode *rpci = RPC_I(inode); | 723 | struct rpc_pipe *pipe = RPC_I(inode)->pipe; |
726 | struct gss_upcall_msg *gss_msg; | 724 | struct gss_upcall_msg *gss_msg; |
727 | 725 | ||
728 | restart: | 726 | restart: |
729 | spin_lock(&inode->i_lock); | 727 | spin_lock(&pipe->lock); |
730 | list_for_each_entry(gss_msg, &rpci->in_downcall, list) { | 728 | list_for_each_entry(gss_msg, &pipe->in_downcall, list) { |
731 | 729 | ||
732 | if (!list_empty(&gss_msg->msg.list)) | 730 | if (!list_empty(&gss_msg->msg.list)) |
733 | continue; | 731 | continue; |
734 | gss_msg->msg.errno = -EPIPE; | 732 | gss_msg->msg.errno = -EPIPE; |
735 | atomic_inc(&gss_msg->count); | 733 | atomic_inc(&gss_msg->count); |
736 | __gss_unhash_msg(gss_msg); | 734 | __gss_unhash_msg(gss_msg); |
737 | spin_unlock(&inode->i_lock); | 735 | spin_unlock(&pipe->lock); |
738 | gss_release_msg(gss_msg); | 736 | gss_release_msg(gss_msg); |
739 | goto restart; | 737 | goto restart; |
740 | } | 738 | } |
741 | spin_unlock(&inode->i_lock); | 739 | spin_unlock(&pipe->lock); |
742 | 740 | ||
743 | put_pipe_version(); | 741 | put_pipe_version(); |
744 | } | 742 | } |
@@ -759,6 +757,75 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) | |||
759 | } | 757 | } |
760 | } | 758 | } |
761 | 759 | ||
760 | static void gss_pipes_dentries_destroy(struct rpc_auth *auth) | ||
761 | { | ||
762 | struct gss_auth *gss_auth; | ||
763 | |||
764 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
765 | if (gss_auth->pipe[0]->dentry) | ||
766 | rpc_unlink(gss_auth->pipe[0]->dentry); | ||
767 | if (gss_auth->pipe[1]->dentry) | ||
768 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
769 | } | ||
770 | |||
771 | static int gss_pipes_dentries_create(struct rpc_auth *auth) | ||
772 | { | ||
773 | int err; | ||
774 | struct gss_auth *gss_auth; | ||
775 | struct rpc_clnt *clnt; | ||
776 | |||
777 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
778 | clnt = gss_auth->client; | ||
779 | |||
780 | gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | ||
781 | "gssd", | ||
782 | clnt, gss_auth->pipe[1]); | ||
783 | if (IS_ERR(gss_auth->pipe[1]->dentry)) | ||
784 | return PTR_ERR(gss_auth->pipe[1]->dentry); | ||
785 | gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | ||
786 | gss_auth->mech->gm_name, | ||
787 | clnt, gss_auth->pipe[0]); | ||
788 | if (IS_ERR(gss_auth->pipe[0]->dentry)) { | ||
789 | err = PTR_ERR(gss_auth->pipe[0]->dentry); | ||
790 | goto err_unlink_pipe_1; | ||
791 | } | ||
792 | return 0; | ||
793 | |||
794 | err_unlink_pipe_1: | ||
795 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
796 | return err; | ||
797 | } | ||
798 | |||
799 | static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt, | ||
800 | struct rpc_auth *auth) | ||
801 | { | ||
802 | struct net *net = rpc_net_ns(clnt); | ||
803 | struct super_block *sb; | ||
804 | |||
805 | sb = rpc_get_sb_net(net); | ||
806 | if (sb) { | ||
807 | if (clnt->cl_dentry) | ||
808 | gss_pipes_dentries_destroy(auth); | ||
809 | rpc_put_sb_net(net); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt, | ||
814 | struct rpc_auth *auth) | ||
815 | { | ||
816 | struct net *net = rpc_net_ns(clnt); | ||
817 | struct super_block *sb; | ||
818 | int err = 0; | ||
819 | |||
820 | sb = rpc_get_sb_net(net); | ||
821 | if (sb) { | ||
822 | if (clnt->cl_dentry) | ||
823 | err = gss_pipes_dentries_create(auth); | ||
824 | rpc_put_sb_net(net); | ||
825 | } | ||
826 | return err; | ||
827 | } | ||
828 | |||
762 | /* | 829 | /* |
763 | * NOTE: we have the opportunity to use different | 830 | * NOTE: we have the opportunity to use different |
764 | * parameters based on the input flavor (which must be a pseudoflavor) | 831 | * parameters based on the input flavor (which must be a pseudoflavor) |
@@ -801,32 +868,33 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
801 | * that we supported only the old pipe. So we instead create | 868 | * that we supported only the old pipe. So we instead create |
802 | * the new pipe first. | 869 | * the new pipe first. |
803 | */ | 870 | */ |
804 | gss_auth->dentry[1] = rpc_mkpipe(clnt->cl_path.dentry, | 871 | gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1, |
805 | "gssd", | 872 | RPC_PIPE_WAIT_FOR_OPEN); |
806 | clnt, &gss_upcall_ops_v1, | 873 | if (IS_ERR(gss_auth->pipe[1])) { |
807 | RPC_PIPE_WAIT_FOR_OPEN); | 874 | err = PTR_ERR(gss_auth->pipe[1]); |
808 | if (IS_ERR(gss_auth->dentry[1])) { | ||
809 | err = PTR_ERR(gss_auth->dentry[1]); | ||
810 | goto err_put_mech; | 875 | goto err_put_mech; |
811 | } | 876 | } |
812 | 877 | ||
813 | gss_auth->dentry[0] = rpc_mkpipe(clnt->cl_path.dentry, | 878 | gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0, |
814 | gss_auth->mech->gm_name, | 879 | RPC_PIPE_WAIT_FOR_OPEN); |
815 | clnt, &gss_upcall_ops_v0, | 880 | if (IS_ERR(gss_auth->pipe[0])) { |
816 | RPC_PIPE_WAIT_FOR_OPEN); | 881 | err = PTR_ERR(gss_auth->pipe[0]); |
817 | if (IS_ERR(gss_auth->dentry[0])) { | 882 | goto err_destroy_pipe_1; |
818 | err = PTR_ERR(gss_auth->dentry[0]); | ||
819 | goto err_unlink_pipe_1; | ||
820 | } | 883 | } |
884 | err = gss_pipes_dentries_create_net(clnt, auth); | ||
885 | if (err) | ||
886 | goto err_destroy_pipe_0; | ||
821 | err = rpcauth_init_credcache(auth); | 887 | err = rpcauth_init_credcache(auth); |
822 | if (err) | 888 | if (err) |
823 | goto err_unlink_pipe_0; | 889 | goto err_unlink_pipes; |
824 | 890 | ||
825 | return auth; | 891 | return auth; |
826 | err_unlink_pipe_0: | 892 | err_unlink_pipes: |
827 | rpc_unlink(gss_auth->dentry[0]); | 893 | gss_pipes_dentries_destroy_net(clnt, auth); |
828 | err_unlink_pipe_1: | 894 | err_destroy_pipe_0: |
829 | rpc_unlink(gss_auth->dentry[1]); | 895 | rpc_destroy_pipe_data(gss_auth->pipe[0]); |
896 | err_destroy_pipe_1: | ||
897 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | ||
830 | err_put_mech: | 898 | err_put_mech: |
831 | gss_mech_put(gss_auth->mech); | 899 | gss_mech_put(gss_auth->mech); |
832 | err_free: | 900 | err_free: |
@@ -839,8 +907,9 @@ out_dec: | |||
839 | static void | 907 | static void |
840 | gss_free(struct gss_auth *gss_auth) | 908 | gss_free(struct gss_auth *gss_auth) |
841 | { | 909 | { |
842 | rpc_unlink(gss_auth->dentry[1]); | 910 | gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth); |
843 | rpc_unlink(gss_auth->dentry[0]); | 911 | rpc_destroy_pipe_data(gss_auth->pipe[0]); |
912 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | ||
844 | gss_mech_put(gss_auth->mech); | 913 | gss_mech_put(gss_auth->mech); |
845 | 914 | ||
846 | kfree(gss_auth); | 915 | kfree(gss_auth); |
@@ -1547,7 +1616,9 @@ static const struct rpc_authops authgss_ops = { | |||
1547 | .create = gss_create, | 1616 | .create = gss_create, |
1548 | .destroy = gss_destroy, | 1617 | .destroy = gss_destroy, |
1549 | .lookup_cred = gss_lookup_cred, | 1618 | .lookup_cred = gss_lookup_cred, |
1550 | .crcreate = gss_create_cred | 1619 | .crcreate = gss_create_cred, |
1620 | .pipes_create = gss_pipes_dentries_create, | ||
1621 | .pipes_destroy = gss_pipes_dentries_destroy, | ||
1551 | }; | 1622 | }; |
1552 | 1623 | ||
1553 | static const struct rpc_credops gss_credops = { | 1624 | static const struct rpc_credops gss_credops = { |
@@ -1591,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = { | |||
1591 | .release_pipe = gss_pipe_release, | 1662 | .release_pipe = gss_pipe_release, |
1592 | }; | 1663 | }; |
1593 | 1664 | ||
1665 | static __net_init int rpcsec_gss_init_net(struct net *net) | ||
1666 | { | ||
1667 | return gss_svc_init_net(net); | ||
1668 | } | ||
1669 | |||
1670 | static __net_exit void rpcsec_gss_exit_net(struct net *net) | ||
1671 | { | ||
1672 | gss_svc_shutdown_net(net); | ||
1673 | } | ||
1674 | |||
1675 | static struct pernet_operations rpcsec_gss_net_ops = { | ||
1676 | .init = rpcsec_gss_init_net, | ||
1677 | .exit = rpcsec_gss_exit_net, | ||
1678 | }; | ||
1679 | |||
1594 | /* | 1680 | /* |
1595 | * Initialize RPCSEC_GSS module | 1681 | * Initialize RPCSEC_GSS module |
1596 | */ | 1682 | */ |
@@ -1604,8 +1690,13 @@ static int __init init_rpcsec_gss(void) | |||
1604 | err = gss_svc_init(); | 1690 | err = gss_svc_init(); |
1605 | if (err) | 1691 | if (err) |
1606 | goto out_unregister; | 1692 | goto out_unregister; |
1693 | err = register_pernet_subsys(&rpcsec_gss_net_ops); | ||
1694 | if (err) | ||
1695 | goto out_svc_exit; | ||
1607 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); | 1696 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); |
1608 | return 0; | 1697 | return 0; |
1698 | out_svc_exit: | ||
1699 | gss_svc_shutdown(); | ||
1609 | out_unregister: | 1700 | out_unregister: |
1610 | rpcauth_unregister(&authgss_ops); | 1701 | rpcauth_unregister(&authgss_ops); |
1611 | out: | 1702 | out: |
@@ -1614,6 +1705,7 @@ out: | |||
1614 | 1705 | ||
1615 | static void __exit exit_rpcsec_gss(void) | 1706 | static void __exit exit_rpcsec_gss(void) |
1616 | { | 1707 | { |
1708 | unregister_pernet_subsys(&rpcsec_gss_net_ops); | ||
1617 | gss_svc_shutdown(); | 1709 | gss_svc_shutdown(); |
1618 | rpcauth_unregister(&authgss_ops); | 1710 | rpcauth_unregister(&authgss_ops); |
1619 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 1711 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 9576f35ab701..0f43e894bc0a 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -600,11 +600,14 @@ gss_krb5_cts_crypt(struct crypto_blkcipher *cipher, struct xdr_buf *buf, | |||
600 | u32 ret; | 600 | u32 ret; |
601 | struct scatterlist sg[1]; | 601 | struct scatterlist sg[1]; |
602 | struct blkcipher_desc desc = { .tfm = cipher, .info = iv }; | 602 | struct blkcipher_desc desc = { .tfm = cipher, .info = iv }; |
603 | u8 data[crypto_blkcipher_blocksize(cipher) * 2]; | 603 | u8 data[GSS_KRB5_MAX_BLOCKSIZE * 2]; |
604 | struct page **save_pages; | 604 | struct page **save_pages; |
605 | u32 len = buf->len - offset; | 605 | u32 len = buf->len - offset; |
606 | 606 | ||
607 | BUG_ON(len > crypto_blkcipher_blocksize(cipher) * 2); | 607 | if (len > ARRAY_SIZE(data)) { |
608 | WARN_ON(0); | ||
609 | return -ENOMEM; | ||
610 | } | ||
608 | 611 | ||
609 | /* | 612 | /* |
610 | * For encryption, we want to read from the cleartext | 613 | * For encryption, we want to read from the cleartext |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 8c67890de427..8eff8c32d1b9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -344,7 +344,7 @@ out_err: | |||
344 | return PTR_ERR(p); | 344 | return PTR_ERR(p); |
345 | } | 345 | } |
346 | 346 | ||
347 | struct crypto_blkcipher * | 347 | static struct crypto_blkcipher * |
348 | context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) | 348 | context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) |
349 | { | 349 | { |
350 | struct crypto_blkcipher *cp; | 350 | struct crypto_blkcipher *cp; |
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index d7941eab7796..62ae3273186c 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c | |||
@@ -159,7 +159,7 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, | |||
159 | return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; | 159 | return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; |
160 | } | 160 | } |
161 | 161 | ||
162 | u32 | 162 | static u32 |
163 | gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, | 163 | gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, |
164 | struct xdr_netobj *token) | 164 | struct xdr_netobj *token) |
165 | { | 165 | { |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 8d0f7d3c71c8..1600cfb1618c 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <linux/sunrpc/svcauth_gss.h> | 48 | #include <linux/sunrpc/svcauth_gss.h> |
49 | #include <linux/sunrpc/cache.h> | 49 | #include <linux/sunrpc/cache.h> |
50 | 50 | ||
51 | #include "../netns.h" | ||
52 | |||
51 | #ifdef RPC_DEBUG | 53 | #ifdef RPC_DEBUG |
52 | # define RPCDBG_FACILITY RPCDBG_AUTH | 54 | # define RPCDBG_FACILITY RPCDBG_AUTH |
53 | #endif | 55 | #endif |
@@ -75,10 +77,8 @@ struct rsi { | |||
75 | int major_status, minor_status; | 77 | int major_status, minor_status; |
76 | }; | 78 | }; |
77 | 79 | ||
78 | static struct cache_head *rsi_table[RSI_HASHMAX]; | 80 | static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old); |
79 | static struct cache_detail rsi_cache; | 81 | static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item); |
80 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old); | ||
81 | static struct rsi *rsi_lookup(struct rsi *item); | ||
82 | 82 | ||
83 | static void rsi_free(struct rsi *rsii) | 83 | static void rsi_free(struct rsi *rsii) |
84 | { | 84 | { |
@@ -216,7 +216,7 @@ static int rsi_parse(struct cache_detail *cd, | |||
216 | if (dup_to_netobj(&rsii.in_token, buf, len)) | 216 | if (dup_to_netobj(&rsii.in_token, buf, len)) |
217 | goto out; | 217 | goto out; |
218 | 218 | ||
219 | rsip = rsi_lookup(&rsii); | 219 | rsip = rsi_lookup(cd, &rsii); |
220 | if (!rsip) | 220 | if (!rsip) |
221 | goto out; | 221 | goto out; |
222 | 222 | ||
@@ -258,21 +258,20 @@ static int rsi_parse(struct cache_detail *cd, | |||
258 | if (dup_to_netobj(&rsii.out_token, buf, len)) | 258 | if (dup_to_netobj(&rsii.out_token, buf, len)) |
259 | goto out; | 259 | goto out; |
260 | rsii.h.expiry_time = expiry; | 260 | rsii.h.expiry_time = expiry; |
261 | rsip = rsi_update(&rsii, rsip); | 261 | rsip = rsi_update(cd, &rsii, rsip); |
262 | status = 0; | 262 | status = 0; |
263 | out: | 263 | out: |
264 | rsi_free(&rsii); | 264 | rsi_free(&rsii); |
265 | if (rsip) | 265 | if (rsip) |
266 | cache_put(&rsip->h, &rsi_cache); | 266 | cache_put(&rsip->h, cd); |
267 | else | 267 | else |
268 | status = -ENOMEM; | 268 | status = -ENOMEM; |
269 | return status; | 269 | return status; |
270 | } | 270 | } |
271 | 271 | ||
272 | static struct cache_detail rsi_cache = { | 272 | static struct cache_detail rsi_cache_template = { |
273 | .owner = THIS_MODULE, | 273 | .owner = THIS_MODULE, |
274 | .hash_size = RSI_HASHMAX, | 274 | .hash_size = RSI_HASHMAX, |
275 | .hash_table = rsi_table, | ||
276 | .name = "auth.rpcsec.init", | 275 | .name = "auth.rpcsec.init", |
277 | .cache_put = rsi_put, | 276 | .cache_put = rsi_put, |
278 | .cache_upcall = rsi_upcall, | 277 | .cache_upcall = rsi_upcall, |
@@ -283,24 +282,24 @@ static struct cache_detail rsi_cache = { | |||
283 | .alloc = rsi_alloc, | 282 | .alloc = rsi_alloc, |
284 | }; | 283 | }; |
285 | 284 | ||
286 | static struct rsi *rsi_lookup(struct rsi *item) | 285 | static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item) |
287 | { | 286 | { |
288 | struct cache_head *ch; | 287 | struct cache_head *ch; |
289 | int hash = rsi_hash(item); | 288 | int hash = rsi_hash(item); |
290 | 289 | ||
291 | ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); | 290 | ch = sunrpc_cache_lookup(cd, &item->h, hash); |
292 | if (ch) | 291 | if (ch) |
293 | return container_of(ch, struct rsi, h); | 292 | return container_of(ch, struct rsi, h); |
294 | else | 293 | else |
295 | return NULL; | 294 | return NULL; |
296 | } | 295 | } |
297 | 296 | ||
298 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | 297 | static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old) |
299 | { | 298 | { |
300 | struct cache_head *ch; | 299 | struct cache_head *ch; |
301 | int hash = rsi_hash(new); | 300 | int hash = rsi_hash(new); |
302 | 301 | ||
303 | ch = sunrpc_cache_update(&rsi_cache, &new->h, | 302 | ch = sunrpc_cache_update(cd, &new->h, |
304 | &old->h, hash); | 303 | &old->h, hash); |
305 | if (ch) | 304 | if (ch) |
306 | return container_of(ch, struct rsi, h); | 305 | return container_of(ch, struct rsi, h); |
@@ -339,10 +338,8 @@ struct rsc { | |||
339 | char *client_name; | 338 | char *client_name; |
340 | }; | 339 | }; |
341 | 340 | ||
342 | static struct cache_head *rsc_table[RSC_HASHMAX]; | 341 | static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); |
343 | static struct cache_detail rsc_cache; | 342 | static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item); |
344 | static struct rsc *rsc_update(struct rsc *new, struct rsc *old); | ||
345 | static struct rsc *rsc_lookup(struct rsc *item); | ||
346 | 343 | ||
347 | static void rsc_free(struct rsc *rsci) | 344 | static void rsc_free(struct rsc *rsci) |
348 | { | 345 | { |
@@ -444,7 +441,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
444 | if (expiry == 0) | 441 | if (expiry == 0) |
445 | goto out; | 442 | goto out; |
446 | 443 | ||
447 | rscp = rsc_lookup(&rsci); | 444 | rscp = rsc_lookup(cd, &rsci); |
448 | if (!rscp) | 445 | if (!rscp) |
449 | goto out; | 446 | goto out; |
450 | 447 | ||
@@ -506,22 +503,21 @@ static int rsc_parse(struct cache_detail *cd, | |||
506 | 503 | ||
507 | } | 504 | } |
508 | rsci.h.expiry_time = expiry; | 505 | rsci.h.expiry_time = expiry; |
509 | rscp = rsc_update(&rsci, rscp); | 506 | rscp = rsc_update(cd, &rsci, rscp); |
510 | status = 0; | 507 | status = 0; |
511 | out: | 508 | out: |
512 | gss_mech_put(gm); | 509 | gss_mech_put(gm); |
513 | rsc_free(&rsci); | 510 | rsc_free(&rsci); |
514 | if (rscp) | 511 | if (rscp) |
515 | cache_put(&rscp->h, &rsc_cache); | 512 | cache_put(&rscp->h, cd); |
516 | else | 513 | else |
517 | status = -ENOMEM; | 514 | status = -ENOMEM; |
518 | return status; | 515 | return status; |
519 | } | 516 | } |
520 | 517 | ||
521 | static struct cache_detail rsc_cache = { | 518 | static struct cache_detail rsc_cache_template = { |
522 | .owner = THIS_MODULE, | 519 | .owner = THIS_MODULE, |
523 | .hash_size = RSC_HASHMAX, | 520 | .hash_size = RSC_HASHMAX, |
524 | .hash_table = rsc_table, | ||
525 | .name = "auth.rpcsec.context", | 521 | .name = "auth.rpcsec.context", |
526 | .cache_put = rsc_put, | 522 | .cache_put = rsc_put, |
527 | .cache_parse = rsc_parse, | 523 | .cache_parse = rsc_parse, |
@@ -531,24 +527,24 @@ static struct cache_detail rsc_cache = { | |||
531 | .alloc = rsc_alloc, | 527 | .alloc = rsc_alloc, |
532 | }; | 528 | }; |
533 | 529 | ||
534 | static struct rsc *rsc_lookup(struct rsc *item) | 530 | static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item) |
535 | { | 531 | { |
536 | struct cache_head *ch; | 532 | struct cache_head *ch; |
537 | int hash = rsc_hash(item); | 533 | int hash = rsc_hash(item); |
538 | 534 | ||
539 | ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash); | 535 | ch = sunrpc_cache_lookup(cd, &item->h, hash); |
540 | if (ch) | 536 | if (ch) |
541 | return container_of(ch, struct rsc, h); | 537 | return container_of(ch, struct rsc, h); |
542 | else | 538 | else |
543 | return NULL; | 539 | return NULL; |
544 | } | 540 | } |
545 | 541 | ||
546 | static struct rsc *rsc_update(struct rsc *new, struct rsc *old) | 542 | static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old) |
547 | { | 543 | { |
548 | struct cache_head *ch; | 544 | struct cache_head *ch; |
549 | int hash = rsc_hash(new); | 545 | int hash = rsc_hash(new); |
550 | 546 | ||
551 | ch = sunrpc_cache_update(&rsc_cache, &new->h, | 547 | ch = sunrpc_cache_update(cd, &new->h, |
552 | &old->h, hash); | 548 | &old->h, hash); |
553 | if (ch) | 549 | if (ch) |
554 | return container_of(ch, struct rsc, h); | 550 | return container_of(ch, struct rsc, h); |
@@ -558,7 +554,7 @@ static struct rsc *rsc_update(struct rsc *new, struct rsc *old) | |||
558 | 554 | ||
559 | 555 | ||
560 | static struct rsc * | 556 | static struct rsc * |
561 | gss_svc_searchbyctx(struct xdr_netobj *handle) | 557 | gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) |
562 | { | 558 | { |
563 | struct rsc rsci; | 559 | struct rsc rsci; |
564 | struct rsc *found; | 560 | struct rsc *found; |
@@ -566,11 +562,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle) | |||
566 | memset(&rsci, 0, sizeof(rsci)); | 562 | memset(&rsci, 0, sizeof(rsci)); |
567 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) | 563 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) |
568 | return NULL; | 564 | return NULL; |
569 | found = rsc_lookup(&rsci); | 565 | found = rsc_lookup(cd, &rsci); |
570 | rsc_free(&rsci); | 566 | rsc_free(&rsci); |
571 | if (!found) | 567 | if (!found) |
572 | return NULL; | 568 | return NULL; |
573 | if (cache_check(&rsc_cache, &found->h, NULL)) | 569 | if (cache_check(cd, &found->h, NULL)) |
574 | return NULL; | 570 | return NULL; |
575 | return found; | 571 | return found; |
576 | } | 572 | } |
@@ -968,20 +964,20 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) | |||
968 | } | 964 | } |
969 | 965 | ||
970 | static inline int | 966 | static inline int |
971 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | 967 | gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip) |
972 | { | 968 | { |
973 | struct rsc *rsci; | 969 | struct rsc *rsci; |
974 | int rc; | 970 | int rc; |
975 | 971 | ||
976 | if (rsip->major_status != GSS_S_COMPLETE) | 972 | if (rsip->major_status != GSS_S_COMPLETE) |
977 | return gss_write_null_verf(rqstp); | 973 | return gss_write_null_verf(rqstp); |
978 | rsci = gss_svc_searchbyctx(&rsip->out_handle); | 974 | rsci = gss_svc_searchbyctx(cd, &rsip->out_handle); |
979 | if (rsci == NULL) { | 975 | if (rsci == NULL) { |
980 | rsip->major_status = GSS_S_NO_CONTEXT; | 976 | rsip->major_status = GSS_S_NO_CONTEXT; |
981 | return gss_write_null_verf(rqstp); | 977 | return gss_write_null_verf(rqstp); |
982 | } | 978 | } |
983 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); | 979 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); |
984 | cache_put(&rsci->h, &rsc_cache); | 980 | cache_put(&rsci->h, cd); |
985 | return rc; | 981 | return rc; |
986 | } | 982 | } |
987 | 983 | ||
@@ -1000,6 +996,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1000 | struct xdr_netobj tmpobj; | 996 | struct xdr_netobj tmpobj; |
1001 | struct rsi *rsip, rsikey; | 997 | struct rsi *rsip, rsikey; |
1002 | int ret; | 998 | int ret; |
999 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1003 | 1000 | ||
1004 | /* Read the verifier; should be NULL: */ | 1001 | /* Read the verifier; should be NULL: */ |
1005 | *authp = rpc_autherr_badverf; | 1002 | *authp = rpc_autherr_badverf; |
@@ -1028,17 +1025,17 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1028 | } | 1025 | } |
1029 | 1026 | ||
1030 | /* Perform upcall, or find upcall result: */ | 1027 | /* Perform upcall, or find upcall result: */ |
1031 | rsip = rsi_lookup(&rsikey); | 1028 | rsip = rsi_lookup(sn->rsi_cache, &rsikey); |
1032 | rsi_free(&rsikey); | 1029 | rsi_free(&rsikey); |
1033 | if (!rsip) | 1030 | if (!rsip) |
1034 | return SVC_CLOSE; | 1031 | return SVC_CLOSE; |
1035 | if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) | 1032 | if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) |
1036 | /* No upcall result: */ | 1033 | /* No upcall result: */ |
1037 | return SVC_CLOSE; | 1034 | return SVC_CLOSE; |
1038 | 1035 | ||
1039 | ret = SVC_CLOSE; | 1036 | ret = SVC_CLOSE; |
1040 | /* Got an answer to the upcall; use it: */ | 1037 | /* Got an answer to the upcall; use it: */ |
1041 | if (gss_write_init_verf(rqstp, rsip)) | 1038 | if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip)) |
1042 | goto out; | 1039 | goto out; |
1043 | if (resv->iov_len + 4 > PAGE_SIZE) | 1040 | if (resv->iov_len + 4 > PAGE_SIZE) |
1044 | goto out; | 1041 | goto out; |
@@ -1055,7 +1052,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1055 | 1052 | ||
1056 | ret = SVC_COMPLETE; | 1053 | ret = SVC_COMPLETE; |
1057 | out: | 1054 | out: |
1058 | cache_put(&rsip->h, &rsi_cache); | 1055 | cache_put(&rsip->h, sn->rsi_cache); |
1059 | return ret; | 1056 | return ret; |
1060 | } | 1057 | } |
1061 | 1058 | ||
@@ -1079,6 +1076,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1079 | __be32 *rpcstart; | 1076 | __be32 *rpcstart; |
1080 | __be32 *reject_stat = resv->iov_base + resv->iov_len; | 1077 | __be32 *reject_stat = resv->iov_base + resv->iov_len; |
1081 | int ret; | 1078 | int ret; |
1079 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1082 | 1080 | ||
1083 | dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", | 1081 | dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", |
1084 | argv->iov_len); | 1082 | argv->iov_len); |
@@ -1129,7 +1127,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1129 | case RPC_GSS_PROC_DESTROY: | 1127 | case RPC_GSS_PROC_DESTROY: |
1130 | /* Look up the context, and check the verifier: */ | 1128 | /* Look up the context, and check the verifier: */ |
1131 | *authp = rpcsec_gsserr_credproblem; | 1129 | *authp = rpcsec_gsserr_credproblem; |
1132 | rsci = gss_svc_searchbyctx(&gc->gc_ctx); | 1130 | rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx); |
1133 | if (!rsci) | 1131 | if (!rsci) |
1134 | goto auth_err; | 1132 | goto auth_err; |
1135 | switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { | 1133 | switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { |
@@ -1209,7 +1207,7 @@ drop: | |||
1209 | ret = SVC_DROP; | 1207 | ret = SVC_DROP; |
1210 | out: | 1208 | out: |
1211 | if (rsci) | 1209 | if (rsci) |
1212 | cache_put(&rsci->h, &rsc_cache); | 1210 | cache_put(&rsci->h, sn->rsc_cache); |
1213 | return ret; | 1211 | return ret; |
1214 | } | 1212 | } |
1215 | 1213 | ||
@@ -1362,6 +1360,7 @@ svcauth_gss_release(struct svc_rqst *rqstp) | |||
1362 | struct rpc_gss_wire_cred *gc = &gsd->clcred; | 1360 | struct rpc_gss_wire_cred *gc = &gsd->clcred; |
1363 | struct xdr_buf *resbuf = &rqstp->rq_res; | 1361 | struct xdr_buf *resbuf = &rqstp->rq_res; |
1364 | int stat = -EINVAL; | 1362 | int stat = -EINVAL; |
1363 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1365 | 1364 | ||
1366 | if (gc->gc_proc != RPC_GSS_PROC_DATA) | 1365 | if (gc->gc_proc != RPC_GSS_PROC_DATA) |
1367 | goto out; | 1366 | goto out; |
@@ -1404,7 +1403,7 @@ out_err: | |||
1404 | put_group_info(rqstp->rq_cred.cr_group_info); | 1403 | put_group_info(rqstp->rq_cred.cr_group_info); |
1405 | rqstp->rq_cred.cr_group_info = NULL; | 1404 | rqstp->rq_cred.cr_group_info = NULL; |
1406 | if (gsd->rsci) | 1405 | if (gsd->rsci) |
1407 | cache_put(&gsd->rsci->h, &rsc_cache); | 1406 | cache_put(&gsd->rsci->h, sn->rsc_cache); |
1408 | gsd->rsci = NULL; | 1407 | gsd->rsci = NULL; |
1409 | 1408 | ||
1410 | return stat; | 1409 | return stat; |
@@ -1429,30 +1428,96 @@ static struct auth_ops svcauthops_gss = { | |||
1429 | .set_client = svcauth_gss_set_client, | 1428 | .set_client = svcauth_gss_set_client, |
1430 | }; | 1429 | }; |
1431 | 1430 | ||
1431 | static int rsi_cache_create_net(struct net *net) | ||
1432 | { | ||
1433 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1434 | struct cache_detail *cd; | ||
1435 | int err; | ||
1436 | |||
1437 | cd = cache_create_net(&rsi_cache_template, net); | ||
1438 | if (IS_ERR(cd)) | ||
1439 | return PTR_ERR(cd); | ||
1440 | err = cache_register_net(cd, net); | ||
1441 | if (err) { | ||
1442 | cache_destroy_net(cd, net); | ||
1443 | return err; | ||
1444 | } | ||
1445 | sn->rsi_cache = cd; | ||
1446 | return 0; | ||
1447 | } | ||
1448 | |||
1449 | static void rsi_cache_destroy_net(struct net *net) | ||
1450 | { | ||
1451 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1452 | struct cache_detail *cd = sn->rsi_cache; | ||
1453 | |||
1454 | sn->rsi_cache = NULL; | ||
1455 | cache_purge(cd); | ||
1456 | cache_unregister_net(cd, net); | ||
1457 | cache_destroy_net(cd, net); | ||
1458 | } | ||
1459 | |||
1460 | static int rsc_cache_create_net(struct net *net) | ||
1461 | { | ||
1462 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1463 | struct cache_detail *cd; | ||
1464 | int err; | ||
1465 | |||
1466 | cd = cache_create_net(&rsc_cache_template, net); | ||
1467 | if (IS_ERR(cd)) | ||
1468 | return PTR_ERR(cd); | ||
1469 | err = cache_register_net(cd, net); | ||
1470 | if (err) { | ||
1471 | cache_destroy_net(cd, net); | ||
1472 | return err; | ||
1473 | } | ||
1474 | sn->rsc_cache = cd; | ||
1475 | return 0; | ||
1476 | } | ||
1477 | |||
1478 | static void rsc_cache_destroy_net(struct net *net) | ||
1479 | { | ||
1480 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1481 | struct cache_detail *cd = sn->rsc_cache; | ||
1482 | |||
1483 | sn->rsc_cache = NULL; | ||
1484 | cache_purge(cd); | ||
1485 | cache_unregister_net(cd, net); | ||
1486 | cache_destroy_net(cd, net); | ||
1487 | } | ||
1488 | |||
1432 | int | 1489 | int |
1433 | gss_svc_init(void) | 1490 | gss_svc_init_net(struct net *net) |
1434 | { | 1491 | { |
1435 | int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); | 1492 | int rv; |
1493 | |||
1494 | rv = rsc_cache_create_net(net); | ||
1436 | if (rv) | 1495 | if (rv) |
1437 | return rv; | 1496 | return rv; |
1438 | rv = cache_register(&rsc_cache); | 1497 | rv = rsi_cache_create_net(net); |
1439 | if (rv) | 1498 | if (rv) |
1440 | goto out1; | 1499 | goto out1; |
1441 | rv = cache_register(&rsi_cache); | ||
1442 | if (rv) | ||
1443 | goto out2; | ||
1444 | return 0; | 1500 | return 0; |
1445 | out2: | ||
1446 | cache_unregister(&rsc_cache); | ||
1447 | out1: | 1501 | out1: |
1448 | svc_auth_unregister(RPC_AUTH_GSS); | 1502 | rsc_cache_destroy_net(net); |
1449 | return rv; | 1503 | return rv; |
1450 | } | 1504 | } |
1451 | 1505 | ||
1452 | void | 1506 | void |
1507 | gss_svc_shutdown_net(struct net *net) | ||
1508 | { | ||
1509 | rsi_cache_destroy_net(net); | ||
1510 | rsc_cache_destroy_net(net); | ||
1511 | } | ||
1512 | |||
1513 | int | ||
1514 | gss_svc_init(void) | ||
1515 | { | ||
1516 | return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); | ||
1517 | } | ||
1518 | |||
1519 | void | ||
1453 | gss_svc_shutdown(void) | 1520 | gss_svc_shutdown(void) |
1454 | { | 1521 | { |
1455 | cache_unregister(&rsc_cache); | ||
1456 | cache_unregister(&rsi_cache); | ||
1457 | svc_auth_unregister(RPC_AUTH_GSS); | 1522 | svc_auth_unregister(RPC_AUTH_GSS); |
1458 | } | 1523 | } |