summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-10-12 22:33:34 -0400
committerPeter Eisentraut <peter_e@gmx.net>2017-10-12 22:37:14 -0400
commitcf1238cd9763f0a6e3454ddf75ac56ff722f18ee (patch)
tree3808def2692773c5dd0dc595632cfacd04c6ff50
parent1feff99fe4576d4685c14dff18d1f845a1456f10 (diff)
Log diagnostic messages if errors occur during LDAP auth.
Diagnostic messages seem likely to help users diagnose root causes more easily, so let's report them as errdetail. Author: Thomas Munro Reviewed-By: Ashutosh Bapat, Christoph Berg, Alvaro Herrera, Peter Eisentraut Discussion: https://postgr.es/m/CAEepm=2_dA-SYpFdmNVwvKsEBXOUj=K4ooKovHmvj6jnMdt8dw@mail.gmail.com
-rw-r--r--src/backend/libpq/auth.c48
-rw-r--r--src/test/ldap/t/001_auth.pl11
2 files changed, 51 insertions, 8 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 11ef4a58588..2728c66a352 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2305,6 +2305,8 @@ CheckBSDAuth(Port *port, char *user)
*/
#ifdef USE_LDAP
+static int errdetail_for_ldap(LDAP *ldap);
+
/*
* Initialize a connection to the LDAP server, including setting up
* TLS if requested.
@@ -2332,7 +2334,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
{
ereport(LOG,
- (errmsg("could not set LDAP protocol version: %s", ldap_err2string(r))));
+ (errmsg("could not set LDAP protocol version: %s",
+ ldap_err2string(r)),
+ errdetail_for_ldap(*ldap)));
ldap_unbind(*ldap);
return STATUS_ERROR;
}
@@ -2385,7 +2389,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
#endif
{
ereport(LOG,
- (errmsg("could not start LDAP TLS session: %s", ldap_err2string(r))));
+ (errmsg("could not start LDAP TLS session: %s",
+ ldap_err2string(r)),
+ errdetail_for_ldap(*ldap)));
ldap_unbind(*ldap);
return STATUS_ERROR;
}
@@ -2508,7 +2514,9 @@ CheckLDAPAuth(Port *port)
{
ereport(LOG,
(errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
- port->hba->ldapbinddn, port->hba->ldapserver, ldap_err2string(r))));
+ port->hba->ldapbinddn, port->hba->ldapserver,
+ ldap_err2string(r)),
+ errdetail_for_ldap(ldap)));
ldap_unbind(ldap);
pfree(passwd);
return STATUS_ERROR;
@@ -2534,7 +2542,8 @@ CheckLDAPAuth(Port *port)
{
ereport(LOG,
(errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s",
- filter, port->hba->ldapserver, ldap_err2string(r))));
+ filter, port->hba->ldapserver, ldap_err2string(r)),
+ errdetail_for_ldap(ldap)));
ldap_unbind(ldap);
pfree(passwd);
pfree(filter);
@@ -2573,7 +2582,9 @@ CheckLDAPAuth(Port *port)
(void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
ereport(LOG,
(errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
- filter, port->hba->ldapserver, ldap_err2string(error))));
+ filter, port->hba->ldapserver,
+ ldap_err2string(error)),
+ errdetail_for_ldap(ldap)));
ldap_unbind(ldap);
pfree(passwd);
pfree(filter);
@@ -2618,23 +2629,46 @@ CheckLDAPAuth(Port *port)
port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
r = ldap_simple_bind_s(ldap, fulluser, passwd);
- ldap_unbind(ldap);
if (r != LDAP_SUCCESS)
{
ereport(LOG,
(errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s",
- fulluser, port->hba->ldapserver, ldap_err2string(r))));
+ fulluser, port->hba->ldapserver, ldap_err2string(r)),
+ errdetail_for_ldap(ldap)));
+ ldap_unbind(ldap);
pfree(passwd);
pfree(fulluser);
return STATUS_ERROR;
}
+ ldap_unbind(ldap);
pfree(passwd);
pfree(fulluser);
return STATUS_OK;
}
+
+/*
+ * Add a detail error message text to the current error if one can be
+ * constructed from the LDAP 'diagnostic message'.
+ */
+static int
+errdetail_for_ldap(LDAP *ldap)
+{
+ char *message;
+ int rc;
+
+ rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message);
+ if (rc == LDAP_SUCCESS && message != NULL)
+ {
+ errdetail("LDAP diagnostics: %s", message);
+ ldap_memfree(message);
+ }
+
+ return 0;
+}
+
#endif /* USE_LDAP */
diff --git a/src/test/ldap/t/001_auth.pl b/src/test/ldap/t/001_auth.pl
index a7cac6210b5..38760ece617 100644
--- a/src/test/ldap/t/001_auth.pl
+++ b/src/test/ldap/t/001_auth.pl
@@ -2,7 +2,7 @@ use strict;
use warnings;
use TestLib;
use PostgresNode;
-use Test::More tests => 14;
+use Test::More tests => 15;
my ($slapd, $ldap_bin_dir, $ldap_schema_dir);
@@ -175,3 +175,12 @@ $node->reload;
$ENV{"PGPASSWORD"} = 'secret1';
test_access($node, 'test1', 0, 'combined LDAP URL and search filter');
+
+note "diagnostic message";
+
+unlink($node->data_dir . '/pg_hba.conf');
+$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="uid=" ldapsuffix=",dc=example,dc=net" ldaptls=1});
+$node->reload;
+
+$ENV{"PGPASSWORD"} = 'secret1';
+test_access($node, 'test1', 2, 'any attempt fails due to unsupported TLS');