summaryrefslogtreecommitdiffstats
path: root/pykolab
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2015-08-05 12:19:38 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2015-08-05 12:20:12 +0200
commita0b90e065764de2869546b4a479d394a03acaed3 (patch)
tree6fe14c88547bc0f01a1a65ada2728ba2a0276cb6 /pykolab
parent0c2e627c483eec35d12fd51cb2d96d5c5aa11637 (diff)
downloadpykolab-a0b90e065764de2869546b4a479d394a03acaed3.tar.gz
Allow LDAP _search() to reconnect the original specific _search method, if the exception that caused _search to fail is an ldap.SERVER_DOWN exception. (#5180)
Diffstat (limited to 'pykolab')
-rw-r--r--pykolab/auth/ldap/__init__.py127
1 files changed, 77 insertions, 50 deletions
diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index 6b9f56c..03c465b 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -24,6 +24,7 @@ import ldap.controls
import ldap.filter
import logging
import time
+import traceback
import pykolab
import pykolab.base
@@ -206,12 +207,19 @@ class LDAP(pykolab.base.Base):
['entrydn']
)
- (
- _result_type,
- _result_data,
- _result_msgid,
- _result_controls
- ) = self.ldap.result3(_search)
+ try:
+ (
+ _result_type,
+ _result_data,
+ _result_msgid,
+ _result_controls
+ ) = self.ldap.result3(_search)
+
+ except ldap.SERVER_DOWN, errmsg:
+ log.error(_("LDAP server unavailable: %r") % (errmsg))
+ log.error(_("%s") % (traceback.format_exc())
+ self._disconnect()
+ return False
if len(_result_data) >= 1:
(entry_dn, entry_attrs) = _result_data[0]
@@ -229,6 +237,12 @@ class LDAP(pykolab.base.Base):
except Exception, errmsg:
log.error(_("Authentication cache failed: %r") % (errmsg))
pass
+
+ except ldap.SERVER_DOWN, errmsg:
+ log.error(_("Authentication failed, LDAP server unavailable"))
+ self._disconnect()
+ pass
+
except:
try:
log.debug(
@@ -249,6 +263,7 @@ class LDAP(pykolab.base.Base):
self.ldap.simple_bind_s(entry_dn, login[1])
auth_cache.set_entry(_filter, entry_dn)
retval = True
+
except ldap.NO_SUCH_OBJECT, errmsg:
log.debug(_("Error occured, there is no such object: %r") % (errmsg), level=8)
self.bind = False
@@ -965,6 +980,10 @@ class LDAP(pykolab.base.Base):
return entry_modifications
+ def reconnect(self):
+ self._disconnect()
+ self.connect()
+
def search_entry_by_attribute(self, attr, value, **kw):
self._bind()
@@ -1085,10 +1104,8 @@ class LDAP(pykolab.base.Base):
callback=callback,
)
except Exception, errmsg:
- log.error("Exception occurred: %r" % (errmsg))
- if conf.debuglevel > 8:
- import traceback
- traceback.print_exc()
+ log.error("An error occurred: %r" % (errmsg))
+ log.error(_("%s") % (traceback.format_exc()))
def user_quota(self, entry_id, folder):
default_quota = self.config_get('default_quota')
@@ -1179,15 +1196,14 @@ class LDAP(pykolab.base.Base):
self.ldap.simple_bind_s(bind_dn, bind_pw)
self.bind = True
except ldap.SERVER_DOWN:
- # Can't contact LDAP server
- #
- # - Service not started
- # - Service faulty
- # - Firewall
- pass
+ log.error(_("LDAP server unavailable: %r") % (errmsg))
+ log.error(_("%s") % (traceback.format_exc()))
except ldap.INVALID_CREDENTIALS:
log.error(_("Invalid DN, username and/or password."))
+ else:
+ log.debug(_("_bind called, but already bound"), level=9)
+
def _change_add_group(self, entry, change):
"""
An entry of type group was added.
@@ -1498,10 +1514,9 @@ class LDAP(pykolab.base.Base):
for _type in ['user','group','resource','role','sharedfolder']:
try:
success = eval("self._change_delete_%s(entry, change)" % (_type))
- except:
- if conf.debuglevel > 8:
- import traceback
- log.error(_("%s") % (traceback.format_exc()))
+ except Exception, errmsg:
+ log.error(_("An error occured: %r") % (errmsg))
+ log.error(_("%s") % (traceback.format_exc()))
success = False
@@ -2874,41 +2889,53 @@ class LDAP(pykolab.base.Base):
_use_ldap_controls = self.ldap.supported_controls
for supported_control in _use_ldap_controls:
- try:
- exec("""_results = self.%s(
- %r,
- scope=%r,
- filterstr=%r,
- attrlist=%r,
- attrsonly=%r,
- timeout=%r,
- callback=callback,
- primary_domain=%r,
- secondary_domains=%r
- )""" % (
- supported_control,
- base_dn,
- scope,
- filterstr,
- attrlist,
- attrsonly,
- timeout,
- primary_domain,
- secondary_domains
+ # Repeat the same supported control until
+ # a failure (Exception) occurs that been
+ # recognized as not an error related to the
+ # supported control (such as ldap.SERVER_DOWN).
+ failed_ok = False
+
+ while not failed_ok:
+ try:
+ exec("""_results = self.%s(
+ %r,
+ scope=%r,
+ filterstr=%r,
+ attrlist=%r,
+ attrsonly=%r,
+ timeout=%r,
+ callback=callback,
+ primary_domain=%r,
+ secondary_domains=%r
+ )""" % (
+ supported_control,
+ base_dn,
+ scope,
+ filterstr,
+ attrlist,
+ attrsonly,
+ timeout,
+ primary_domain,
+ secondary_domains
+ )
)
- )
- break
+ break
- except Exception, errmsg:
- log.error(_("An error occured using %s: %r") % (supported_control, errmsg))
- import traceback
+ except ldap.SERVER_DOWN, errmsg:
+ log.error(_("LDAP server unavailable: %r") % (errmsg))
+ log.error(_("%s") % (traceback.format_exc()))
+ log.error(_("-- reconnecting in 10 seconds."))
- if conf.debuglevel > 8:
- traceback.print_exc()
+ time.sleep(10)
+ self.reconnect()
- log.error(_("%s") % (traceback.format_exc()))
+ except Exception, errmsg:
+ failed_ok = True
+
+ log.error(_("An error occured using %s: %r") % (supported_control, errmsg))
+ log.error(_("%s") % (traceback.format_exc()))
- continue
+ continue
return _results