From: neilbrown Date: Sun, 9 Apr 2006 23:49:36 +0000 (+0000) Subject: 2006-04-10 kwc@citi.umich.edu X-Git-Tag: nfs-utils-1-0-8~7 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=802e3cfc690a5b1f7d5d7ecd102dd44297b21160 2006-04-10 kwc@citi.umich.edu Fix memory leak of the AUTH structure on context negotiations Free AUTH structure after completing context negotiation and sending context information to the kernel. --- diff --git a/ChangeLog b/ChangeLog index 7fdc5cc..ff32fbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2006-04-10 kwc@citi.umich.edu + Fix memory leak of the AUTH structure on context negotiations + + Free AUTH structure after completing context negotiation and sending + context information to the kernel. + 2006-04-10 kwc@citi.umich.edu Fix support/include/config.h.in such as would be done be running autoheader. diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c index 8b456b0..bac0520 100644 --- a/utils/gssd/gssd_proc.c +++ b/utils/gssd/gssd_proc.c @@ -472,6 +472,7 @@ out_err: * gss context with a server. */ int create_auth_rpc_client(struct clnt_info *clp, + CLIENT **clnt_return, AUTH **auth_return, uid_t uid, int authtype) @@ -490,6 +491,16 @@ int create_auth_rpc_client(struct clnt_info *clp, char service[64]; char *at_sign; + /* Create the context as the user (not as root) */ + save_uid = geteuid(); + if (seteuid(uid) != 0) { + printerr(0, "WARNING: Failed to seteuid for " + "user with uid %d\n", uid); + goto out_fail; + } + printerr(2, "creating context using euid %d (save_uid %d)\n", + geteuid(), save_uid); + sec.qop = GSS_C_QOP_DEFAULT; sec.svc = RPCSEC_GSS_SVC_NONE; sec.cred = GSS_C_NO_CREDENTIAL; @@ -527,16 +538,6 @@ int create_auth_rpc_client(struct clnt_info *clp, #endif } - /* Create the context as the user (not as root) */ - save_uid = geteuid(); - if (seteuid(uid) != 0) { - printerr(0, "WARNING: Failed to seteuid for " - "user with uid %d\n", uid); - goto out_fail; - } - printerr(2, "creating context using euid %d (save_uid %d)\n", - geteuid(), save_uid); - /* create an rpc connection to the nfs server */ printerr(2, "creating %s client for server %s\n", clp->protocol, @@ -634,29 +635,28 @@ int create_auth_rpc_client(struct clnt_info *clp, goto out_fail; } - /* Restore euid to original value */ - if (seteuid(save_uid) != 0) { - printerr(0, "WARNING: Failed to restore euid" - " to uid %d\n", save_uid); - goto out_fail; - } - save_uid = -1; - /* Success !!! */ + rpc_clnt->cl_auth = auth; + *clnt_return = rpc_clnt; *auth_return = auth; retval = 0; - out_fail: + out: + if (sec.cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&min_stat, &sec.cred); + if (a != NULL) freeaddrinfo(a); + /* Restore euid to original value */ if ((save_uid != -1) && (seteuid(save_uid) != 0)) { printerr(0, "WARNING: Failed to restore euid" - " to uid %d (in error path)\n", save_uid); + " to uid %d\n", save_uid); } - if (sec.cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&min_stat, &sec.cred); + return retval; + + out_fail: + /* Only destroy here if failure. Otherwise, caller is responsible */ if (rpc_clnt) clnt_destroy(rpc_clnt); - if (a != NULL) freeaddrinfo(a); - return retval; + goto out; } @@ -668,7 +668,8 @@ void handle_krb5_upcall(struct clnt_info *clp) { uid_t uid; - AUTH *auth; + CLIENT *rpc_clnt = NULL; + AUTH *auth = NULL; struct authgss_private_data pd; gss_buffer_desc token; char **credlist = NULL; @@ -678,6 +679,7 @@ handle_krb5_upcall(struct clnt_info *clp) token.length = 0; token.value = NULL; + memset(&pd, 0, sizeof(struct authgss_private_data)); if (read(clp->krb5_fd, &uid, sizeof(uid)) < sizeof(uid)) { printerr(0, "WARNING: failed reading uid from krb5 " @@ -700,7 +702,7 @@ handle_krb5_upcall(struct clnt_info *clp) } for (ccname = credlist; ccname && *ccname; ccname++) { gssd_setup_krb5_machine_gss_ccache(*ccname); - if ((create_auth_rpc_client(clp, &auth, uid, + if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_KRB5)) == 0) { /* Success! */ success++; @@ -724,7 +726,8 @@ handle_krb5_upcall(struct clnt_info *clp) /* Tell krb5 gss which credentials cache to use */ gssd_setup_krb5_user_gss_ccache(uid, clp->servername); - if (create_auth_rpc_client(clp, &auth, uid, AUTHTYPE_KRB5)) { + if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, + AUTHTYPE_KRB5)) != 0) { printerr(0, "WARNING: Failed to create krb5 context " "for user with uid %d for server %s\n", uid, clp->servername); @@ -748,14 +751,20 @@ handle_krb5_upcall(struct clnt_info *clp) do_downcall(clp->krb5_fd, uid, &pd, &token); +out: if (token.value) free(token.value); -out: + if (pd.pd_ctx_hndl.length != 0) + authgss_free_private_data(&pd); + if (auth) + AUTH_DESTROY(auth); + if (rpc_clnt) + clnt_destroy(rpc_clnt); return; out_return_error: do_error_downcall(clp->krb5_fd, uid, -1); - return; + goto out; } /* @@ -766,7 +775,8 @@ void handle_spkm3_upcall(struct clnt_info *clp) { uid_t uid; - AUTH *auth; + CLIENT *rpc_clnt = NULL; + AUTH *auth = NULL; struct authgss_private_data pd; gss_buffer_desc token; @@ -781,7 +791,7 @@ handle_spkm3_upcall(struct clnt_info *clp) goto out; } - if (create_auth_rpc_client(clp, &auth, uid, AUTHTYPE_SPKM3)) { + if (create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_SPKM3)) { printerr(0, "WARNING: Failed to create spkm3 context for " "user with uid %d\n", uid); goto out_return_error; @@ -803,12 +813,16 @@ handle_spkm3_upcall(struct clnt_info *clp) do_downcall(clp->spkm3_fd, uid, &pd, &token); +out: if (token.value) free(token.value); -out: + if (auth) + AUTH_DESTROY(auth); + if (rpc_clnt) + clnt_destroy(rpc_clnt); return; out_return_error: do_error_downcall(clp->spkm3_fd, uid, -1); - return; + goto out; }