Sort out getpeereid() and peer auth handling on Windows
authorPeter Eisentraut
Wed, 30 Oct 2019 11:58:32 +0000 (12:58 +0100)
committerPeter Eisentraut
Mon, 16 Dec 2019 08:36:08 +0000 (09:36 +0100)
The getpeereid() uses have so far been protected by HAVE_UNIX_SOCKETS,
so they didn't ever care about Windows support.  But in anticipation
of Unix-domain socket support on Windows, that needs to be handled
differently.

Windows doesn't support getpeereid() at this time, so we use the
existing not-supported code path.  We let configure do its usual thing
of picking up the replacement from libpgport, instead of the custom
overrides that it was doing before.

But then Windows doesn't have struct passwd, so this patch sprinkles
some additional #ifdef WIN32 around to make it work.  This is similar
to existing code that deals with this issue.

Reviewed-by: Andrew Dunstan
Discussion: https://www.postgresql.org/message-id/5974caea-1267-7708-40f2-6009a9d653b0@2ndquadrant.com

configure
configure.in
src/backend/libpq/auth.c
src/include/port.h
src/interfaces/libpq/fe-connect.c
src/tools/msvc/Mkvcbuild.pm

index 3d9bd0bdf873664403d93eb2d2bd546ef764d089..de431d0d38b78db5db09bccd3333adcd88a69333 100755 (executable)
--- a/configure
+++ b/configure
@@ -15685,6 +15685,19 @@ esac
 
 fi
 
+ac_fn_c_check_func "$LINENO" "getpeereid" "ac_cv_func_getpeereid"
+if test "x$ac_cv_func_getpeereid" = xyes; then :
+  $as_echo "#define HAVE_GETPEEREID 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" getpeereid.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getpeereid.$ac_objext"
+ ;;
+esac
+
+fi
+
 ac_fn_c_check_func "$LINENO" "getrusage" "ac_cv_func_getrusage"
 if test "x$ac_cv_func_getrusage" = xyes; then :
   $as_echo "#define HAVE_GETRUSAGE 1" >>confdefs.h
@@ -15863,19 +15876,13 @@ $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 esac
 
 case $host_os in
-
         # Windows uses a specialised env handler
-        # and doesn't need a replacement getpeereid because it doesn't use
-        # Unix sockets.
         mingw*)
 
 $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
 
-
-$as_echo "#define HAVE_GETPEEREID 1" >>confdefs.h
-
                 ac_cv_func_unsetenv=yes
-                ac_cv_func_getpeereid=yes;;
+                ;;
         *)
                 ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
 if test "x$ac_cv_func_unsetenv" = xyes; then :
@@ -15890,21 +15897,8 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "getpeereid" "ac_cv_func_getpeereid"
-if test "x$ac_cv_func_getpeereid" = xyes; then :
-  $as_echo "#define HAVE_GETPEEREID 1" >>confdefs.h
 
-else
-  case " $LIBOBJS " in
-  *" getpeereid.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getpeereid.$ac_objext"
- ;;
-esac
-
-fi
-
-
-       ;;
+                ;;
 esac
 
 # System's version of getaddrinfo(), if any, may be used only if we found
index 34aea0b4ace8fc8009f84180dadb80c1c5e3c6a4..85829be069a47d1dc7f7e8d232850b40fa0b7373 100644 (file)
@@ -1729,6 +1729,7 @@ AC_REPLACE_FUNCS(m4_normalize([
    explicit_bzero
    fls
    getopt
+   getpeereid
    getrusage
    inet_aton
    mkdtemp
@@ -1757,18 +1758,14 @@ case $host_os in
 esac
 
 case $host_os in
-
         # Windows uses a specialised env handler
-        # and doesn't need a replacement getpeereid because it doesn't use
-        # Unix sockets.
         mingw*)
                 AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
-                AC_DEFINE(HAVE_GETPEEREID, 1, [Define to 1 because function not required.])
                 ac_cv_func_unsetenv=yes
-                ac_cv_func_getpeereid=yes;;
+                ;;
         *)
-                AC_REPLACE_FUNCS([unsetenv getpeereid])
-       ;;
+                AC_REPLACE_FUNCS([unsetenv])
+                ;;
 esac
 
 # System's version of getaddrinfo(), if any, may be used only if we found
index c12b810c3d5b7c2f7e0c81c679ffb278fcc1eef9..5399144c20c9d7f71926fab3546e52184efdbf8f 100644 (file)
@@ -77,9 +77,7 @@ static int    ident_inet(hbaPort *port);
  * Peer authentication
  *----------------------------------------------------------------
  */
-#ifdef HAVE_UNIX_SOCKETS
 static int auth_peer(hbaPort *port);
-#endif
 
 
 /*----------------------------------------------------------------
@@ -559,11 +557,7 @@ ClientAuthentication(Port *port)
            break;
 
        case uaPeer:
-#ifdef HAVE_UNIX_SOCKETS
            status = auth_peer(port);
-#else
-           Assert(false);
-#endif
            break;
 
        case uaIdent:
@@ -1984,16 +1978,16 @@ ident_inet_done:
  *
  * Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
  */
-#ifdef HAVE_UNIX_SOCKETS
-
 static int
 auth_peer(hbaPort *port)
 {
    uid_t       uid;
    gid_t       gid;
+#ifndef WIN32
    struct passwd *pw;
    char       *peer_user;
    int         ret;
+#endif
 
    if (getpeereid(port->sock, &uid, &gid) != 0)
    {
@@ -2009,6 +2003,7 @@ auth_peer(hbaPort *port)
        return STATUS_ERROR;
    }
 
+#ifndef WIN32
    errno = 0;                  /* clear errno before call */
    pw = getpwuid(uid);
    if (!pw)
@@ -2030,8 +2025,12 @@ auth_peer(hbaPort *port)
    pfree(peer_user);
 
    return ret;
+#else
+   /* should have failed with ENOSYS above */
+   Assert(false);
+   return STATUS_ERROR;
+#endif
 }
-#endif                         /* HAVE_UNIX_SOCKETS */
 
 
 /*----------------------------------------------------------------
index bfd2e2759f690a3d9e4a175022086061cbbaa376..9567590581bca0596fc68aca9f8d1cd369cf2d07 100644 (file)
@@ -354,7 +354,7 @@ extern int  fls(int mask);
 #define ftello(a)      ftell(a)
 #endif
 
-#if !defined(HAVE_GETPEEREID) && !defined(WIN32)
+#ifndef HAVE_GETPEEREID
 extern int getpeereid(int sock, uid_t *uid, gid_t *gid);
 #endif
 
index 66a912860564d98a1376097ffc114f0e6a157e30..3ca7e0560cdd4e72990d3c70ec0cc313e8259be6 100644 (file)
@@ -2733,8 +2733,6 @@ keep_going:                       /* We will come back to here until there is
                char       *startpacket;
                int         packetlen;
 
-#ifdef HAVE_UNIX_SOCKETS
-
                /*
                 * Implement requirepeer check, if requested and it's a
                 * Unix-domain socket.
@@ -2742,10 +2740,12 @@ keep_going:                     /* We will come back to here until there is
                if (conn->requirepeer && conn->requirepeer[0] &&
                    IS_AF_UNIX(conn->raddr.addr.ss_family))
                {
+#ifndef WIN32
                    char        pwdbuf[BUFSIZ];
                    struct passwd pass_buf;
                    struct passwd *pass;
                    int         passerr;
+#endif
                    uid_t       uid;
                    gid_t       gid;
 
@@ -2766,6 +2766,7 @@ keep_going:                       /* We will come back to here until there is
                        goto error_return;
                    }
 
+#ifndef WIN32
                    passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
                    if (pass == NULL)
                    {
@@ -2788,8 +2789,11 @@ keep_going:                      /* We will come back to here until there is
                                          conn->requirepeer, pass->pw_name);
                        goto error_return;
                    }
+#else                          /* WIN32 */
+                   /* should have failed with ENOSYS above */
+                   Assert(false);
+#endif                         /* WIN32 */
                }
-#endif                         /* HAVE_UNIX_SOCKETS */
 
                if (IS_AF_UNIX(conn->raddr.addr.ss_family))
                {
index 275f3bb6991eac9dd6dd816930d09bd51dff08f1..3d6ef0de84b00c1c8d16f171f60f0963a316dcce 100644 (file)
@@ -94,7 +94,7 @@ sub mkvcbuild
    $solution = CreateSolution($vsVersion, $config);
 
    our @pgportfiles = qw(
-     chklocale.c explicit_bzero.c fls.c fseeko.c getrusage.c inet_aton.c random.c
+     chklocale.c explicit_bzero.c fls.c fseeko.c getpeereid.c getrusage.c inet_aton.c random.c
      srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
      erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
      dirent.c dlopen.c getopt.c getopt_long.c