aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/libpq/auth.c28
-rw-r--r--src/backend/libpq/hba.c34
-rw-r--r--src/backend/libpq/ip.c5
-rw-r--r--src/backend/postmaster/postmaster.c38
4 files changed, 65 insertions, 40 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 9cdee2bb3e7..c65427e53c4 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -440,15 +440,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 828f6dcc8e1..09e8715c798 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -565,35 +565,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/libpq/ip.c b/src/backend/libpq/ip.c
index 550e11b68cf..db3a5252efd 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -247,11 +247,6 @@ getnameinfo_unix(const struct sockaddr_un * sa, int salen,
(node == NULL && service == NULL))
return EAI_FAIL;
- /* We don't support those. */
- if ((node && !(flags & NI_NUMERICHOST))
- || (service && !(flags & NI_NUMERICSERV)))
- return EAI_FAIL;
-
if (node)
{
ret = snprintf(node, nodelen, "%s", "[local]");
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index b96b505834a..95640622bc1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -3381,6 +3381,7 @@ static void
BackendInitialize(Port *port)
{
int status;
+ int ret;
char remote_host[NI_MAXHOST];
char remote_port[NI_MAXSERV];
char remote_ps_data[NI_MAXHOST];
@@ -3442,21 +3443,13 @@ BackendInitialize(Port *port)
*/
remote_host[0] = '\0';
remote_port[0] = '\0';
- if (pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+ if ((ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
remote_host, sizeof(remote_host),
remote_port, sizeof(remote_port),
- (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV) != 0)
- {
- int ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
- remote_host, sizeof(remote_host),
- remote_port, sizeof(remote_port),
- NI_NUMERICHOST | NI_NUMERICSERV);
-
- if (ret != 0)
- ereport(WARNING,
- (errmsg_internal("pg_getnameinfo_all() failed: %s",
- gai_strerror(ret))));
- }
+ (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) != 0)
+ ereport(WARNING,
+ (errmsg_internal("pg_getnameinfo_all() failed: %s",
+ gai_strerror(ret))));
if (remote_port[0] == '\0')
snprintf(remote_ps_data, sizeof(remote_ps_data), "%s", remote_host);
else
@@ -3480,8 +3473,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