On Thu, Jun 2, 2011 at 5:49 PM, Tom Lane <[email protected]> wrote:
> Marko Kreen <[email protected]> writes:
>> Here's my attempt for it. As conditional port module seems trouble,
>> I set up an unconditional pgGetpeereid() that is always defined.
>
> -1 ... why would you think that a conditional substitution is trouble?
> We have plenty of others.
Because it required touching autoconf. ;)
So now I did it. I hope it was that simple.
As there was no going back now, I even touched msvc.pm.
--
marko
*** a/configure.in
--- b/configure.in
***************
*** 1191,1197 **** PGAC_VAR_INT_TIMEZONE
AC_FUNC_ACCEPT_ARGTYPES
PGAC_FUNC_GETTIMEOFDAY_1ARG
! AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeereid getpeerucred getrlimit memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
AC_REPLACE_FUNCS(fseeko)
case $host_os in
--- 1191,1199 ----
AC_FUNC_ACCEPT_ARGTYPES
PGAC_FUNC_GETTIMEOFDAY_1ARG
! AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
!
! AC_REPLACE_FUNCS(getpeereid)
AC_REPLACE_FUNCS(fseeko)
case $host_os in
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
***************
*** 17,28 ****
#include <sys/param.h>
#include <sys/socket.h>
- #ifdef HAVE_UCRED_H
- #include <ucred.h>
- #endif
- #ifdef HAVE_SYS_UCRED_H
- #include <sys/ucred.h>
- #endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
--- 17,22 ----
***************
*** 1757,1839 **** auth_peer(hbaPort *port)
{
char ident_user[IDENT_USERNAME_MAX + 1];
uid_t uid = 0;
struct passwd *pass;
- #if defined(HAVE_GETPEEREID)
- /* Most BSDen, including OS X: use getpeereid() */
- gid_t gid;
-
- errno = 0;
if (getpeereid(port->sock, &uid, &gid) != 0)
{
- /* We didn't get a valid credentials struct. */
ereport(LOG,
(errcode_for_socket_access(),
errmsg("could not get peer credentials: %m")));
return STATUS_ERROR;
}
- #elif defined(SO_PEERCRED)
- /* Linux: use getsockopt(SO_PEERCRED) */
- struct ucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(port->sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred))
- {
- /* We didn't get a valid credentials struct. */
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
- uid = peercred.uid;
- #elif defined(LOCAL_PEERCRED)
- /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */
- struct xucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(port->sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred) ||
- peercred.cr_version != XUCRED_VERSION)
- {
- /* We didn't get a valid credentials struct. */
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
- uid = peercred.cr_uid;
- #elif defined(HAVE_GETPEERUCRED)
- /* Solaris: use getpeerucred() */
- ucred_t *ucred;
-
- ucred = NULL; /* must be initialized to NULL */
- if (getpeerucred(port->sock, &ucred) == -1)
- {
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get peer credentials: %m")));
- return STATUS_ERROR;
- }
-
- if ((uid = ucred_geteuid(ucred)) == -1)
- {
- ereport(LOG,
- (errcode_for_socket_access(),
- errmsg("could not get effective UID from peer credentials: %m")));
- return STATUS_ERROR;
- }
-
- ucred_free(ucred);
- #else
- ereport(LOG,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("Peer authentication is not supported on local connections on this platform")));
-
- return STATUS_ERROR;
- #endif
pass = getpwuid(uid);
--- 1751,1766 ----
{
char ident_user[IDENT_USERNAME_MAX + 1];
uid_t uid = 0;
+ gid_t gid = 0;
struct passwd *pass;
if (getpeereid(port->sock, &uid, &gid) != 0)
{
ereport(LOG,
(errcode_for_socket_access(),
errmsg("could not get peer credentials: %m")));
return STATUS_ERROR;
}
pass = getpwuid(uid);
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 470,473 **** extern int pg_check_dir(const char *dir);
--- 470,478 ----
/* port/pgmkdirp.c */
extern int pg_mkdir_p(char *path, int omode);
+ /* port/getpeereid.c */
+ #ifndef HAVE_GETPEEREID
+ extern int getpeereid(int sock, uid_t *uid, gid_t *gid);
+ #endif
+
#endif /* PG_PORT_H */
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 21,32 ****
#include <ctype.h>
#include <time.h>
#include <unistd.h>
- #ifdef HAVE_UCRED_H
- #include <ucred.h>
- #endif
- #ifdef HAVE_SYS_UCRED_H
- #include <sys/ucred.h>
- #endif
#include "libpq-fe.h"
#include "libpq-int.h"
--- 21,26 ----
***************
*** 1866,1928 **** 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))
{
- #if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(LOCAL_PEERCRED) || defined(HAVE_GETPEERUCRED)
char pwdbuf[BUFSIZ];
struct passwd pass_buf;
struct passwd *pass;
uid_t uid;
-
- #if defined(HAVE_GETPEEREID)
- /* Most BSDen, including OS X: use getpeereid() */
gid_t gid;
- errno = 0;
- if (getpeereid(conn->sock, &uid, &gid) != 0)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- #elif defined(SO_PEERCRED)
- /* Linux: use getsockopt(SO_PEERCRED) */
- struct ucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED,
- &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred))
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- uid = peercred.uid;
- #elif defined(LOCAL_PEERCRED)
- /* Debian with FreeBSD kernel: use LOCAL_PEERCRED */
- struct xucred peercred;
- ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
-
- errno = 0;
- if (getsockopt(conn->sock, 0, LOCAL_PEERCRED,
- &peercred, &so_len) != 0 ||
- so_len != sizeof(peercred) ||
- peercred.cr_version != XUCRED_VERSION)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- goto error_return;
- }
- uid = peercred.cr_uid;
- #elif defined(HAVE_GETPEERUCRED)
- /* Solaris: use getpeerucred() */
- ucred_t *ucred;
! ucred = NULL; /* must be initialized to NULL */
! if (getpeerucred(conn->sock, &ucred) == -1)
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get peer credentials: %s\n"),
--- 1860,1873 ----
if (conn->requirepeer && conn->requirepeer[0] &&
IS_AF_UNIX(conn->raddr.addr.ss_family))
{
char pwdbuf[BUFSIZ];
struct passwd pass_buf;
struct passwd *pass;
uid_t uid;
gid_t gid;
! if (getpeereid(conn->sock, &uid, &gid) != 0)
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get peer credentials: %s\n"),
***************
*** 1930,1948 **** keep_going: /* We will come back to here until there is
goto error_return;
}
- if ((uid = ucred_geteuid(ucred)) == -1)
- {
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not get effective UID from peer credentials: %s\n"),
- pqStrerror(errno, sebuf, sizeof(sebuf)));
- ucred_free(ucred);
- goto error_return;
- }
- ucred_free(ucred);
- #else
- #error missing implementation method for requirepeer
- #endif
-
pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
if (pass == NULL)
--- 1875,1880 ----
***************
*** 1960,1970 **** keep_going: /* We will come back to here until there is
conn->requirepeer, pass->pw_name);
goto error_return;
}
- #else /* can't support requirepeer */
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("requirepeer parameter is not supported on this platform\n"));
- goto error_return;
- #endif
}
#ifdef USE_SSL
--- 1892,1897 ----
*** /dev/null
--- b/src/port/getpeereid.c
***************
*** 0 ****
--- 1,79 ----
+ /*-------------------------------------------------------------------------
+ *
+ * getpeereid.c
+ * get peer userid for UNIX socket
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * src/port/getpeereid.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "c.h"
+
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #ifdef HAVE_SYS_UN_H
+ #include <sys/un.h>
+ #endif
+ #ifdef HAVE_UCRED_H
+ #include <ucred.h>
+ #endif
+ #ifdef HAVE_SYS_UCRED_H
+ #include <sys/ucred.h>
+ #endif
+
+ /*
+ * BSD-style getpeereid() for non-BSD platforms.
+ */
+ int getpeereid(int sock, uid_t *uid, gid_t *gid)
+ {
+ #if defined(SO_PEERCRED)
+ /* Linux: use getsockopt(SO_PEERCRED) */
+ struct ucred peercred;
+ ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
+ so_len != sizeof(peercred))
+ return -1;
+ *uid = peercred.uid;
+ *gid = peercred.gid;
+ return 0;
+ #elif defined(LOCAL_PEERCRED)
+ /* Debian with FreeBSD kernel: use LOCAL_PEERCRED */
+ struct xucred peercred;
+ ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(conn->sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
+ so_len != sizeof(peercred) ||
+ peercred.cr_version != XUCRED_VERSION)
+ return -1;
+ *uid = peercred.cr_uid;
+ *gid = peercred.cr_gid;
+ return 0;
+ #elif defined(HAVE_GETPEERUCRED)
+ /* Solaris: use getpeerucred() */
+ ucred_t *ucred;
+
+ errno = 0;
+ ucred = NULL; /* must be initialized to NULL */
+ if (getpeerucred(sock, &ucred) == -1)
+ return -1;
+
+ *uid = ucred_geteuid(ucred);
+ *gid = ucred_getegid(ucred);
+ ucred_free(ucred);
+ if (*uid == (pid_t)(-1) || *gid == (gid_t)(-1))
+ return -1;
+ return 0;
+ #else
+ errno = ENOSYS;
+ return -1;
+ #endif
+ }
*** a/src/tools/msvc/Mkvcbuild.pm
--- b/src/tools/msvc/Mkvcbuild.pm
***************
*** 53,59 **** sub mkvcbuild
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c
pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c
sprompt.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
! win32error.c);
$libpgport = $solution->AddProject('libpgport','lib','misc');
$libpgport->AddDefine('FRONTEND');
--- 53,59 ----
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c
pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c
sprompt.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
! win32error.c getpeereid.c);
$libpgport = $solution->AddProject('libpgport','lib','misc');
$libpgport->AddDefine('FRONTEND');
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers