Hello Phil,
Thursday, August 29, 2002, 7:59:32 PM, you wrote:
PC> I am not an LDAP expert, so I may need to be corrected here. If so, my apologies.
PC> It may also be a difference between versions of LDAP (I have openldap2).
PC> I have only looked at the SEARCH_LDAP_AUTH case, but expect the same problem in all
PC> cases .
Wrong.
All others (!= SEARCH_LDAP_AUTH) with ldap_bind() failure return DEFER.
Variable error_yield initialized with DEFER and set to FAIL if:
-- search_type == SEARCH_LDAP_AUTH:
A failed bind when just checking credentials returns FAIL
but see below
-- too few (zero) entries returned
-- no attributes found
PC> As far as I can see control_ldap_search() in ldap.c will only work along the
PC> list of ldap servers if ldap_init() fails. If ldap_bind() fails then that results
PC> in a hard failure. The man page for ldap_init() says it does not make a connection,
PC> so the connection is made by the call to ldap_bind(). I have checked some code
PC> outside of exim and find that ldap_init() still retuns OK even when given the name
PC> of a server which does not run ldap. It looks to me as if one needs to check the
PC> return code from ldap_bind() for LDAP_UNAVAILABLE and treat that as DEFER.
Right! Both ldap_init() and OpenLDAP-2.x.x ldap_initialize() DO NOT make
any connections. Only ldap_bind() does (at least with OpenLDAP-2.x.x).
So, cycling through servers is now *impossible* in case of
SEARCH_LDAP_AUTH. However, it does not make much sense in case of just
one server because the nature of authentication. It can not be
deferred.
I don't like checking against rc == LDAP_UNAVAILABLE. I'd like
LDAP_INVALID_CREDENTIALS since this is more authentication-specific.
Result codes can be found in draft-ietf-ldapext-ldap-c-api-xx and
are expected to be permanent across different LDAP implementations.
This draft is under docs/drafts/ directory.
Robust implementation could make several result code checks.
Regarding Exim. The following code in ldap.c
=cut
/* A failed bind when just checking credentials returns FAIL. */
if (search_type == SEARCH_LDAP_AUTH)
{
DEBUG(D_lookup) debug_printf(
"Bind failed: ldapauth returns FAIL\n");
error_yield = FAIL;
goto RETURN_ERROR_NOMSG;
}
=cut
Should be replaced with (something like) this:
=cut
if (search_type == SEARCH_LDAP_AUTH)
{
if (rc == LDAP_INVALID_CREDENTIALS)
{
DEBUG(D_lookup) debug_printf("Bind failed: ldapauth returns FAIL\n");
error_yield = FAIL;
goto RETURN_ERROR_NOMSG;
}
else
{
/* Service unavaliable or whatever, cycle through servers */
/* error_yield = DEFER; */ /* already set to DEFER at top */
goto RETURN_ERROR;
}
}
=cut
PC> ldap_open() does return a failure, but the man page says that is deprecated in
PC> favour of ldap_init().
As for OpenLDAP2, both ldap_open() and ldap_init() are deprecated in
favour of ldap_initialize(), which accepts URL instead of a host name.
This is because OpenLDAP2 accepts ldap:// ldaps:// and ldapi:// URL
schemes.
According to Philip Hazel:
Philip, that's another small issue I will patch my Exim for
immediately. Sir, I expect it in 4.11 if possible ;-)
Thank You.
--
Best regards,
Peter mailto:spam4octan@highway.ru