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

Reply via email to