summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishakha Agarwal <agarwalvishakha18@gmail.com>2018-09-18 15:17:07 +0530
committerColleen Murphy <colleen@gazlene.net>2018-10-02 14:14:38 +0000
commit55fda22d5b9f6c99ce093aefe13b3cb728e47748 (patch)
tree7cb8a9ca446fcf058361dc832e58cf592ad3caa9
parent6c63f8eab082b9cc0403727e08a70da6d01579e9 (diff)
LDAP attribute names non-case-sensitivestable/pike
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 (cherry picked from commit 816b472a9d20e4e7cfe33f2f40ef5daae590795e)
Notes
Notes (review): Code-Review+2: Morgan Fainberg <morgan.fainberg@gmail.com> Workflow+1: Morgan Fainberg <morgan.fainberg@gmail.com> Code-Review+1: Vishakha Agarwal <agarwalvishakha18@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 04 Oct 2018 08:36:56 +0000 Reviewed-on: https://review.openstack.org/607198 Project: openstack/keystone Branch: refs/heads/stable/pike
-rw-r--r--keystone/identity/backends/ldap/common.py29
-rw-r--r--keystone/tests/unit/test_backend_ldap.py47
-rw-r--r--releasenotes/notes/bug-1753585-7e11213743754999.yaml6
3 files changed, 73 insertions, 9 deletions
diff --git a/keystone/identity/backends/ldap/common.py b/keystone/identity/backends/ldap/common.py
index 8d632aa..a7b3e60 100644
--- a/keystone/identity/backends/ldap/common.py
+++ b/keystone/identity/backends/ldap/common.py
@@ -1402,20 +1402,31 @@ class BaseLdap(object):
1402 raise ValueError('"%(attr)s" is not a valid value for' 1402 raise ValueError('"%(attr)s" is not a valid value for'
1403 ' "%(attr_name)s"' % {'attr': attr, 1403 ' "%(attr_name)s"' % {'attr': attr,
1404 'attr_name': attr_name}) 1404 'attr_name': attr_name})
1405
1406 # consider attr = "cn" and
1407 # ldap_result = [{'uid': ['fake_id1']}, , 'cN': ["name"]}]
1408 # doing lower case on both user_name_attribute and ldap users
1409 # attribute
1405 result = [] 1410 result = []
1406 # consider attr = "cn" and 1411 # consider attr = "cn" and
1407 # ldap_result = [{'uid': ['fake_id1']}, 1412 # ldap_result = [(u'cn=fake1,o=ex_domain', {'uid': ['fake_id1']}),
1408 # {'uid': ['fake_id2'], 'cn': [' ']}, 1413 # (u'cn=fake2,o=ex_domain', {'uid': ['fake_id2'],
1409 # {'uid': ['fake_id3'], 'cn': ['']}, 1414 # 'cn': [' ']}),
1410 # {'uid': ['fake_id4'], 'cn': []}, 1415 # (u'cn=fake3,o=ex_domain', {'uid': ['fake_id3'],
1411 # {'uid': ['fake_id5'], 'cn': ["name"]}] 1416 # 'cn': ['']}),
1417 # (u'cn=fake4,o=ex_domain', {'uid': ['fake_id4'],
1418 # 'cn': []}),
1419 # (u'cn=fake5,o=ex_domain', {'uid': ['fake_id5'],
1420 # 'cn': ["name"]})]
1412 for obj in ldap_result: 1421 for obj in ldap_result:
1413 # ignore ldap object(user/group entry) which has no attr set 1422 # ignore ldap object(user/group entry) which has no attr set
1414 # in it or whose value is empty list. 1423 # in it or whose value is empty list.
1415 if obj[1].get(attr): 1424 ldap_res_low_keys_dict = {k.lower(): v for k, v in obj[1].items()}
1416 # ignore ldap object whose attr value has empty strings or 1425 result_attr_vals = ldap_res_low_keys_dict.get(attr.lower())
1417 # contains only whitespaces. 1426 # ignore ldap object whose attr value has empty strings or
1418 if obj[1].get(attr)[0] and obj[1].get(attr)[0].strip(): 1427 # contains only whitespaces.
1428 if result_attr_vals:
1429 if result_attr_vals[0] and result_attr_vals[0].strip():
1419 result.append(obj) 1430 result.append(obj)
1420 # except {'uid': ['fake_id5'], 'cn': ["name"]}, all entries 1431 # except {'uid': ['fake_id5'], 'cn': ["name"]}, all entries
1421 # will be ignored in ldap_result 1432 # will be ignored in ldap_result
diff --git a/keystone/tests/unit/test_backend_ldap.py b/keystone/tests/unit/test_backend_ldap.py
index e42c678..052f9a2 100644
--- a/keystone/tests/unit/test_backend_ldap.py
+++ b/keystone/tests/unit/test_backend_ldap.py
@@ -1250,6 +1250,53 @@ class LDAPIdentity(BaseLDAPIdentity, unit.TestCase):
1250 self.assertEqual('junk1', user_refs[0]['name']) 1250 self.assertEqual('junk1', user_refs[0]['name'])
1251 self.assertEqual('sn=junk1,dc=example,dc=com', user_refs[0]['dn']) 1251 self.assertEqual('sn=junk1,dc=example,dc=com', user_refs[0]['dn'])
1252 1252
1253 @mock.patch.object(common_ldap.KeystoneLDAPHandler, 'connect')
1254 @mock.patch.object(common_ldap.KeystoneLDAPHandler, 'search_s')
1255 @mock.patch.object(common_ldap.KeystoneLDAPHandler, 'simple_bind_s')
1256 def test_filter_ldap_result_with_case_sensitive_attr(self,
1257 mock_simple_bind_s,
1258 mock_search_s,
1259 mock_connect):
1260 # Mock the ldap search results to return user entries
1261 # irrespective of lowercase and uppercase characters in
1262 # ldap_result attribute keys e.g. {'Sn': ['junk1']} with
1263 # user_name_attribute('sn')
1264 mock_search_s.return_value = [(
1265 'sn=junk1,dc=example,dc=com',
1266 {
1267 'cn': [uuid.uuid4().hex],
1268 'email': [uuid.uuid4().hex],
1269 'sN': ['junk1']
1270 }
1271 ),
1272 (
1273 'sn=junk1,dc=example,dc=com',
1274 {
1275 'cn': [uuid.uuid4().hex],
1276 'email': [uuid.uuid4().hex],
1277 'Sn': ['junk1']
1278 }
1279 ),
1280 (
1281 'sn=junk1,dc=example,dc=com',
1282 {
1283 'cn': [uuid.uuid4().hex],
1284 'email': [uuid.uuid4().hex],
1285 'sn': [' ']
1286 }
1287 )
1288 ]
1289
1290 user_api = identity.backends.ldap.UserApi(CONF)
1291 user_refs = user_api.get_all()
1292 # validate that keystone.identity.backends.ldap.common.BaseLdap.
1293 # _filter_ldap_result_by_attr() method filtered the ldap query results
1294 # whose name attribute keys having case insensitive characters.
1295 self.assertEqual(2, len(user_refs))
1296
1297 self.assertEqual('junk1', user_refs[0]['name'])
1298 self.assertEqual('sn=junk1,dc=example,dc=com', user_refs[0]['dn'])
1299
1253 @mock.patch.object(common_ldap.BaseLdap, '_ldap_get') 1300 @mock.patch.object(common_ldap.BaseLdap, '_ldap_get')
1254 def test_user_enabled_attribute_handles_expired(self, mock_ldap_get): 1301 def test_user_enabled_attribute_handles_expired(self, mock_ldap_get):
1255 # If using 'passwordisexpired' as enabled attribute, and inverting it, 1302 # If using 'passwordisexpired' as enabled attribute, and inverting it,
diff --git a/releasenotes/notes/bug-1753585-7e11213743754999.yaml b/releasenotes/notes/bug-1753585-7e11213743754999.yaml
new file mode 100644
index 0000000..83b77a0
--- /dev/null
+++ b/releasenotes/notes/bug-1753585-7e11213743754999.yaml
@@ -0,0 +1,6 @@
1---
2fixes:
3 - |
4 ['bug 1753585 <https://bugs.launchpad.net/keystone/+bug/1753585>'_]
5 LDAP attribute names are now matched case insensitively to comply with
6 LDAP implementations. \ No newline at end of file