aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c69
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
114gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) 114gss_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
128static int
129gss_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
141static const void * 127static 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;
870out: 853out:
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
919static 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*/
939static int 943static int
940gss_refresh(struct rpc_task *task) 944gss_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; 959out:
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 */