Ah, good old ldap.SERVER_DOWN. Just when you think you've got everything
working....

I've hit similar problems myself. I just looked at my code, and in my case,
when I hit SERVER_DOWN, I actually destroy and recreate my LDAP object,
i.e. in my LDAP class, I have:

    def bind(self):
        try:
            if self.reconnect_attempts < 3:
                self.reconnect_attempts += 1
                ldap.set_option(ldap.OPT_REFERRALS, self.referrals)
                self.logger.debug('Binding to ' + self.ldapuri)
                self.l = ldap.initialize(self.ldapuri)
                self.l.protocol_version = 3
                self.l.bind_s(self.binddn, self.bindpw)
                self.logger.debug('Bound.')
                self.reconnect_attempts = 0
            else:
                self.logger.critical("Fatal error rebinding to LDAP server,
max reconnect attempts exceeded")
                raise IOError("Lost connection to LDAP server and cannot
reconnect.")

And further down:
        except ldap.SERVER_DOWN, e:
            self.logger.debug('Exception ldap.SERVER_DOWN in bind(),
rebinding...')
            self.bind()

        except ldap.SERVER_DOWN, e:
            # Likely a timeout, which does happen
            self.logger.debug('Exception ldap.SERVER_DOWN in bind(),
rebinding...')
            self.bind()

Cheers,

Chris



On Tue, Jul 23, 2013 at 1:25 PM, Brian May
<[email protected]>wrote:

> Never mind. Think I found the problem.
>
> It appears if the connection attempt fails, because the server is down,
> the initialize(...) call succeeds - it is a lazy call.  That is it returns
> what appears to be a valid connection, hasn't tried to talk to the server.
> The simple_bind_s does talk to the server and fails.
>
> Then when the server comes up, it uses the connection returned by the last
> initialize(...) call, where the bind failed, and tries to do the operation
> on it. This operation doesn't fail, because it thinks there is a good
> connection, even though bind failed.
>
> The solution seems to be to set self._obj = None at the top of _reconnect,
> and only set it after the simple_bind_s call succeeded. So that way it will
> never try to use an existing connection unless the bind succeeded.
>
> What is strange is I thought I had fully tested this code :-(
>
> My updated revision:
>
> https://gist.github.com/brianmay/6059401
>
> _______________________________________________
> melbourne-pug mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/melbourne-pug
>
>
_______________________________________________
melbourne-pug mailing list
[email protected]
http://mail.python.org/mailman/listinfo/melbourne-pug

Reply via email to