mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
Rename ident authentication over local connections to peer
This removes an overloading of two authentication options where one is very secure (peer) and one is often insecure (ident). Peer is also the name used in libpq from 9.1 to specify the same type of authentication. Also make initdb select peer for local connections when ident is chosen, and ident for TCP connections when peer is chosen. ident keyword in pg_hba.conf is still accepted and maps to peer authentication.
This commit is contained in:
@ -457,16 +457,29 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
<term><literal>ident</></term>
|
<term><literal>ident</></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Obtain the operating system user name of the client (for
|
Obtain the operating system user name of the client
|
||||||
TCP/IP connections by contacting the ident server on the
|
by contacting the ident server on the client
|
||||||
client, for local connections by getting it from the
|
and check if it matches the requested database user name.
|
||||||
operating system) and check if it matches the requested
|
Ident authentication can only be used on TCP/IP
|
||||||
database user name.
|
connections. When specified for local connections, peer
|
||||||
|
authentication will be used instead.
|
||||||
See <xref linkend="auth-ident"> for details.
|
See <xref linkend="auth-ident"> for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<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.
|
||||||
|
This is only available for local connections.
|
||||||
|
See <xref linkend="auth-peer"> for details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>ldap</></term>
|
<term><literal>ldap</></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -1200,7 +1213,7 @@ omicron bryanh guest1
|
|||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="auth-ident">
|
<sect2 id="auth-ident">
|
||||||
<title>Ident-based Authentication</title>
|
<title>Ident Authentication</title>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>ident</primary>
|
<primary>ident</primary>
|
||||||
@ -1208,13 +1221,19 @@ omicron bryanh guest1
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The ident authentication method works by obtaining the client's
|
The ident authentication method works by obtaining the client's
|
||||||
operating system user name and using it as the allowed database user
|
operating system user name from an ident server and using it as
|
||||||
name (with an optional user name mapping).
|
the allowed database user name (with an optional user name mapping).
|
||||||
The determination of the client's
|
This is only supported on TCP/IP connections.
|
||||||
user name is the security-critical point, and it works differently
|
|
||||||
depending on the connection type, as described below.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
When ident is specified for a local (non-TCP/IP) connection,
|
||||||
|
peer authentication (see <xref linkend="auth-peer">) will be
|
||||||
|
used instead.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following configuration options are supported for <productname>ident</productname>:
|
The following configuration options are supported for <productname>ident</productname>:
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@ -1230,9 +1249,6 @@ omicron bryanh guest1
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>Ident Authentication Over TCP/IP</title>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <quote>Identification Protocol</quote> is described in
|
The <quote>Identification Protocol</quote> is described in
|
||||||
RFC 1413. Virtually every Unix-like
|
RFC 1413. Virtually every Unix-like
|
||||||
@ -1275,36 +1291,48 @@ omicron bryanh guest1
|
|||||||
since <productname>PostgreSQL</> does not have any way to decrypt the
|
since <productname>PostgreSQL</> does not have any way to decrypt the
|
||||||
returned string to determine the actual user name.
|
returned string to determine the actual user name.
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect2>
|
||||||
|
|
||||||
<sect3>
|
<sect2 id="auth-peer">
|
||||||
<title>Ident Authentication Over Local Sockets</title>
|
<title>Peer Authentication</title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>peer</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
On systems supporting <symbol>SO_PEERCRED</symbol> requests for
|
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.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following configuration options are supported for <productname>peer</productname>:
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>map</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows for mapping between system and database user names. See
|
||||||
|
<xref linkend="auth-username-maps"> for details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Peer authentication is only available on systems supporting
|
||||||
|
<symbol>SO_PEERCRED</symbol> requests for
|
||||||
Unix-domain sockets (currently <systemitem
|
Unix-domain sockets (currently <systemitem
|
||||||
class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
|
class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
|
||||||
<systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
|
<systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
|
||||||
<systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>), ident authentication can also
|
<systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>).
|
||||||
be applied to local connections.
|
|
||||||
<productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
|
<productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
|
||||||
the operating system name of the connected client process.
|
the operating system name of the connected client process.
|
||||||
In this case, no security risk is added by
|
|
||||||
using ident authentication; indeed it is a preferable choice for
|
|
||||||
local connections on such systems.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
On systems without <symbol>SO_PEERCRED</> requests, ident
|
|
||||||
authentication is only available for TCP/IP connections. As a
|
|
||||||
work-around, it is possible to specify the <systemitem
|
|
||||||
class="systemname">localhost</> address <systemitem
|
|
||||||
class="systemname">127.0.0.1</> and make connections to this
|
|
||||||
address. This method is trustworthy to the extent that you trust
|
|
||||||
the local ident server.
|
|
||||||
</para>
|
|
||||||
</sect3>
|
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="auth-ldap">
|
<sect2 id="auth-ldap">
|
||||||
|
@ -148,7 +148,7 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
|
|||||||
mode is not used; or modify the generated <filename>pg_hba.conf</filename>
|
mode is not used; or modify the generated <filename>pg_hba.conf</filename>
|
||||||
file after running <command>initdb</command>, but
|
file after running <command>initdb</command>, but
|
||||||
<emphasis>before</> you start the server for the first time. (Other
|
<emphasis>before</> you start the server for the first time. (Other
|
||||||
reasonable approaches include using <literal>ident</literal> authentication
|
reasonable approaches include using <literal>peer</literal> authentication
|
||||||
or file system permissions to restrict connections. See <xref
|
or file system permissions to restrict connections. See <xref
|
||||||
linkend="client-authentication"> for more information.)
|
linkend="client-authentication"> for more information.)
|
||||||
</para>
|
</para>
|
||||||
|
@ -60,7 +60,10 @@ static int recv_and_check_password_packet(Port *port);
|
|||||||
/* Standard TCP port number for Ident service. Assigned by IANA */
|
/* Standard TCP port number for Ident service. Assigned by IANA */
|
||||||
#define IDENT_PORT 113
|
#define IDENT_PORT 113
|
||||||
|
|
||||||
static int authident(hbaPort *port);
|
static int ident_inet(hbaPort *port);
|
||||||
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
|
static int auth_peer(hbaPort *port);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
@ -269,6 +272,9 @@ auth_failed(Port *port, int status)
|
|||||||
case uaIdent:
|
case uaIdent:
|
||||||
errstr = gettext_noop("Ident authentication failed for user \"%s\"");
|
errstr = gettext_noop("Ident authentication failed for user \"%s\"");
|
||||||
break;
|
break;
|
||||||
|
case uaPeer:
|
||||||
|
errstr = gettext_noop("Peer authentication failed for user \"%s\"");
|
||||||
|
break;
|
||||||
case uaPassword:
|
case uaPassword:
|
||||||
case uaMD5:
|
case uaMD5:
|
||||||
errstr = gettext_noop("password authentication failed for user \"%s\"");
|
errstr = gettext_noop("password authentication failed for user \"%s\"");
|
||||||
@ -506,11 +512,12 @@ ClientAuthentication(Port *port)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case uaIdent:
|
case uaPeer:
|
||||||
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are doing ident on unix-domain sockets, use SCM_CREDS
|
* If we are doing peer on unix-domain sockets, use SCM_CREDS only
|
||||||
* only if it is defined and SO_PEERCRED isn't.
|
* if it is defined and SO_PEERCRED isn't.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
|
#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
|
||||||
(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
|
(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
|
||||||
@ -535,7 +542,14 @@ ClientAuthentication(Port *port)
|
|||||||
sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
|
sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
status = authident(port);
|
status = auth_peer(port);
|
||||||
|
#else /* HAVE_UNIX_SOCKETS */
|
||||||
|
Assert(false);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case uaIdent:
|
||||||
|
status = ident_inet(port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case uaMD5:
|
case uaMD5:
|
||||||
@ -1599,11 +1613,12 @@ interpret_ident_response(const char *ident_response,
|
|||||||
*
|
*
|
||||||
* But iff we're unable to get the information from ident, return false.
|
* But iff we're unable to get the information from ident, return false.
|
||||||
*/
|
*/
|
||||||
static bool
|
static int
|
||||||
ident_inet(const SockAddr remote_addr,
|
ident_inet(hbaPort *port)
|
||||||
const SockAddr local_addr,
|
|
||||||
char *ident_user)
|
|
||||||
{
|
{
|
||||||
|
const SockAddr remote_addr = port->raddr;
|
||||||
|
const SockAddr local_addr = port->laddr;
|
||||||
|
char ident_user[IDENT_USERNAME_MAX + 1];
|
||||||
pgsocket sock_fd, /* File descriptor for socket on which we talk
|
pgsocket sock_fd, /* File descriptor for socket on which we talk
|
||||||
* to Ident */
|
* to Ident */
|
||||||
rc; /* Return code from a locally called function */
|
rc; /* Return code from a locally called function */
|
||||||
@ -1646,7 +1661,7 @@ ident_inet(const SockAddr remote_addr,
|
|||||||
{
|
{
|
||||||
if (ident_serv)
|
if (ident_serv)
|
||||||
pg_freeaddrinfo_all(hints.ai_family, ident_serv);
|
pg_freeaddrinfo_all(hints.ai_family, ident_serv);
|
||||||
return false; /* we don't expect this to happen */
|
return STATUS_ERROR; /* we don't expect this to happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
@ -1662,7 +1677,7 @@ ident_inet(const SockAddr remote_addr,
|
|||||||
{
|
{
|
||||||
if (la)
|
if (la)
|
||||||
pg_freeaddrinfo_all(hints.ai_family, la);
|
pg_freeaddrinfo_all(hints.ai_family, la);
|
||||||
return false; /* we don't expect this to happen */
|
return STATUS_ERROR; /* we don't expect this to happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
|
sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
|
||||||
@ -1751,7 +1766,11 @@ ident_inet_done:
|
|||||||
closesocket(sock_fd);
|
closesocket(sock_fd);
|
||||||
pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
|
pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
|
||||||
pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
|
pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
|
||||||
return ident_return;
|
|
||||||
|
if (ident_return)
|
||||||
|
/* Success! Check the usermap */
|
||||||
|
return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
|
||||||
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1763,9 +1782,12 @@ ident_inet_done:
|
|||||||
*/
|
*/
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
|
|
||||||
static bool
|
static int
|
||||||
ident_unix(int sock, char *ident_user)
|
auth_peer(hbaPort *port)
|
||||||
{
|
{
|
||||||
|
int sock = port->sock;
|
||||||
|
char ident_user[IDENT_USERNAME_MAX + 1];
|
||||||
|
|
||||||
#if defined(HAVE_GETPEEREID)
|
#if defined(HAVE_GETPEEREID)
|
||||||
/* OpenBSD style: */
|
/* OpenBSD style: */
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
@ -1779,7 +1801,7 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get peer credentials: %m")));
|
errmsg("could not get peer credentials: %m")));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass = getpwuid(uid);
|
pass = getpwuid(uid);
|
||||||
@ -1789,12 +1811,11 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("local user with ID %d does not exist",
|
(errmsg("local user with ID %d does not exist",
|
||||||
(int) uid)));
|
(int) uid)));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
||||||
|
|
||||||
return true;
|
|
||||||
#elif defined(SO_PEERCRED)
|
#elif defined(SO_PEERCRED)
|
||||||
/* Linux style: use getsockopt(SO_PEERCRED) */
|
/* Linux style: use getsockopt(SO_PEERCRED) */
|
||||||
struct ucred peercred;
|
struct ucred peercred;
|
||||||
@ -1809,7 +1830,7 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get peer credentials: %m")));
|
errmsg("could not get peer credentials: %m")));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass = getpwuid(peercred.uid);
|
pass = getpwuid(peercred.uid);
|
||||||
@ -1819,12 +1840,11 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("local user with ID %d does not exist",
|
(errmsg("local user with ID %d does not exist",
|
||||||
(int) peercred.uid)));
|
(int) peercred.uid)));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
||||||
|
|
||||||
return true;
|
|
||||||
#elif defined(HAVE_GETPEERUCRED)
|
#elif defined(HAVE_GETPEERUCRED)
|
||||||
/* Solaris > 10 */
|
/* Solaris > 10 */
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
@ -1837,7 +1857,7 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get peer credentials: %m")));
|
errmsg("could not get peer credentials: %m")));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uid = ucred_geteuid(ucred)) == -1)
|
if ((uid = ucred_geteuid(ucred)) == -1)
|
||||||
@ -1845,7 +1865,7 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get effective UID from peer credentials: %m")));
|
errmsg("could not get effective UID from peer credentials: %m")));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ucred_free(ucred);
|
ucred_free(ucred);
|
||||||
@ -1856,12 +1876,11 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("local user with ID %d does not exist",
|
(errmsg("local user with ID %d does not exist",
|
||||||
(int) uid)));
|
(int) uid)));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
|
||||||
|
|
||||||
return true;
|
|
||||||
#elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
|
#elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
|
|
||||||
@ -1913,7 +1932,7 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get peer credentials: %m")));
|
errmsg("could not get peer credentials: %m")));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
cred = (Cred *) CMSG_DATA(cmsg);
|
cred = (Cred *) CMSG_DATA(cmsg);
|
||||||
@ -1925,59 +1944,22 @@ ident_unix(int sock, char *ident_user)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("local user with ID %d does not exist",
|
(errmsg("local user with ID %d does not exist",
|
||||||
(int) cred->cruid)));
|
(int) cred->cruid)));
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
|
strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
|
||||||
|
|
||||||
return true;
|
|
||||||
#else
|
#else
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("Ident authentication is not supported on local connections on this platform")));
|
errmsg("Ident authentication is not supported on local connections on this platform")));
|
||||||
|
|
||||||
return false;
|
return STATUS_ERROR;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine the username of the initiator of the connection described
|
|
||||||
* by "port". Then look in the usermap file under the usermap
|
|
||||||
* port->hba->usermap and see if that user is equivalent to Postgres user
|
|
||||||
* port->user.
|
|
||||||
*
|
|
||||||
* Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
authident(hbaPort *port)
|
|
||||||
{
|
|
||||||
char ident_user[IDENT_USERNAME_MAX + 1];
|
|
||||||
|
|
||||||
switch (port->raddr.addr.ss_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
#endif
|
|
||||||
if (!ident_inet(port->raddr, port->laddr, ident_user))
|
|
||||||
return STATUS_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
|
||||||
case AF_UNIX:
|
|
||||||
if (!ident_unix(port->sock, ident_user))
|
|
||||||
return STATUS_ERROR;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
|
return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
|
@ -1060,6 +1060,8 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
|
|||||||
parsedline->auth_method = uaTrust;
|
parsedline->auth_method = uaTrust;
|
||||||
else if (strcmp(token, "ident") == 0)
|
else if (strcmp(token, "ident") == 0)
|
||||||
parsedline->auth_method = uaIdent;
|
parsedline->auth_method = uaIdent;
|
||||||
|
else if (strcmp(token, "peer") == 0)
|
||||||
|
parsedline->auth_method = uaPeer;
|
||||||
else if (strcmp(token, "password") == 0)
|
else if (strcmp(token, "password") == 0)
|
||||||
parsedline->auth_method = uaPassword;
|
parsedline->auth_method = uaPassword;
|
||||||
else if (strcmp(token, "krb5") == 0)
|
else if (strcmp(token, "krb5") == 0)
|
||||||
@ -1137,6 +1139,14 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: When using ident on local connections, change it to peer, for
|
||||||
|
* backwards compatibility.
|
||||||
|
*/
|
||||||
|
if (parsedline->conntype == ctLocal &&
|
||||||
|
parsedline->auth_method == uaIdent)
|
||||||
|
parsedline->auth_method = uaPeer;
|
||||||
|
|
||||||
/* Invalid authentication combinations */
|
/* Invalid authentication combinations */
|
||||||
if (parsedline->conntype == ctLocal &&
|
if (parsedline->conntype == ctLocal &&
|
||||||
parsedline->auth_method == uaKrb5)
|
parsedline->auth_method == uaKrb5)
|
||||||
@ -1160,6 +1170,17 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parsedline->conntype != ctLocal &&
|
||||||
|
parsedline->auth_method == uaPeer)
|
||||||
|
{
|
||||||
|
ereport(LOG,
|
||||||
|
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
||||||
|
errmsg("peer authentication is only supported on local sockets"),
|
||||||
|
errcontext("line %d of configuration file \"%s\"",
|
||||||
|
line_num, HbaFileName)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSPI authentication can never be enabled on ctLocal connections,
|
* SSPI authentication can never be enabled on ctLocal connections,
|
||||||
* because it's only supported on Windows, where ctLocal isn't supported.
|
* because it's only supported on Windows, where ctLocal isn't supported.
|
||||||
@ -1203,11 +1224,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
|
|||||||
if (strcmp(token, "map") == 0)
|
if (strcmp(token, "map") == 0)
|
||||||
{
|
{
|
||||||
if (parsedline->auth_method != uaIdent &&
|
if (parsedline->auth_method != uaIdent &&
|
||||||
|
parsedline->auth_method != uaPeer &&
|
||||||
parsedline->auth_method != uaKrb5 &&
|
parsedline->auth_method != uaKrb5 &&
|
||||||
parsedline->auth_method != uaGSS &&
|
parsedline->auth_method != uaGSS &&
|
||||||
parsedline->auth_method != uaSSPI &&
|
parsedline->auth_method != uaSSPI &&
|
||||||
parsedline->auth_method != uaCert)
|
parsedline->auth_method != uaCert)
|
||||||
INVALID_AUTH_OPTION("map", gettext_noop("ident, krb5, gssapi, sspi and cert"));
|
INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, krb5, gssapi, sspi and cert"));
|
||||||
parsedline->usermap = pstrdup(c);
|
parsedline->usermap = pstrdup(c);
|
||||||
}
|
}
|
||||||
else if (strcmp(token, "clientcert") == 0)
|
else if (strcmp(token, "clientcert") == 0)
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
# directly connected to.
|
# directly connected to.
|
||||||
#
|
#
|
||||||
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
|
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
|
||||||
# "krb5", "ident", "pam", "ldap", "radius" or "cert". Note that
|
# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that
|
||||||
# "password" sends passwords in clear text; "md5" is preferred since
|
# "password" sends passwords in clear text; "md5" is preferred since
|
||||||
# it sends encrypted passwords.
|
# it sends encrypted passwords.
|
||||||
#
|
#
|
||||||
@ -75,7 +75,7 @@
|
|||||||
# TYPE DATABASE USER ADDRESS METHOD
|
# TYPE DATABASE USER ADDRESS METHOD
|
||||||
|
|
||||||
@remove-line-for-nolocal@# "local" is for Unix domain socket connections only
|
@remove-line-for-nolocal@# "local" is for Unix domain socket connections only
|
||||||
@remove-line-for-nolocal@local all all @authmethod@
|
@remove-line-for-nolocal@local all all @authmethodlocal@
|
||||||
# IPv4 local connections:
|
# IPv4 local connections:
|
||||||
host all all 127.0.0.1/32 @authmethod@
|
host all all 127.0.0.1/32 @authmethod@
|
||||||
# IPv6 local connections:
|
# IPv6 local connections:
|
||||||
|
@ -82,6 +82,7 @@ static char *username = "";
|
|||||||
static bool pwprompt = false;
|
static bool pwprompt = false;
|
||||||
static char *pwfilename = NULL;
|
static char *pwfilename = NULL;
|
||||||
static char *authmethod = "";
|
static char *authmethod = "";
|
||||||
|
static char *authmethodlocal = "";
|
||||||
static bool debug = false;
|
static bool debug = false;
|
||||||
static bool noclean = false;
|
static bool noclean = false;
|
||||||
static bool show_setting = false;
|
static bool show_setting = false;
|
||||||
@ -1076,6 +1077,9 @@ setup_config(void)
|
|||||||
conflines = replace_token(conflines,
|
conflines = replace_token(conflines,
|
||||||
"@authmethod@",
|
"@authmethod@",
|
||||||
authmethod);
|
authmethod);
|
||||||
|
conflines = replace_token(conflines,
|
||||||
|
"@authmethodlocal@",
|
||||||
|
authmethodlocal);
|
||||||
|
|
||||||
conflines = replace_token(conflines,
|
conflines = replace_token(conflines,
|
||||||
"@authcomment@",
|
"@authcomment@",
|
||||||
@ -2637,6 +2641,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(authmethod, "md5") &&
|
if (strcmp(authmethod, "md5") &&
|
||||||
|
strcmp(authmethod, "peer") &&
|
||||||
strcmp(authmethod, "ident") &&
|
strcmp(authmethod, "ident") &&
|
||||||
strcmp(authmethod, "trust") &&
|
strcmp(authmethod, "trust") &&
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
@ -2666,6 +2671,20 @@ main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When ident is specified, use peer for local connections. Mirrored, when
|
||||||
|
* peer is specified, use ident for TCP connections.
|
||||||
|
*/
|
||||||
|
if (strcmp(authmethod, "ident") == 0)
|
||||||
|
authmethodlocal = "peer";
|
||||||
|
else if (strcmp(authmethod, "peer") == 0)
|
||||||
|
{
|
||||||
|
authmethodlocal = "peer";
|
||||||
|
authmethod = "ident";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
authmethodlocal = authmethod;
|
||||||
|
|
||||||
if (strlen(pg_data) == 0)
|
if (strlen(pg_data) == 0)
|
||||||
{
|
{
|
||||||
pgdenv = getenv("PGDATA");
|
pgdenv = getenv("PGDATA");
|
||||||
|
@ -29,7 +29,8 @@ typedef enum UserAuth
|
|||||||
uaPAM,
|
uaPAM,
|
||||||
uaLDAP,
|
uaLDAP,
|
||||||
uaCert,
|
uaCert,
|
||||||
uaRADIUS
|
uaRADIUS,
|
||||||
|
uaPeer
|
||||||
} UserAuth;
|
} UserAuth;
|
||||||
|
|
||||||
typedef enum IPCompareMethod
|
typedef enum IPCompareMethod
|
||||||
|
Reference in New Issue
Block a user