summaryrefslogtreecommitdiffstats
path: root/pykolab
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2016-05-07 13:05:33 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2016-05-07 13:05:33 +0200
commit39e31385df84f1d46576ecc8461ab1d0177de1e7 (patch)
tree01e333a9e01a706d58169535864f2e396387cac9 /pykolab
parentce96bb25f424f88ac3a4843c0c9381eb820649d2 (diff)
downloadpykolab-39e31385df84f1d46576ecc8461ab1d0177de1e7.tar.gz
Fix binding current user after LDAP reconnection (T1171)
Summary: Fixes T1171 Reviewers: #pykolab_developers, vanmeeuwen Maniphest Tasks: T1171 Differential Revision: https://git.kolab.org/D126
Diffstat (limited to 'pykolab')
-rw-r--r--pykolab/auth/ldap/__init__.py89
1 files changed, 45 insertions, 44 deletions
diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index ac9dfe9..d40a118 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -116,7 +116,8 @@ class LDAP(pykolab.base.Base):
pykolab.base.Base.__init__(self, domain=domain)
self.ldap = None
- self.bind = False
+ self.bind = None
+
if domain == None:
self.domain = conf.get('kolab', 'primary_domain')
else:
@@ -225,13 +226,9 @@ class LDAP(pykolab.base.Base):
(entry_dn, entry_attrs) = _result_data[0]
try:
- log.debug(_("Binding with user_dn %s and password %s")
- % (entry_dn, '*' * len(login[1])))
-
# Needs to be synchronous or succeeds and continues setting retval
# to True!!
- self.ldap.simple_bind_s(entry_dn, login[1])
- retval = True
+ retval = self._bind(entry_dn, login[1])
try:
auth_cache.set_entry(_filter, entry_dn)
except Exception, errmsg:
@@ -255,18 +252,14 @@ class LDAP(pykolab.base.Base):
retval = False
else:
try:
- log.debug(_("Binding with user_dn %s and password %s")
- % (entry_dn, '*' * len(login[1])))
-
# Needs to be synchronous or succeeds and continues setting retval
# to True!!
- self.ldap.simple_bind_s(entry_dn, login[1])
+ retval = self._bind(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
+ self.bind = None
try:
auth_cache.del_entry(_filter)
except:
@@ -981,8 +974,11 @@ class LDAP(pykolab.base.Base):
return entry_modifications
def reconnect(self):
+ bind = self.bind
self._disconnect()
self.connect()
+ if bind is not None:
+ self._bind(bind['dn'], bind['pw'])
def search_entry_by_attribute(self, attr, value, **kw):
self._bind()
@@ -1006,13 +1002,15 @@ class LDAP(pykolab.base.Base):
override_search='_regular_search'
)
-
def set_entry_attribute(self, entry_id, attribute, value):
log.debug(_("Setting entry attribute %r to %r for %r") % (attribute, value, entry_id), level=9)
self.set_entry_attributes(entry_id, { attribute: value })
def set_entry_attributes(self, entry_id, attributes):
- self._bind()
+ bind_dn = self.config_get('bind_dn')
+ bind_pw = self.config_get('bind_pw')
+
+ self._bind(bind_dn, bind_pw)
entry_dn = self.entry_dn(entry_id)
@@ -1046,6 +1044,9 @@ class LDAP(pykolab.base.Base):
except:
log.error(_("Could not update dn %r:\n%r") % (dn, modlist))
+ # Drop the privileges
+ self._unbind()
+
def synchronize(self, mode=0, callback=None):
"""
Synchronize with LDAP
@@ -1183,26 +1184,45 @@ class LDAP(pykolab.base.Base):
### API depth level increasing!
###
- def _bind(self):
- if self.ldap == None:
+ def _bind(self, bind_dn=None, bind_pw=None):
+ # If we have no LDAP, we have no previous state.
+ if self.ldap is None:
+ self.bind = None
self.connect()
- if not self.bind:
- bind_dn = self.config_get('bind_dn')
- bind_pw = self.config_get('bind_pw')
+ # If we are to bind as foo, we have no state.
+ if bind_dn is not None:
+ self.bind = None
+
+ # Only if we have no state and no bind credentials specified in the
+ # function call.
+ if self.bind is None:
+
+ if bind_dn is None:
+ bind_dn = self.config_get('service_bind_dn')
+
+ if bind_pw is None:
+ bind_pw = self.config_get('service_bind_pw')
+
+ if bind_dn is not None:
+ log.debug(_("Binding with bind_dn: %s and password: %s")
+ % (bind_dn, '*' * len(bind_pw)))
# TODO: Binding errors control
try:
self.ldap.simple_bind_s(bind_dn, bind_pw)
- self.bind = True
+ self.bind = {'dn': bind_dn, 'pw': bind_pw}
+ return True
except ldap.SERVER_DOWN, errmsg:
log.error(_("LDAP server unavailable: %r") % (errmsg))
log.error(_("%s") % (traceback.format_exc()))
+ return False
except ldap.INVALID_CREDENTIALS:
log.error(_("Invalid DN, username and/or password."))
-
+ return False
else:
- log.debug(_("_bind called, but already bound"), level=9)
+ log.debug(_("bind() called but already bound"), level=8)
+ return True
def _change_add_group(self, entry, change):
"""
@@ -1979,7 +1999,7 @@ class LDAP(pykolab.base.Base):
self._unbind()
del self.ldap
self.ldap = None
- self.bind = False
+ self.bind = None
def _domain_naming_context(self, domain):
self._bind()
@@ -2172,11 +2192,7 @@ class LDAP(pykolab.base.Base):
log.debug(_("Finding domain root dn for domain %s") % (domain), level=8)
- bind_dn = conf.get('ldap', 'bind_dn')
- bind_pw = conf.get('ldap', 'bind_pw')
-
domain_base_dn = conf.get('ldap', 'domain_base_dn', quiet=True)
-
domain_filter = conf.get('ldap', 'domain_filter')
if not domain_filter == None:
@@ -2257,9 +2273,7 @@ class LDAP(pykolab.base.Base):
log.debug(_("Listing domains..."), level=8)
self.connect()
-
- bind_dn = conf.get('ldap', 'bind_dn')
- bind_pw = conf.get('ldap', 'bind_pw')
+ self._bind()
domain_base_dn = conf.get('ldap', 'domain_base_dn', quiet=True)
@@ -2277,12 +2291,6 @@ class LDAP(pykolab.base.Base):
if domain_base_dn == None or domain_filter == None:
return []
- # TODO: this function should be wrapped for error handling
- try:
- self.ldap.simple_bind_s(bind_dn, bind_pw)
- except ldap.SERVER_DOWN, e:
- raise AuthBackendError, _("Authentication database DOWN")
-
dna = self.config_get('domain_name_attribute')
if dna == None:
dna = 'associateddomain'
@@ -2319,13 +2327,6 @@ class LDAP(pykolab.base.Base):
return domains
- def _reconnect(self):
- """
- Reconnect to LDAP
- """
- self._disconnect()
- self.connect()
-
def _synchronize_callback(self, *args, **kw):
"""
Determine the characteristics of the callback being placed, and
@@ -2446,7 +2447,7 @@ class LDAP(pykolab.base.Base):
"""
self.ldap.unbind()
- self.bind = False
+ self.bind = None
###
### Backend search functions