1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Replace use of credential control messages with getsockopt(LOCAL_PEERCRED).

It turns out the reason we hadn't found out about the portability issues
with our credential-control-message code is that almost no modern platforms
use that code at all; the ones that used to need it now offer getpeereid(),
which we choose first.  The last holdout was NetBSD, and they added
getpeereid() as of 5.0.  So far as I can tell, the only live platform on
which that code was being exercised was Debian/kFreeBSD, ie, FreeBSD kernel
with Linux userland --- since glibc doesn't provide getpeereid(), we fell
back to the control message code.  However, the FreeBSD kernel provides a
LOCAL_PEERCRED socket parameter that's functionally equivalent to Linux's
SO_PEERCRED.  That is both much simpler to use than control messages, and
superior because it doesn't require receiving a message from the other end
at just the right time.

Therefore, add code to use LOCAL_PEERCRED when necessary, and rip out all
the credential-control-message code in the backend.  (libpq still has such
code so that it can still talk to pre-9.1 servers ... but eventually we can
get rid of it there too.)  Clean up related autoconf probes, too.

This means that libpq's requirepeer parameter now works on exactly the same
platforms where the backend supports peer authentication, so adjust the
documentation accordingly.
This commit is contained in:
Tom Lane
2011-05-31 16:10:46 -04:00
parent 13c00ae8c7
commit be4585b1c2
10 changed files with 119 additions and 434 deletions

View File

@ -48,7 +48,8 @@
runs. If all the users of a particular server also have accounts on
the server's machine, it makes sense to assign database user names
that match their operating system user names. However, a server that
accepts remote connections might have many database users who have no local operating system
accepts remote connections might have many database users who have no local
operating system
account, and in such cases there need be no connection between
database user names and OS user names.
</para>
@ -472,8 +473,8 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<term><literal>peer</></term>
<listitem>
<para>
Obtain the operating system user name from the operating system
and check if it matches the requested database user name.
Obtain the client's operating system user name from the operating
system and check if it matches the requested database user name.
This is only available for local connections.
See <xref linkend="auth-peer"> for details.
</para>
@ -1304,7 +1305,7 @@ omicron bryanh guest1
The peer authentication method works by obtaining the client's
operating system user name from the kernel and using it as the
allowed database user name (with optional user name mapping). This
is only supported on local connections.
method is only supported on local connections.
</para>
<para>
@ -1323,14 +1324,13 @@ omicron bryanh guest1
</para>
<para>
Peer authentication is only available on systems supporting
<symbol>SO_PEERCRED</symbol> requests for
Unix-domain sockets (currently <systemitem
class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
<systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
<systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>).
<productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
the operating system name of the connected client process.
Peer authentication is only available on operating systems providing
the <function>getpeereid()</> function, the <symbol>SO_PEERCRED</symbol>
socket parameter, or similar mechanisms. Currently that includes
<systemitem class="osname">Linux</>,
most flavors of <systemitem class="osname">BSD</> including
<systemitem class="osname">Mac OS X</>,
and <systemitem class="osname">Solaris</systemitem>.
</para>
</sect2>

View File

@ -549,20 +549,21 @@ PGconn *PQconnectdbParams(const char **keywords, const char **values, int expand
<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 publicly 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.
This parameter specifies the operating-system user name of the
server, for example <literal>requirepeer=postgres</literal>.
When making a Unix-domain socket connection, if this
parameter is set, the client checks at the beginning of the
connection that the server process is running under the specified
user name; if it is not, the connection is aborted with an error.
This parameter can be used to provide server authentication similar
to that available with SSL certificates on TCP/IP connections.
(Note that if the Unix-domain socket is in
<filename>/tmp</filename> or another publicly writable location,
any user could start a server listening there. Use this parameter
to ensure that you are connected to a server run by a trusted user.)
This option is only supported on platforms for which the
<literal>peer</> authentication method is implemented; see
<xref linkend="auth-peer">.
</para>
</listitem>
</varlistentry>

View File

@ -314,6 +314,8 @@
the credential message.) If the credential is acceptable,
the server responds with an
AuthenticationOk, otherwise it responds with an ErrorResponse.
(This message type is only issued by pre-9.1 servers. It may
eventually be removed from the protocol specification.)
</para>
</listitem>
</varlistentry>