Hi all,below is a small patch for the LDAP address book to address the following two issues:
(a) handling referralsI use the LDAP address book at work, where it reads information from a (ugh!) M$ Active Directory server. After the IT dept of my company moved that server to a different machine, all completion lookups failed... Debugging the connection in Wireshark, I noticed that AD always returns a referral to the DNS zones directory. OpenLDAP in turn tries to bind anonymously to that, and as this fails, the whole operation fails with LDAP_OPERATIONS_ERROR. As OpenLDAP has no means to pass credentials to the bind operation of the "nested" search, IMHO the only solution is to switch off following referrals completely (which is the way ldapsearch works, btw.). We then have to catch LDAP_PARTIAL_RESULTS as return code of ldap_search_ext_s. I have no idea if the behaviour of AD is wrong or not, but it shouldn't have any influence on LDAP server /not/ returning any referrals. Unfortunately, this topic is not documented at all in OpenLDAP.
(b) improved completion search stringChange the mail search pattern from "%s *" to "%s* *". If e.g. an LDAP entry
cn = Smith, Bill sn = Smith mail = bill smith linux orgexists, simply typing "bill" (i.e. the beginning of the mail address) in the To: entry did not find this entry. The drawback of the new pattern is that usually more entries will be returned, though.
Any opinions? Cheers, Albrecht. -- Dr. Albrecht Dreß LIOS Technology GmbH Project Engineering / Software Design Schanzenstrasse 6 - 20 D-51063 Cologne / Germany Phone +49 221 676 2742 Fax +49 221 676 2069 Managing Director: Thomas Oldemeyer Registration Court Amtsgericht Cologne, Reg.-No. HRB 33482 -- Albrecht Dreß - Johanna-Kirchner-Straße 13 - D-53123 Bonn (Germany) Phone (+49) 228 6199571 - mailto:albrecht dress arcor de GnuPG public key: http://www.mynetcologne.de/~nc-dreszal/pubkey.asc
Index: libbalsa/address-book-ldap.c =================================================================== --- libbalsa/address-book-ldap.c (Revision 7583) +++ libbalsa/address-book-ldap.c (Arbeitskopie) @@ -345,6 +345,11 @@ } #endif /* HAVE_CYRUS_SASL */ + /* do not follow referrals (OpenLDAP binds anonymously here, which will usually + * fail */ + if (result == LDAP_SUCCESS) + result = ldap_set_option(ab->directory, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF); + if (result != LDAP_SUCCESS) { libbalsa_address_book_set_status(lbab, g_strdup(ldap_err2string(result))); @@ -396,7 +401,7 @@ /* g_print("Performing full lookup...\n"); */ ldap_filter = filter ? g_strdup_printf("(&(objectClass=organizationalPerson)(mail=*)" - "(|(cn=%s*)(sn=%s*)(mail=%s *)))", + "(|(cn=%s*)(sn=%s*)(mail=%s* *)))", filter, filter, filter) : g_strdup("(&(objectClass=organizationalPerson)(mail=*))"); if(DEBUG_LDAP) @@ -969,7 +974,7 @@ ldap = rfc_2254_escape(prefix); filter = g_strdup_printf("(&(objectClass=organizationalPerson)(mail=*)" - "(|(cn=%s*)(sn=%s*)(mail=%s *)))", + "(|(cn=%s*)(sn=%s*)(mail=%s* *)))", ldap, ldap, ldap); g_free(ldap); result = NULL; @@ -983,13 +988,15 @@ g_free(filter); switch (rc) { case LDAP_SUCCESS: - for(e = ldap_first_entry(ldap_ab->directory, result); - e != NULL; e = ldap_next_entry(ldap_ab->directory, e)) { - addr = lbabl_get_internet_address(ldap_ab->directory, e); - if(new_prefix && !*new_prefix) - *new_prefix = internet_address_to_string(addr, FALSE); - res = g_list_prepend(res, addr); - } + case LDAP_PARTIAL_RESULTS: + if (result) + for(e = ldap_first_entry(ldap_ab->directory, result); + e != NULL; e = ldap_next_entry(ldap_ab->directory, e)) { + addr = lbabl_get_internet_address(ldap_ab->directory, e); + if(new_prefix && !*new_prefix) + *new_prefix = internet_address_to_string(addr, FALSE); + res = g_list_prepend(res, addr); + } case LDAP_SIZELIMIT_EXCEEDED: case LDAP_TIMELIMIT_EXCEEDED: /*
Attachment:
pgpWdIctO7zye.pgp
Description: PGP signature