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
This commit is contained in:
Tom Lane 2008-01-03 21:28:42 +00:00
parent 108b19d860
commit f39ff783bc

View File

@ -85,6 +85,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;
@ -168,6 +169,7 @@ typedef struct remoteConnHashEnt
else \
{ \
connstr = conname_or_str; \
dblink_security_check(conn, rcon, connstr); \
conn = PQconnectdb(connstr); \
if (PQstatus(conn) == CONNECTION_BAD) \
{ \
@ -210,27 +212,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);
@ -2269,3 +2252,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);
}
}