Arrange for the authentication request type to be preserved in
authorJoe Conway <mail@joeconway.com>
Sun, 8 Jul 2007 17:11:51 +0000 (17:11 +0000)
committerJoe Conway <mail@joeconway.com>
Sun, 8 Jul 2007 17:11:51 +0000 (17:11 +0000)
PGconn. Invent a new libpq connection-status function,
PQconnectionUsedPassword() that returns true if the server
demanded a password during authentication, false otherwise.
This may be useful to clients in general, but is immediately
useful to help plug a privilege escalation path in dblink.
Per list discussion and design proposed by Tom Lane.

doc/src/sgml/libpq.sgml
src/include/libpq/pqcomm.h
src/interfaces/libpq/exports.txt
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-fe.h
src/interfaces/libpq/libpq-int.h

index ca6edbf769e431774ab0848be4929ed15811129d..a105b6a19a2cd2a12ab97613387e1ef0b8e21f58 100644 (file)
@@ -1059,6 +1059,20 @@ SSL *PQgetssl(const PGconn *conn);
      </listitem>
     </varlistentry>
 
+    <varlistentry>
+     <term><function>PQconnectionUsedPassword</function><indexterm><primary>PQconnectionUsedPassword</></></term>
+     <listitem>
+      <para>
+       Returns true (1) if the connection authentication method
+       required a password to be supplied. Returns false (0)
+       otherwise.
+       <synopsis>
+       bool PQconnectionUsedPassword(const PGconn *conn);
+       </synopsis>
+      </para>
+     </listitem>
+    </varlistentry>
+
 </variablelist>
 </para>
 
index 5a571a32063ec87aed8a6946e4e7f7e406f50b37..5116cf43ecd65c41c75584798fbedd9f346d05eb 100644 (file)
@@ -156,6 +156,7 @@ extern bool Db_user_namespace;
 #define AUTH_REQ_CRYPT         4       /* crypt password */
 #define AUTH_REQ_MD5           5       /* md5 password */
 #define AUTH_REQ_SCM_CREDS     6       /* transfer SCM credentials */
+#define AUTH_REQ_UNK           7       /* User has not yet attempted to authenticate */
 
 typedef uint32 AuthRequest;
 
index 85352e6ef2357c682f2171813cb4235e351f4e25..bc453c119780350e941e991f990e843b1b332d5a 100644 (file)
@@ -137,3 +137,4 @@ PQdescribePortal          134
 PQsendDescribePrepared    135
 PQsendDescribePortal      136
 lo_truncate               137
+PQconnectionUsedPassword  138
index 4e813f308e324f710557a49ed3cd6848b711c447..e58b94abdb01ea77b633d871b85000e8fba18480 100644 (file)
@@ -1641,6 +1641,10 @@ keep_going:                                              /* We will come back to here until there is
                                        return PGRES_POLLING_READING;
                                }
 
+                               /* save the authentication request type */
+                               if (conn->areq == AUTH_REQ_UNK)
+                                       conn->areq = areq;
+
                                /* Get the password salt if there is one. */
                                if (areq == AUTH_REQ_MD5)
                                {
@@ -1873,6 +1877,7 @@ makeEmptyPGconn(void)
        conn->std_strings = false;      /* unless server says differently */
        conn->verbosity = PQERRORS_DEFAULT;
        conn->sock = -1;
+       conn->areq = AUTH_REQ_UNK;
 #ifdef USE_SSL
        conn->allow_ssl_try = true;
        conn->wait_ssl_try = false;
@@ -3441,6 +3446,17 @@ PQsetClientEncoding(PGconn *conn, const char *encoding)
        return status;
 }
 
+bool
+PQconnectionUsedPassword(const PGconn *conn)
+{
+       if (conn->areq == AUTH_REQ_MD5 ||
+               conn->areq == AUTH_REQ_CRYPT ||
+               conn->areq == AUTH_REQ_PASSWORD)
+               return true;
+       else
+               return false;
+}
+
 PGVerbosity
 PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
 {
index e3476a145d8089f6bfb67b529d25de8f135ec673..285b3998e017301a9e1fbfa9093c0481c393d5ba 100644 (file)
@@ -23,10 +23,11 @@ extern              "C"
 #include <stdio.h>
 
 /*
- * postgres_ext.h defines the backend's externally visible types,
+ * defines the backend's externally visible types,
  * such as Oid.
  */
 #include "postgres_ext.h"
+#include "postgres_fe.h"
 
 /* Application-visible enum types */
 
@@ -265,6 +266,7 @@ extern int  PQsocket(const PGconn *conn);
 extern int     PQbackendPID(const PGconn *conn);
 extern int     PQclientEncoding(const PGconn *conn);
 extern int     PQsetClientEncoding(PGconn *conn, const char *encoding);
+extern bool    PQconnectionUsedPassword(const PGconn *conn);
 
 /* Get the OpenSSL structure associated with a connection. Returns NULL for
  * unencrypted connections or if any other TLS library is in use. */
index b5a6fe5cfa80bd0caa3ee01c422198bfdbc9898c..2cbf9243877ba8fa0b9b7572919cebaac12552fd 100644 (file)
@@ -299,6 +299,7 @@ struct pg_conn
        SockAddr        raddr;                  /* Remote address */
        ProtocolVersion pversion;       /* FE/BE protocol version in use */
        int                     sversion;               /* server version, e.g. 70401 for 7.4.1 */
+       AuthRequest     areq;                   /* server demanded password during auth */
 
        /* Transient state needed while establishing connection */
        struct addrinfo *addrlist;      /* list of possible backend addresses */