diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-04-21 03:32:53 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-04-21 03:32:53 +0000 |
commit | a2c3931a244b67115a0eac1ee5fde9eb7cb4e42c (patch) | |
tree | 29ce8f4c20563cde96048a4e562b2456a159aa28 /src | |
parent | a3c6d105752c28dbd19d0558733a2157e6ab55e0 (diff) | |
download | postgresql-a2c3931a244b67115a0eac1ee5fde9eb7cb4e42c.tar.gz postgresql-a2c3931a244b67115a0eac1ee5fde9eb7cb4e42c.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/libpq/auth.c | 105 | ||||
-rw-r--r-- | src/backend/libpq/hba.c | 17 | ||||
-rw-r--r-- | src/backend/replication/libpqwalreceiver/libpqwalreceiver.c | 4 |
3 files changed, 88 insertions, 38 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index ac26317d264..c4e234186e6 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -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; } diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 11443f76e2d..e5fb65f75d3 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -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) diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index d41858e49a2..1807fde9e4b 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -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)))); /* |