Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit029decf

Browse files
committed
Fix assorted issues in client host name lookup.
The code for matching clients to pg_hba.conf lines that specify host names(instead of IP address ranges) failed to complain if reverse DNS lookupfailed; instead it silently didn't match, so that you might end up gettinga surprising "no pg_hba.conf entry for ..." error, as seen in bug #9518from Mike Blackwell. Since we don't want to make this a fatal error insituations where pg_hba.conf contains a mixture of host names and IPaddresses (clients matching one of the numeric entries should not have tohave rDNS data), remember the lookup failure and mention it as DETAIL ifwe get to "no pg_hba.conf entry". Apply the same approach to forward-DNSlookup failures, too, rather than treating them as immediate hard errors.Along the way, fix a couple of bugs that prevented us from detecting anrDNS lookup error reliably, and make sure that we make only one rDNS lookupattempt; formerly, if the lookup attempt failed, the code would try againfor each host name entry in pg_hba.conf. Since more or less the wholepoint of this design is to ensure there's only one lookup attempt not oneper entry, the latter point represents a performance bug that seemssufficient justification for back-patching.Also, adjust src/port/getaddrinfo.c so that it plays as well as it canwith this code. Which is not all that well, since it does not have actualsupport for rDNS lookup, but at least it should return the expected (andrequired by spec) error codes so that the main code correctly perceives thelack of functionality as a lookup failure. It's unlikely that PG is stillbeing used in production on any machines that require our getaddrinfo.c,so I'm not excited about working harder than this.To keep the code in the various branches similar, this includesback-patching commitsc424d0d and1997f34 into 9.2 and earlier.Back-patch to 9.1 where the facility for hostnames in pg_hba.conf wasintroduced.
1 parente83bee8 commit029decf

File tree

7 files changed

+94
-55
lines changed

7 files changed

+94
-55
lines changed

‎src/backend/libpq/auth.c‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,15 +440,25 @@ ClientAuthentication(Port *port)
440440
NI_NUMERICHOST);
441441

442442
#defineHOSTNAME_LOOKUP_DETAIL(port) \
443-
(port->remote_hostname \
444-
? (port->remote_hostname_resolv == +1\
445-
? errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", port->remote_hostname) \
446-
: (port->remote_hostname_resolv == 0\
447-
? errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", port->remote_hostname) \
448-
: (port->remote_hostname_resolv == -1\
449-
? errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", port->remote_hostname) \
450-
: 0)))\
451-
: 0)
443+
(port->remote_hostname ? \
444+
(port->remote_hostname_resolv == +1 ? \
445+
errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
446+
port->remote_hostname) : \
447+
port->remote_hostname_resolv == 0 ? \
448+
errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
449+
port->remote_hostname) : \
450+
port->remote_hostname_resolv == -1 ? \
451+
errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
452+
port->remote_hostname) : \
453+
port->remote_hostname_resolv == -2 ? \
454+
errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
455+
port->remote_hostname, \
456+
gai_strerror(port->remote_hostname_errcode)) : \
457+
0) \
458+
: (port->remote_hostname_resolv == -2 ? \
459+
errdetail_log("Could not resolve client IP address to a host name: %s.", \
460+
gai_strerror(port->remote_hostname_errcode)) : \
461+
0))
452462

453463
if (am_walsender)
454464
{

‎src/backend/libpq/hba.c‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -565,35 +565,47 @@ check_hostname(hbaPort *port, const char *hostname)
565565
intret;
566566
boolfound;
567567

568+
/* Quick out if remote host name already known bad */
569+
if (port->remote_hostname_resolv<0)
570+
return false;
571+
568572
/* Lookup remote host name if not already done */
569573
if (!port->remote_hostname)
570574
{
571575
charremote_hostname[NI_MAXHOST];
572576

573-
if (pg_getnameinfo_all(&port->raddr.addr,port->raddr.salen,
574-
remote_hostname,sizeof(remote_hostname),
575-
NULL,0,
576-
0)!=0)
577+
ret=pg_getnameinfo_all(&port->raddr.addr,port->raddr.salen,
578+
remote_hostname,sizeof(remote_hostname),
579+
NULL,0,
580+
NI_NAMEREQD);
581+
if (ret!=0)
582+
{
583+
/* remember failure; don't complain in the postmaster log yet */
584+
port->remote_hostname_resolv=-2;
585+
port->remote_hostname_errcode=ret;
577586
return false;
587+
}
578588

579589
port->remote_hostname=pstrdup(remote_hostname);
580590
}
581591

592+
/* Now see if remote host name matches this pg_hba line */
582593
if (!hostname_match(hostname,port->remote_hostname))
583594
return false;
584595

585-
/* Lookup IP from host name and check against original IP */
586-
596+
/* If we already verified the forward lookup, we're done */
587597
if (port->remote_hostname_resolv==+1)
588598
return true;
589-
if (port->remote_hostname_resolv==-1)
590-
return false;
591599

600+
/* Lookup IP from host name and check against original IP */
592601
ret=getaddrinfo(port->remote_hostname,NULL,NULL,&gai_result);
593602
if (ret!=0)
594-
ereport(ERROR,
595-
(errmsg("could not translate host name \"%s\" to address: %s",
596-
port->remote_hostname,gai_strerror(ret))));
603+
{
604+
/* remember failure; don't complain in the postmaster log yet */
605+
port->remote_hostname_resolv=-2;
606+
port->remote_hostname_errcode=ret;
607+
return false;
608+
}
597609

598610
found= false;
599611
for (gai=gai_result;gai;gai=gai->ai_next)

‎src/backend/libpq/ip.c‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,6 @@ getnameinfo_unix(const struct sockaddr_un * sa, int salen,
247247
(node==NULL&&service==NULL))
248248
returnEAI_FAIL;
249249

250-
/* We don't support those. */
251-
if ((node&& !(flags&NI_NUMERICHOST))
252-
|| (service&& !(flags&NI_NUMERICSERV)))
253-
returnEAI_FAIL;
254-
255250
if (node)
256251
{
257252
ret=snprintf(node,nodelen,"%s","[local]");

‎src/backend/postmaster/postmaster.c‎

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,6 +3381,7 @@ static void
33813381
BackendInitialize(Port*port)
33823382
{
33833383
intstatus;
3384+
intret;
33843385
charremote_host[NI_MAXHOST];
33853386
charremote_port[NI_MAXSERV];
33863387
charremote_ps_data[NI_MAXHOST];
@@ -3442,21 +3443,13 @@ BackendInitialize(Port *port)
34423443
*/
34433444
remote_host[0]='\0';
34443445
remote_port[0]='\0';
3445-
if (pg_getnameinfo_all(&port->raddr.addr,port->raddr.salen,
3446+
if ((ret=pg_getnameinfo_all(&port->raddr.addr,port->raddr.salen,
34463447
remote_host,sizeof(remote_host),
34473448
remote_port,sizeof(remote_port),
3448-
(log_hostname ?0 :NI_NUMERICHOST) |NI_NUMERICSERV)!=0)
3449-
{
3450-
intret=pg_getnameinfo_all(&port->raddr.addr,port->raddr.salen,
3451-
remote_host,sizeof(remote_host),
3452-
remote_port,sizeof(remote_port),
3453-
NI_NUMERICHOST |NI_NUMERICSERV);
3454-
3455-
if (ret!=0)
3456-
ereport(WARNING,
3457-
(errmsg_internal("pg_getnameinfo_all() failed: %s",
3458-
gai_strerror(ret))));
3459-
}
3449+
(log_hostname ?0 :NI_NUMERICHOST) |NI_NUMERICSERV))!=0)
3450+
ereport(WARNING,
3451+
(errmsg_internal("pg_getnameinfo_all() failed: %s",
3452+
gai_strerror(ret))));
34603453
if (remote_port[0]=='\0')
34613454
snprintf(remote_ps_data,sizeof(remote_ps_data),"%s",remote_host);
34623455
else
@@ -3480,8 +3473,23 @@ BackendInitialize(Port *port)
34803473
*/
34813474
port->remote_host=strdup(remote_host);
34823475
port->remote_port=strdup(remote_port);
3483-
if (log_hostname)
3484-
port->remote_hostname=port->remote_host;
3476+
3477+
/*
3478+
* If we did a reverse lookup to name, we might as well save the results
3479+
* rather than possibly repeating the lookup during authentication.
3480+
*
3481+
* Note that we don't want to specify NI_NAMEREQD above, because then we'd
3482+
* get nothing useful for a client without an rDNS entry. Therefore, we
3483+
* must check whether we got a numeric IPv4 or IPv6 address, and not save
3484+
* it into remote_hostname if so. (This test is conservative and might
3485+
* sometimes classify a hostname as numeric, but an error in that
3486+
* direction is safe; it only results in a possible extra lookup.)
3487+
*/
3488+
if (log_hostname&&
3489+
ret==0&&
3490+
strspn(remote_host,"0123456789.")<strlen(remote_host)&&
3491+
strspn(remote_host,"0123456789ABCDEFabcdef:")<strlen(remote_host))
3492+
port->remote_hostname=strdup(remote_host);
34853493

34863494
/*
34873495
* Ready to begin client interaction. We will give up and exit(1) after a

‎src/include/getaddrinfo.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@
8282
#ifndefNI_NUMERICSERV
8383
#defineNI_NUMERICSERV2
8484
#endif
85+
#ifndefNI_NAMEREQD
86+
#defineNI_NAMEREQD4
87+
#endif
8588

8689
#ifndefNI_MAXHOST
8790
#defineNI_MAXHOST1025

‎src/include/libpq/libpq-be.h‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ typedef struct
9999
* still available when a backend is running (see MyProcPort).The data
100100
* it points to must also be malloc'd, or else palloc'd in TopMemoryContext,
101101
* so that it survives into PostgresMain execution!
102+
*
103+
* remote_hostname is set if we did a successful reverse lookup of the
104+
* client's IP address during connection setup.
105+
* remote_hostname_resolv tracks the state of hostname verification:
106+
*+1 = remote_hostname is known to resolve to client's IP address
107+
*-1 = remote_hostname is known NOT to resolve to client's IP address
108+
* 0 = we have not done the forward DNS lookup yet
109+
*-2 = there was an error in name resolution
110+
* If reverse lookup of the client IP address fails, remote_hostname will be
111+
* left NULL while remote_hostname_resolv is set to -2. If reverse lookup
112+
* succeeds but forward lookup fails, remote_hostname_resolv is also set to -2
113+
* (the case is distinguishable because remote_hostname isn't NULL). In
114+
* either of the -2 cases, remote_hostname_errcode saves the lookup return
115+
* code for possible later use with gai_strerror.
102116
*/
103117

104118
typedefstructPort
@@ -111,12 +125,7 @@ typedef struct Port
111125
char*remote_host;/* name (or ip addr) of remote host */
112126
char*remote_hostname;/* name (not ip addr) of remote host, if
113127
* available */
114-
intremote_hostname_resolv;/* +1 = remote_hostname is known to
115-
* resolve to client's IP address; -1
116-
* = remote_hostname is known NOT to
117-
* resolve to client's IP address; 0 =
118-
* we have not done the forward DNS
119-
* lookup yet */
128+
intremote_hostname_resolv;/* see above */
120129
char*remote_port;/* text rep of remote port */
121130
CAC_statecanAcceptConnections;/* postmaster connection status */
122131

@@ -178,6 +187,9 @@ typedef struct Port
178187
char*peer_cn;
179188
unsigned longcount;
180189
#endif
190+
191+
/* This field will be in a saner place in 9.4 and up */
192+
intremote_hostname_errcode;/* see above */
181193
}Port;
182194

183195

‎src/port/getaddrinfo.c‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ getaddrinfo(const char *node, const char *service,
182182
elseif (hints.ai_flags&AI_NUMERICHOST)
183183
{
184184
if (!inet_aton(node,&sin.sin_addr))
185-
returnEAI_FAIL;
185+
returnEAI_NONAME;
186186
}
187187
else
188188
{
@@ -349,8 +349,8 @@ gai_strerror(int errcode)
349349
/*
350350
* Convert an ipv4 address to a hostname.
351351
*
352-
* Bugs:- Only supports NI_NUMERICHOST and NI_NUMERICSERV
353-
* It will neverresolv a hostname.
352+
* Bugs:- Only supports NI_NUMERICHOST and NI_NUMERICSERV behavior.
353+
* It will neverresolve a hostname.
354354
*- No IPv6 support.
355355
*/
356356
int
@@ -373,16 +373,15 @@ getnameinfo(const struct sockaddr * sa, int salen,
373373
if (sa==NULL|| (node==NULL&&service==NULL))
374374
returnEAI_FAIL;
375375

376-
/* We don't support those. */
377-
if ((node&& !(flags&NI_NUMERICHOST))
378-
|| (service&& !(flags&NI_NUMERICSERV)))
379-
returnEAI_FAIL;
380-
381376
#ifdefHAVE_IPV6
382377
if (sa->sa_family==AF_INET6)
383378
returnEAI_FAMILY;
384379
#endif
385380

381+
/* Unsupported flags. */
382+
if (flags&NI_NAMEREQD)
383+
returnEAI_AGAIN;
384+
386385
if (node)
387386
{
388387
if (sa->sa_family==AF_INET)
@@ -405,7 +404,7 @@ getnameinfo(const struct sockaddr * sa, int salen,
405404
ret=snprintf(service,servicelen,"%d",
406405
ntohs(((structsockaddr_in*)sa)->sin_port));
407406
}
408-
if (ret==-1||ret>servicelen)
407+
if (ret==-1||ret >=servicelen)
409408
returnEAI_MEMORY;
410409
}
411410

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp