]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
With gssencmode='require', check credential cache before connecting
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 7 Apr 2024 23:49:35 +0000 (02:49 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 7 Apr 2024 23:49:35 +0000 (02:49 +0300)
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

src/interfaces/libpq/fe-connect.c

index 01e49c6975e2fd6d20d6d797c90a84677e4510ab..4f477f97527efc84952ef0ed8bed6c344873a616 100644 (file)
@@ -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