aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-07-13 11:57:55 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-07-13 11:58:09 -0400
commit8e6f134a9a8db52cbd2818ce8a60b9e5cdadfc8f (patch)
tree8f1755cb9d0e3dc3028a826608eb99be2778778b /src
parentae290059e1aa5bc2272a0345184bcf05407f69a4 (diff)
downloadpostgresql-8e6f134a9a8db52cbd2818ce8a60b9e5cdadfc8f.tar.gz
postgresql-8e6f134a9a8db52cbd2818ce8a60b9e5cdadfc8f.zip
Fix bugs in libpq's management of GSS encryption state.
GSS-related resources should be cleaned up in pqDropConnection, not freePGconn, else the wrong things happen when resetting a connection or trying to switch to a different server. It's also critical to reset conn->gssenc there. During connection setup, initialize conn->try_gss at the correct place, else switching to a different server won't work right. Remove now-redundant cleanup of GSS resources around one (and, for some reason, only one) pqDropConnection call in connectDBStart. Per report from Kyotaro Horiguchi that psql would freeze up, rather than successfully resetting a GSS-encrypted connection after a server restart. This is YA oversight in commit b0b39f72b, so back-patch to v12. Discussion: https://postgr.es/m/20200710.173803.435804731896516388.horikyota.ntt@gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-connect.c37
1 files changed, 9 insertions, 28 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index fcd2457116b..86e196064eb 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -477,6 +477,11 @@ pqDropConnection(PGconn *conn, bool flushInput)
{
OM_uint32 min_s;
+ if (conn->gcred != GSS_C_NO_CREDENTIAL)
+ {
+ gss_release_cred(&min_s, &conn->gcred);
+ conn->gcred = GSS_C_NO_CREDENTIAL;
+ }
if (conn->gctx)
gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
if (conn->gtarg_nam)
@@ -496,6 +501,7 @@ pqDropConnection(PGconn *conn, bool flushInput)
free(conn->gss_ResultBuffer);
conn->gss_ResultBuffer = NULL;
}
+ conn->gssenc = false;
}
#endif
#ifdef ENABLE_SSPI
@@ -2023,11 +2029,6 @@ connectDBStart(PGconn *conn)
*/
resetPQExpBuffer(&conn->errorMessage);
-#ifdef ENABLE_GSS
- if (conn->gssencmode[0] == 'd') /* "disable" */
- conn->try_gss = false;
-#endif
-
/*
* Set up to try to connect to the first host. (Setting whichhost = -1 is
* a bit of a cheat, but PQconnectPoll will advance it to 0 before
@@ -2464,6 +2465,9 @@ keep_going: /* We will come back to here until there is
conn->allow_ssl_try = (conn->sslmode[0] != 'd'); /* "disable" */
conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */
#endif
+#ifdef ENABLE_GSS
+ conn->try_gss = (conn->gssencmode[0] != 'd'); /* "disable" */
+#endif
reset_connection_state_machine = false;
need_new_connection = true;
@@ -3345,12 +3349,8 @@ keep_going: /* We will come back to here until there is
*/
if (conn->gssenc && conn->gssencmode[0] == 'p')
{
- OM_uint32 minor;
-
/* postmaster expects us to drop the connection */
conn->try_gss = false;
- conn->gssenc = false;
- gss_delete_sec_context(&minor, &conn->gctx, NULL);
pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
@@ -3902,9 +3902,6 @@ makeEmptyPGconn(void)
conn->verbosity = PQERRORS_DEFAULT;
conn->show_context = PQSHOW_CONTEXT_ERRORS;
conn->sock = PGINVALID_SOCKET;
-#ifdef ENABLE_GSS
- conn->try_gss = true;
-#endif
/*
* We try to send at least 8K at a time, which is the usual size of pipe
@@ -4061,22 +4058,6 @@ freePGconn(PGconn *conn)
free(conn->gsslib);
if (conn->connip)
free(conn->connip);
-#ifdef ENABLE_GSS
- if (conn->gcred != GSS_C_NO_CREDENTIAL)
- {
- OM_uint32 minor;
-
- gss_release_cred(&minor, &conn->gcred);
- conn->gcred = GSS_C_NO_CREDENTIAL;
- }
- if (conn->gctx)
- {
- OM_uint32 minor;
-
- gss_delete_sec_context(&minor, &conn->gctx, GSS_C_NO_BUFFER);
- conn->gctx = NULL;
- }
-#endif
/* Note that conn->Pfdebug is not ours to close or free */
if (conn->last_query)
free(conn->last_query);