Possible bug: pg_hba.conf file

Started by Nonameover 21 years ago3 messagesbugs
Jump to latest
#1Noname
kael@canada.com

Hey guys,

I'm a fairly new user to the postgresql world... so *perhaps* this is not a bug. But I cannot get
the following entry to work in the pg_hba.conf file:

host all all 0.0.0.0/0 md5 <-- doesn't work

host all all 4.0.0.0/8 md5 <-- matches anything 4.x.x.x (works correctly)

My intent is to recognize any external IP, and if they can supply a correct user/password then they
can get access. So I'm guessing there is something wrong with the way 0.0.0.0/0 is being
recognized?

Thanks for you help!
Tyson Thomson

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Noname (#1)
Re: Possible bug: pg_hba.conf file

kael@canada.com writes:

So I'm guessing there is something wrong with the way 0.0.0.0/0 is being
recognized?

Hmm, I'm betting you are on a machine where shifting a 32-bit quantity
left 32 bits doesn't reliably give zero. This misbehavior is actually
allowed by the C standard :-( ... but it's certainly caught many a
programmer. Including us. I've applied the attached patch, if you
want to fix it locally --- or you could just avoid the bug by using a
separate all-zeroes mask field, for now.

Thanks for the report!

regards, tom lane

Index: ip.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/ip.c,v
retrieving revision 1.23.2.1
diff -c -r1.23.2.1 ip.c
*** ip.c	24 Apr 2004 20:10:47 -0000	1.23.2.1
--- ip.c	8 Nov 2004 01:45:01 -0000
***************
*** 344,380 ****
  {
  	long		bits;
  	char	   *endptr;
- 	struct sockaddr_in mask4;
- 
- #ifdef	HAVE_IPV6
- 	struct sockaddr_in6 mask6;
- #endif

bits = strtol(numbits, &endptr, 10);

if (*numbits == '\0' || *endptr != '\0')
return -1;

- if ((bits < 0) || (family == AF_INET && bits > 32)
- #ifdef HAVE_IPV6
- || (family == AF_INET6 && bits > 128)
- #endif
- )
- return -1;
-
switch (family)
{
case AF_INET:
! mask4.sin_addr.s_addr =
! htonl((0xffffffffUL << (32 - bits))
! & 0xffffffffUL);
! memcpy(mask, &mask4, sizeof(mask4));
! break;
#ifdef HAVE_IPV6
case AF_INET6:
{
int i;

  				for (i = 0; i < 16; i++)
  				{
  					if (bits <= 0)
--- 344,383 ----
  {
  	long		bits;
  	char	   *endptr;

bits = strtol(numbits, &endptr, 10);

if (*numbits == '\0' || *endptr != '\0')
return -1;

switch (family)
{
case AF_INET:
! {
! struct sockaddr_in mask4;
! long maskl;
!
! if (bits < 0 || bits > 32)
! return -1;
! /* avoid "x << 32", which is not portable */
! if (bits > 0)
! maskl = (0xffffffffUL << (32 - (int) bits))
! & 0xffffffffUL;
! else
! maskl = 0;
! mask4.sin_addr.s_addr = htonl(maskl);
! memcpy(mask, &mask4, sizeof(mask4));
! break;
! }
!
#ifdef HAVE_IPV6
case AF_INET6:
{
+ struct sockaddr_in6 mask6;
int i;

+ 				if (bits < 0 || bits > 128)
+ 					return -1;
  				for (i = 0; i < 16; i++)
  				{
  					if (bits <= 0)
***************
*** 384,390 ****
  					else
  					{
  						mask6.sin6_addr.s6_addr[i] =
! 							(0xff << (8 - bits)) & 0xff;
  					}
  					bits -= 8;
  				}
--- 387,393 ----
  					else
  					{
  						mask6.sin6_addr.s6_addr[i] =
! 							(0xff << (8 - (int) bits)) & 0xff;
  					}
  					bits -= 8;
  				}
#3Gaetano Mendola
mendola@bigfoot.com
In reply to: Tom Lane (#2)
Re: Possible bug: pg_hba.conf file

Tom Lane wrote:

! maskl = (0xffffffffUL << (32 - (int) bits))
! & 0xffffffffUL;

Is that "& 0xffffffffUL" required ?