mirror of
https://github.com/postgres/postgres.git
synced 2025-11-13 16:22:44 +03:00
Second try at IPv4-to-v6 mapping code; avoid assuming that the struct
returned by getaddrinfo_all will have enough room for an IPv6 address.
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.113 2003/09/05 20:31:35 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.114 2003/09/05 23:07:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -550,12 +550,12 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
char *token;
|
||||
char *db;
|
||||
char *user;
|
||||
struct addrinfo *file_ip_addr = NULL,
|
||||
*file_ip_mask = NULL;
|
||||
struct addrinfo *gai_result;
|
||||
struct addrinfo hints;
|
||||
struct sockaddr_storage *mask;
|
||||
char *cidr_slash;
|
||||
int ret;
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_storage mask;
|
||||
char *cidr_slash;
|
||||
|
||||
Assert(line != NIL);
|
||||
line_number = lfirsti(line);
|
||||
@@ -648,6 +648,7 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
if (cidr_slash)
|
||||
*cidr_slash = '\0';
|
||||
|
||||
/* Get the IP address either way */
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = 0;
|
||||
@@ -657,9 +658,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
/* Get the IP address either way */
|
||||
ret = getaddrinfo_all(token, NULL, &hints, &file_ip_addr);
|
||||
if (ret || !file_ip_addr)
|
||||
ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
|
||||
if (ret || !gai_result)
|
||||
{
|
||||
ereport(LOG,
|
||||
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
||||
@@ -667,17 +667,21 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
token, gai_strerror(ret))));
|
||||
if (cidr_slash)
|
||||
*cidr_slash = '/';
|
||||
if (gai_result)
|
||||
freeaddrinfo_all(hints.ai_family, gai_result);
|
||||
goto hba_syntax;
|
||||
}
|
||||
|
||||
if (cidr_slash)
|
||||
*cidr_slash = '/';
|
||||
|
||||
memcpy(&addr, gai_result->ai_addr, gai_result->ai_addrlen);
|
||||
freeaddrinfo_all(hints.ai_family, gai_result);
|
||||
|
||||
/* Get the netmask */
|
||||
if (cidr_slash)
|
||||
{
|
||||
if (SockAddr_cidr_mask(&mask, cidr_slash + 1,
|
||||
file_ip_addr->ai_family) < 0)
|
||||
if (SockAddr_cidr_mask(&mask, cidr_slash + 1, addr.ss_family) < 0)
|
||||
goto hba_syntax;
|
||||
}
|
||||
else
|
||||
@@ -688,17 +692,22 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
goto hba_syntax;
|
||||
token = lfirst(line);
|
||||
|
||||
ret = getaddrinfo_all(token, NULL, &hints, &file_ip_mask);
|
||||
if (ret || !file_ip_mask)
|
||||
ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
|
||||
if (ret || !gai_result)
|
||||
{
|
||||
if (gai_result)
|
||||
freeaddrinfo_all(hints.ai_family, gai_result);
|
||||
goto hba_syntax;
|
||||
}
|
||||
|
||||
mask = (struct sockaddr_storage *) file_ip_mask->ai_addr;
|
||||
memcpy(&mask, gai_result->ai_addr, gai_result->ai_addrlen);
|
||||
freeaddrinfo_all(hints.ai_family, gai_result);
|
||||
|
||||
if (file_ip_addr->ai_family != mask->ss_family)
|
||||
if (addr.ss_family != mask.ss_family)
|
||||
goto hba_syntax;
|
||||
}
|
||||
|
||||
if (file_ip_addr->ai_family != port->raddr.addr.ss_family)
|
||||
if (addr.ss_family != port->raddr.addr.ss_family)
|
||||
{
|
||||
/*
|
||||
* Wrong address family. We allow only one case: if the
|
||||
@@ -706,20 +715,24 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
* address to IPv6 and try to match that way.
|
||||
*/
|
||||
#ifdef HAVE_IPV6
|
||||
if (file_ip_addr->ai_family == AF_INET &&
|
||||
if (addr.ss_family == AF_INET &&
|
||||
port->raddr.addr.ss_family == AF_INET6)
|
||||
{
|
||||
promote_v4_to_v6_addr((struct sockaddr_storage *) file_ip_addr->ai_addr);
|
||||
promote_v4_to_v6_mask(mask);
|
||||
promote_v4_to_v6_addr(&addr);
|
||||
promote_v4_to_v6_mask(&mask);
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_IPV6 */
|
||||
{
|
||||
freeaddrinfo_all(hints.ai_family, file_ip_addr);
|
||||
/* Line doesn't match client port, so ignore it. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore line if client port is not in the matching addr range. */
|
||||
if (!rangeSockAddr(&port->raddr.addr, &addr, &mask))
|
||||
return;
|
||||
|
||||
/* Read the rest of the line. */
|
||||
line = lnext(line);
|
||||
if (!line)
|
||||
@@ -727,16 +740,6 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
|
||||
parse_hba_auth(line, &port->auth_method, &port->auth_arg, error_p);
|
||||
if (*error_p)
|
||||
goto hba_syntax;
|
||||
|
||||
/* Must meet network restrictions */
|
||||
if (!rangeSockAddr(&port->raddr.addr,
|
||||
(struct sockaddr_storage *) file_ip_addr->ai_addr,
|
||||
mask))
|
||||
goto hba_freeaddr;
|
||||
|
||||
freeaddrinfo_all(hints.ai_family, file_ip_addr);
|
||||
if (file_ip_mask)
|
||||
freeaddrinfo_all(hints.ai_family, file_ip_mask);
|
||||
}
|
||||
else
|
||||
goto hba_syntax;
|
||||
@@ -763,12 +766,6 @@ hba_syntax:
|
||||
line_number)));
|
||||
|
||||
*error_p = true;
|
||||
|
||||
hba_freeaddr:
|
||||
if (file_ip_addr)
|
||||
freeaddrinfo_all(hints.ai_family, file_ip_addr);
|
||||
if (file_ip_mask)
|
||||
freeaddrinfo_all(hints.ai_family, file_ip_mask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user