Changeset View
Changeset View
Standalone View
Standalone View
pykolab/auth/ldap/__init__.py
Show First 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | class LDAP(pykolab.base.Base): | ||||
def __init__(self, domain=None): | def __init__(self, domain=None): | ||||
""" | """ | ||||
Initialize the LDAP object for domain. If no domain is specified, | Initialize the LDAP object for domain. If no domain is specified, | ||||
domain name space configured as 'kolab'.'primary_domain' is used. | domain name space configured as 'kolab'.'primary_domain' is used. | ||||
""" | """ | ||||
pykolab.base.Base.__init__(self, domain=domain) | pykolab.base.Base.__init__(self, domain=domain) | ||||
self.ldap = None | self.ldap = None | ||||
self.ldap_priv = None | |||||
self.bind = None | self.bind = None | ||||
if domain == None: | if domain == None: | ||||
self.domain = conf.get('kolab', 'primary_domain') | self.domain = conf.get('kolab', 'primary_domain') | ||||
else: | else: | ||||
self.domain = domain | self.domain = domain | ||||
def authenticate(self, login, realm): | def authenticate(self, login, realm): | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | def authenticate(self, login, realm): | ||||
) | ) | ||||
except: | except: | ||||
pass | pass | ||||
retval = False | retval = False | ||||
return retval | return retval | ||||
def connect(self): | def connect(self, priv=None): | ||||
""" | """ | ||||
Connect to the LDAP server through the uri configured. | Connect to the LDAP server through the uri configured. | ||||
""" | """ | ||||
if not self.ldap == None: | if priv is None and self.ldap is not None: | ||||
return | |||||
if priv is not None and self.ldap_priv is not None: | |||||
return | return | ||||
log.debug(_("Connecting to LDAP..."), level=8) | log.debug(_("Connecting to LDAP..."), level=8) | ||||
uri = self.config_get('ldap_uri') | uri = self.config_get('ldap_uri') | ||||
log.debug(_("Attempting to use LDAP URI %s") % (uri), level=8) | log.debug(_("Attempting to use LDAP URI %s") % (uri), level=8) | ||||
trace_level = 0 | trace_level = 0 | ||||
if conf.debuglevel > 8: | if conf.debuglevel > 8: | ||||
trace_level = 1 | trace_level = 1 | ||||
self.ldap = ldap.ldapobject.ReconnectLDAPObject( | conn = ldap.ldapobject.ReconnectLDAPObject( | ||||
uri, | uri, | ||||
trace_level=trace_level, | trace_level=trace_level, | ||||
retry_max=200, | retry_max=200, | ||||
retry_delay=3.0 | retry_delay=3.0 | ||||
) | ) | ||||
self.ldap.protocol_version = 3 | conn.protocol_version = 3 | ||||
self.ldap.supported_controls = [] | conn.supported_controls = [] | ||||
if priv is None: | |||||
self.ldap = conn | |||||
else: | |||||
self.ldap_priv = conn | |||||
def entry_dn(self, entry_id): | def entry_dn(self, entry_id): | ||||
""" | """ | ||||
Get a entry's distinguished name for an entry ID. | Get a entry's distinguished name for an entry ID. | ||||
The entry ID may be any of: | The entry ID may be any of: | ||||
- an entry's value for the configured unique_attribute, | - an entry's value for the configured unique_attribute, | ||||
▲ Show 20 Lines • Show All 754 Lines • ▼ Show 20 Lines | def search_entry_by_attribute(self, attr, value, **kw): | ||||
override_search='_regular_search' | override_search='_regular_search' | ||||
) | ) | ||||
def set_entry_attribute(self, entry_id, attribute, value): | 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) | log.debug(_("Setting entry attribute %r to %r for %r") % (attribute, value, entry_id), level=9) | ||||
self.set_entry_attributes(entry_id, { attribute: value }) | self.set_entry_attributes(entry_id, { attribute: value }) | ||||
def set_entry_attributes(self, entry_id, attributes): | def set_entry_attributes(self, entry_id, attributes): | ||||
bind_dn = self.config_get('bind_dn') | self._bind() | ||||
bind_pw = self.config_get('bind_pw') | |||||
self._bind(bind_dn, bind_pw) | |||||
entry_dn = self.entry_dn(entry_id) | entry_dn = self.entry_dn(entry_id) | ||||
entry = self.get_entry_attributes(entry_dn, ['*']) | entry = self.get_entry_attributes(entry_dn, ['*']) | ||||
attrs = {} | attrs = {} | ||||
for attribute in attributes.keys(): | for attribute in attributes.keys(): | ||||
Show All 11 Lines | def set_entry_attributes(self, entry_id, attributes): | ||||
elif entry.has_key(attribute) and not entry[attribute] == None: | elif entry.has_key(attribute) and not entry[attribute] == None: | ||||
if attrs[attribute] == None: | if attrs[attribute] == None: | ||||
modlist.append((ldap.MOD_DELETE, attribute, entry[attribute])) | modlist.append((ldap.MOD_DELETE, attribute, entry[attribute])) | ||||
else: | else: | ||||
modlist.append((ldap.MOD_REPLACE, attribute, attrs[attribute])) | modlist.append((ldap.MOD_REPLACE, attribute, attrs[attribute])) | ||||
dn = entry_dn | dn = entry_dn | ||||
if len(modlist) > 0: | if len(modlist) > 0 and self._bind_priv() is True: | ||||
try: | try: | ||||
self.ldap.modify_s(dn, modlist) | self.ldap_priv.modify_s(dn, modlist) | ||||
except: | except: | ||||
log.error(_("Could not update dn %r:\n%r") % (dn, modlist)) | log.error(_("Could not update dn %r:\n%r") % (dn, modlist)) | ||||
# Drop the privileges | |||||
self._unbind() | |||||
def synchronize(self, mode=0, callback=None): | def synchronize(self, mode=0, callback=None): | ||||
""" | """ | ||||
Synchronize with LDAP | Synchronize with LDAP | ||||
""" | """ | ||||
self._bind() | self._bind() | ||||
_filter = self._kolab_filter() | _filter = self._kolab_filter() | ||||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | def _bind(self, bind_dn=None, bind_pw=None): | ||||
return False | return False | ||||
except ldap.INVALID_CREDENTIALS: | except ldap.INVALID_CREDENTIALS: | ||||
log.error(_("Invalid DN, username and/or password.")) | log.error(_("Invalid DN, username and/or password.")) | ||||
return False | return False | ||||
else: | else: | ||||
log.debug(_("bind() called but already bound"), level=8) | log.debug(_("bind() called but already bound"), level=8) | ||||
return True | return True | ||||
def _bind_priv(self): | |||||
if self.ldap_priv is None: | |||||
self.connect(True) | |||||
bind_dn = self.config_get('bind_dn') | |||||
bind_pw = self.config_get('bind_pw') | |||||
try: | |||||
self.ldap_priv.simple_bind_s(bind_dn, 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_priv() called but already bound"), level=8) | |||||
return True | |||||
def _change_add_group(self, entry, change): | def _change_add_group(self, entry, change): | ||||
""" | """ | ||||
An entry of type group was added. | An entry of type group was added. | ||||
The Kolab daemon has little to do for this type of action on this | The Kolab daemon has little to do for this type of action on this | ||||
type of entry. | type of entry. | ||||
""" | """ | ||||
pass | pass | ||||
▲ Show 20 Lines • Show All 756 Lines • ▼ Show 20 Lines | def _change_none_user(self, entry, change): | ||||
log.warning( | log.warning( | ||||
_("Kolab user %s does not have a result attribute %r") % ( | _("Kolab user %s does not have a result attribute %r") % ( | ||||
entry['id'], | entry['id'], | ||||
result_attribute | result_attribute | ||||
) | ) | ||||
) | ) | ||||
def _disconnect(self): | def _disconnect(self): | ||||
self._unbind() | |||||
del self.ldap | del self.ldap | ||||
del self.ldap_priv | |||||
self.ldap = None | self.ldap = None | ||||
self.ldap_priv = None | |||||
self.bind = None | self.bind = None | ||||
def _domain_naming_context(self, domain): | def _domain_naming_context(self, domain): | ||||
self._bind() | self._bind() | ||||
# The list of naming contexts in the LDAP server | # The list of naming contexts in the LDAP server | ||||
attrs = self.get_entry_attributes("", ['namingContexts']) | attrs = self.get_entry_attributes("", ['namingContexts']) | ||||
▲ Show 20 Lines • Show All 423 Lines • ▼ Show 20 Lines | |||||
# | # | ||||
# if not self.imap.user_mailbox_exists(entry[result_attribute]): | # if not self.imap.user_mailbox_exists(entry[result_attribute]): | ||||
# folder = self.imap.user_mailbox_create( | # folder = self.imap.user_mailbox_create( | ||||
# entry[result_attribute] | # entry[result_attribute] | ||||
# ) | # ) | ||||
# | # | ||||
# server = self.imap.user_mailbox_server(folder) | # server = self.imap.user_mailbox_server(folder) | ||||
def _unbind(self): | |||||
""" | |||||
Discard the current set of bind credentials. | |||||
Virtually disconnects the LDAP connection, and should be followed by | |||||
a call to _bind() afterwards. | |||||
""" | |||||
self.ldap.unbind() | |||||
self.bind = None | |||||
### | ### | ||||
### Backend search functions | ### Backend search functions | ||||
### | ### | ||||
def _persistent_search(self, | def _persistent_search(self, | ||||
base_dn, | base_dn, | ||||
scope=ldap.SCOPE_SUBTREE, | scope=ldap.SCOPE_SUBTREE, | ||||
filterstr="(objectClass=*)", | filterstr="(objectClass=*)", | ||||
▲ Show 20 Lines • Show All 411 Lines • Show Last 20 Lines |