From e3f99e03e2ec65e7ddb1f3056b545f2afa57b2d0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 1 Aug 2018 12:30:36 -0400 Subject: Fix libpq's code for searching .pgpass; rationalize empty-list-item cases. Before v10, we always searched ~/.pgpass using the host parameter, and nothing else, to match to the "hostname" field of ~/.pgpass. (However, null host or host matching DEFAULT_PGSOCKET_DIR was replaced by "localhost".) In v10, this got broken by commit 274bb2b38, repaired by commit bdac9836d, and broken again by commit 7b02ba62e; in the code actually shipped, we'd search with hostaddr if both that and host were specified --- though oddly, *not* if only hostaddr were specified. Since this is directly contrary to the documentation, and not backwards-compatible, it's clearly a bug. However, the change wasn't totally without justification, even though it wasn't done quite right, because the pre-v10 behavior has arguably been buggy since we added hostaddr. If hostaddr is specified and host isn't, the pre-v10 code will search ~/.pgpass for "localhost", and ship that password off to a server that most likely isn't local at all. That's unhelpful at best, and could be a security breach at worst. Therefore, rather than just revert to that old behavior, let's define the behavior as "search with host if provided, else with hostaddr if provided, else search for localhost". (As before, a host name matching DEFAULT_PGSOCKET_DIR is replaced by localhost.) This matches the behavior of the actual connection code, so that we don't pick up an inappropriate password; and it allows useful searches to happen when only hostaddr is given. While we're messing around here, ensure that empty elements within a host or hostaddr list select the same behavior as a totally-empty field would; for instance "host=a,,b" is equivalent to "host=a,/tmp,b" if DEFAULT_PGSOCKET_DIR is /tmp. Things worked that way in some cases already, but not consistently so, which contributed to the confusion about what key ~/.pgpass would get searched with. Update documentation accordingly, and also clarify some nearby text. Back-patch to v10 where the host/hostaddr list functionality was introduced. Discussion: https://postgr.es/m/30805.1532749137@sss.pgh.pa.us --- doc/src/sgml/libpq.sgml | 53 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index d67212b8311..caab9700b86 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -938,8 +938,8 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname If a password file is used, you can have different passwords for different hosts. All the other connection options are the same for every - host, it is not possible to e.g. specify a different username for - different hosts. + host in the list; it is not possible to e.g. specify different + usernames for different hosts. @@ -961,7 +961,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname name of the directory in which the socket file is stored. If multiple host names are specified, each will be tried in turn in the order given. The default behavior when host is - not specified is to connect to a Unix-domain + not specified, or is empty, is to connect to a Unix-domain socketUnix domain socket in /tmp (or whatever socket directory was specified when PostgreSQL was built). On machines without @@ -969,7 +969,8 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname A comma-separated list of host names is also accepted, in which case - each host name in the list is tried in order. See + each host name in the list is tried in order; an empty item in the + list selects the default behavior as explained above. See for details. @@ -1020,14 +1021,17 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname Note that authentication is likely to fail if host is not the name of the server at network address hostaddr. - Also, note that host rather than hostaddr + Also, when both host and hostaddr + are specified, host is used to identify the connection in a password file (see ). A comma-separated list of hostaddr values is also - accepted, in which case each host in the list is tried in order. See + accepted, in which case each host in the list is tried in order. + An empty item in the list causes the corresponding host name to be + used, or the default host name if that is empty as well. See for details. @@ -1047,9 +1051,12 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname name extension for Unix-domain connections.port If multiple hosts were given in the host or - hostaddr parameters, this parameter may specify a list - of ports of equal length, or it may specify a single port number to - be used for all hosts. + hostaddr parameters, this parameter may specify a + comma-separated list of ports of the same length as the host list, or + it may specify a single port number to be used for all hosts. + An empty string, or an empty item in a comma-separated list, + specifies the default port number established + when PostgreSQL was built. @@ -1683,6 +1690,17 @@ char *PQuser(const PGconn *conn); char *PQpass(const PGconn *conn); + + + PQpass will return either the password specified + in the connection parameters, or if there was none and the password + was obtained from the password + file, it will return that. In the latter case, + if multiple hosts were specified in the connection parameters, it is + not possible to rely on the result of PQpass until + the connection is established. The status of the connection can be + checked using the function PQstatus. + @@ -7521,13 +7539,18 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) used. (Therefore, put more-specific entries first when you are using wildcards.) If an entry needs to contain : or \, escape this character with \. - A host name of localhost matches both TCP (host name - localhost) and Unix domain socket (pghost empty - or the default socket directory) connections coming from the local - machine. In a standby server, a database name of replication + The host name field is matched to the host connection + parameter if that is specified, otherwise to + the hostaddr parameter if that is specified; if neither + are given then the host name localhost is searched for. + The host name localhost is also searched for when + the connection is a Unix-domain socket connection and + the host parameter + matches libpq's default socket directory path. + In a standby server, a database field of replication matches streaming replication connections made to the master server. - The database field is of limited usefulness because - users have the same password for all databases in the same cluster. + The database field is of limited usefulness otherwise, because users have + the same password for all databases in the same cluster. -- cgit v1.2.3