From 573437511f741cdd9163aefec028894354756365 Mon Sep 17 00:00:00 2001 From: Adam Young Date: Thu, 21 Feb 2013 11:09:57 -0500 Subject: Fix id_to_dn for creating objects Only do the lookup if the scope is not ONELEVEL For ONELEVEL, there is no point in paying the price of the lookup. If the object is not found for scoped queries, return the top level DN so the object can be created. Bug 1131265 Change-Id: I1ca41bf87c3bdea30fbdf607b19192f37dd0bfd6 --- keystone/common/ldap/core.py | 27 +++++++++++++++++---------- keystone/common/ldap/fakeldap.py | 24 +++++++++++++----------- tests/test_backend_ldap.py | 3 --- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py index f9099df7..f0a5cac6 100644 --- a/keystone/common/ldap/core.py +++ b/keystone/common/ldap/core.py @@ -143,19 +143,26 @@ class BaseLdap(object): return conn + def _id_to_dn_string(self, id): + return '%s=%s,%s' % (self.id_attr, + ldap.dn.escape_dn_chars(str(id)), + self.tree_dn) + def _id_to_dn(self, id): + if self.LDAP_SCOPE == ldap.SCOPE_ONELEVEL: + return self._id_to_dn_string(id) 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: + search_result = 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}) + if search_result: + dn, attrs = search_result[0] return dn + else: + return self._id_to_dn_string(id) @staticmethod def _dn_to_id(dn): diff --git a/keystone/common/ldap/fakeldap.py b/keystone/common/ldap/fakeldap.py index f38ad43c..56eedee1 100644 --- a/keystone/common/ldap/fakeldap.py +++ b/keystone/common/ldap/fakeldap.py @@ -41,6 +41,8 @@ SCOPE_NAMES = { LOG = logging.getLogger(__name__) +#Only enable a lower level than WARN if you are actively debugging +LOG.level = logging.WARN def _match_query(query, attrs): @@ -158,19 +160,19 @@ class FakeLdap(object): try: attrs = self.db['%s%s' % (self.__prefix, dn)] except KeyError: - LOG.error(_('FakeLdap bind fail: dn=%s not found'), dn) + LOG.debug(_('FakeLdap bind fail: dn=%s not found'), dn) raise ldap.NO_SUCH_OBJECT db_password = None try: db_password = attrs['userPassword'][0] except (KeyError, IndexError): - LOG.error(_('FakeLdap bind fail: password for dn=%s not found'), + LOG.debug(_('FakeLdap bind fail: password for dn=%s not found'), dn) raise ldap.INAPPROPRIATE_AUTH if not utils.ldap_check_password(password, db_password): - LOG.error(_('FakeLdap bind fail: password for dn=%s does' + LOG.debug(_('FakeLdap bind fail: password for dn=%s does' ' not match') % dn) raise ldap.INVALID_CREDENTIALS @@ -187,7 +189,7 @@ class FakeLdap(object): key = '%s%s' % (self.__prefix, dn) LOG.debug(_('FakeLdap add item: dn=%s, attrs=%s'), dn, attrs) if key in self.db: - LOG.error(_('FakeLdap add item failed: dn=%s is' + LOG.debug(_('FakeLdap add item failed: dn=%s is' ' already in store.'), dn) raise ldap.ALREADY_EXISTS(dn) @@ -205,7 +207,7 @@ class FakeLdap(object): try: del self.db[key] except KeyError: - LOG.error(_('FakeLdap delete item failed: dn=%s not found.'), dn) + LOG.debug(_('FakeLdap delete item failed: dn=%s not found.'), dn) raise ldap.NO_SUCH_OBJECT self.db.sync() @@ -219,7 +221,7 @@ class FakeLdap(object): try: del self.db[key] except KeyError: - LOG.error(_('FakeLdap delete item failed: dn=%s not found.'), dn) + LOG.debug(_('FakeLdap delete item failed: dn=%s not found.'), dn) raise ldap.NO_SUCH_OBJECT self.db.sync() @@ -238,7 +240,7 @@ class FakeLdap(object): try: entry = self.db[key] except KeyError: - LOG.error(_('FakeLdap modify item failed: dn=%s not found.'), dn) + LOG.debug(_('FakeLdap modify item failed: dn=%s not found.'), dn) raise ldap.NO_SUCH_OBJECT for cmd, k, v in attrs: @@ -255,7 +257,7 @@ class FakeLdap(object): elif cmd == ldap.MOD_DELETE: if v is None: if len(values) == 0: - LOG.error(_('FakeLdap modify item failed: ' + LOG.debug(_('FakeLdap modify item failed: ' 'item has no attribute "%s" to delete'), k) raise ldap.NO_SUCH_ATTRIBUTE values[:] = [] @@ -266,12 +268,12 @@ class FakeLdap(object): try: values.remove(val) except ValueError: - LOG.error(_('FakeLdap modify item failed:' + LOG.debug(_('FakeLdap modify item failed:' ' item has no attribute "%s" with' ' value "%s" to delete'), k, val) raise ldap.NO_SUCH_ATTRIBUTE else: - LOG.error(_('FakeLdap modify item failed: unknown' + LOG.debug(_('FakeLdap modify item failed: unknown' ' command %s'), cmd) raise NotImplementedError(_('modify_s action %s not' ' implemented') % cmd) @@ -310,7 +312,7 @@ class FakeLdap(object): for k, v in self.db.iteritems() if re.match('%s\w+=[^,]+,%s' % (self.__prefix, dn), k)] else: - LOG.error('FakeLdap search fail: unknown scope %s', scope) + LOG.debug('FakeLdap search fail: unknown scope %s', scope) raise NotImplementedError(_('Search scope %s not implemented.') % scope) diff --git a/tests/test_backend_ldap.py b/tests/test_backend_ldap.py index d4e96884..72bc09a1 100644 --- a/tests/test_backend_ldap.py +++ b/tests/test_backend_ldap.py @@ -44,9 +44,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): test.testsdir('test_overrides.conf'), test.testsdir('backend_ldap.conf')]) clear_database() - self.stubs.Set(ldap_common.BaseLdap, "_id_to_dn", - lambda self, id: '%s=%s,%s' % (self.id_attr, - str(id), self.tree_dn)) self.identity_api = identity_ldap.Identity() self.load_fixtures(default_fixtures) -- cgit