Skip to content

Commit 040aee2

Browse files
committed
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
1 parent ed92bec commit 040aee2

File tree

3 files changed

+123
-3
lines changed

3 files changed

+123
-3
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.314 2010/07/14 17:09:45 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.315 2010/07/18 11:37:25 petere Exp $ -->
22

33
<chapter id="libpq">
44
<title><application>libpq</application> - C Library</title>
@@ -509,6 +509,28 @@
509509
</listitem>
510510
</varlistentry>
511511

512+
<varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
513+
<term><literal>requirepeer</literal></term>
514+
<listitem>
515+
<para>
516+
For Unix-domain socket connections, if this parameter is
517+
set, the client checks at the beginning of the connection
518+
that the server process runs under the specified user name,
519+
otherwise the connection is aborted with an error. This
520+
parameter can be used to achieve the kind of server
521+
authentication that SSL certificates achieve on TCP/IP
522+
connections. (Note that if the Unix-domain socket is
523+
in <filename>/tmp</filename> or another publically writable
524+
location, any user could start a server there. Use this
525+
parameter to ensure that you are connected to a server run
526+
by a trusted user,
527+
e.g., <literal>requirepeer=postgres</literal>.) This
528+
option is only supported on some platforms, currently
529+
Linux, FreeBSD, NetBSD, OpenBSD, and Solaris.
530+
</para>
531+
</listitem>
532+
</varlistentry>
533+
512534
<varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
513535
<term><literal>krbsrvname</literal></term>
514536
<listitem>
@@ -6139,6 +6161,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
61396161
</para>
61406162
</listitem>
61416163

6164+
<listitem>
6165+
<para>
6166+
<indexterm>
6167+
<primary><envar>PGREQUIREPEER</envar></primary>
6168+
</indexterm>
6169+
<envar>PGREQUIREPEER</envar> behaves the same as the <xref
6170+
linkend="libpq-connect-requirepeer"> connection parameter.
6171+
</para>
6172+
</listitem>
6173+
61426174
<listitem>
61436175
<para>
61446176
<indexterm>

src/interfaces/libpq/fe-connect.c

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.398 2010/07/08 16:19:50 mha Exp $
11+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.399 2010/07/18 11:37:26 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -229,6 +229,9 @@ static const PQconninfoOption PQconninfoOptions[] = {
229229
{"sslcrl", "PGSSLCRL", NULL, NULL,
230230
"SSL-Revocation-List", "", 64},
231231

232+
{"requirepeer", "PGREQUIREPEER", NULL, NULL,
233+
"Require-Peer", "", 10},
234+
232235
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
233236
/* Kerberos and GSSAPI authentication support specifying the service name */
234237
{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
@@ -595,6 +598,8 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
595598
conn->sslmode = strdup("require");
596599
}
597600
#endif
601+
tmp = conninfo_getval(connOptions, "requirepeer");
602+
conn->requirepeer = tmp ? strdup(tmp) : NULL;
598603
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
599604
tmp = conninfo_getval(connOptions, "krbsrvname");
600605
conn->krbsrvname = tmp ? strdup(tmp) : NULL;
@@ -1746,6 +1751,86 @@ PQconnectPoll(PGconn *conn)
17461751
char *startpacket;
17471752
int packetlen;
17481753

1754+
#ifdef HAVE_UNIX_SOCKETS
1755+
if (conn->requirepeer)
1756+
{
1757+
char pwdbuf[BUFSIZ];
1758+
struct passwd pass_buf;
1759+
struct passwd *pass;
1760+
uid_t uid;
1761+
1762+
# if defined(HAVE_GETPEEREID)
1763+
gid_t gid;
1764+
1765+
errno = 0;
1766+
if (getpeereid(sock, &uid, &gid) != 0)
1767+
{
1768+
appendPQExpBuffer(&conn->errorMessage,
1769+
libpq_gettext("could not get peer credentials: %s\n"),
1770+
pqStrerror(errno, sebuf, sizeof(sebuf)));
1771+
goto error_return;
1772+
}
1773+
# elif defined(SO_PEERCRED)
1774+
struct ucred peercred;
1775+
ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
1776+
1777+
errno = 0;
1778+
if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
1779+
so_len != sizeof(peercred))
1780+
{
1781+
appendPQExpBuffer(&conn->errorMessage,
1782+
libpq_gettext("could not get peer credentials: %s\n"),
1783+
pqStrerror(errno, sebuf, sizeof(sebuf)));
1784+
goto error_return;
1785+
}
1786+
uid = peercred.uid;
1787+
# elif defined(HAVE_GETPEERUCRED)
1788+
ucred_t *ucred;
1789+
1790+
ucred = NULL; /* must be initialized to NULL */
1791+
if (getpeerucred(sock, &ucred) == -1)
1792+
{
1793+
appendPQExpBuffer(&conn->errorMessage,
1794+
libpq_gettext("could not get peer credentials: %s\n"),
1795+
pqStrerror(errno, sebuf, sizeof(sebuf)));
1796+
goto error_return;
1797+
}
1798+
1799+
if ((uid = ucred_geteuid(ucred)) == -1)
1800+
{
1801+
appendPQExpBuffer(&conn->errorMessage,
1802+
libpq_gettext("could not get effective UID from peer credentials: %s\n"),
1803+
pqStrerror(errno, sebuf, sizeof(sebuf)));
1804+
ucred_free(ucred);
1805+
goto error_return;
1806+
}
1807+
ucred_free(ucred);
1808+
# else
1809+
appendPQExpBuffer(&conn->errorMessage,
1810+
libpq_gettext("requirepeer parameter is not supported on this platform\n"));
1811+
goto error_return;
1812+
# endif
1813+
1814+
pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
1815+
1816+
if (pass == NULL)
1817+
{
1818+
appendPQExpBuffer(&conn->errorMessage,
1819+
libpq_gettext("local user with ID %d does not exist\n"),
1820+
(int) peercred.uid);
1821+
goto error_return;
1822+
}
1823+
1824+
if (strcmp(pass->pw_name, conn->requirepeer) != 0)
1825+
{
1826+
appendPQExpBuffer(&conn->errorMessage,
1827+
libpq_gettext("requirepeer failed (actual: %s != required: %s)\n"),
1828+
pass->pw_name, conn->requirepeer);
1829+
goto error_return;
1830+
}
1831+
}
1832+
#endif /* HAVE_UNIX_SOCKETS */
1833+
17491834
#ifdef USE_SSL
17501835

17511836
/*
@@ -2553,6 +2638,8 @@ freePGconn(PGconn *conn)
25532638
free(conn->sslrootcert);
25542639
if (conn->sslcrl)
25552640
free(conn->sslcrl);
2641+
if (conn->requirepeer)
2642+
free(conn->requirepeer);
25562643
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
25572644
if (conn->krbsrvname)
25582645
free(conn->krbsrvname);

src/interfaces/libpq/libpq-int.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.153 2010/07/14 17:09:45 tgl Exp $
15+
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.154 2010/07/18 11:37:26 petere Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -310,6 +310,7 @@ struct pg_conn
310310
char *sslcert; /* client certificate filename */
311311
char *sslrootcert; /* root certificate filename */
312312
char *sslcrl; /* certificate revocation list filename */
313+
char *requirepeer; /* required peer credentials for local sockets */
313314

314315
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
315316
char *krbsrvname; /* Kerberos service name */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy