Re: [Exim] use of ldap_init

Top Page
Delete this message
Reply to this message
Author: Peter A. Savitch
Date:  
To: Phil Chambers, Philip Hazel
CC: exim-users
Subject: Re: [Exim] use of ldap_init
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