summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Conway2007-07-08 17:11:51 +0000
committerJoe Conway2007-07-08 17:11:51 +0000
commit2135d1ed7c94d6b786f78e935f88b6f5fc7b993b (patch)
tree8146aa83e6a577d1745932e2b1fac4643d3e6d9c
parent882824ceea290994a211e79b4740f401c840bcba (diff)
Arrange for the authentication request type to be preserved in
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.
-rw-r--r--doc/src/sgml/libpq.sgml14
-rw-r--r--src/include/libpq/pqcomm.h1
-rw-r--r--src/interfaces/libpq/exports.txt1
-rw-r--r--src/interfaces/libpq/fe-connect.c16
-rw-r--r--src/interfaces/libpq/libpq-fe.h4
-rw-r--r--src/interfaces/libpq/libpq-int.h1
6 files changed, 36 insertions, 1 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index ca6edbf769..a105b6a19a 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -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>
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 5a571a3206..5116cf43ec 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -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;
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index 85352e6ef2..bc453c1197 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -137,3 +137,4 @@ PQdescribePortal 134
PQsendDescribePrepared 135
PQsendDescribePortal 136
lo_truncate 137
+PQconnectionUsedPassword 138
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 4e813f308e..e58b94abdb 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -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)
{
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index e3476a145d..285b3998e0 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -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. */
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index b5a6fe5cfa..2cbf924387 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -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 */