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
This commit is contained in:
parent
1feff99fe4
commit
cf1238cd97
|
@ -2305,6 +2305,8 @@ CheckBSDAuth(Port *port, char *user)
|
||||||
*/
|
*/
|
||||||
#ifdef USE_LDAP
|
#ifdef USE_LDAP
|
||||||
|
|
||||||
|
static int errdetail_for_ldap(LDAP *ldap);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a connection to the LDAP server, including setting up
|
* Initialize a connection to the LDAP server, including setting up
|
||||||
* TLS if requested.
|
* 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)
|
if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
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);
|
ldap_unbind(*ldap);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2385,7 +2389,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
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);
|
ldap_unbind(*ldap);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2508,7 +2514,9 @@ CheckLDAPAuth(Port *port)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
|
(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);
|
ldap_unbind(ldap);
|
||||||
pfree(passwd);
|
pfree(passwd);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
|
@ -2534,7 +2542,8 @@ CheckLDAPAuth(Port *port)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s",
|
(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);
|
ldap_unbind(ldap);
|
||||||
pfree(passwd);
|
pfree(passwd);
|
||||||
pfree(filter);
|
pfree(filter);
|
||||||
|
@ -2573,7 +2582,9 @@ CheckLDAPAuth(Port *port)
|
||||||
(void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
|
(void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
|
(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);
|
ldap_unbind(ldap);
|
||||||
pfree(passwd);
|
pfree(passwd);
|
||||||
pfree(filter);
|
pfree(filter);
|
||||||
|
@ -2618,23 +2629,46 @@ CheckLDAPAuth(Port *port)
|
||||||
port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
|
port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
|
||||||
|
|
||||||
r = ldap_simple_bind_s(ldap, fulluser, passwd);
|
r = ldap_simple_bind_s(ldap, fulluser, passwd);
|
||||||
ldap_unbind(ldap);
|
|
||||||
|
|
||||||
if (r != LDAP_SUCCESS)
|
if (r != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s",
|
(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(passwd);
|
||||||
pfree(fulluser);
|
pfree(fulluser);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldap_unbind(ldap);
|
||||||
pfree(passwd);
|
pfree(passwd);
|
||||||
pfree(fulluser);
|
pfree(fulluser);
|
||||||
|
|
||||||
return STATUS_OK;
|
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 */
|
#endif /* USE_LDAP */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use PostgresNode;
|
use PostgresNode;
|
||||||
use Test::More tests => 14;
|
use Test::More tests => 15;
|
||||||
|
|
||||||
my ($slapd, $ldap_bin_dir, $ldap_schema_dir);
|
my ($slapd, $ldap_bin_dir, $ldap_schema_dir);
|
||||||
|
|
||||||
|
@ -175,3 +175,12 @@ $node->reload;
|
||||||
|
|
||||||
$ENV{"PGPASSWORD"} = 'secret1';
|
$ENV{"PGPASSWORD"} = 'secret1';
|
||||||
test_access($node, 'test1', 0, 'combined LDAP URL and search filter');
|
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');
|
||||||
|
|
Loading…
Reference in New Issue