mirror of
https://github.com/postgres/postgres.git
synced 2025-06-06 00:02:36 -04:00
Add server authentication over Unix-domain sockets
This adds a libpq connection parameter requirepeer that specifies the user name that the server process is expected to run under. reviewed by KaiGai Kohei
This commit is contained in:
parent
ed92bec079
commit
040aee295e
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.314 2010/07/14 17:09:45 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.315 2010/07/18 11:37:25 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="libpq">
|
<chapter id="libpq">
|
||||||
<title><application>libpq</application> - C Library</title>
|
<title><application>libpq</application> - C Library</title>
|
||||||
@ -509,6 +509,28 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
|
||||||
|
<term><literal>requirepeer</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
For Unix-domain socket connections, if this parameter is
|
||||||
|
set, the client checks at the beginning of the connection
|
||||||
|
that the server process runs under the specified user name,
|
||||||
|
otherwise the connection is aborted with an error. This
|
||||||
|
parameter can be used to achieve the kind of server
|
||||||
|
authentication that SSL certificates achieve on TCP/IP
|
||||||
|
connections. (Note that if the Unix-domain socket is
|
||||||
|
in <filename>/tmp</filename> or another publically writable
|
||||||
|
location, any user could start a server there. Use this
|
||||||
|
parameter to ensure that you are connected to a server run
|
||||||
|
by a trusted user,
|
||||||
|
e.g., <literal>requirepeer=postgres</literal>.) This
|
||||||
|
option is only supported on some platforms, currently
|
||||||
|
Linux, FreeBSD, NetBSD, OpenBSD, and Solaris.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
|
<varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
|
||||||
<term><literal>krbsrvname</literal></term>
|
<term><literal>krbsrvname</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -6139,6 +6161,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<indexterm>
|
||||||
|
<primary><envar>PGREQUIREPEER</envar></primary>
|
||||||
|
</indexterm>
|
||||||
|
<envar>PGREQUIREPEER</envar> behaves the same as the <xref
|
||||||
|
linkend="libpq-connect-requirepeer"> connection parameter.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.398 2010/07/08 16:19:50 mha Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.399 2010/07/18 11:37:26 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -229,6 +229,9 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
|||||||
{"sslcrl", "PGSSLCRL", NULL, NULL,
|
{"sslcrl", "PGSSLCRL", NULL, NULL,
|
||||||
"SSL-Revocation-List", "", 64},
|
"SSL-Revocation-List", "", 64},
|
||||||
|
|
||||||
|
{"requirepeer", "PGREQUIREPEER", NULL, NULL,
|
||||||
|
"Require-Peer", "", 10},
|
||||||
|
|
||||||
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
||||||
/* Kerberos and GSSAPI authentication support specifying the service name */
|
/* Kerberos and GSSAPI authentication support specifying the service name */
|
||||||
{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
|
{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
|
||||||
@ -595,6 +598,8 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
|
|||||||
conn->sslmode = strdup("require");
|
conn->sslmode = strdup("require");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
tmp = conninfo_getval(connOptions, "requirepeer");
|
||||||
|
conn->requirepeer = tmp ? strdup(tmp) : NULL;
|
||||||
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
||||||
tmp = conninfo_getval(connOptions, "krbsrvname");
|
tmp = conninfo_getval(connOptions, "krbsrvname");
|
||||||
conn->krbsrvname = tmp ? strdup(tmp) : NULL;
|
conn->krbsrvname = tmp ? strdup(tmp) : NULL;
|
||||||
@ -1746,6 +1751,86 @@ keep_going: /* We will come back to here until there is
|
|||||||
char *startpacket;
|
char *startpacket;
|
||||||
int packetlen;
|
int packetlen;
|
||||||
|
|
||||||
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
|
if (conn->requirepeer)
|
||||||
|
{
|
||||||
|
char pwdbuf[BUFSIZ];
|
||||||
|
struct passwd pass_buf;
|
||||||
|
struct passwd *pass;
|
||||||
|
uid_t uid;
|
||||||
|
|
||||||
|
# if defined(HAVE_GETPEEREID)
|
||||||
|
gid_t gid;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (getpeereid(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)
|
||||||
|
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(HAVE_GETPEERUCRED)
|
||||||
|
ucred_t *ucred;
|
||||||
|
|
||||||
|
ucred = NULL; /* must be initialized to NULL */
|
||||||
|
if (getpeerucred(sock, &ucred) == -1)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("could not get peer credentials: %s\n"),
|
||||||
|
pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||||
|
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
|
||||||
|
appendPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("requirepeer parameter is not supported on this platform\n"));
|
||||||
|
goto error_return;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
|
||||||
|
|
||||||
|
if (pass == NULL)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("local user with ID %d does not exist\n"),
|
||||||
|
(int) peercred.uid);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(pass->pw_name, conn->requirepeer) != 0)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("requirepeer failed (actual: %s != required: %s)\n"),
|
||||||
|
pass->pw_name, conn->requirepeer);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2553,6 +2638,8 @@ freePGconn(PGconn *conn)
|
|||||||
free(conn->sslrootcert);
|
free(conn->sslrootcert);
|
||||||
if (conn->sslcrl)
|
if (conn->sslcrl)
|
||||||
free(conn->sslcrl);
|
free(conn->sslcrl);
|
||||||
|
if (conn->requirepeer)
|
||||||
|
free(conn->requirepeer);
|
||||||
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
||||||
if (conn->krbsrvname)
|
if (conn->krbsrvname)
|
||||||
free(conn->krbsrvname);
|
free(conn->krbsrvname);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.153 2010/07/14 17:09:45 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.154 2010/07/18 11:37:26 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -310,6 +310,7 @@ struct pg_conn
|
|||||||
char *sslcert; /* client certificate filename */
|
char *sslcert; /* client certificate filename */
|
||||||
char *sslrootcert; /* root certificate filename */
|
char *sslrootcert; /* root certificate filename */
|
||||||
char *sslcrl; /* certificate revocation list filename */
|
char *sslcrl; /* certificate revocation list filename */
|
||||||
|
char *requirepeer; /* required peer credentials for local sockets */
|
||||||
|
|
||||||
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
||||||
char *krbsrvname; /* Kerberos service name */
|
char *krbsrvname; /* Kerberos service name */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user