[rcardenes at debian.org: Re: Bug#179108: ldap_initialize patch]

Ricardo Javier Cardenes ricardo at conysis.com
Thu Apr 10 18:25:47 CEST 2003


On Sun, Apr 06, 2003 at 05:33:16PM +0200, Michael Ströder wrote:

> >Passing a NULL argument to ldap_initialize, you prevent this code from
> >running (excerpt from ldap_initialize/OpenLDAP 2.0.27):
> >
> >        if (url != NULL) {
> >                rc = ldap_set_option(ld, LDAP_OPT_URI, url);
> >                if ( rc != LDAP_SUCCESS ) {
> >                        ldap_ld_free(ld, 1, NULL, NULL);
> >                        return rc;
> >                }
> >        }
> >
> >I haven't checked deeply, but it seems to deactivate further URI
> >checkins, making the LDAP library assume that you want to connect to a
> >local LDAP server.
> 
> What does local exactly mean? I guess the LDAP URI is taken from ldap.conf 
> if uri is NULL. Is that right? If yes, I have to admit that I have some 
> objections to introduce (implicit) support for ldap.conf in python-ldap.

Ok. Now I've checked deeply :-) Note that I wasn't thinking of speaking
truth, but just making some guesses looking at ldap_initialize and my
practical experience (in fact, I was expecting to be corrected, as I
couldn't explain the strange behaviour). Now, there's how this works:

   * If you pass some string as "url" to ldap_initialize, then it
     calls ldap_set_option and sets LDAP_INT_GLOBAL_OPT()->ldo_defludp
     with "url" (or "urls", if you have more than one).
   * If you pass NULL as "url" to ldap_initialize, it doesn't call
     ldap_set_option, and so you get the default value. If we look at
     libraries/libldap/init.c:

      void ldap_int_initialize_global_options(...) {
         ...
         ...
            ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
         ...
         ...
      }

     This (if I've read ldap_url_parselist well) loads
     "ldap://localhost/" as the default value.

So, ldap_initialize(&ldp, NULL) is the same (to all effects) that
ldap_initialize(&ldp, "ldap://localhost/"). Of course, that doesn't
explain my previous problems with LDAP lookups (again, that problems
_seemed_ as DNS lookup timeouts, I'm not 100% sure).

Oddly enough, I've those problems no more :-? in any of the three
machines I've tried, including two of them which were showing thatu
problem. I know that both of them was upgraded to Debian Testing
recently, so I can't provide info about OpenLDAP versions. :-/

> Well, at some point you have to make a DNS lookup. Where does the speed up 
> come from?

I still don't know (now I'm more confused). Any:

   ldapsearch -h SOME_NAME_FOR_LOCAL_LDAP_HOST ...........

made me wait several seconds until some timeout (even "localhost"),
while:

   ldapsearch  ............

didn't. But now that I think about it, I'm not the only admin on those
machines, and maybe someone played tricks with /etc/ldap/ldap.conf

> Or do you suspect the OpenLDAP libs to do reverse lookups in the URL 
> checking?
>
> Did you compile your OpenLDAP with --enable-wrappers (TCP wrapper support)? 
> This could cause reverse lookups on the server's side. Not sure if it also 
> has an effect on the client libs.

That's what I was suspecting the first time, but I discarded it. A
change in client side's options shouldn't affect server's behaviour on
doing reverses.

In fact, haven't read more deeply the library code I was thinking at
that moment on some kind of "direct access" (ie: UNIX sockets vs. TCP
sockets).

> >Anyway, there's no reason to not been able to send a NULL as URL
> >argument to ldap_initialize, since the API _does_ recognize it as a
> >valid argument
> 
> I have some plans to let python-ldap be just a wrapper above other APIs 
> (e.g. ADSI on Win32 or maybe a pure Python version). Therefore there MUST 
> be a good rationale to change semantics of the uri argument of 
> ldap.initialize() or introduce a dependency on OpenLDAP's ldap.conf.

Well, a NULL url seems to mean "get the default server URL, whatever
it is", and it seems like a reasonable semantic, since you can't define
default arguments on C callables. Anyway, looking at current OpenLDAP
stable implementation (2.0.27, as I said), the library sets some internal
defaults (including ldo_defludp = "http://localhost/") before looking into
ldap.conf (no ldap.conf dependency at all).

> >Of course, if Michael has a more deep view of OpenLDAP internals than I

Note that I wasn't looking for any type of offence. I regretted about
this particular statement after sending the mail.

> No, I don't have more insight. In fact I'm not very familiar with the C 
> part of python-ldap which is hard to maintain for me since David Leonard 
> does not have time to spent anymore. Contributions welcome (e.g. support 
> for extended controls).

Mmh... I can help if you need someone doing the C part. I'm somewhat
experienced dealing with C/C++ extending/embedding Python :-)

> >I can keep applying patches.
> 
> Instead you could derive from ldap.ldapobject.LDAPObject and do the host 
> lookup once(!) in the __init__() method passing an IP address to underlying 
> _ldap.initialize(). Or better rewrite your LDAP applications to keep 
> persistent connections. See ldap.ldapobject.ReconnectLDAPObject for a 
> pickable version of LDAPObject.

The actual lookup is delayed until ldap_bind :-), and I dit it twice.
Anyway, this is not a problem now.

> Ciao, Michael.

Regards,
	Ricardo




More information about the python-ldap mailing list