Hi,
When LDAPError receives an errnum from ldap_get_option(l,
LDAP_OPT_ERROR_NUMBER, &errnum) that is out of bounds it causes a segfault.
I have attached a script that triggers it and patch that fixes it.
The test script requires an ldap URI and a BaseDN on the command line. The
ldap server can be OpenLDAP 2.3 or 2.4 and the BaseDN should be configured
with a syncprov overlay and have syncprov-reloadhint TRUE. eg:
/tmp/ldap-segfault.py ldap://ldap.example.com dc=example,dc=com
After patching _ldap.so we get a valid Exception:
Traceback (most recent call last):
File "/tmp/ldap-segfault.py", line 39, in ?
rtype, rdata, rmsgid, serverctrls = conn.result3(all=1, timeout=60)
File "/usr/lib/python2.4/site-packages/ldap/ldapobject.py", line 438, in
result3
rtype, rdata, rmsgid, serverctrls =
self._ldap_call(self._l.result3,msgid,all,timeout)
File "/usr/lib/python2.4/site-packages/ldap/ldapobject.py", line 97, in
_ldap_call
result = func(*args,**kwargs)
ldap.LDAPError: {'info': 'sync cookie is stale', 'desc': 'Content Sync
Refresh Required'}
--
Thanks,
Sean Burford
--- python-ldap-2.3.1/Modules/errors.c 2007-03-27 13:34:31.000000000 -0700
+++ python-ldap-2.3.1.patched/Modules/errors.c 2009-03-20 11:14:30.000000000 -0700
@@ -51,20 +51,25 @@ LDAPerror( LDAP*l, char*msg )
return NULL;
}
else {
- int errnum;
+ int errnum, opt_errnum;
PyObject *errobj;
PyObject *info;
PyObject *str;
char *matched, *error;
- if (ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum) < 0)
- errobj = LDAPexception_class; /* unknown error XXX */
- else
- errobj = errobjects[errnum+LDAP_ERROR_OFFSET];
-
+
+ opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum);
+ if (opt_errnum != LDAP_OPT_SUCCESS)
+ errnum = opt_errnum;
+
if (errnum == LDAP_NO_MEMORY)
return PyErr_NoMemory();
+ if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX)
+ errobj = errobjects[errnum+LDAP_ERROR_OFFSET];
+ else
+ errobj = LDAPexception_class;
+
info = PyDict_New();
if (info == NULL)
return NULL;
#!/usr/bin/python2.4
import ldap
import ldap.controls
import struct
import sys
class SyncRequestControl(ldap.controls.LDAPControl):
controlType='1.3.6.1.4.1.4203.1.9.1.1'
def encodeControlValue(self, value):
cookie = value
len_cookie = len(cookie)
result_content = struct.pack('BBBBBBB', 0x30, len_cookie + 5, 0x0A, 0x01, 0x01, 0x04, len_cookie)
return result_content + cookie
try:
host=sys.argv[1]
base=sys.argv[2]
except IndexError:
print 'Usage: %s ldap://HOSTNAME BASEDN'
print 'HOSTNAME should have "syncprov-reloadhint TRUE" set for BASEDN'
sys.exit(1)
cookie='rid=000,sid=000,csn=20010101010101.000000Z#000000#000#000000'
ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
ldap.set_option(ldap.OPT_REFERRALS, 0)
conn = ldap.initialize(host)
sync_req_ctrl=SyncRequestControl(controlType=SyncRequestControl.controlType,
criticality=True, controlValue=cookie)
conn.search_ext(base, ldap.SCOPE_SUBTREE, attrlist=('dn','entryCSN',),
serverctrls=(sync_req_ctrl,))
rtype, rdata, rmsgid, serverctrls = conn.result3(all=1, timeout=60)
rtype, rdata, rmsgid, serverctrls = conn.result3(all=1, timeout=60)
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
Python-LDAP-dev mailing list
Python-LDAP-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/python-ldap-dev