|
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
|