Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)