Building python-ldap against Netscape's LDAP-SDK 4.11

David Leonard david.leonard at csee.uq.edu.au
Fri Oct 6 01:45:22 CEST 2000


On Thu, 5 Oct 2000, Michael Ströder typed thusly:

> > Ok, I edited Modules/LDAPObject.c to use only 2 arguments. The

really, configure.in should be modified to test for and pick that up...
can you send me your diffs to LDAPObject.c?

> > module builds now and import ldap works. But it gives me undefined
> > exceptions.
> > 
> > ldap.LDAPError: unknown error (C API does not expose error)

I just looked at netscape's docs and found the function ldap_get_lderrno().
i've added it in (untested patch at end of message)

i'm also going to upgrade Misc/openldap.sh to grab an OpenLDAP 2 release
but it seems I'll need to bundle libtool into the distribution :(

> It's me again. ;-)

talking to yourself is a sign of impending madness :)

> I managed to connect to a OpenLDAP 2.0.6 server (which is LDAPv3).
> Connecting to OpenLDAP 1.2.11 server (LDAPv2) does not work. It
> seems it has something to do with choosing LDAPv3 during connect and
> falling back to LDAPv2 if v3 fails.
> 
> I can browse my test data on the OpenLDAP 2.0 server. But when I hit
> a LDAPv3 referral entry the exception above is raised. I guess the
> C-LDAP-SDK returns some LDAPv3 specific data not known to
> python-ldap.

no, its probably a simple error, just have to teach the module how to find it.

> BTW: The following code is also rejected (it works with OpenLDAP
> 1.2.11 libs):
> 
> ldap_obj.deref = ldap.DEREF_NEVER
> ldap_obj.options = 0
> 
> Traceback:
> [..]
>     ldap_obj.options = 0
> NameError: cannot set that field
> 
> Why I want this?

hmm, perhaps this is a design error. if the C API doesn't support things
like options, then there will be no .options attribute to set. I had 
originally imagined people writing code like:

	if hasattr(ldap_obj, 'options'): ldap_obj.options = 0

which shows the variability of the C libraries.

however at this level (_ldap), I really wanted to get as close to the
C api as possible, and leave it to "higher-level" abstractions to deal with 
such nitty gritty logic.

> I would like to actively catch LDAPv3 referrals. This works slightly
> well with catching ldap.PARTIAL_RESULTS and pulling the referral
> LDAP URL out of the info field.
> However, if binding via LDAPv2 (OpenLDAP 1.2.x libs) to a LDAPv3
> server
> 1. the server is free to just ignore my request if a referral is hit
> and
> 2. I don't get the search continuations of the referral entry when
> doing a one level search.
> This causes a lot of inconsistent behaviour of my client (besides
> all those broken LDAP servers out there...sigh!).

suggested patches are welcome :)

d
-- 
David Leonard                           David.Leonard at csee.uq.edu.au
Dept of Comp. Sci. and Elec. Engg   _   Room:78-640  Ph:+61 7 336 51187
The University of Queensland       |+|  http://www.csee.uq.edu.au/~leonard/
QLD 4072  AUSTRALIA               ~` '~ B73CD65FBEF4C089B79A8EBADF1A932F13EA0FC8

Index: errors.c
===================================================================
RCS file: /cvsroot/python-ldap/python-ldap/Modules/errors.c,v
retrieving revision 1.3
diff -u -r1.3 errors.c
--- errors.c	2000/08/14 22:37:37	1.3
+++ errors.c	2000/10/05 23:44:05
@@ -30,7 +30,7 @@
 		PyErr_SetFromErrno( LDAPexception_class );
 		return NULL;
 	}
-#ifdef LDAP_TYPE_IS_OPAQUE
+#if !defined(HAVE_LDAP_GET_LDERRNO) && defined(LDAP_TYPE_IS_OPAQUE)
 	else {
 		PyErr_SetString(LDAPexception_class,
 			"unknown error (C API does not expose error)");
@@ -42,8 +42,16 @@
 		PyObject *errobj;
 		PyObject *info;
 		PyObject *str;
+		char *m, *s;
 
+#if defined(HAVE_LDAP_GET_LDERRNO)
+		errnum = ldap_get_lderrno(l, &m, &s);
+#else
 		errnum = l->ld_errno;
+		m = l->ld_matched;
+		s = l->ld_error;
+#endif
+
 		if (errnum<0 || errnum>=NUM_LDAP_ERRORS)
 			errobj = LDAPexception_class;	/* unknown error XXX */
 		else
@@ -60,22 +68,19 @@
 		if (str)
 			PyDict_SetItemString( info, "desc", str );
 		Py_XDECREF(str);
+
+		if (m == NULL && (str = PyString_FromString(m)) != NULL) {
+		   PyDict_SetItemString(info, "matched", str);
+		   Py_DECREF(str);
+		} else
+		   PyDict_SetItemString(info, "matched", Py_None);
+
+		if (s == NULL && (str = PyString_FromString(s)) != NULL) {
+		   PyDict_SetItemString(info, "info", str);
+		   Py_DECREF(str);
+		} else
+		   PyDict_SetItemString(info, "info", Py_None);
 
-		if (l->ld_matched != NULL && *l->ld_matched != '\0') 
-		{
-		   str = PyString_FromString(l->ld_matched);
-		   if (str)
-			   PyDict_SetItemString( info, "matched", str );
-		   Py_XDECREF(str);
-		}
-
-		if (l->ld_error != NULL && *l->ld_error != '\0') 
-		{
-		   str = PyString_FromString(l->ld_error);
-		   if (str)
-			   PyDict_SetItemString( info, "info", str );
-		   Py_XDECREF(str);
-		}
 		PyErr_SetObject( errobj, info );
 		Py_DECREF(info);
 		return NULL;






More information about the python-ldap mailing list