diff --git a/etc/keystone.conf.sample b/etc/keystone.conf.sample index 96369b580c..2bfd21edac 100644 --- a/etc/keystone.conf.sample +++ b/etc/keystone.conf.sample @@ -831,6 +831,12 @@ # dereferencing configured by your ldap.conf. (string value) #alias_dereferencing=default +# Sets the LDAP debugging level for LDAP calls. A value of 0 +# means that debugging is not enabled. This value is a +# bitmask, consult your LDAP documentation for possible +# values. (integer value) +#debug_level= + # Override the system's default referral chasing behavior for # queries. (boolean value) #chase_referrals= diff --git a/keystone/common/config.py b/keystone/common/config.py index f7d6635e66..e936973f70 100644 --- a/keystone/common/config.py +++ b/keystone/common/config.py @@ -440,6 +440,11 @@ FILE_OPTIONS = { '"finding" or "default". The "default" option falls ' 'back to using default dereferencing configured by ' 'your ldap.conf.'), + cfg.IntOpt('debug_level', default=None, + help='Sets the LDAP debugging level for LDAP calls. ' + 'A value of 0 means that debugging is not enabled. ' + 'This value is a bitmask, consult your LDAP ' + 'documentation for possible values.'), cfg.BoolOpt('chase_referrals', default=None, help='Override the system\'s default referral chasing ' 'behavior for queries.'), diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py index fd452c1860..625ac2dd03 100644 --- a/keystone/common/ldap/core.py +++ b/keystone/common/ldap/core.py @@ -239,7 +239,7 @@ class LDAPHandler(object): @abc.abstractmethod def connect(self, url, page_size=0, alias_dereferencing=None, use_tls=False, tls_cacertfile=None, tls_cacertdir=None, - tls_req_cert='demand', chase_referrals=None): + tls_req_cert='demand', chase_referrals=None, debug_level=None): raise exception.NotImplemented() @abc.abstractmethod @@ -307,16 +307,15 @@ class PythonLDAPHandler(LDAPHandler): def connect(self, url, page_size=0, alias_dereferencing=None, use_tls=False, tls_cacertfile=None, tls_cacertdir=None, - tls_req_cert='demand', chase_referrals=None): + tls_req_cert='demand', chase_referrals=None, debug_level=None): LOG.debug("LDAP init: url=%s", url) LOG.debug('LDAP init: use_tls=%s tls_cacertfile=%s tls_cacertdir=%s ' 'tls_req_cert=%s tls_avail=%s', use_tls, tls_cacertfile, tls_cacertdir, tls_req_cert, ldap.TLS_AVAIL) - # NOTE(topol) - # for extra debugging uncomment the following line - # ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095) + if debug_level is not None: + ldap.set_option(ldap.OPT_DEBUG_LEVEL, debug_level) using_ldaps = url.lower().startswith("ldaps") @@ -453,10 +452,11 @@ class KeystoneLDAPHandler(LDAPHandler): def connect(self, url, page_size=0, alias_dereferencing=None, use_tls=False, tls_cacertfile=None, tls_cacertdir=None, - tls_req_cert='demand', chase_referrals=None): + tls_req_cert='demand', chase_referrals=None, debug_level=None): return self.conn.connect(url, page_size, alias_dereferencing, use_tls, tls_cacertfile, tls_cacertdir, - tls_req_cert, chase_referrals) + tls_req_cert, chase_referrals, + debug_level=debug_level) def set_option(self, option, invalue): return self.conn.set_option(option, invalue) @@ -687,6 +687,7 @@ class BaseLdap(object): self.tls_req_cert = parse_tls_cert(conf.ldap.tls_req_cert) self.attribute_mapping = {} self.chase_referrals = conf.ldap.chase_referrals + self.debug_level = conf.ldap.debug_level if self.options_name is not None: self.suffix = conf.ldap.suffix @@ -776,7 +777,8 @@ class BaseLdap(object): tls_cacertfile=self.tls_cacertfile, tls_cacertdir=self.tls_cacertdir, tls_req_cert=self.tls_req_cert, - chase_referrals=self.chase_referrals) + chase_referrals=self.chase_referrals, + debug_level=self.debug_level) if user is None: user = self.LDAP_USER diff --git a/keystone/tests/fakeldap.py b/keystone/tests/fakeldap.py index 77ac3f6a20..5118f5ee5d 100644 --- a/keystone/tests/fakeldap.py +++ b/keystone/tests/fakeldap.py @@ -194,7 +194,7 @@ class FakeLdap(core.LDAPHandler): def connect(self, url, page_size=0, alias_dereferencing=None, use_tls=False, tls_cacertfile=None, tls_cacertdir=None, - tls_req_cert='demand', chase_referrals=None): + tls_req_cert='demand', chase_referrals=None, debug_level=None): if url.startswith('fake://memory'): if url not in FakeShelves: FakeShelves[url] = FakeShelve() diff --git a/keystone/tests/test_backend_ldap.py b/keystone/tests/test_backend_ldap.py index 70627b776a..538ef063ba 100644 --- a/keystone/tests/test_backend_ldap.py +++ b/keystone/tests/test_backend_ldap.py @@ -973,6 +973,21 @@ class LDAPIdentity(BaseLDAPIdentity, tests.TestCase): # is as expected. self.assertTrue(mocked_fakeldap.call_args[-1]['chase_referrals']) + @mock.patch.object(common_ldap_core.KeystoneLDAPHandler, 'connect') + def test_debug_level_set(self, mocked_fakeldap): + level = 12345 + self.config_fixture.config( + group='ldap', + url='fake://memory', + debug_level=level) + user_api = identity.backends.ldap.UserApi(CONF) + user_api.get_connection(user=None, password=None) + + # The last call_arg should be a dictionary and should contain + # debug_level. Check to make sure the value of debug_level + # is as expected. + self.assertEqual(level, mocked_fakeldap.call_args[-1]['debug_level']) + def test_wrong_ldap_scope(self): self.config_fixture.config(group='ldap', query_scope=uuid.uuid4().hex) self.assertRaisesRegexp(