Changeset View
Changeset View
Standalone View
Standalone View
pykolab/auth/ldap/__init__.py
Show First 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | def authenticate(self, login, realm): | ||||
base_dn = None | base_dn = None | ||||
try: | try: | ||||
base_dn = auth_cache.get_entry(self.domain) | base_dn = auth_cache.get_entry(self.domain) | ||||
except Exception as errmsg: | except Exception as errmsg: | ||||
log.error(_l("Authentication cache failed: %r") % (errmsg)) | log.error(_l("Authentication cache failed: %r") % (errmsg)) | ||||
if base_dn is None: | if base_dn is None: | ||||
config_base_dn = self.config_get('base_dn') | base_dn = self._base_dn() | ||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
try: | try: | ||||
auth_cache.set_entry(self.domain, base_dn) | auth_cache.set_entry(self.domain, base_dn) | ||||
except Exception as errmsg: | except Exception as errmsg: | ||||
log.error(_l("Authentication cache failed: %r") % (errmsg)) | log.error(_l("Authentication cache failed: %r") % (errmsg)) | ||||
try: | try: | ||||
user_filter = self.config_get_raw('user_filter') % ( | user_filter = self.config_get_raw('user_filter') % ( | ||||
▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | def entry_dn(self, entry_id): | ||||
if self._entry_dn(entry_id): | if self._entry_dn(entry_id): | ||||
return entry_id | return entry_id | ||||
if self._entry_dict(entry_id): | if self._entry_dict(entry_id): | ||||
return entry_id['dn'] | return entry_id['dn'] | ||||
unique_attribute = self.config_get('unique_attribute') | unique_attribute = self.config_get('unique_attribute') | ||||
config_base_dn = self.config_get('base_dn') | |||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
_filter = "(%s=%s)" % (unique_attribute, ldap.filter.escape_filter_chars(entry_id)) | _filter = "(%s=%s)" % (unique_attribute, ldap.filter.escape_filter_chars(entry_id)) | ||||
_search = self.ldap.search_ext( | _search = self.ldap.search_ext( | ||||
base_dn, | self._base_dn(), | ||||
ldap.SCOPE_SUBTREE, | ldap.SCOPE_SUBTREE, | ||||
_filter, | _filter, | ||||
['entrydn'] | ['entrydn'] | ||||
) | ) | ||||
( | ( | ||||
_result_type, | _result_type, | ||||
_result_data, | _result_data, | ||||
▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | def find_recipient(self, address="*", exclude_entry_id=None, search_attrs=None): | ||||
else: | else: | ||||
for _address in address: | for _address in address: | ||||
_filter += "(%s=%s)" % (recipient_address_attr, _address) | _filter += "(%s=%s)" % (recipient_address_attr, _address) | ||||
_filter += ")" | _filter += ")" | ||||
_filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) | _filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) | ||||
log.debug(_l("Finding recipient with filter %r") % (_filter), level=8) | base_dn = self._base_dn() | ||||
log.debug(_l("Finding recipient with filter %r in %s") % (_filter, base_dn), level=8) | |||||
if len(_filter) <= 6: | if len(_filter) <= 6: | ||||
return None | return None | ||||
config_base_dn = self.config_get('base_dn') | |||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
_results = self.ldap.search_s( | _results = self.ldap.search_s( | ||||
base_dn, | base_dn, | ||||
scope=ldap.SCOPE_SUBTREE, | scope=ldap.SCOPE_SUBTREE, | ||||
filterstr=_filter, | filterstr=_filter, | ||||
attrlist=result_attributes, | attrlist=result_attributes, | ||||
attrsonly=True | attrsonly=True | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | def find_resource(self, address="*", exclude_entry_id=None): | ||||
else: | else: | ||||
for _address in address: | for _address in address: | ||||
_filter += "(%s=%s)" % (recipient_address_attr, _address) | _filter += "(%s=%s)" % (recipient_address_attr, _address) | ||||
_filter += ")" | _filter += ")" | ||||
_filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) | _filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) | ||||
log.debug(_l("Finding resource with filter %r") % (_filter), level=8) | |||||
if len(_filter) <= 6: | if len(_filter) <= 6: | ||||
return None | return None | ||||
resource_base_dn = self._object_base_dn('resource') | resource_base_dn = self._object_base_dn('resource') | ||||
log.debug(_l("Finding resource with filter %s in %s") % (_filter, resource_base_dn), level=8) | |||||
_results = self.ldap.search_s( | _results = self.ldap.search_s( | ||||
resource_base_dn, | resource_base_dn, | ||||
scope=ldap.SCOPE_SUBTREE, | scope=ldap.SCOPE_SUBTREE, | ||||
filterstr=_filter, | filterstr=_filter, | ||||
attrlist=result_attributes, | attrlist=result_attributes, | ||||
attrsonly=True | attrsonly=True | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 407 Lines • ▼ Show 20 Lines | def reconnect(self): | ||||
if bind is not None: | if bind is not None: | ||||
self._bind(bind['dn'], bind['pw']) | self._bind(bind['dn'], bind['pw']) | ||||
def search_entry_by_attribute(self, attr, value, **kw): | def search_entry_by_attribute(self, attr, value, **kw): | ||||
self._bind() | self._bind() | ||||
_filter = "(%s=%s)" % (attr, ldap.filter.escape_filter_chars(value)) | _filter = "(%s=%s)" % (attr, ldap.filter.escape_filter_chars(value)) | ||||
config_base_dn = self.config_get('base_dn') | base_dn = self._base_dn() | ||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | log.debug(_l("Finding entry %s in %s") % (_filter, base_dn), level=8) | ||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
_results = self._search( | _results = self._search( | ||||
base_dn, | base_dn, | ||||
filterstr=_filter, | filterstr=_filter, | ||||
attrlist=[ | attrlist=[ | ||||
'*', | '*', | ||||
], | ], | ||||
override_search='_regular_search' | override_search='_regular_search' | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | def synchronize(self, mode=0, callback=None): | ||||
modifytimestamp_format | modifytimestamp_format | ||||
) | ) | ||||
else: | else: | ||||
modified_after = self.get_latest_sync_timestamp() | modified_after = self.get_latest_sync_timestamp() | ||||
_filter = "(&%s(modifytimestamp>=%s))" % (_filter, modified_after) | _filter = "(&%s(modifytimestamp>=%s))" % (_filter, modified_after) | ||||
log.debug(_l("Synchronization is using filter %r") % (_filter), level=8) | |||||
if mode != 0: | if mode != 0: | ||||
override_search = mode | override_search = mode | ||||
else: | else: | ||||
override_search = False | override_search = False | ||||
config_base_dn = self.config_get('base_dn') | base_dn = self._base_dn() | ||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
log.debug(_l("Synchronization is searching against base DN: %s") % (base_dn), level=8) | log.debug(_l("Synchronization is searching for %s in %s") % (_filter, base_dn), level=8) | ||||
if callback is None: | if callback is None: | ||||
callback = self._synchronize_callback | callback = self._synchronize_callback | ||||
try: | try: | ||||
self._search( | self._search( | ||||
base_dn, | base_dn, | ||||
filterstr=_filter, | filterstr=_filter, | ||||
▲ Show 20 Lines • Show All 1,065 Lines • ▼ Show 20 Lines | |||||
def _entry_type(self, entry_id): | def _entry_type(self, entry_id): | ||||
""" | """ | ||||
Return the type of object for an entry. | Return the type of object for an entry. | ||||
""" | """ | ||||
self._bind() | self._bind() | ||||
entry_dn = self.entry_dn(entry_id) | entry_dn = self.entry_dn(entry_id) | ||||
base_dn = self._base_dn() | |||||
config_base_dn = self.config_get('base_dn') | |||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
for _type in ['user', 'group', 'sharedfolder']: | for _type in ['user', 'group', 'sharedfolder']: | ||||
__filter = self.config_get('kolab_%s_filter' % (_type)) | __filter = self.config_get('kolab_%s_filter' % (_type)) | ||||
if __filter is None: | if __filter is None: | ||||
__filter = self.config_get('%s_filter' % (_type)) | __filter = self.config_get('%s_filter' % (_type)) | ||||
if __filter is not None: | if __filter is not None: | ||||
try: | try: | ||||
Show All 9 Lines | def _entry_type(self, entry_id): | ||||
if not result: | if not result: | ||||
continue | continue | ||||
else: | else: | ||||
return _type | return _type | ||||
return None | return None | ||||
def _find_user_dn(self, login, kolabuser=False): | def _find_user_dn(self, login, kolabuser=False, domain=None): | ||||
""" | """ | ||||
Find the distinguished name (DN) for a (Kolab) user entry in LDAP. | Find the distinguished name (DN) for a (Kolab) user entry in LDAP. | ||||
""" | """ | ||||
conf_prefix = 'kolab_' if kolabuser else '' | conf_prefix = 'kolab_' if kolabuser else '' | ||||
user_base_dn = self._object_base_dn('user', conf_prefix) | user_base_dn = self._object_base_dn('user', conf_prefix, domain) | ||||
auth_attrs = self.config_get_list('auth_attributes') | auth_attrs = self.config_get_list('auth_attributes') | ||||
auth_search_filter = ['(|'] | auth_search_filter = ['(|'] | ||||
for auth_attr in auth_attrs: | for auth_attr in auth_attrs: | ||||
auth_search_filter.append('(%s=%s)' % (auth_attr, login)) | auth_search_filter.append('(%s=%s)' % (auth_attr, login)) | ||||
if '@' not in login: | if '@' not in login: | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | def _list_domains(self, domain=None): | ||||
secondary_domains = [x.lower() for x in domain_attrs[dna]] | secondary_domains = [x.lower() for x in domain_attrs[dna]] | ||||
else: | else: | ||||
primary_domain = domain_attrs[dna].lower() | primary_domain = domain_attrs[dna].lower() | ||||
domains.append((primary_domain, secondary_domains)) | domains.append((primary_domain, secondary_domains)) | ||||
return domains | return domains | ||||
def _object_base_dn(self, objectType, prefix=''): | def _object_base_dn(self, objectType, prefix='', domain=None): | ||||
""" | """ | ||||
Get configured base DN for specified Kolab object type | Get configured base DN for specified Kolab object type | ||||
""" | """ | ||||
object_base_dn = self.config_get(prefix + objectType + '_base_dn') | object_base_dn = self.config_get_raw(prefix + objectType + '_base_dn') | ||||
config_base_dn = self.config_get('base_dn') | base_dn = self._base_dn(domain) | ||||
ldap_base_dn = self._kolab_domain_root_dn(self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
base_dn = ldap_base_dn | |||||
else: | |||||
base_dn = config_base_dn | |||||
if object_base_dn is None: | if object_base_dn is None: | ||||
object_base_dn = base_dn | object_base_dn = base_dn | ||||
else: | else: | ||||
object_base_dn = object_base_dn % ({'base_dn': base_dn}) | object_base_dn = object_base_dn % ({'base_dn': base_dn}) | ||||
return object_base_dn | return object_base_dn | ||||
def _base_dn(self, domain=None): | |||||
config_base_dn = self.config_get('base_dn') | |||||
ldap_base_dn = self._kolab_domain_root_dn(domain if domain is not None else self.domain) | |||||
if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: | |||||
return ldap_base_dn | |||||
return config_base_dn | |||||
def _synchronize_callback(self, *args, **kw): | def _synchronize_callback(self, *args, **kw): | ||||
""" | """ | ||||
Determine the characteristics of the callback being placed, and | Determine the characteristics of the callback being placed, and | ||||
what data is contained within *args and **kw exactly. | what data is contained within *args and **kw exactly. | ||||
The exact form and shape of the feedback very much depends on the | The exact form and shape of the feedback very much depends on the | ||||
supportedControl used to even get the data. | supportedControl used to even get the data. | ||||
""" | """ | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | ): | ||||
ldap.controls.psearch.PersistentSearchControl( | ldap.controls.psearch.PersistentSearchControl( | ||||
criticality=True, | criticality=True, | ||||
changeTypes=['add', 'delete', 'modify', 'modDN'], | changeTypes=['add', 'delete', 'modify', 'modDN'], | ||||
changesOnly=False, | changesOnly=False, | ||||
returnECs=True | returnECs=True | ||||
) | ) | ||||
) | ) | ||||
log.debug(_l("Searching with filter %r in %s") % (filterstr, base_dn), level=8) | |||||
_search = self.ldap.search_ext( | _search = self.ldap.search_ext( | ||||
base_dn, | base_dn, | ||||
scope=scope, | scope=scope, | ||||
filterstr=filterstr, | filterstr=filterstr, | ||||
attrlist=attrlist, | attrlist=attrlist, | ||||
attrsonly=attrsonly, | attrsonly=attrsonly, | ||||
timeout=timeout, | timeout=timeout, | ||||
serverctrls=psearch_server_controls | serverctrls=psearch_server_controls | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | def _paged_search( | ||||
secondary_domains=[] | secondary_domains=[] | ||||
): | ): | ||||
page_size = 500 | page_size = 500 | ||||
_results = [] | _results = [] | ||||
server_page_control = ldap.controls.libldap.SimplePagedResultsControl(size=page_size,cookie='') | server_page_control = ldap.controls.libldap.SimplePagedResultsControl(size=page_size,cookie='') | ||||
log.debug(_l("Searching for %r in %s") % (filterstr, base_dn), level=8) | |||||
_search = self.ldap.search_ext( | _search = self.ldap.search_ext( | ||||
base_dn, | base_dn, | ||||
scope=scope, | scope=scope, | ||||
filterstr=filterstr, | filterstr=filterstr, | ||||
attrlist=attrlist, | attrlist=attrlist, | ||||
attrsonly=attrsonly, | attrsonly=attrsonly, | ||||
serverctrls=[server_page_control] | serverctrls=[server_page_control] | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | def _regular_search( | ||||
callback=False, | callback=False, | ||||
primary_domain=None, | primary_domain=None, | ||||
secondary_domains=[] | secondary_domains=[] | ||||
): | ): | ||||
if timeout is None: | if timeout is None: | ||||
timeout = float(self.config_get('ldap', 'timeout', default=10)) | timeout = float(self.config_get('ldap', 'timeout', default=10)) | ||||
log.debug(_l("Searching with filter %r") % (filterstr), level=8) | log.debug(_l("Searching for %r in %s") % (filterstr, base_dn), level=8) | ||||
_search = self.ldap.search( | _search = self.ldap.search( | ||||
base_dn, | base_dn, | ||||
scope=scope, | scope=scope, | ||||
filterstr=filterstr, | filterstr=filterstr, | ||||
attrlist=attrlist, | attrlist=attrlist, | ||||
attrsonly=attrsonly | attrsonly=attrsonly | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 175 Lines • Show Last 20 Lines |