diff -Naur pgsql/src/interfaces/libpq/fe-auth.c pgsql-patched/src/interfaces/libpq/fe-auth.c --- pgsql/src/interfaces/libpq/fe-auth.c Wed Apr 24 23:00:40 2002 +++ pgsql-patched/src/interfaces/libpq/fe-auth.c Mon May 20 19:00:16 2002 @@ -268,22 +268,33 @@ * Various krb5 state which is not connection specfic, and a flag to * indicate whether we have initialised it yet. */ +/* static int pg_krb5_initialised; static krb5_context pg_krb5_context; static krb5_ccache pg_krb5_ccache; static krb5_principal pg_krb5_client; static char *pg_krb5_name; +*/ + +struct krb5_info +{ + int pg_krb5_initialised; + krb5_context pg_krb5_context; + krb5_ccache pg_krb5_ccache; + krb5_principal pg_krb5_client; + char *pg_krb5_name; +}; static int -pg_krb5_init(char *PQerrormsg) +pg_krb5_init(char *PQerrormsg, struct krb5_info *info) { krb5_error_code retval; - if (pg_krb5_initialised) + if (info->pg_krb5_initialised) return STATUS_OK; - retval = krb5_init_context(&pg_krb5_context); + retval = krb5_init_context(&(info->pg_krb5_context)); if (retval) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, @@ -292,46 +303,56 @@ return STATUS_ERROR; } - retval = krb5_cc_default(pg_krb5_context, &pg_krb5_ccache); + retval = krb5_cc_default(info->pg_krb5_context, &(info->pg_krb5_ccache)); if (retval) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, "pg_krb5_init: krb5_cc_default: %s\n", error_message(retval)); - krb5_free_context(pg_krb5_context); + krb5_free_context(info->pg_krb5_context); return STATUS_ERROR; } - retval = krb5_cc_get_principal(pg_krb5_context, pg_krb5_ccache, - &pg_krb5_client); + retval = krb5_cc_get_principal(info->pg_krb5_context, info->pg_krb5_ccache, + &(info->pg_krb5_client)); if (retval) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, "pg_krb5_init: krb5_cc_get_principal: %s\n", error_message(retval)); - krb5_cc_close(pg_krb5_context, pg_krb5_ccache); - krb5_free_context(pg_krb5_context); + krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache); + krb5_free_context(info->pg_krb5_context); return STATUS_ERROR; } - retval = krb5_unparse_name(pg_krb5_context, pg_krb5_client, &pg_krb5_name); + retval = krb5_unparse_name(info->pg_krb5_context, info->pg_krb5_client, &(info->pg_krb5_name)); if (retval) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, "pg_krb5_init: krb5_unparse_name: %s\n", error_message(retval)); - krb5_free_principal(pg_krb5_context, pg_krb5_client); - krb5_cc_close(pg_krb5_context, pg_krb5_ccache); - krb5_free_context(pg_krb5_context); + krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client); + krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache); + krb5_free_context(info->pg_krb5_context); return STATUS_ERROR; } - pg_krb5_name = pg_an_to_ln(pg_krb5_name); + info->pg_krb5_name = pg_an_to_ln(info->pg_krb5_name); - pg_krb5_initialised = 1; + info->pg_krb5_initialised = 1; return STATUS_OK; } +static void +pg_krb5_destroy(struct krb5_info *info) +{ + krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client); + krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache); + krb5_free_context(info->pg_krb5_context); + free(info->pg_krb5_name); +} + + /* * pg_krb5_authname -- returns a pointer to static space containing whatever @@ -340,10 +361,16 @@ static const char * pg_krb5_authname(char *PQerrormsg) { - if (pg_krb5_init(PQerrormsg) != STATUS_OK) + char *tmp_name; + struct krb5_info info; + info.pg_krb5_initialised = 0; + + if (pg_krb5_init(PQerrormsg, &info) != STATUS_OK) return NULL; + tmp_name = strdup(info.pg_krb5_name); + pg_krb5_destroy(&info); - return pg_krb5_name; + return tmp_name; } @@ -363,18 +390,21 @@ krb5_auth_context auth_context = NULL; krb5_error *err_ret = NULL; int flags; + struct krb5_info info; + info.pg_krb5_initialised = 0; - ret = pg_krb5_init(PQerrormsg); + ret = pg_krb5_init(PQerrormsg, &info); if (ret != STATUS_OK) return ret; - retval = krb5_sname_to_principal(pg_krb5_context, hostname, PG_KRB_SRVNAM, + retval = krb5_sname_to_principal(info.pg_krb5_context, hostname, PG_KRB_SRVNAM, KRB5_NT_SRV_HST, &server); if (retval) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, "pg_krb5_sendauth: krb5_sname_to_principal: %s\n", error_message(retval)); + pg_krb5_destroy(&info); return STATUS_ERROR; } @@ -388,16 +418,17 @@ { snprintf(PQerrormsg, PQERRORMSG_LENGTH, libpq_gettext("could not set socket to blocking mode: %s\n"), strerror(errno)); - krb5_free_principal(pg_krb5_context, server); + krb5_free_principal(info.pg_krb5_context, server); + pg_krb5_destroy(&info); return STATUS_ERROR; } - retval = krb5_sendauth(pg_krb5_context, &auth_context, + retval = krb5_sendauth(info.pg_krb5_context, &auth_context, (krb5_pointer) & sock, PG_KRB_SRVNAM, - pg_krb5_client, server, + info.pg_krb5_client, server, AP_OPTS_MUTUAL_REQUIRED, NULL, 0, /* no creds, use ccache instead */ - pg_krb5_ccache, &err_ret, NULL, NULL); + info.pg_krb5_ccache, &err_ret, NULL, NULL); if (retval) { if (retval == KRB5_SENDAUTH_REJECTED && err_ret) @@ -422,12 +453,12 @@ } if (err_ret) - krb5_free_error(pg_krb5_context, err_ret); + krb5_free_error(info.pg_krb5_context, err_ret); ret = STATUS_ERROR; } - krb5_free_principal(pg_krb5_context, server); + krb5_free_principal(info.pg_krb5_context, server); if (fcntl(sock, F_SETFL, (long) flags)) { @@ -436,6 +467,7 @@ strerror(errno)); ret = STATUS_ERROR; } + pg_krb5_destroy(&info); return ret; } @@ -731,5 +763,9 @@ if (name && (authn = (char *) malloc(strlen(name) + 1))) strcpy(authn, name); +#ifdef KRB5 + if(name) + free(name); +#endif return authn; }