Skip to content

Commit 105925f

Browse files
authored
fix(ReconnectLDAPObject): reconnect race condition
Move calling `unbind_s()` inside the locked region so that `self._l` is handled atomically. Add a new parameter `force` to either forcefully close any previous connection or keep re-use the previous connection if it still is supposed to work.
1 parent ec74e5b commit 105925f

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

Lib/ldap/ldapobject.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ def __setstate__(self,d):
893893
self._reconnect_lock = ldap.LDAPLock(desc='reconnect lock within %s' % (repr(self)))
894894
# XXX cannot pickle file, use default trace file
895895
self._trace_file = ldap._trace_file
896-
self.reconnect(self._uri)
896+
self.reconnect(self._uri,force=True)
897897

898898
def _store_last_bind(self,_method,*args,**kwargs):
899899
self._last_bind = (_method,args,kwargs)
@@ -914,11 +914,16 @@ def _restore_options(self):
914914
def passwd_s(self,*args,**kwargs):
915915
return self._apply_method_s(SimpleLDAPObject.passwd_s,*args,**kwargs)
916916

917-
def reconnect(self,uri,retry_max=1,retry_delay=60.0):
917+
def reconnect(self,uri,retry_max=1,retry_delay=60.0,force=True):
918918
# Drop and clean up old connection completely
919919
# Reconnect
920920
self._reconnect_lock.acquire()
921921
try:
922+
if hasattr(self,'_l'):
923+
if force:
924+
SimpleLDAPObject.unbind_s(self)
925+
else:
926+
return
922927
reconnect_counter = retry_max
923928
while reconnect_counter:
924929
counter_text = '%d. (of %d)' % (retry_max-reconnect_counter+1,retry_max)
@@ -962,14 +967,12 @@ def reconnect(self,uri,retry_max=1,retry_delay=60.0):
962967
return # reconnect()
963968

964969
def _apply_method_s(self,func,*args,**kwargs):
965-
if not hasattr(self,'_l'):
966-
self.reconnect(self._uri,retry_max=self._retry_max,retry_delay=self._retry_delay)
970+
self.reconnect(self._uri,retry_max=self._retry_max,retry_delay=self._retry_delay,force=False)
967971
try:
968972
return func(self,*args,**kwargs)
969973
except ldap.SERVER_DOWN:
970-
SimpleLDAPObject.unbind_s(self)
971974
# Try to reconnect
972-
self.reconnect(self._uri,retry_max=self._retry_max,retry_delay=self._retry_delay)
975+
self.reconnect(self._uri,retry_max=self._retry_max,retry_delay=self._retry_delay,force=True)
973976
# Re-try last operation
974977
return func(self,*args,**kwargs)
975978

0 commit comments

Comments
 (0)