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.

Reviewed-by: Andrew Dunstan <andrew.dunstan@2ndquadrant.com>
Discussion: https://www.postgresql.org/message-id/5974caea-1267-7708-40f2-6009a9d653b0@2ndquadrant.com
This commit is contained in:
Peter Eisentraut 2019-10-30 12:58:32 +01:00
parent 956ef58753
commit f14413b684
6 changed files with 36 additions and 42 deletions

36
configure vendored
View File

@ -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

View 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

View 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 */
/*----------------------------------------------------------------

View 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

View 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))
{

View 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