Commit 2f1d2b7a authored by Peter Eisentraut's avatar Peter Eisentraut

Set PAM_RHOST item for PAM authentication

The PAM_RHOST item is set to the remote IP address or host name and can
be used by PAM modules.  A pg_hba.conf option is provided to choose
between IP address and resolved host name.

From: Grzegorz Sampolski <grzsmp@gmail.com>
Reviewed-by: default avatarHaribabu Kommi <kommi.haribabu@gmail.com>
parent 4e55b3f0
...@@ -1617,10 +1617,11 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" ...@@ -1617,10 +1617,11 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
<literal>password</literal> except that it uses PAM (Pluggable <literal>password</literal> except that it uses PAM (Pluggable
Authentication Modules) as the authentication mechanism. The Authentication Modules) as the authentication mechanism. The
default PAM service name is <literal>postgresql</literal>. default PAM service name is <literal>postgresql</literal>.
PAM is used only to validate user name/password pairs. PAM is used only to validate user name/password pairs and optionally the
Therefore the user must already exist in the database before PAM connected remote host name or IP address. Therefore the user must already
can be used for authentication. For more information about exist in the database before PAM can be used for authentication. For more
PAM, please read the <ulink url="http://www.kernel.org/pub/linux/libs/pam/"> information about PAM, please read the
<ulink url="http://www.kernel.org/pub/linux/libs/pam/">
<productname>Linux-PAM</> Page</ulink>. <productname>Linux-PAM</> Page</ulink>.
</para> </para>
...@@ -1635,6 +1636,20 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" ...@@ -1635,6 +1636,20 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>pam_use_hostname</literal></term>
<listitem>
<para>
Determines whether the remote IP address or the host name is provided
to PAM modules through the <symbol>PAM_RHOST</symbol> item. By
default, the IP address is used. Set this option to 1 to use the
resolved host name instead. Host name resolution can lead to login
delays. (Most PAM configurations don't use this information, so it is
only necessary to consider this setting if a PAM configuration was
specifically created to make use of it.)
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
......
...@@ -1739,6 +1739,18 @@ CheckPAMAuth(Port *port, char *user, char *password) ...@@ -1739,6 +1739,18 @@ CheckPAMAuth(Port *port, char *user, char *password)
{ {
int retval; int retval;
pam_handle_t *pamh = NULL; pam_handle_t *pamh = NULL;
char hostinfo[NI_MAXHOST];
retval = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
hostinfo, sizeof(hostinfo), NULL, 0,
port->hba->pam_use_hostname ? 0 : NI_NUMERICHOST | NI_NUMERICSERV);
if (retval != 0)
{
ereport(WARNING,
(errmsg_internal("pg_getnameinfo_all() failed: %s",
gai_strerror(retval))));
return STATUS_ERROR;
}
/* /*
* We can't entirely rely on PAM to pass through appdata --- it appears * We can't entirely rely on PAM to pass through appdata --- it appears
...@@ -1784,6 +1796,17 @@ CheckPAMAuth(Port *port, char *user, char *password) ...@@ -1784,6 +1796,17 @@ CheckPAMAuth(Port *port, char *user, char *password)
return STATUS_ERROR; return STATUS_ERROR;
} }
retval = pam_set_item(pamh, PAM_RHOST, hostinfo);
if (retval != PAM_SUCCESS)
{
ereport(LOG,
(errmsg("pam_set_item(PAM_RHOST) failed: %s",
pam_strerror(pamh, retval))));
pam_passwd = NULL;
return STATUS_ERROR;
}
retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv); retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
if (retval != PAM_SUCCESS) if (retval != PAM_SUCCESS)
......
...@@ -1447,6 +1447,15 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) ...@@ -1447,6 +1447,15 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam");
hbaline->pamservice = pstrdup(val); hbaline->pamservice = pstrdup(val);
} }
else if (strcmp(name, "pam_use_hostname") == 0)
{
REQUIRE_AUTH_OPTION(uaPAM, "pam_use_hostname", "pam");
if (strcmp(val, "1") == 0)
hbaline->pam_use_hostname = true;
else
hbaline->pam_use_hostname = false;
}
else if (strcmp(name, "ldapurl") == 0) else if (strcmp(name, "ldapurl") == 0)
{ {
#ifdef LDAP_API_FEATURE_X_OPENLDAP #ifdef LDAP_API_FEATURE_X_OPENLDAP
......
...@@ -64,6 +64,7 @@ typedef struct HbaLine ...@@ -64,6 +64,7 @@ typedef struct HbaLine
char *usermap; char *usermap;
char *pamservice; char *pamservice;
bool pam_use_hostname;
bool ldaptls; bool ldaptls;
char *ldapserver; char *ldapserver;
int ldapport; int ldapport;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment