Avoid logging complaints about abandoned connections when using PAM.

For a long time (since commit aed378e8d) we have had a policy to log
nothing about a connection if the client disconnects when challenged
for a password.  This is because libpq-using clients will typically
do that, and then come back for a new connection attempt once they've
collected a password from their user, so that logging the abandoned
connection attempt will just result in log spam.  However, this did
not work well for PAM authentication: the bottom-level function
pam_passwd_conv_proc() was on board with it, but we logged messages
at higher levels anyway, for lack of any reporting mechanism.
Add a flag and tweak the logic so that the case is silent, as it is
for other password-using auth mechanisms.

Per complaint from Yoann La Cancellera.  It's been like this for awhile,
so back-patch to all supported branches.

Discussion: https://postgr.es/m/CACP=ajbrFFYUrLyJBLV8=q+eNCapa1xDEyvXhMoYrNphs-xqPw@mail.gmail.com
This commit is contained in:
Tom Lane 2019-11-05 14:27:37 -05:00
parent a30531c5c8
commit 3affe76ef8
1 changed files with 17 additions and 9 deletions

View File

@ -110,6 +110,7 @@ static const char *pam_passwd = NULL; /* Workaround for Solaris 2.6
* brokenness */ * brokenness */
static Port *pam_port_cludge; /* Workaround for passing "Port *port" into static Port *pam_port_cludge; /* Workaround for passing "Port *port" into
* pam_passwd_conv_proc */ * pam_passwd_conv_proc */
static bool pam_no_password; /* For detecting no-password-given */
#endif /* USE_PAM */ #endif /* USE_PAM */
@ -2099,8 +2100,10 @@ pam_passwd_conv_proc(int num_msg, const struct pam_message **msg,
{ {
/* /*
* Client didn't want to send password. We * Client didn't want to send password. We
* intentionally do not log anything about this. * intentionally do not log anything about this,
* either here or at higher levels.
*/ */
pam_no_password = true;
goto fail; goto fail;
} }
} }
@ -2159,6 +2162,7 @@ CheckPAMAuth(Port *port, const char *user, const char *password)
*/ */
pam_passwd = password; pam_passwd = password;
pam_port_cludge = port; pam_port_cludge = port;
pam_no_password = false;
/* /*
* Set the application data portion of the conversation struct. This is * Set the application data portion of the conversation struct. This is
@ -2244,22 +2248,26 @@ CheckPAMAuth(Port *port, const char *user, const char *password)
if (retval != PAM_SUCCESS) if (retval != PAM_SUCCESS)
{ {
ereport(LOG, /* If pam_passwd_conv_proc saw EOF, don't log anything */
(errmsg("pam_authenticate failed: %s", if (!pam_no_password)
pam_strerror(pamh, retval)))); ereport(LOG,
(errmsg("pam_authenticate failed: %s",
pam_strerror(pamh, retval))));
pam_passwd = NULL; /* Unset pam_passwd */ pam_passwd = NULL; /* Unset pam_passwd */
return STATUS_ERROR; return pam_no_password ? STATUS_EOF : STATUS_ERROR;
} }
retval = pam_acct_mgmt(pamh, 0); retval = pam_acct_mgmt(pamh, 0);
if (retval != PAM_SUCCESS) if (retval != PAM_SUCCESS)
{ {
ereport(LOG, /* If pam_passwd_conv_proc saw EOF, don't log anything */
(errmsg("pam_acct_mgmt failed: %s", if (!pam_no_password)
pam_strerror(pamh, retval)))); ereport(LOG,
(errmsg("pam_acct_mgmt failed: %s",
pam_strerror(pamh, retval))));
pam_passwd = NULL; /* Unset pam_passwd */ pam_passwd = NULL; /* Unset pam_passwd */
return STATUS_ERROR; return pam_no_password ? STATUS_EOF : STATUS_ERROR;
} }
retval = pam_end(pamh, retval); retval = pam_end(pamh, retval);