aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-02-01 12:19:27 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-02-01 12:52:25 -0500
commitfba3bad488a2eec2d76c067edb7a5ff92ef42431 (patch)
treea7cee933e9089e5c187008b396ee7bcbdb57ff80 /net
parentadb12f63e0f837078c6832fa2c90649ddeaab54f (diff)
SUNRPC: Move upcall out of auth->au_ops->crcreate()
This fixes a bug whereby if two processes try to look up the same auth_gss credential, they may end up creating two creds, and triggering two upcalls because the upcall is performed before the credential is added to the credcache. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth.c8
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c23
2 files changed, 22 insertions, 9 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 1ca89c36da7a..8d6f1a176b15 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -232,6 +232,14 @@ retry:
232 goto retry; 232 goto retry;
233 } else 233 } else
234 cred = new; 234 cred = new;
235 } else if ((cred->cr_flags & RPCAUTH_CRED_NEW)
236 && cred->cr_ops->cr_init != NULL
237 && !(flags & RPCAUTH_LOOKUP_NEW)) {
238 int res = cred->cr_ops->cr_init(auth, cred);
239 if (res < 0) {
240 put_rpccred(cred);
241 cred = ERR_PTR(res);
242 }
235 } 243 }
236 244
237 return (struct rpc_cred *) cred; 245 return (struct rpc_cred *) cred;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 03affcbf6292..bb46efd92e57 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -788,15 +788,6 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
788 cred->gc_base.cr_ops = &gss_credops; 788 cred->gc_base.cr_ops = &gss_credops;
789 cred->gc_base.cr_flags = RPCAUTH_CRED_NEW; 789 cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
790 cred->gc_service = gss_auth->service; 790 cred->gc_service = gss_auth->service;
791 /* Is the caller prepared to initialise the credential? */
792 if (flags & RPCAUTH_LOOKUP_NEW)
793 goto out;
794 do {
795 err = gss_create_upcall(gss_auth, cred);
796 } while (err == -EAGAIN);
797 if (err < 0)
798 goto out_err;
799out:
800 return &cred->gc_base; 791 return &cred->gc_base;
801 792
802out_err: 793out_err:
@@ -806,6 +797,19 @@ out_err:
806} 797}
807 798
808static int 799static int
800gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
801{
802 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
803 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
804 int err;
805
806 do {
807 err = gss_create_upcall(gss_auth, gss_cred);
808 } while (err == -EAGAIN);
809 return err;
810}
811
812static int
809gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) 813gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
810{ 814{
811 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 815 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
@@ -1254,6 +1258,7 @@ static struct rpc_authops authgss_ops = {
1254static struct rpc_credops gss_credops = { 1258static struct rpc_credops gss_credops = {
1255 .cr_name = "AUTH_GSS", 1259 .cr_name = "AUTH_GSS",
1256 .crdestroy = gss_destroy_cred, 1260 .crdestroy = gss_destroy_cred,
1261 .cr_init = gss_cred_init,
1257 .crmatch = gss_match, 1262 .crmatch = gss_match,
1258 .crmarshal = gss_marshal, 1263 .crmarshal = gss_marshal,
1259 .crrefresh = gss_refresh, 1264 .crrefresh = gss_refresh,