On Thu, Jun 2, 2011 at 5:49 PM, Tom Lane <t...@sss.pgh.pa.us> wrote: > Marko Kreen <mark...@gmail.com> 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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers