diff options
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 6f1b4e2f5e81..621c07f322c4 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -114,28 +114,14 @@ static void | |||
| 114 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) | 114 | gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) |
| 115 | { | 115 | { |
| 116 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); | 116 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); |
| 117 | struct gss_cl_ctx *old; | ||
| 118 | 117 | ||
| 119 | old = gss_cred->gc_ctx; | 118 | if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) |
| 119 | return; | ||
| 120 | gss_get_ctx(ctx); | 120 | gss_get_ctx(ctx); |
| 121 | rcu_assign_pointer(gss_cred->gc_ctx, ctx); | 121 | rcu_assign_pointer(gss_cred->gc_ctx, ctx); |
| 122 | set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); | 122 | set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); |
| 123 | smp_mb__before_clear_bit(); | ||
| 123 | clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); | 124 | clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); |
| 124 | if (old) | ||
| 125 | gss_put_ctx(old); | ||
| 126 | } | ||
| 127 | |||
| 128 | static int | ||
| 129 | gss_cred_is_uptodate_ctx(struct rpc_cred *cred) | ||
| 130 | { | ||
| 131 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); | ||
| 132 | int res = 0; | ||
| 133 | |||
| 134 | rcu_read_lock(); | ||
| 135 | if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx) | ||
| 136 | res = 1; | ||
| 137 | rcu_read_unlock(); | ||
| 138 | return res; | ||
| 139 | } | 125 | } |
| 140 | 126 | ||
| 141 | static const void * | 127 | static const void * |
| @@ -857,15 +843,12 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) | |||
| 857 | { | 843 | { |
| 858 | struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); | 844 | struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); |
| 859 | 845 | ||
| 860 | /* | 846 | if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) |
| 861 | * If the searchflags have set RPCAUTH_LOOKUP_NEW, then | ||
| 862 | * we don't really care if the credential has expired or not, | ||
| 863 | * since the caller should be prepared to reinitialise it. | ||
| 864 | */ | ||
| 865 | if ((flags & RPCAUTH_LOOKUP_NEW) && test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) | ||
| 866 | goto out; | 847 | goto out; |
| 867 | /* Don't match with creds that have expired. */ | 848 | /* Don't match with creds that have expired. */ |
| 868 | if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) | 849 | if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) |
| 850 | return 0; | ||
| 851 | if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) | ||
| 869 | return 0; | 852 | return 0; |
| 870 | out: | 853 | out: |
| 871 | if (acred->machine_cred != gss_cred->gc_machine_cred) | 854 | if (acred->machine_cred != gss_cred->gc_machine_cred) |
| @@ -933,16 +916,48 @@ out_put_ctx: | |||
| 933 | return NULL; | 916 | return NULL; |
| 934 | } | 917 | } |
| 935 | 918 | ||
| 919 | static int gss_renew_cred(struct rpc_task *task) | ||
| 920 | { | ||
| 921 | struct rpc_cred *oldcred = task->tk_msg.rpc_cred; | ||
| 922 | struct gss_cred *gss_cred = container_of(oldcred, | ||
| 923 | struct gss_cred, | ||
| 924 | gc_base); | ||
| 925 | struct rpc_auth *auth = oldcred->cr_auth; | ||
| 926 | struct auth_cred acred = { | ||
| 927 | .uid = oldcred->cr_uid, | ||
| 928 | .machine_cred = gss_cred->gc_machine_cred, | ||
| 929 | }; | ||
| 930 | struct rpc_cred *new; | ||
| 931 | |||
| 932 | new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW); | ||
| 933 | if (IS_ERR(new)) | ||
| 934 | return PTR_ERR(new); | ||
| 935 | task->tk_msg.rpc_cred = new; | ||
| 936 | put_rpccred(oldcred); | ||
| 937 | return 0; | ||
| 938 | } | ||
| 939 | |||
| 936 | /* | 940 | /* |
| 937 | * Refresh credentials. XXX - finish | 941 | * Refresh credentials. XXX - finish |
| 938 | */ | 942 | */ |
| 939 | static int | 943 | static int |
| 940 | gss_refresh(struct rpc_task *task) | 944 | gss_refresh(struct rpc_task *task) |
| 941 | { | 945 | { |
| 946 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | ||
| 947 | int ret = 0; | ||
| 948 | |||
| 949 | if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && | ||
| 950 | !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { | ||
| 951 | ret = gss_renew_cred(task); | ||
| 952 | if (ret < 0) | ||
| 953 | goto out; | ||
| 954 | cred = task->tk_msg.rpc_cred; | ||
| 955 | } | ||
| 942 | 956 | ||
| 943 | if (!gss_cred_is_uptodate_ctx(task->tk_msg.rpc_cred)) | 957 | if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) |
| 944 | return gss_refresh_upcall(task); | 958 | ret = gss_refresh_upcall(task); |
| 945 | return 0; | 959 | out: |
| 960 | return ret; | ||
| 946 | } | 961 | } |
| 947 | 962 | ||
| 948 | /* Dummy refresh routine: used only when destroying the context */ | 963 | /* Dummy refresh routine: used only when destroying the context */ |
