diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/libpq/auth.c | 28 | ||||
-rw-r--r-- | src/backend/libpq/hba.c | 34 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 19 |
3 files changed, 59 insertions, 22 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 31ade0bdbe4..d062c1d8cef 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -425,15 +425,25 @@ ClientAuthentication(Port *port) NI_NUMERICHOST); #define HOSTNAME_LOOKUP_DETAIL(port) \ - (port->remote_hostname \ - ? (port->remote_hostname_resolv == +1 \ - ? errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", port->remote_hostname) \ - : (port->remote_hostname_resolv == 0 \ - ? errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", port->remote_hostname) \ - : (port->remote_hostname_resolv == -1 \ - ? errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", port->remote_hostname) \ - : 0))) \ - : 0) + (port->remote_hostname ? \ + (port->remote_hostname_resolv == +1 ? \ + errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \ + port->remote_hostname) : \ + port->remote_hostname_resolv == 0 ? \ + errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \ + port->remote_hostname) : \ + port->remote_hostname_resolv == -1 ? \ + errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \ + port->remote_hostname) : \ + port->remote_hostname_resolv == -2 ? \ + errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \ + port->remote_hostname, \ + gai_strerror(port->remote_hostname_errcode)) : \ + 0) \ + : (port->remote_hostname_resolv == -2 ? \ + errdetail_log("Could not resolve client IP address to a host name: %s.", \ + gai_strerror(port->remote_hostname_errcode)) : \ + 0)) if (am_walsender) { diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 77434f410ae..83dd1474081 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -592,35 +592,47 @@ check_hostname(hbaPort *port, const char *hostname) int ret; bool found; + /* Quick out if remote host name already known bad */ + if (port->remote_hostname_resolv < 0) + return false; + /* Lookup remote host name if not already done */ if (!port->remote_hostname) { char remote_hostname[NI_MAXHOST]; - if (pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, - remote_hostname, sizeof(remote_hostname), - NULL, 0, - 0) != 0) + ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, + remote_hostname, sizeof(remote_hostname), + NULL, 0, + NI_NAMEREQD); + if (ret != 0) + { + /* remember failure; don't complain in the postmaster log yet */ + port->remote_hostname_resolv = -2; + port->remote_hostname_errcode = ret; return false; + } port->remote_hostname = pstrdup(remote_hostname); } + /* Now see if remote host name matches this pg_hba line */ if (!hostname_match(hostname, port->remote_hostname)) return false; - /* Lookup IP from host name and check against original IP */ - + /* If we already verified the forward lookup, we're done */ if (port->remote_hostname_resolv == +1) return true; - if (port->remote_hostname_resolv == -1) - return false; + /* Lookup IP from host name and check against original IP */ ret = getaddrinfo(port->remote_hostname, NULL, NULL, &gai_result); if (ret != 0) - ereport(ERROR, - (errmsg("could not translate host name \"%s\" to address: %s", - port->remote_hostname, gai_strerror(ret)))); + { + /* remember failure; don't complain in the postmaster log yet */ + port->remote_hostname_resolv = -2; + port->remote_hostname_errcode = ret; + return false; + } found = false; for (gai = gai_result; gai; gai = gai->ai_next) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index e9072b76efc..7a2c45af382 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -3952,8 +3952,23 @@ BackendInitialize(Port *port) */ port->remote_host = strdup(remote_host); port->remote_port = strdup(remote_port); - if (log_hostname) - port->remote_hostname = port->remote_host; + + /* + * If we did a reverse lookup to name, we might as well save the results + * rather than possibly repeating the lookup during authentication. + * + * Note that we don't want to specify NI_NAMEREQD above, because then we'd + * get nothing useful for a client without an rDNS entry. Therefore, we + * must check whether we got a numeric IPv4 or IPv6 address, and not save + * it into remote_hostname if so. (This test is conservative and might + * sometimes classify a hostname as numeric, but an error in that + * direction is safe; it only results in a possible extra lookup.) + */ + if (log_hostname && + ret == 0 && + strspn(remote_host, "0123456789.") < strlen(remote_host) && + strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host)) + port->remote_hostname = strdup(remote_host); /* * Ready to begin client interaction. We will give up and exit(1) after a |