mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +03:00
Fix pg_hba.conf matching so that replication connections only match records
with database = replication. The previous coding would allow them to match ordinary records too, but that seems like a recipe for security breaches. Improve the messages associated with no-such-pg_hba.conf entry to report replication connections as such, since that's now a critical aspect of whether the connection matches. Make some cursory improvements in the related documentation, too.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.199 2010/04/19 19:02:18 sriggs Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.200 2010/04/21 03:32:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -36,6 +36,7 @@
|
||||
#include "libpq/pqformat.h"
|
||||
#include "libpq/md5.h"
|
||||
#include "miscadmin.h"
|
||||
#include "replication/walsender.h"
|
||||
#include "storage/ipc.h"
|
||||
|
||||
|
||||
@ -250,6 +251,7 @@ auth_failed(Port *port, int status)
|
||||
switch (port->hba->auth_method)
|
||||
{
|
||||
case uaReject:
|
||||
case uaImplicitReject:
|
||||
errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
|
||||
break;
|
||||
case uaKrb5:
|
||||
@ -363,12 +365,14 @@ ClientAuthentication(Port *port)
|
||||
case uaReject:
|
||||
|
||||
/*
|
||||
* An explicit "reject" entry in pg_hba.conf. Take pity on the poor
|
||||
* user and issue a helpful error message.
|
||||
* NOTE: this is not a security breach, because all the info
|
||||
* reported here is known at the frontend and must be assumed
|
||||
* known to bad guys. We're merely helping out the less clueful
|
||||
* good guys.
|
||||
* An explicit "reject" entry in pg_hba.conf. This report exposes
|
||||
* the fact that there's an explicit reject entry, which is perhaps
|
||||
* not so desirable from a security standpoint; but the message
|
||||
* for an implicit reject could confuse the DBA a lot when the
|
||||
* true situation is a match to an explicit reject. And we don't
|
||||
* want to change the message for an implicit reject. As noted
|
||||
* below, the additional information shown here doesn't expose
|
||||
* anything not known to an attacker.
|
||||
*/
|
||||
{
|
||||
char hostinfo[NI_MAXHOST];
|
||||
@ -378,29 +382,50 @@ ClientAuthentication(Port *port)
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
|
||||
if (am_walsender)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects host \"%s\", user \"%s\", database \"%s\", %s",
|
||||
hostinfo, port->user_name, port->database_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
|
||||
hostinfo, port->user_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
#else
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects host \"%s\", user \"%s\", database \"%s\"",
|
||||
hostinfo, port->user_name, port->database_name)));
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"",
|
||||
hostinfo, port->user_name)));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
|
||||
hostinfo, port->user_name,
|
||||
port->database_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
#else
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"",
|
||||
hostinfo, port->user_name,
|
||||
port->database_name)));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case uaImplicitReject:
|
||||
|
||||
/*
|
||||
* No matching entry so tell the user we fell through.
|
||||
* NOTE: this is not a security breach, because all the info
|
||||
* reported here is known at the frontend and must be assumed
|
||||
* known to bad guys. We're merely helping out the less clueful
|
||||
* good guys.
|
||||
* No matching entry, so tell the user we fell through.
|
||||
*
|
||||
* NOTE: the extra info reported here is not a security breach,
|
||||
* because all that info is known at the frontend and must be
|
||||
* assumed known to bad guys. We're merely helping out the less
|
||||
* clueful good guys.
|
||||
*/
|
||||
{
|
||||
char hostinfo[NI_MAXHOST];
|
||||
@ -410,18 +435,38 @@ ClientAuthentication(Port *port)
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
|
||||
if (am_walsender)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
|
||||
hostinfo, port->user_name, port->database_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
|
||||
hostinfo, port->user_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
#else
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
|
||||
hostinfo, port->user_name, port->database_name)));
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"",
|
||||
hostinfo, port->user_name)));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
|
||||
hostinfo, port->user_name,
|
||||
port->database_name,
|
||||
port->ssl ? _("SSL on") : _("SSL off"))));
|
||||
#else
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
|
||||
hostinfo, port->user_name,
|
||||
port->database_name)));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.205 2010/04/19 19:02:18 sriggs Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.206 2010/04/21 03:32:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -513,7 +513,13 @@ check_db(const char *dbname, const char *role, Oid roleid, char *param_str)
|
||||
tok != NULL;
|
||||
tok = strtok(NULL, MULTI_VALUE_SEP))
|
||||
{
|
||||
if (strcmp(tok, "all\n") == 0)
|
||||
if (am_walsender)
|
||||
{
|
||||
/* walsender connections can only match replication keyword */
|
||||
if (strcmp(tok, "replication\n") == 0)
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(tok, "all\n") == 0)
|
||||
return true;
|
||||
else if (strcmp(tok, "sameuser\n") == 0)
|
||||
{
|
||||
@ -526,9 +532,8 @@ check_db(const char *dbname, const char *role, Oid roleid, char *param_str)
|
||||
if (is_member(roleid, dbname))
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(tok, "replication\n") == 0 &&
|
||||
am_walsender)
|
||||
return true;
|
||||
else if (strcmp(tok, "replication\n") == 0)
|
||||
continue; /* never match this if not walsender */
|
||||
else if (strcmp(tok, dbname) == 0)
|
||||
return true;
|
||||
}
|
||||
@ -1812,7 +1817,7 @@ load_ident(void)
|
||||
*
|
||||
* Note that STATUS_ERROR indicates a problem with the hba config file.
|
||||
* If the file is OK but does not contain any entry matching the request,
|
||||
* we return STATUS_OK and method = uaReject.
|
||||
* we return STATUS_OK and method = uaImplicitReject.
|
||||
*/
|
||||
int
|
||||
hba_getauthmethod(hbaPort *port)
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c,v 1.9 2010/04/19 14:10:45 mha Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c,v 1.10 2010/04/21 03:32:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -91,7 +91,7 @@ libpqrcv_connect(char *conninfo, XLogRecPtr startpoint)
|
||||
streamConn = PQconnectdb(conninfo_repl);
|
||||
if (PQstatus(streamConn) != CONNECTION_OK)
|
||||
ereport(ERROR,
|
||||
(errmsg("could not connect to the primary server : %s",
|
||||
(errmsg("could not connect to the primary server: %s",
|
||||
PQerrorMessage(streamConn))));
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user