Skip to content

Commit 77e0b19

Browse files
committed
Some detection whether we need to use -lldap_r to get threadsafe libldap
Closes #432
1 parent 9d7ca92 commit 77e0b19

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

setup.cfg

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ defines = HAVE_SASL HAVE_TLS HAVE_LIBLDAP_R
2121
extra_compile_args =
2222
extra_objects =
2323

24+
# Uncomment this if auto-detection doesn't work for you (e.g. loading
25+
# libldap needs to take 'library_dirs' into account)
2426
# Example for full-featured build:
2527
# Support for StartTLS/LDAPS, SASL bind and reentrant libldap_r.
26-
libs = ldap_r lber
28+
#libs = ldap_r lber
2729

2830
# Installation options
2931
[install]
@@ -33,7 +35,7 @@ optimize = 1
3335
# Linux distributors/packagers should adjust these settings
3436
[bdist_rpm]
3537
provides = python-ldap
36-
requires = python libldap-2_4
38+
requires = python libldap-2
3739
vendor = python-ldap project
3840
packager = python-ldap team
3941
distribution_name = openSUSE 11.x

setup.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class OpenLDAP2:
2424
extra_compile_args = []
2525
extra_link_args = []
2626
extra_objects = []
27-
libs = ['ldap', 'lber']
27+
libs = None
2828
defines = []
2929
extra_files = []
3030

@@ -38,6 +38,49 @@ class OpenLDAP2:
3838
if cfg.has_option('_ldap', name):
3939
setattr(LDAP_CLASS, name, cfg.get('_ldap', name).split())
4040

41+
if LDAP_CLASS.libs is None:
42+
# libldap(_r) not selected by setup.cfg, turn to auto-detection
43+
from ctypes import cdll, c_void_p, c_char_p, c_int, byref, Structure
44+
import ctypes.util
45+
46+
NULL = c_void_p()
47+
LDAP_OPT_API_FEATURE_INFO = 0x15
48+
class ldap_apifeature_info(Structure):
49+
_fields_ = [
50+
("ldapaif_info_version", c_int),
51+
("ldapaif_name", c_char_p),
52+
("ldapaif_version", c_int)
53+
]
54+
55+
for name in ('ldap', 'ldap_r'):
56+
ldapname = ctypes.util.find_library(name)
57+
if not ldapname:
58+
continue
59+
60+
try:
61+
libldap = cdll.LoadLibrary(ldapname)
62+
except OSError:
63+
# Cannot load this version of libldap
64+
continue
65+
66+
info = ldap_apifeature_info(1, b"X_OPENLDAP_THREAD_SAFE")
67+
68+
if libldap.ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, byref(info)):
69+
# Does not support THREADSAFE
70+
continue
71+
72+
if info.ldapaif_version != 1:
73+
# Does not support THREADSAFE
74+
continue
75+
76+
LDAP_CLASS.libs = [name, 'lber']
77+
if 'HAVE_LIBLDAP_R' not in LDAP_CLASS.defines:
78+
LDAP_CLASS.defines.append('HAVE_LIBLDAP_R')
79+
break
80+
else:
81+
# At least try
82+
LDAP_CLASS.libs = ['ldap', 'lber']
83+
4184
for i in range(len(LDAP_CLASS.defines)):
4285
LDAP_CLASS.defines[i]=((LDAP_CLASS.defines[i],None))
4386

@@ -132,7 +175,6 @@ class OpenLDAP2:
132175
extra_objects = LDAP_CLASS.extra_objects,
133176
runtime_library_dirs = (not sys.platform.startswith("win"))*LDAP_CLASS.library_dirs,
134177
define_macros = LDAP_CLASS.defines + \
135-
('ldap_r' in LDAP_CLASS.libs or 'oldap_r' in LDAP_CLASS.libs)*[('HAVE_LIBLDAP_R',None)] + \
136178
('sasl' in LDAP_CLASS.libs or 'sasl2' in LDAP_CLASS.libs or 'libsasl' in LDAP_CLASS.libs)*[('HAVE_SASL',None)] + \
137179
('ssl' in LDAP_CLASS.libs and 'crypto' in LDAP_CLASS.libs)*[('HAVE_TLS',None)] + \
138180
[

0 commit comments

Comments
 (0)