diff options
author | Peter Eisentraut | 2016-04-08 14:45:16 +0000 |
---|---|---|
committer | Peter Eisentraut | 2016-04-08 14:48:44 +0000 |
commit | 2f1d2b7a75fecad25295cb3f453503eb6a176d4f (patch) | |
tree | 8404aa676cf8aeb71bce8a76c8e554633686b856 | |
parent | 4e55b3f0335c2aa658cd9d1fda4dea2a1f9ab80d (diff) |
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 <[email protected]>
Reviewed-by: Haribabu Kommi <[email protected]>
-rw-r--r-- | doc/src/sgml/client-auth.sgml | 23 | ||||
-rw-r--r-- | src/backend/libpq/auth.c | 23 | ||||
-rw-r--r-- | src/backend/libpq/hba.c | 9 | ||||
-rw-r--r-- | src/include/libpq/hba.h | 1 |
4 files changed, 52 insertions, 4 deletions
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index 3b2935c4f3..7b204fb48e 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -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 Authentication Modules) as the authentication mechanism. The default PAM service name is <literal>postgresql</literal>. - PAM is used only to validate user name/password pairs. - Therefore the user must already exist in the database before PAM - can be used for authentication. For more information about - PAM, please read the <ulink url="http://www.kernel.org/pub/linux/libs/pam/"> + PAM is used only to validate user name/password pairs and optionally the + connected remote host name or IP address. Therefore the user must already + exist in the database before PAM can be used for authentication. For more + information about PAM, please read the + <ulink url="http://www.kernel.org/pub/linux/libs/pam/"> <productname>Linux-PAM</> Page</ulink>. </para> @@ -1635,6 +1636,20 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" </para> </listitem> </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> </para> diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index f21056e244..630762cc6b 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1739,6 +1739,18 @@ CheckPAMAuth(Port *port, char *user, char *password) { int retval; 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 @@ -1784,6 +1796,17 @@ CheckPAMAuth(Port *port, char *user, char *password) 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); if (retval != PAM_SUCCESS) diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 28f9fb54ae..5a397464d7 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -1447,6 +1447,15 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); 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) { #ifdef LDAP_API_FEATURE_X_OPENLDAP diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 68a953aa62..b306baf1a5 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -64,6 +64,7 @@ typedef struct HbaLine char *usermap; char *pamservice; + bool pam_use_hostname; bool ldaptls; char *ldapserver; int ldapport; |