I have applied the following patch. I added a configure.in symbol check
for getpeereid(), and added doc updated. I also modified the code to
more closely match current CVS.
The second patch guards against platforms that may have getpeereid()
_and_ one of the other local creditials methods. Both patches should be
applied before testing.
Please let me know how it works on OpenBSD.
---------------------------------------------------------------------------
William Ahern wrote:
> On Fri, Nov 15, 2002 at 12:24:35PM -0500, Bruce Momjian wrote:
> > William Ahern wrote:
> > > here's the original patch:
> > >
> > > http://archives.postgresql.org/pgsql-patches/2001-12/msg00001.php
> > >
> > > however, a cursory look at 7.2.3 w/ the SO_PEERCRED code makes me think
> > > this patch might not fit well.
> > >
> > > My Darwin man page says that its getpeereid() is a wrapper around setsockopt
> > > and LOCAL_PEERCRED. maybe it would be worth it to write an xgetpeereid()
> > > wrapper if #ndef HAVE_GET_PEEREID since the getpeereid syntax seems so much
> > > more cleaner. tho, i remember looking thru the code that some platforms
> > > need to setsockopt(), then read/write and only *then* see the creds... tho
> > > a multiple call convention to getpeereid...
> > >
> > > anyhow.... ;)
> >
> > I will take a look at it later.
> >
>
> maybe this will make it easier ;) i went thru the code and unless i
> misunderstood something (definetly possible), this might be all that is
> needed (w/ the exception of an AC_CHECK_FUNC(getpeereid) in configure.ac. if
> i have some time i'll try to recompile, but i spent all of yesterday
> figuring out openbsd wasn't supported, so i'm loathe to waste more time.
>
> this is against the released 7.2.3 in src/backend/libpg
>
> cheers
>
> --- hba.c~ 2002-01-09 14:13:40.000000000 -0500
> +++ hba.c 2002-11-15 16:56:31.000000000 -0500
> @@ -880,7 +880,40 @@
> static bool
> ident_unix(int sock, char *ident_user)
> {
> -#if defined(SO_PEERCRED)
> +#if defined(HAVE_GETPEEREID)
> + /* OpenBSD style: */
> + uid_t uid;
> + gid_t gid;
> + struct passwd *pass;
> +
> + errno = 0;
> + if (getpeereid(sock,&uid,&gid) != 0)
> + {
> + snprintf(PQerrormsg, PQERRORMSG_LENGTH,
> + "ident_unix: error receiving credentials: %s\n",
> + strerror(errno));
> + fputs(PQerrormsg, stderr);
> + pqdebug("%s", PQerrormsg);
> + return false;
> +
> + }
> +
> + pass = getpwuid(uid);
> +
> + if (pass == NULL)
> + {
> + snprintf(PQerrormsg, PQERRORMSG_LENGTH,
> + "ident_unix: unknown local user with uid %d\n", uid);
> + fputs(PQerrormsg, stderr);
> + pqdebug("%s", PQerrormsg);
> + return false;
> + }
> +
> + StrNCpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
> +
> + return true;
> +
> +#elsif defined(SO_PEERCRED)
> /* Linux style: use getsockopt(SO_PEERCRED) */
> struct ucred peercred;
> ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
>
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: configure
===================================================================
RCS file: /cvsroot/pgsql-server/configure,v
retrieving revision 1.227
diff -c -c -r1.227 configure
*** configure 4 Nov 2002 21:36:13 -0000 1.227
--- configure 3 Dec 2002 21:43:28 -0000
***************
*** 9819,9825 ****
! for ac_func in cbrt fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
--- 9819,9826 ----
!
! for ac_func in cbrt fcvt getopt_long getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen
fdatasync
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql-server/configure.in,v
retrieving revision 1.218
diff -c -c -r1.218 configure.in
*** configure.in 4 Nov 2002 21:36:13 -0000 1.218
--- configure.in 3 Dec 2002 21:43:30 -0000
***************
*** 782,788 ****
# SunOS doesn't handle negative byte comparisons properly with +/- return
AC_FUNC_MEMCMP
! AC_CHECK_FUNCS([cbrt fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen
fdatasync])
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
--- 782,788 ----
# SunOS doesn't handle negative byte comparisons properly with +/- return
AC_FUNC_MEMCMP
! AC_CHECK_FUNCS([cbrt fcvt getopt_long getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen
fdatasync])
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
Index: doc/src/sgml/client-auth.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/client-auth.sgml,v
retrieving revision 1.41
diff -c -c -r1.41 client-auth.sgml
*** doc/src/sgml/client-auth.sgml 15 Nov 2002 03:11:15 -0000 1.41
--- doc/src/sgml/client-auth.sgml 3 Dec 2002 21:43:40 -0000
***************
*** 318,324 ****
support Unix-domain socket credentials (currently
<systemitem class=osname>Linux</>, <systemitem
class=osname>FreeBSD</>, <systemitem class=osname>NetBSD</>,
! and <systemitem class=osname>BSD/OS</>).
</para>
<para>
--- 318,325 ----
support Unix-domain socket credentials (currently
<systemitem class=osname>Linux</>, <systemitem
class=osname>FreeBSD</>, <systemitem class=osname>NetBSD</>,
! <systemitem class=osname>OpenBSD</>, and
! <systemitem class=osname>BSD/OS</>).
</para>
<para>
Index: src/backend/libpq/hba.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/libpq/hba.c,v
retrieving revision 1.87
diff -c -c -r1.87 hba.c
*** src/backend/libpq/hba.c 4 Sep 2002 20:31:19 -0000 1.87
--- src/backend/libpq/hba.c 3 Dec 2002 21:43:42 -0000
***************
*** 1216,1222 ****
static bool
ident_unix(int sock, char *ident_user)
{
! #if defined(SO_PEERCRED)
/* Linux style: use getsockopt(SO_PEERCRED) */
struct ucred peercred;
ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
--- 1216,1249 ----
static bool
ident_unix(int sock, char *ident_user)
{
! #if defined(HAVE_GETPEEREID)
! /* OpenBSD style: */
! uid_t uid;
! gid_t gid;
! struct passwd *pass;
!
! errno = 0;
! if (getpeereid(sock,&uid,&gid) != 0)
! {
! /* We didn't get a valid credentials struct. */
! elog(LOG, "ident_unix: error receiving credentials: %m");
! return false;
! }
!
! pass = getpwuid(uid);
!
! if (pass == NULL)
! {
! elog(LOG, "ident_unix: unknown local user with uid %d",
! (int) uid);
! return false;
! }
!
! StrNCpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
!
! return true;
!
! #elsif defined(SO_PEERCRED)
/* Linux style: use getsockopt(SO_PEERCRED) */
struct ucred peercred;
ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
Index: src/backend/libpq/auth.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/libpq/auth.c,v
retrieving revision 1.91
diff -c -c -r1.91 auth.c
*** src/backend/libpq/auth.c 4 Sep 2002 23:31:34 -0000 1.91
--- src/backend/libpq/auth.c 3 Dec 2002 22:05:58 -0000
***************
*** 430,436 ****
break;
case uaIdent:
! #if !defined(SO_PEERCRED) && (defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) ||
(defined(HAVE_STRUCT_SOCKCRED)&& defined(LOCAL_CREDS)))
/*
* If we are doing ident on unix-domain sockets, use SCM_CREDS
--- 430,438 ----
break;
case uaIdent:
! #if defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
! (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)) && \
! !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED)
/*
* If we are doing ident on unix-domain sockets, use SCM_CREDS
Index: src/interfaces/libpq/fe-auth.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-auth.c,v
retrieving revision 1.71
diff -c -c -r1.71 fe-auth.c
*** src/interfaces/libpq/fe-auth.c 4 Sep 2002 20:31:46 -0000 1.71
--- src/interfaces/libpq/fe-auth.c 3 Dec 2002 22:06:01 -0000
***************
*** 449,455 ****
static int
pg_local_sendauth(char *PQerrormsg, PGconn *conn)
{
! #if defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) &&
defined(LOCAL_CREDS))
char buf;
struct iovec iov;
struct msghdr msg;
--- 449,457 ----
static int
pg_local_sendauth(char *PQerrormsg, PGconn *conn)
{
! #if defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
! (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)) && \
! !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED)
char buf;
struct iovec iov;
struct msghdr msg;