summaryrefslogtreecommitdiff
path: root/src/backend/libpq/hba.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2003-06-12 07:36:51 +0000
committerBruce Momjian <bruce@momjian.us>2003-06-12 07:36:51 +0000
commitb4cea00a1fc9d2270bfe9aeeee44915378d5f733 (patch)
tree16a6702b864f8e8795a498c4e2bf5f91fee54862 /src/backend/libpq/hba.c
parente5549a272d922c5d9ed177a823914fdee6ada08d (diff)
IPv6 cleanups.
Kurt Roeckx Andrew Dunstan
Diffstat (limited to 'src/backend/libpq/hba.c')
-rw-r--r--src/backend/libpq/hba.c205
1 files changed, 146 insertions, 59 deletions
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 4310261a16b..c277c90d1b9 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.102 2003/06/12 07:00:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.103 2003/06/12 07:36:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -542,9 +542,14 @@ static void
parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
{
int line_number;
- char *token;
- char *db;
- char *user;
+ char *token;
+ char *db;
+ char *user;
+ struct addrinfo *file_ip_addr = NULL, *file_ip_mask = NULL;
+ struct addrinfo hints;
+ struct sockaddr_storage *mask;
+ char *cidr_slash;
+ int ret;
Assert(line != NIL);
line_number = lfirsti(line);
@@ -582,12 +587,11 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
port->auth_method == uaKrb5)
goto hba_syntax;
- if (port->raddr.sa.sa_family != AF_UNIX)
+ if (port->raddr.addr.ss_family != AF_UNIX)
return;
}
else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
{
- SockAddr file_ip_addr, mask;
if (strcmp(token, "hostssl") == 0)
{
@@ -618,26 +622,77 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto hba_syntax;
user = lfirst(line);
- /* Read the IP address field. */
+ /* Read the IP address field. (with or without CIDR netmask) */
line = lnext(line);
if (!line)
goto hba_syntax;
token = lfirst(line);
- if(SockAddr_pton(&file_ip_addr, token) < 0)
- goto hba_syntax;
+ /* Check if it has a CIDR suffix and if so isolate it */
+ cidr_slash = index(token,'/');
+ if (cidr_slash)
+ {
+ *cidr_slash = '\0';
+ }
- /* Read the mask field. */
- line = lnext(line);
- if (!line)
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+
+ /* Get the IP address either way */
+ ret = getaddrinfo2(token, NULL, &hints, &file_ip_addr);
+ if (ret)
+ {
+ elog(LOG, "getaddrinfo2() returned %d", ret);
+ if (cidr_slash)
+ {
+ *cidr_slash = '/';
+ }
goto hba_syntax;
- token = lfirst(line);
+ }
- if(SockAddr_pton(&mask, token) < 0)
- goto hba_syntax;
+ if (file_ip_addr->ai_family != port->raddr.addr.ss_family)
+ {
+ /* Wrong address family. */
+ freeaddrinfo2(hints.ai_family, file_ip_addr);
+ return;
+ }
- if(file_ip_addr.sa.sa_family != mask.sa.sa_family)
- goto hba_syntax;
+ /* Get the netmask */
+ if (cidr_slash)
+ {
+ *cidr_slash = '/';
+ if (SockAddr_cidr_mask(&mask, cidr_slash + 1,
+ file_ip_addr->ai_family) < 0)
+ {
+ goto hba_syntax;
+ }
+ }
+ else
+ {
+ /* Read the mask field. */
+ line = lnext(line);
+ if (!line)
+ goto hba_syntax;
+ token = lfirst(line);
+
+ ret = getaddrinfo2(token, NULL, &hints, &file_ip_mask);
+ if (ret)
+ {
+ goto hba_syntax;
+ }
+ mask = (struct sockaddr_storage *)file_ip_mask->ai_addr;
+
+ if(file_ip_addr->ai_family != mask->ss_family)
+ {
+ goto hba_syntax;
+ }
+ }
/* Read the rest of the line. */
line = lnext(line);
@@ -648,9 +703,16 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto hba_syntax;
/* Must meet network restrictions */
- if (!isAF_INETx(port->raddr.sa.sa_family) ||
- !rangeSockAddr(&port->raddr, &file_ip_addr, &mask))
- return;
+ if (!rangeSockAddr(&port->raddr.addr,
+ (struct sockaddr_storage *)file_ip_addr->ai_addr, mask))
+ {
+ goto hba_freeaddr;
+ }
+ freeaddrinfo2(hints.ai_family, file_ip_addr);
+ if (file_ip_mask)
+ {
+ freeaddrinfo2(hints.ai_family, file_ip_mask);
+ }
}
else
goto hba_syntax;
@@ -670,6 +732,16 @@ hba_syntax:
line ? (const char *) lfirst(line) : "(end of line)");
*error_p = true;
+
+hba_freeaddr:
+ if (file_ip_addr)
+ {
+ freeaddrinfo2(hints.ai_family, file_ip_addr);
+ }
+ if (file_ip_mask)
+ {
+ freeaddrinfo2(hints.ai_family, file_ip_mask);
+ }
return;
}
@@ -1106,10 +1178,8 @@ interpret_ident_response(char *ident_response,
* But iff we're unable to get the information from ident, return false.
*/
static bool
-ident_inet(const struct in_addr remote_ip_addr,
- const struct in_addr local_ip_addr,
- const ushort remote_port,
- const ushort local_port,
+ident_inet(const SockAddr remote_addr,
+ const SockAddr local_addr,
char *ident_user)
{
int sock_fd, /* File descriptor for socket on which we
@@ -1117,8 +1187,39 @@ ident_inet(const struct in_addr remote_ip_addr,
rc; /* Return code from a locally called
* function */
bool ident_return;
+ char remote_addr_s[NI_MAXHOST];
+ char remote_port[NI_MAXSERV];
+ char local_addr_s[NI_MAXHOST];
+ char local_port[NI_MAXSERV];
+ char ident_port[NI_MAXSERV];
+ struct addrinfo *ident_serv = NULL, *la = NULL, hints;
+
+ /* Might look a little weird to first convert it to text and
+ * then back to sockaddr, but it's protocol indepedant. */
+ getnameinfo((struct sockaddr *)&remote_addr.addr,
+ remote_addr.salen, remote_addr_s, sizeof(remote_addr_s),
+ remote_port, sizeof(remote_port),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ getnameinfo((struct sockaddr *)&local_addr.addr,
+ local_addr.salen, local_addr_s, sizeof(local_addr_s),
+ local_port, sizeof(local_port),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+
+ snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = remote_addr.addr.ss_family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ getaddrinfo2(remote_addr_s, ident_port, &hints, &ident_serv);
+ getaddrinfo2(local_addr_s, NULL, &hints, &la);
+
+ sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
+ ident_serv->ai_protocol);
- sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock_fd == -1)
{
elog(LOG, "Failed to create socket on which to talk to Ident server: %m");
@@ -1126,42 +1227,27 @@ ident_inet(const struct in_addr remote_ip_addr,
}
else
{
- struct sockaddr_in ident_server;
- struct sockaddr_in la;
-
- /*
- * Socket address of Ident server on the system from which client
- * is attempting to connect to us.
- */
- ident_server.sin_family = AF_INET;
- ident_server.sin_port = htons(IDENT_PORT);
- ident_server.sin_addr = remote_ip_addr;
-
/*
* Bind to the address which the client originally contacted,
* otherwise the ident server won't be able to match up the right
* connection. This is necessary if the PostgreSQL server is
* running on an IP alias.
*/
- memset(&la, 0, sizeof(la));
- la.sin_family = AF_INET;
- la.sin_addr = local_ip_addr;
- rc = bind(sock_fd, (struct sockaddr *) & la, sizeof(la));
+
+ rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
if (rc == 0)
{
- rc = connect(sock_fd,
- (struct sockaddr *) & ident_server, sizeof(ident_server));
+ rc = connect(sock_fd, ident_serv->ai_addr,
+ ident_serv->ai_addrlen);
}
if (rc != 0)
{
- /* save_errno is in case inet_ntoa changes errno */
- int save_errno = errno;
+ int save_errno = errno;
elog(LOG, "Unable to connect to Ident server on the host which is "
"trying to connect to Postgres "
- "(IP address %s, Port %d): %s",
- inet_ntoa(remote_ip_addr), IDENT_PORT,
- strerror(save_errno));
+ "(Address %s, Port %s): %s", remote_addr_s,
+ ident_port, strerror(save_errno));
ident_return = false;
}
else
@@ -1169,8 +1255,8 @@ ident_inet(const struct in_addr remote_ip_addr,
char ident_query[80];
/* The query we send to the Ident server */
- snprintf(ident_query, sizeof(ident_query), "%d,%d\n",
- ntohs(remote_port), ntohs(local_port));
+ snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
+ remote_port, local_port);
/* loop in case send is interrupted */
do
{
@@ -1181,10 +1267,9 @@ ident_inet(const struct in_addr remote_ip_addr,
int save_errno = errno;
elog(LOG, "Unable to send query to Ident server on the host which is "
- "trying to connect to Postgres (Host %s, Port %d), "
+ "trying to connect to Postgres (Host %s, Port %s), "
"even though we successfully connected to it: %s",
- inet_ntoa(remote_ip_addr), IDENT_PORT,
- strerror(save_errno));
+ remote_addr_s, ident_port, strerror(save_errno));
ident_return = false;
}
else
@@ -1199,9 +1284,9 @@ ident_inet(const struct in_addr remote_ip_addr,
elog(LOG, "Unable to receive response from Ident server "
"on the host which is "
- "trying to connect to Postgres (Host %s, Port %d), "
+ "trying to connect to Postgres (Host %s, Port %s), "
"even though we successfully sent our query to it: %s",
- inet_ntoa(remote_ip_addr), IDENT_PORT,
+ remote_addr_s, ident_port,
strerror(save_errno));
ident_return = false;
}
@@ -1215,6 +1300,8 @@ ident_inet(const struct in_addr remote_ip_addr,
closesocket(sock_fd);
}
}
+ freeaddrinfo2(hints.ai_family, la);
+ freeaddrinfo2(hints.ai_family, ident_serv);
return ident_return;
}
@@ -1371,13 +1458,13 @@ authident(hbaPort *port)
{
char ident_user[IDENT_USERNAME_MAX + 1];
- switch (port->raddr.sa.sa_family)
+ switch (port->raddr.addr.ss_family)
{
case AF_INET:
- if (!ident_inet(port->raddr.in.sin_addr,
- port->laddr.in.sin_addr,
- port->raddr.in.sin_port,
- port->laddr.in.sin_port, ident_user))
+#ifdef HAVE_IPV6
+ case AF_INET6:
+#endif
+ if (!ident_inet(port->raddr, port->laddr, ident_user))
return STATUS_ERROR;
break;
case AF_UNIX: