To move this topic a long, I'll submit some preparatory patches in a committable order.

First is the patch to deal with getpeereid() that was already included in the previous patch series. This is just some refactoring that reduces the difference between Windows and other platforms and prepares the Unix-domain socket specific code to compile cleanly on Windows.

--
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From adcad11992f4fde0a1eda4f96fef4abeb8570cdc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Wed, 30 Oct 2019 12:58:32 +0100
Subject: [PATCH v4] Sort out getpeereid() and peer auth handling on Windows

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.
---
 configure                         | 36 +++++++++++++------------------
 configure.in                      | 11 ++++------
 src/backend/libpq/auth.c          | 17 +++++++--------
 src/include/port.h                |  2 +-
 src/interfaces/libpq/fe-connect.c | 10 ++++++---
 src/tools/msvc/Mkvcbuild.pm       |  2 +-
 6 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/configure b/configure
index 6b1c779ee3..5d4998d9e1 100755
--- a/configure
+++ b/configure
@@ -15743,6 +15743,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
@@ -15921,19 +15934,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 :
@@ -15948,21 +15955,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
diff --git a/configure.in b/configure.in
index 2b9025cac3..ebbeea8b2b 100644
--- a/configure.in
+++ b/configure.in
@@ -1718,6 +1718,7 @@ AC_REPLACE_FUNCS(m4_normalize([
        explicit_bzero
        fls
        getopt
+       getpeereid
        getrusage
        inet_aton
        mkdtemp
@@ -1746,18 +1747,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
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index d28271c1d8..0bafb83557 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -78,9 +78,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:
@@ -1985,16 +1979,16 @@ ident_inet(hbaPort *port)
  *
  *     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)
        {
@@ -2010,6 +2004,7 @@ auth_peer(hbaPort *port)
                return STATUS_ERROR;
        }
 
+#ifndef WIN32
        errno = 0;                                      /* clear errno before 
call */
        pw = getpwuid(uid);
        if (!pw)
@@ -2031,8 +2026,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 */
 
 
 /*----------------------------------------------------------------
diff --git a/src/include/port.h b/src/include/port.h
index 10dcb5f0a6..e3bbd4d517 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -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
 
diff --git a/src/interfaces/libpq/fe-connect.c 
b/src/interfaces/libpq/fe-connect.c
index dcd86ee804..58b18cb417 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2729,8 +2729,6 @@ PQconnectPoll(PGconn *conn)
                                char       *startpacket;
                                int                     packetlen;
 
-#ifdef HAVE_UNIX_SOCKETS
-
                                /*
                                 * Implement requirepeer check, if requested 
and it's a
                                 * Unix-domain socket.
@@ -2738,10 +2736,12 @@ PQconnectPoll(PGconn *conn)
                                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;
 
@@ -2762,6 +2762,7 @@ PQconnectPoll(PGconn *conn)
                                                goto error_return;
                                        }
 
+#ifndef WIN32
                                        passerr = pqGetpwuid(uid, &pass_buf, 
pwdbuf, sizeof(pwdbuf), &pass);
                                        if (pass == NULL)
                                        {
@@ -2784,8 +2785,11 @@ PQconnectPoll(PGconn *conn)
                                                                                
  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))
                                {
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 7a103e6140..cda1adaeea 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -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

base-commit: c5e1df951d9d70ab7d53ce47caaf73f3b2d6b1e1
-- 
2.23.0

Reply via email to