From: Alain S. <asp...@gm...> - 2007-01-26 23:23:02
|
On 1/26/07, Michael Str=F6der <mi...@st...> wrote: > Alain Spineux wrote: > > When testing ReconnectLDAPObject I found a bug. > > The object doesn't reconnect after a main failure ! > > [..] > > I thing the main probleme is here ! > > Look ! > > Yes, I can reproduce your observation. Thanks for pointing it out. Don't forget we are on the same boat Captain ! :-) > > > l=3Dldap.ldapobject.ReconnectLDAPObject(ldap_url.initializeUrl()) > > print 'search', l.search_s(ldap_url.dn, ldap.SCOPE_SUBTREE, "(objectCla= ss=3D*)") > > > > this work too ! And don't give any error while their is no bind ! > > work like if l.simple_bind_s('', '') where used just before the search = ! > > Yes, this works as intended in LDAPv3. In opposite to LDAPv2 you MAY > send a LDAP request without prior bind request. > > > I wrote a patch but this is only a workaround that detect the main > > failure, set a flag and force a reconnect before any request if the > > flag is set. > > Where's the patch? This is still only a workin "draft" I need to reread it's logic, anyway I add it at the end > Can't figure out why it does not send the formerly > sent bind request. It has all the data around. And if you take the > server down it will re-send the bind request. The trick is it doesn't try to reconnect AFTER the main failure (or BEFORE the next statement) ! Because the first try (of the next ldap statement) doesn't generate any error, it doesn't try to reconnect and then give the answer as is ! But this is the answer it got like an unauthenticated user ! Look, this is the tcpdump of the last statement ! 00:14:21.109514 IP 127.0.0.1.36250 > 127.0.0.1.ldap: S 1795648490:1795648490(0) win 00:14:21.110352 IP 127.0.0.1.ldap > 127.0.0.1.36250: S 1793421325:1793421325(0) ack 1795648491 win 32768 <mss 16396,sackOK,timestamp 516494160 516494159,nop,wscale 7> 00:14:21.110430 IP 127.0.0.1.36250 > 127.0.0.1.ldap: . ack 1 win 257 <nop,nop,timestamp 516494160 516494160> You can identify the well known 3-way handshaking ! This is a new connectio= n ! I thing libldap open a new connection, but libldap dont store anything about the credential and then cannot authenticate with the good user ! I will try to reproduce this in C with libc Here is the patch (including my whoami_s() ) *** ldapobject.py.disconnet Fri Jan 26 22:22:57 2007 --- ldapobject.py.orig Fri Jan 26 13:42:59 2007 *************** *** 678,684 **** self._retry_delay =3D retry_delay self._start_tls =3D 0 self._reconnects_done =3D 0L - self._disconnected=3DTrue def __getstate__(self): """return data representation for pickled object""" --- 678,683 ---- *************** *** 723,730 **** self.start_tls_s() # Repeat last simple or SASL bind self._apply_last_bind() ! except Exception, e: ! self._disconnected=3DTrue if __debug__ and self._trace_level>=3D1: self._trace_file.write('*** %d. reconnect to %s failed\n' % ( self._retry_max-reconnect_counter+1,uri --- 722,728 ---- self.start_tls_s() # Repeat last simple or SASL bind self._apply_last_bind() ! except: if __debug__ and self._trace_level>=3D1: self._trace_file.write('*** %d. reconnect to %s failed\n' % ( self._retry_max-reconnect_counter+1,uri *************** *** 736,742 **** self._trace_file.write('=3D> delay %s...\n' % (self._retry_dela= y)) time.sleep(self._retry_delay) else: - self._disconnected=3DFalse if __debug__ and self._trace_level>=3D1: self._trace_file.write('*** %d. reconnect to %s successful, last operation will be repeated\n' % ( self._retry_max-reconnect_counter+1,uri --- 734,739 ---- *************** *** 745,762 **** break def _apply_method_s(self,func,*args,**kwargs): ! if self._disconnected: self.reconnect(self._uri) # Re-try last operation return func(self,*args,**kwargs) - else: - try: - return func(self,*args,**kwargs) - except ldap.SERVER_DOWN: - # Reconnect - self.reconnect(self._uri) - # Re-try last operation - return func(self,*args,**kwargs) def set_option(self,option,invalue): self._options[option] =3D invalue --- 742,754 ---- break def _apply_method_s(self,func,*args,**kwargs): ! try: ! return func(self,*args,**kwargs) ! except ldap.SERVER_DOWN: ! # Reconnect self.reconnect(self._uri) # Re-try last operation return func(self,*args,**kwargs) def set_option(self,option,invalue): self._options[option] =3D invalue *************** *** 764,772 **** def simple_bind_s(self,*args,**kwargs): self._last_bind =3D (self.simple_bind_s,args,kwargs) ! result=3DSimpleLDAPObject.simple_bind_s(self,*args,**kwargs) ! self._disconnected=3DFalse ! return result def start_tls_s(self): res =3D SimpleLDAPObject.start_tls_s(self) --- 756,762 ---- def simple_bind_s(self,*args,**kwargs): self._last_bind =3D (self.simple_bind_s,args,kwargs) ! return SimpleLDAPObject.simple_bind_s(self,*args,**kwargs) def start_tls_s(self): res =3D SimpleLDAPObject.start_tls_s(self) *************** *** 778,786 **** sasl_interactive_bind_s(who, auth) -> None """ self._last_bind =3D (self.sasl_interactive_bind_s,args,kwargs) ! result=3DSimpleLDAPObject.sasl_interactive_bind_s(self,*args,**kwargs= ) ! self._disconnected=3DFalse ! return result def add_ext_s(self,*args,**kwargs): return self._apply_method_s(SimpleLDAPObject.add_ext_s,*args,**kwargs= ) --- 768,774 ---- sasl_interactive_bind_s(who, auth) -> None """ self._last_bind =3D (self.sasl_interactive_bind_s,args,kwargs) ! return SimpleLDAPObject.sasl_interactive_bind_s(self,*args,**kwargs) def add_ext_s(self,*args,**kwargs): return self._apply_method_s(SimpleLDAPObject.add_ext_s,*args,**kwargs= ) *************** *** 800,808 **** def search_ext_s(self,*args,**kwargs): return self._apply_method_s(SimpleLDAPObject.search_ext_s,*args,**kwa= rgs) - def whoami_s(self,*args,**kwargs): - return self._apply_method_s(SimpleLDAPObject.whoami_s,*args,**kwargs) - class SmartLDAPObject(ReconnectLDAPObject): """ --- 788,793 ---- -- Alain Spineux aspineux gmail com May the sources be with you |