aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-04-08 02:49:35 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-04-08 02:49:35 +0300
commit20f9b61cc1926775b1ceb25196df942efaf8bdd2 (patch)
treefdcdf981222b5516f2b1c52a05bb4f4bd9979007 /src/interfaces/libpq/fe-connect.c
parent1169920ff77025550718b90a5cafc6849875f43f (diff)
downloadpostgresql-20f9b61cc1926775b1ceb25196df942efaf8bdd2.tar.gz
postgresql-20f9b61cc1926775b1ceb25196df942efaf8bdd2.zip
With gssencmode='require', check credential cache before connecting
Previously, libpq would establish the TCP connection, and then immediately disconnect if the credentials were not available. The same thing happened if you tried to use a Unix domain socket with gssencmode=require. Check those conditions before establishing the TCP connection. This is a very minor issue, but my motivation to do this now is that I'm about to add more detail to the tests for encryption negotiation. This makes the case of gssencmode=require but no credentials configured fail at the same stage as with gssencmode=require and GSSAPI support not compiled at all. That avoids having to deal with variations in expected output depending on build options. Discussion: https://www.postgresql.org/message-id/CAEze2Wja8VUoZygCepwUeiCrWa4jP316k0mvJrOW4PFmWP0Tcw@mail.gmail.com
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 01e49c6975e..4f477f97527 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2855,6 +2855,33 @@ keep_going: /* We will come back to here until there is
/* Remember current address for possible use later */
memcpy(&conn->raddr, &addr_cur->addr, sizeof(SockAddr));
+#ifdef ENABLE_GSS
+
+ /*
+ * Before establishing the connection, check if it's
+ * doomed to fail because gssencmode='require' but GSSAPI
+ * is not available.
+ */
+ if (conn->gssencmode[0] == 'r')
+ {
+ if (conn->raddr.addr.ss_family == AF_UNIX)
+ {
+ libpq_append_conn_error(conn,
+ "GSSAPI encryption required but it is not supported over a local socket)");
+ goto error_return;
+ }
+ if (conn->gcred == GSS_C_NO_CREDENTIAL)
+ {
+ if (!pg_GSS_have_cred_cache(&conn->gcred))
+ {
+ libpq_append_conn_error(conn,
+ "GSSAPI encryption required but no credential cache");
+ goto error_return;
+ }
+ }
+ }
+#endif
+
/*
* Set connip, too. Note we purposely ignore strdup
* failure; not a big problem if it fails.
@@ -3218,7 +3245,7 @@ keep_going: /* We will come back to here until there is
* for GSSAPI Encryption (and skip past SSL negotiation and
* regular startup below).
*/
- if (conn->try_gss && !conn->gctx)
+ if (conn->try_gss && !conn->gctx && conn->gcred == GSS_C_NO_CREDENTIAL)
conn->try_gss = pg_GSS_have_cred_cache(&conn->gcred);
if (conn->try_gss && !conn->gctx)
{
@@ -3237,8 +3264,9 @@ keep_going: /* We will come back to here until there is
}
else if (!conn->gctx && conn->gssencmode[0] == 'r')
{
+ /* XXX: shouldn't happen */
libpq_append_conn_error(conn,
- "GSSAPI encryption required but was impossible (possibly no credential cache, no server support, or using a local socket)");
+ "GSSAPI encryption required but was impossible");
goto error_return;
}
#endif