Skip to content

Commit 0a27347

Browse files
committed
Make RADIUS authentication use pg_getaddrinfo_all() to get address of
the server. Gets rid of a fairly ugly hack for Solaris, and also provides hostname and IPV6 support.
1 parent d8db6a6 commit 0a27347

File tree

4 files changed

+69
-28
lines changed

4 files changed

+69
-28
lines changed

doc/src/sgml/client-auth.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.129 2010/01/27 13:03:17 mha Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.130 2010/02/02 19:09:36 mha Exp $ -->
22

33
<chapter id="client-authentication">
44
<title>Client Authentication</title>
@@ -1375,8 +1375,8 @@ ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
13751375
<term><literal>radiusserver</literal></term>
13761376
<listitem>
13771377
<para>
1378-
The IP address of the RADIUS server to connect to. This must
1379-
be an IPV4 address and not a hostname. This parameter is required.
1378+
The name or IP address of the RADIUS server to connect to.
1379+
This parameter is required.
13801380
</para>
13811381
</listitem>
13821382
</varlistentry>

src/backend/libpq/auth.c

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.193 2010/01/31 17:27:22 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.194 2010/02/02 19:09:36 mha Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2521,8 +2521,16 @@ CheckRADIUSAuth(Port *port)
25212521
uint8 encryptedpassword[RADIUS_VECTOR_LENGTH];
25222522
int packetlength;
25232523
pgsocket sock;
2524+
#ifdef HAVE_IPV6
2525+
struct sockaddr_in6 localaddr;
2526+
struct sockaddr_in6 remoteaddr;
2527+
#else
25242528
struct sockaddr_in localaddr;
25252529
struct sockaddr_in remoteaddr;
2530+
#endif
2531+
struct addrinfo hint;
2532+
struct addrinfo *serveraddrs;
2533+
char portstr[128];
25262534
ACCEPT_TYPE_ARG3 addrsize;
25272535
fd_set fdset;
25282536
struct timeval timeout;
@@ -2549,17 +2557,22 @@ CheckRADIUSAuth(Port *port)
25492557
if (port->hba->radiusport == 0)
25502558
port->hba->radiusport = 1812;
25512559

2552-
memset(&remoteaddr, 0, sizeof(remoteaddr));
2553-
remoteaddr.sin_family = AF_INET;
2554-
remoteaddr.sin_addr.s_addr = inet_addr(port->hba->radiusserver);
2555-
if (remoteaddr.sin_addr.s_addr == INADDR_NONE)
2560+
MemSet(&hint, 0, sizeof(hint));
2561+
hint.ai_socktype = SOCK_DGRAM;
2562+
hint.ai_family = AF_UNSPEC;
2563+
snprintf(portstr, sizeof(portstr), "%d", port->hba->radiusport);
2564+
2565+
r = pg_getaddrinfo_all(port->hba->radiusserver, portstr, &hint, &serveraddrs);
2566+
if (r || !serveraddrs)
25562567
{
25572568
ereport(LOG,
2558-
(errmsg("RADIUS server '%s' is not a valid IP address",
2559-
port->hba->radiusserver)));
2569+
(errmsg("could not translate RADIUS server name \"%s\" to address: %s",
2570+
port->hba->radiusserver, gai_strerror(r))));
2571+
if (serveraddrs)
2572+
pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
25602573
return STATUS_ERROR;
25612574
}
2562-
remoteaddr.sin_port = htons(port->hba->radiusport);
2575+
/* XXX: add support for multiple returned addresses? */
25632576

25642577
if (port->hba->radiusidentifier && port->hba->radiusidentifier[0])
25652578
identifier = port->hba->radiusidentifier;
@@ -2633,34 +2646,51 @@ CheckRADIUSAuth(Port *port)
26332646
packetlength = packet->length;
26342647
packet->length = htons(packet->length);
26352648

2636-
sock = socket(AF_INET, SOCK_DGRAM, 0);
2649+
sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
26372650
if (sock < 0)
26382651
{
26392652
ereport(LOG,
26402653
(errmsg("could not create RADIUS socket: %m")));
2654+
pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
26412655
return STATUS_ERROR;
26422656
}
26432657

26442658
memset(&localaddr, 0, sizeof(localaddr));
2645-
localaddr.sin_family = AF_INET;
2659+
#ifdef HAVE_IPV6
2660+
localaddr.sin6_family = serveraddrs[0].ai_family;
2661+
localaddr.sin6_addr = in6addr_any;
2662+
if (localaddr.sin6_family == AF_INET6)
2663+
addrsize = sizeof(struct sockaddr_in6);
2664+
else
2665+
addrsize = sizeof(struct sockaddr_in);
2666+
#else
2667+
localaddr.sin_family = serveraddrs[0].ai_family;
26462668
localaddr.sin_addr.s_addr = INADDR_ANY;
2647-
if (bind(sock, (struct sockaddr *) &localaddr, sizeof(localaddr)))
2669+
addrsize = sizeof(struct sockaddr_in);
2670+
#endif
2671+
if (bind(sock, (struct sockaddr *) &localaddr, addrsize))
26482672
{
26492673
ereport(LOG,
26502674
(errmsg("could not bind local RADIUS socket: %m")));
26512675
closesocket(sock);
2676+
pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
26522677
return STATUS_ERROR;
26532678
}
26542679

26552680
if (sendto(sock, radius_buffer, packetlength, 0,
2656-
(struct sockaddr *) &remoteaddr, sizeof(remoteaddr)) < 0)
2681+
serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
26572682
{
26582683
ereport(LOG,
26592684
(errmsg("could not send RADIUS packet: %m")));
26602685
closesocket(sock);
2686+
pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
26612687
return STATUS_ERROR;
26622688
}
26632689

2690+
/* Don't need the server address anymore */
2691+
pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2692+
2693+
/* Wait for a response */
26642694
timeout.tv_sec = RADIUS_TIMEOUT;
26652695
timeout.tv_usec = 0;
26662696
FD_ZERO(&fdset);
@@ -2705,11 +2735,21 @@ CheckRADIUSAuth(Port *port)
27052735

27062736
closesocket(sock);
27072737

2738+
#ifdef HAVE_IPV6
2739+
if (remoteaddr.sin6_port != htons(port->hba->radiusport))
2740+
#else
27082741
if (remoteaddr.sin_port != htons(port->hba->radiusport))
2742+
#endif
27092743
{
2744+
#ifdef HAVE_IPV6
2745+
ereport(LOG,
2746+
(errmsg("RADIUS response was sent from incorrect port: %i",
2747+
ntohs(remoteaddr.sin6_port))));
2748+
#else
27102749
ereport(LOG,
27112750
(errmsg("RADIUS response was sent from incorrect port: %i",
27122751
ntohs(remoteaddr.sin_port))));
2752+
#endif
27132753
return STATUS_ERROR;
27142754
}
27152755

src/backend/libpq/hba.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.196 2010/01/27 12:11:59 mha Exp $
13+
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.197 2010/02/02 19:09:37 mha Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1167,16 +1167,25 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
11671167
else if (strcmp(token, "radiusserver") == 0)
11681168
{
11691169
REQUIRE_AUTH_OPTION(uaRADIUS, "radiusserver", "radius");
1170-
if (inet_addr(c) == INADDR_NONE)
1170+
1171+
MemSet(&hints, 0, sizeof(hints));
1172+
hints.ai_socktype = SOCK_DGRAM;
1173+
hints.ai_family = AF_UNSPEC;
1174+
1175+
ret = pg_getaddrinfo_all(c, NULL, &hints, &gai_result);
1176+
if (ret || !gai_result)
11711177
{
11721178
ereport(LOG,
11731179
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1174-
errmsg("invalid RADIUS server IP address: \"%s\"", c),
1180+
errmsg("could not translate RADIUS server name \"%s\" to address: %s",
1181+
c, gai_strerror(ret)),
11751182
errcontext("line %d of configuration file \"%s\"",
11761183
line_num, HbaFileName)));
1184+
if (gai_result)
1185+
pg_freeaddrinfo_all(hints.ai_family, gai_result);
11771186
return false;
1178-
11791187
}
1188+
pg_freeaddrinfo_all(hints.ai_family, gai_result);
11801189
parsedline->radiusserver = pstrdup(c);
11811190
}
11821191
else if (strcmp(token, "radiusport") == 0)

src/include/port/solaris.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/include/port/solaris.h,v 1.18 2010/01/28 11:36:14 mha Exp $ */
1+
/* $PostgreSQL: pgsql/src/include/port/solaris.h,v 1.19 2010/02/02 19:09:37 mha Exp $ */
22

33
/*
44
* Sort this out for all operating systems some time. The __xxx
@@ -36,11 +36,3 @@
3636
* still use our own fix for the buggy version.
3737
*/
3838
#define HAVE_BUGGY_SOLARIS_STRTOD
39-
40-
/*
41-
* Many versions of Solaris are missing the definition of INADDR_NONE
42-
*/
43-
#ifndef INADDR_NONE
44-
#define INADDR_NONE ((in_addr_t)(-1))
45-
#endif
46-

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy