aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-01-03 21:28:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-01-03 21:28:55 +0000
commit1f42e1cb68e6bdd2b65620cd57c797a848d9be8c (patch)
treecd10da60a1b11f9a2d2493e9f158bad836cde049
parent230d5cfc4739bc4963c8d67e4a7cd84abe53ef93 (diff)
downloadpostgresql-1f42e1cb68e6bdd2b65620cd57c797a848d9be8c.tar.gz
postgresql-1f42e1cb68e6bdd2b65620cd57c797a848d9be8c.zip
The original patch to disallow non-passworded connections to non-superusers
failed to cover all the ways in which a connection can be initiated in dblink. Plug the remaining holes. Also, disallow transient connections in functions for which that feature makes no sense (because they are only sensible as part of a sequence of operations on the same connection). Joe Conway Security: CVE-2007-6601
-rw-r--r--contrib/dblink/dblink.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index d12af7810d4..0a2d70e6b69 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -31,6 +31,8 @@
*/
#include "postgres.h"
+#include <ctype.h>
+
#include "libpq-fe.h"
#include "fmgr.h"
#include "funcapi.h"
@@ -85,6 +87,7 @@ static HeapTuple get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknuma
static Oid get_relid_from_relname(text *relname_text);
static char *generate_relation_name(Oid relid);
static char *connstr_strip_password(const char *connstr);
+static void dblink_security_check(PGconn *conn, remoteConn *rcon, const char *connstr);
/* Global */
List *res_id = NIL;
@@ -159,6 +162,7 @@ typedef struct remoteConnHashEnt
else \
{ \
connstr = conname_or_str; \
+ dblink_security_check(conn, rcon, connstr); \
conn = PQconnectdb(connstr); \
if (PQstatus(conn) == CONNECTION_BAD) \
{ \
@@ -200,27 +204,8 @@ dblink_connect(PG_FUNCTION_ARGS)
if (connname)
rcon = (remoteConn *) palloc(sizeof(remoteConn));
- /* for non-superusers, check that server requires a password */
- if (!superuser())
- {
- /* this attempt must fail */
- conn = PQconnectdb(connstr_strip_password(connstr));
-
- if (PQstatus(conn) == CONNECTION_OK)
- {
- PQfinish(conn);
- if (rcon)
- pfree(rcon);
-
- ereport(ERROR,
- (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
- errmsg("password is required"),
- errdetail("Non-superuser cannot connect if the server does not request a password."),
- errhint("Target server's authentication method must be changed.")));
- }
- else
- PQfinish(conn);
- }
+ /* check password used if not superuser */
+ dblink_security_check(conn, rcon, connstr);
conn = PQconnectdb(connstr);
MemoryContextSwitchTo(oldcontext);
@@ -2124,3 +2109,28 @@ connstr_strip_password(const char *connstr)
return result.data;
}
+
+static void
+dblink_security_check(PGconn *conn, remoteConn *rcon, const char *connstr)
+{
+ if (!superuser())
+ {
+ /* this attempt must fail */
+ conn = PQconnectdb(connstr_strip_password(connstr));
+
+ if (PQstatus(conn) == CONNECTION_OK)
+ {
+ PQfinish(conn);
+ if (rcon)
+ pfree(rcon);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
+ errmsg("password is required"),
+ errdetail("Non-superuser cannot connect if the server does not request a password."),
+ errhint("Target server's authentication method must be changed.")));
+ }
+ else
+ PQfinish(conn);
+ }
+}