]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Avoid logging complaints about abandoned connections when using PAM.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Nov 2019 19:27:37 +0000 (14:27 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Nov 2019 19:27:37 +0000 (14:27 -0500)
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

src/backend/libpq/auth.c

index d28271c1d87ba8bb76a9e547d3b8d49b8585cf9b..5bc42a6726486d9ede27c073103300ca23870f84 100644 (file)
@@ -110,6 +110,7 @@ static const char *pam_passwd = NULL;       /* Workaround for Solaris 2.6
                                                                                 * brokenness */
 static Port *pam_port_cludge;  /* Workaround for passing "Port *port" into
                                                                 * pam_passwd_conv_proc */
+static bool pam_no_password;   /* For detecting no-password-given */
 #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
-                                                * 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;
                                        }
                                }
@@ -2159,6 +2162,7 @@ CheckPAMAuth(Port *port, const char *user, const char *password)
         */
        pam_passwd = password;
        pam_port_cludge = port;
+       pam_no_password = false;
 
        /*
         * 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)
        {
-               ereport(LOG,
-                               (errmsg("pam_authenticate failed: %s",
-                                               pam_strerror(pamh, retval))));
+               /* If pam_passwd_conv_proc saw EOF, don't log anything */
+               if (!pam_no_password)
+                       ereport(LOG,
+                                       (errmsg("pam_authenticate failed: %s",
+                                                       pam_strerror(pamh, retval))));
                pam_passwd = NULL;              /* Unset pam_passwd */
-               return STATUS_ERROR;
+               return pam_no_password ? STATUS_EOF : STATUS_ERROR;
        }
 
        retval = pam_acct_mgmt(pamh, 0);
 
        if (retval != PAM_SUCCESS)
        {
-               ereport(LOG,
-                               (errmsg("pam_acct_mgmt failed: %s",
-                                               pam_strerror(pamh, retval))));
+               /* If pam_passwd_conv_proc saw EOF, don't log anything */
+               if (!pam_no_password)
+                       ereport(LOG,
+                                       (errmsg("pam_acct_mgmt failed: %s",
+                                                       pam_strerror(pamh, retval))));
                pam_passwd = NULL;              /* Unset pam_passwd */
-               return STATUS_ERROR;
+               return pam_no_password ? STATUS_EOF : STATUS_ERROR;
        }
 
        retval = pam_end(pamh, retval);