]> granicus.if.org Git - postgresql/commitdiff
The original patch to disallow non-passworded connections to non-superusers
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Jan 2008 21:28:30 +0000 (21:28 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Jan 2008 21:28:30 +0000 (21:28 +0000)
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

contrib/dblink/dblink.c

index 5f0b06742b975b7d00c8857bfba3a8b7254b06e6..d672edfc7772cf7a83932d761cb0fc1d643b7a96 100644 (file)
@@ -84,6 +84,7 @@ static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 p
 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 *rconn, const char *connstr);
 
 /* Global */
 static remoteConn *pconn = NULL;
@@ -170,6 +171,7 @@ typedef struct remoteConnHashEnt
                        else \
                        { \
                                connstr = conname_or_str; \
+                               dblink_security_check(conn, rconn, connstr); \
                                conn = PQconnectdb(connstr); \
                                if (PQstatus(conn) == CONNECTION_BAD) \
                                { \
@@ -224,27 +226,8 @@ dblink_connect(PG_FUNCTION_ARGS)
        if (connname)
                rconn = (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 (rconn)
-                               pfree(rconn);
-
-                       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, rconn, connstr);
        conn = PQconnectdb(connstr);
 
        MemoryContextSwitchTo(oldcontext);
@@ -2296,3 +2279,28 @@ connstr_strip_password(const char *connstr)
 
        return result.data;
 }
+
+static void
+dblink_security_check(PGconn *conn, remoteConn *rconn, const char *connstr)
+{
+       if (!superuser())
+       {
+               /* this attempt must fail */
+               conn = PQconnectdb(connstr_strip_password(connstr));
+
+               if (PQstatus(conn) == CONNECTION_OK)
+               {
+                       PQfinish(conn);
+                       if (rconn)
+                               pfree(rconn);
+
+                       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);
+       }
+}