Skip to content

Commit b78961b

Browse files
committed
Here is a patch that allows CIDR netmasks in pg_hba.conf. It allows two
address/mask forms: . address/maskbits, or . address netmask (as now) If the patch is accepted I will submit a documentation patch to cover it. This is submitted by agreement with Kurt Roeckx, who has worked on a patch that covers this and other IPv6 issues. Andrew Dunstan
1 parent 310c084 commit b78961b

File tree

3 files changed

+91
-13
lines changed

3 files changed

+91
-13
lines changed

src/backend/libpq/hba.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.100 2003/04/25 01:24:00 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.101 2003/06/12 02:12:58 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -588,6 +588,7 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
588588
else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
589589
{
590590
SockAddr file_ip_addr, mask;
591+
char * cidr_slash;
591592

592593
if (strcmp(token, "hostssl") == 0)
593594
{
@@ -618,26 +619,48 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
618619
goto hba_syntax;
619620
user = lfirst(line);
620621

621-
/* Read the IP address field. */
622+
/* Read the IP address field. (with or without CIDR netmask) */
622623
line = lnext(line);
623624
if (!line)
624625
goto hba_syntax;
625626
token = lfirst(line);
626627

628+
/* Check if it has a CIDR suffix and if so isolate it */
629+
cidr_slash = strchr(token,'/');
630+
if (cidr_slash)
631+
*cidr_slash = '\0';
632+
633+
/* Get the IP address either way */
627634
if(SockAddr_pton(&file_ip_addr, token) < 0)
635+
{
636+
if (cidr_slash)
637+
*cidr_slash = '/';
628638
goto hba_syntax;
639+
}
629640

630-
/* Read the mask field. */
631-
line = lnext(line);
632-
if (!line)
633-
goto hba_syntax;
634-
token = lfirst(line);
641+
/* Get the netmask */
642+
if (cidr_slash)
643+
{
644+
*cidr_slash = '/';
645+
if (SockAddr_cidr_mask(&mask, ++cidr_slash, file_ip_addr.sa.sa_family) < 0)
646+
goto hba_syntax;
647+
}
648+
else
649+
{
650+
/* Read the mask field. */
651+
line = lnext(line);
652+
if (!line)
653+
goto hba_syntax;
654+
token = lfirst(line);
655+
656+
if(SockAddr_pton(&mask, token) < 0)
657+
goto hba_syntax;
658+
659+
if(file_ip_addr.sa.sa_family != mask.sa.sa_family)
660+
goto hba_syntax;
661+
}
635662

636-
if(SockAddr_pton(&mask, token) < 0)
637-
goto hba_syntax;
638663

639-
if(file_ip_addr.sa.sa_family != mask.sa.sa_family)
640-
goto hba_syntax;
641664

642665
/* Read the rest of the line. */
643666
line = lnext(line);

src/backend/libpq/ip.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.9 2003/06/09 17:59:19 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.10 2003/06/12 02:12:58 momjian Exp $
1212
*
1313
* This file and the IPV6 implementation were initially provided by
1414
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -251,6 +251,59 @@ SockAddr_pton(SockAddr *sa, const char *src)
251251
}
252252
}
253253

254+
/*
255+
* SockAddr_cidr_mask - make a network mask of the appropriate family
256+
* and required number of significant bits
257+
*/
258+
259+
int
260+
SockAddr_cidr_mask(SockAddr *mask, char *numbits, int family)
261+
{
262+
int i;
263+
long bits;
264+
char * endptr;
265+
266+
bits = strtol(numbits,&endptr,10);
267+
268+
if (*numbits == '\0' || *endptr != '\0')
269+
return -1;
270+
271+
272+
if ((bits < 0) || (family == AF_INET && bits > 32)
273+
#ifdef HAVE_IPV6
274+
|| (family == AF_INET6 && bits > 128)
275+
#endif
276+
)
277+
return -1;
278+
279+
mask->sa.sa_family = family;
280+
281+
switch (family)
282+
{
283+
case AF_INET:
284+
mask->in.sin_addr.s_addr = htonl((0xffffffffUL << (32 - bits)) & 0xffffffffUL);
285+
break;
286+
#ifdef HAVE_IPV6
287+
case AF_INET6:
288+
for (i = 0; i < 16; i++)
289+
{
290+
if (bits <= 0)
291+
mask->in6.sin6_addr.s6_addr[i]=0;
292+
else if (bits >= 8)
293+
mask->in6.sin6_addr.s6_addr[i]=0xff;
294+
else
295+
mask->in6.sin6_addr.s6_addr[i]=(0xff << (8 - bits)) & 0xff;
296+
bits -= 8;
297+
298+
}
299+
break;
300+
#endif
301+
default:
302+
return -1;
303+
}
304+
return 0;
305+
306+
}
254307

255308
/*
256309
* isAF_INETx - check to see if sa is AF_INET or AF_INET6

src/include/libpq/ip.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 2003, PostgreSQL Global Development Group
77
*
8-
* $Id: ip.h,v 1.5 2003/06/09 17:59:19 tgl Exp $
8+
* $Id: ip.h,v 1.6 2003/06/12 02:12:58 momjian Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -25,6 +25,8 @@ extern char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt,
2525
int v4conv);
2626
extern int SockAddr_pton(SockAddr *sa, const char *src);
2727

28+
extern int SockAddr_cidr_mask(SockAddr *mask, char *numbits, int family);
29+
2830
extern int isAF_INETx(const int family);
2931
extern int rangeSockAddr(const SockAddr *addr, const SockAddr *netaddr,
3032
const SockAddr *netmask);

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