LDAP attribute names non-case-sensitive
keystone was not able to find any users while the LDAP user name attribute was configured to "samaccountname", but could find users when reconfigured to use "sAMAccountName". LDAP is not supposed to be case-sensitive, so either should work. This patch addresses the above problem by making both the attributes into lower case. Also updated the ldap_result example supporting python3. Change-Id: I51813ac41489baed04f3cadbccd748e03025313e Closes-Bug: #1753585
This commit is contained in:
parent
50698fd128
commit
816b472a9d
@ -1402,20 +1402,31 @@ class BaseLdap(object):
|
||||
raise ValueError('"%(attr)s" is not a valid value for'
|
||||
' "%(attr_name)s"' % {'attr': attr,
|
||||
'attr_name': attr_name})
|
||||
|
||||
# consider attr = "cn" and
|
||||
# ldap_result = [{'uid': ['fake_id1']}, , 'cN': ["name"]}]
|
||||
# doing lower case on both user_name_attribute and ldap users
|
||||
# attribute
|
||||
result = []
|
||||
# consider attr = "cn" and
|
||||
# ldap_result = [{'uid': ['fake_id1']},
|
||||
# {'uid': ['fake_id2'], 'cn': [' ']},
|
||||
# {'uid': ['fake_id3'], 'cn': ['']},
|
||||
# {'uid': ['fake_id4'], 'cn': []},
|
||||
# {'uid': ['fake_id5'], 'cn': ["name"]}]
|
||||
# ldap_result = [(u'cn=fake1,o=ex_domain', {'uid': ['fake_id1']}),
|
||||
# (u'cn=fake2,o=ex_domain', {'uid': ['fake_id2'],
|
||||
# 'cn': [' ']}),
|
||||
# (u'cn=fake3,o=ex_domain', {'uid': ['fake_id3'],
|
||||
# 'cn': ['']}),
|
||||
# (u'cn=fake4,o=ex_domain', {'uid': ['fake_id4'],
|
||||
# 'cn': []}),
|
||||
# (u'cn=fake5,o=ex_domain', {'uid': ['fake_id5'],
|
||||
# 'cn': ["name"]})]
|
||||
for obj in ldap_result:
|
||||
# ignore ldap object(user/group entry) which has no attr set
|
||||
# in it or whose value is empty list.
|
||||
if obj[1].get(attr):
|
||||
# ignore ldap object whose attr value has empty strings or
|
||||
# contains only whitespaces.
|
||||
if obj[1].get(attr)[0] and obj[1].get(attr)[0].strip():
|
||||
ldap_res_low_keys_dict = {k.lower(): v for k, v in obj[1].items()}
|
||||
result_attr_vals = ldap_res_low_keys_dict.get(attr.lower())
|
||||
# ignore ldap object whose attr value has empty strings or
|
||||
# contains only whitespaces.
|
||||
if result_attr_vals:
|
||||
if result_attr_vals[0] and result_attr_vals[0].strip():
|
||||
result.append(obj)
|
||||
# except {'uid': ['fake_id5'], 'cn': ["name"]}, all entries
|
||||
# will be ignored in ldap_result
|
||||
|
@ -1308,6 +1308,53 @@ class LDAPIdentity(BaseLDAPIdentity):
|
||||
self.assertEqual('junk1', user_refs[0]['name'])
|
||||
self.assertEqual('sn=junk1,dc=example,dc=com', user_refs[0]['dn'])
|
||||
|
||||
@mock.patch.object(common_ldap.KeystoneLDAPHandler, 'connect')
|
||||
@mock.patch.object(common_ldap.KeystoneLDAPHandler, 'search_s')
|
||||
@mock.patch.object(common_ldap.KeystoneLDAPHandler, 'simple_bind_s')
|
||||
def test_filter_ldap_result_with_case_sensitive_attr(self,
|
||||
mock_simple_bind_s,
|
||||
mock_search_s,
|
||||
mock_connect):
|
||||
# Mock the ldap search results to return user entries
|
||||
# irrespective of lowercase and uppercase characters in
|
||||
# ldap_result attribute keys e.g. {'Sn': ['junk1']} with
|
||||
# user_name_attribute('sn')
|
||||
mock_search_s.return_value = [(
|
||||
'sn=junk1,dc=example,dc=com',
|
||||
{
|
||||
'cn': [uuid.uuid4().hex],
|
||||
'email': [uuid.uuid4().hex],
|
||||
'sN': ['junk1']
|
||||
}
|
||||
),
|
||||
(
|
||||
'sn=junk1,dc=example,dc=com',
|
||||
{
|
||||
'cn': [uuid.uuid4().hex],
|
||||
'email': [uuid.uuid4().hex],
|
||||
'Sn': ['junk1']
|
||||
}
|
||||
),
|
||||
(
|
||||
'sn=junk1,dc=example,dc=com',
|
||||
{
|
||||
'cn': [uuid.uuid4().hex],
|
||||
'email': [uuid.uuid4().hex],
|
||||
'sn': [' ']
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
user_api = identity.backends.ldap.UserApi(CONF)
|
||||
user_refs = user_api.get_all()
|
||||
# validate that keystone.identity.backends.ldap.common.BaseLdap.
|
||||
# _filter_ldap_result_by_attr() method filtered the ldap query results
|
||||
# whose name attribute keys having case insensitive characters.
|
||||
self.assertEqual(2, len(user_refs))
|
||||
|
||||
self.assertEqual('junk1', user_refs[0]['name'])
|
||||
self.assertEqual('sn=junk1,dc=example,dc=com', user_refs[0]['dn'])
|
||||
|
||||
@mock.patch.object(common_ldap.BaseLdap, '_ldap_get')
|
||||
def test_user_enabled_attribute_handles_expired(self, mock_ldap_get):
|
||||
# If using 'passwordisexpired' as enabled attribute, and inverting it,
|
||||
|
6
releasenotes/notes/bug-1753585-7e11213743754999.yaml
Normal file
6
releasenotes/notes/bug-1753585-7e11213743754999.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
['bug 1753585 <https://bugs.launchpad.net/keystone/+bug/1753585>'_]
|
||||
LDAP attribute names are now matched case insensitively to comply with
|
||||
LDAP implementations.
|
Loading…
x
Reference in New Issue
Block a user