diff options
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 42fdfc634e56..36e431ee1c90 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -108,6 +108,7 @@ struct gss_auth { | |||
108 | static DEFINE_SPINLOCK(pipe_version_lock); | 108 | static DEFINE_SPINLOCK(pipe_version_lock); |
109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; | 109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; |
110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); | 110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); |
111 | static void gss_put_auth(struct gss_auth *gss_auth); | ||
111 | 112 | ||
112 | static void gss_free_ctx(struct gss_cl_ctx *); | 113 | static void gss_free_ctx(struct gss_cl_ctx *); |
113 | static const struct rpc_pipe_ops gss_upcall_ops_v0; | 114 | static const struct rpc_pipe_ops gss_upcall_ops_v0; |
@@ -320,6 +321,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
320 | if (gss_msg->ctx != NULL) | 321 | if (gss_msg->ctx != NULL) |
321 | gss_put_ctx(gss_msg->ctx); | 322 | gss_put_ctx(gss_msg->ctx); |
322 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); | 323 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); |
324 | gss_put_auth(gss_msg->auth); | ||
323 | kfree(gss_msg); | 325 | kfree(gss_msg); |
324 | } | 326 | } |
325 | 327 | ||
@@ -498,9 +500,12 @@ gss_alloc_msg(struct gss_auth *gss_auth, | |||
498 | default: | 500 | default: |
499 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); | 501 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); |
500 | if (err) | 502 | if (err) |
501 | goto err_free_msg; | 503 | goto err_put_pipe_version; |
502 | }; | 504 | }; |
505 | kref_get(&gss_auth->kref); | ||
503 | return gss_msg; | 506 | return gss_msg; |
507 | err_put_pipe_version: | ||
508 | put_pipe_version(gss_auth->net); | ||
504 | err_free_msg: | 509 | err_free_msg: |
505 | kfree(gss_msg); | 510 | kfree(gss_msg); |
506 | err: | 511 | err: |
@@ -532,14 +537,7 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred) | |||
532 | 537 | ||
533 | static void warn_gssd(void) | 538 | static void warn_gssd(void) |
534 | { | 539 | { |
535 | static unsigned long ratelimit; | 540 | dprintk("AUTH_GSS upcall failed. Please check user daemon is running.\n"); |
536 | unsigned long now = jiffies; | ||
537 | |||
538 | if (time_after(now, ratelimit)) { | ||
539 | printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" | ||
540 | "Please check user daemon is running.\n"); | ||
541 | ratelimit = now + 15*HZ; | ||
542 | } | ||
543 | } | 541 | } |
544 | 542 | ||
545 | static inline int | 543 | static inline int |
@@ -600,7 +598,6 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | |||
600 | struct rpc_pipe *pipe; | 598 | struct rpc_pipe *pipe; |
601 | struct rpc_cred *cred = &gss_cred->gc_base; | 599 | struct rpc_cred *cred = &gss_cred->gc_base; |
602 | struct gss_upcall_msg *gss_msg; | 600 | struct gss_upcall_msg *gss_msg; |
603 | unsigned long timeout; | ||
604 | DEFINE_WAIT(wait); | 601 | DEFINE_WAIT(wait); |
605 | int err; | 602 | int err; |
606 | 603 | ||
@@ -608,17 +605,16 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | |||
608 | __func__, from_kuid(&init_user_ns, cred->cr_uid)); | 605 | __func__, from_kuid(&init_user_ns, cred->cr_uid)); |
609 | retry: | 606 | retry: |
610 | err = 0; | 607 | err = 0; |
611 | /* Default timeout is 15s unless we know that gssd is not running */ | 608 | /* if gssd is down, just skip upcalling altogether */ |
612 | timeout = 15 * HZ; | 609 | if (!gssd_running(net)) { |
613 | if (!sn->gssd_running) | 610 | warn_gssd(); |
614 | timeout = HZ >> 2; | 611 | return -EACCES; |
612 | } | ||
615 | gss_msg = gss_setup_upcall(gss_auth, cred); | 613 | gss_msg = gss_setup_upcall(gss_auth, cred); |
616 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 614 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
617 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, | 615 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, |
618 | sn->pipe_version >= 0, timeout); | 616 | sn->pipe_version >= 0, 15 * HZ); |
619 | if (sn->pipe_version < 0) { | 617 | if (sn->pipe_version < 0) { |
620 | if (err == 0) | ||
621 | sn->gssd_running = 0; | ||
622 | warn_gssd(); | 618 | warn_gssd(); |
623 | err = -EACCES; | 619 | err = -EACCES; |
624 | } | 620 | } |
@@ -1000,6 +996,8 @@ gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
1000 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); | 996 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); |
1001 | if (gss_auth->service == 0) | 997 | if (gss_auth->service == 0) |
1002 | goto err_put_mech; | 998 | goto err_put_mech; |
999 | if (!gssd_running(gss_auth->net)) | ||
1000 | goto err_put_mech; | ||
1003 | auth = &gss_auth->rpc_auth; | 1001 | auth = &gss_auth->rpc_auth; |
1004 | auth->au_cslack = GSS_CRED_SLACK >> 2; | 1002 | auth->au_cslack = GSS_CRED_SLACK >> 2; |
1005 | auth->au_rslack = GSS_VERF_SLACK >> 2; | 1003 | auth->au_rslack = GSS_VERF_SLACK >> 2; |
@@ -1071,6 +1069,12 @@ gss_free_callback(struct kref *kref) | |||
1071 | } | 1069 | } |
1072 | 1070 | ||
1073 | static void | 1071 | static void |
1072 | gss_put_auth(struct gss_auth *gss_auth) | ||
1073 | { | ||
1074 | kref_put(&gss_auth->kref, gss_free_callback); | ||
1075 | } | ||
1076 | |||
1077 | static void | ||
1074 | gss_destroy(struct rpc_auth *auth) | 1078 | gss_destroy(struct rpc_auth *auth) |
1075 | { | 1079 | { |
1076 | struct gss_auth *gss_auth = container_of(auth, | 1080 | struct gss_auth *gss_auth = container_of(auth, |
@@ -1091,7 +1095,7 @@ gss_destroy(struct rpc_auth *auth) | |||
1091 | gss_auth->gss_pipe[1] = NULL; | 1095 | gss_auth->gss_pipe[1] = NULL; |
1092 | rpcauth_destroy_credcache(auth); | 1096 | rpcauth_destroy_credcache(auth); |
1093 | 1097 | ||
1094 | kref_put(&gss_auth->kref, gss_free_callback); | 1098 | gss_put_auth(gss_auth); |
1095 | } | 1099 | } |
1096 | 1100 | ||
1097 | /* | 1101 | /* |
@@ -1262,7 +1266,7 @@ gss_destroy_nullcred(struct rpc_cred *cred) | |||
1262 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); | 1266 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); |
1263 | if (ctx) | 1267 | if (ctx) |
1264 | gss_put_ctx(ctx); | 1268 | gss_put_ctx(ctx); |
1265 | kref_put(&gss_auth->kref, gss_free_callback); | 1269 | gss_put_auth(gss_auth); |
1266 | } | 1270 | } |
1267 | 1271 | ||
1268 | static void | 1272 | static void |