diff options
author | Ionuț Arțăriși <iartarisi@suse.cz> | 2013-02-11 17:15:23 +0100 |
---|---|---|
committer | Ionuț Arțăriși <iartarisi@suse.cz> | 2013-02-18 17:02:44 +0100 |
commit | 159ffe48e986e524f5930ad41d376bdce2b6a07e (patch) | |
tree | eddb5a177f2b29265b687087a2411608a832737e /keystone/common | |
parent | 63f6e87c5e267a015f4d6054c0941c0efc8526f1 (diff) | |
download | keystone-159ffe48e986e524f5930ad41d376bdce2b6a07e.tar.gz keystone-159ffe48e986e524f5930ad41d376bdce2b6a07e.tar.xz keystone-159ffe48e986e524f5930ad41d376bdce2b6a07e.zip |
make LDAP query scope configurable
Get the DN from the LDAP server itself rather than hardcoding its format.
Fixes bug 1122181
Change-Id: I6f70c480b5c6f1b064e74d3cbd2cd8ca5ee82b0a
Diffstat (limited to 'keystone/common')
-rw-r--r-- | keystone/common/ldap/core.py | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py index eca2084d..2c1d0817 100644 --- a/keystone/common/ldap/core.py +++ b/keystone/common/ldap/core.py @@ -26,6 +26,8 @@ LOG = logging.getLogger(__name__) LDAP_VALUES = {'TRUE': True, 'FALSE': False} CONTROL_TREEDELETE = '1.2.840.113556.1.4.805' +LDAP_SCOPES = {'one': ldap.SCOPE_ONELEVEL, + 'sub': ldap.SCOPE_SUBTREE} def py2ldap(val): @@ -59,6 +61,14 @@ def safe_iter(attrs): yield attrs +def ldap_scope(scope): + try: + return LDAP_SCOPES[scope] + except KeyError: + raise ValueError(_('Invalid LDAP scope: %s. Choose one of: ' % scope) + + ', '.join(LDAP_SCOPES.keys())) + + class BaseLdap(object): DEFAULT_SUFFIX = "dc=example,dc=com" DEFAULT_OU = None @@ -77,6 +87,7 @@ class BaseLdap(object): self.LDAP_URL = conf.ldap.url self.LDAP_USER = conf.ldap.user self.LDAP_PASSWORD = conf.ldap.password + self.LDAP_SCOPE = ldap_scope(conf.ldap.query_scope) if self.options_name is not None: self.suffix = conf.ldap.suffix @@ -133,9 +144,18 @@ class BaseLdap(object): return conn def _id_to_dn(self, id): - return '%s=%s,%s' % (self.id_attr, - ldap.dn.escape_dn_chars(str(id)), - self.tree_dn) + conn = self.get_connection() + try: + dn, attrs = conn.search_s( + self.tree_dn, self.LDAP_SCOPE, + '(&(%(id_attr)s=%(id)s)(objectclass=%(objclass)s))' % + {'id_attr': self.id_attr, + 'id': ldap.filter.escape_filter_chars(str(id)), + 'objclass': self.object_class})[0] + except ValueError, IndexError: + raise ldap.NO_SUCH_OBJECT + else: + return dn @staticmethod def _dn_to_id(dn): @@ -203,16 +223,18 @@ class BaseLdap(object): def _ldap_get(self, id, filter=None): conn = self.get_connection() - query = '(&%s(objectClass=%s))' % (filter or self.filter or '', - self.object_class) + query = ('(&(%(id_attr)s=%(id)s)' + '%(filter)s' + '(objectClass=%(object_class)s))' + % {'id_attr': self.id_attr, + 'id': ldap.filter.escape_filter_chars(str(id)), + 'filter': (filter or self.filter or ''), + 'object_class': self.object_class}) try: - res = conn.search_s(self._id_to_dn(id), - ldap.SCOPE_BASE, - query, + res = conn.search_s(self.tree_dn, self.LDAP_SCOPE, query, self.attribute_mapping.values()) except ldap.NO_SUCH_OBJECT: return None - try: return res[0] except IndexError: @@ -224,7 +246,7 @@ class BaseLdap(object): self.object_class) try: return conn.search_s(self.tree_dn, - ldap.SCOPE_ONELEVEL, + self.LDAP_SCOPE, query, self.attribute_mapping.values()) except ldap.NO_SUCH_OBJECT: |