Thread: Possible bug: pg_hba.conf file

Possible bug: pg_hba.conf file

From
kael@canada.com
Date:
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

Re: Possible bug: pg_hba.conf file

From
Tom Lane
Date:
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;
                  }

Re: Possible bug: pg_hba.conf file

From
Gaetano Mendola
Date:
Tom Lane wrote:
> !                     maskl = (0xffffffffUL << (32 - (int) bits))
> !                         & 0xffffffffUL;

Is that "& 0xffffffffUL"  required ?