diff options
author | Lance Bragstad <lbragstad@gmail.com> | 2020-07-31 15:28:15 -0500 |
---|---|---|
committer | Lance Bragstad <lbragstad@gmail.com> | 2020-11-11 10:43:07 -0600 |
commit | 9beb3a58011596af5c704e3930a0f01d67f5c845 (patch) | |
tree | 4e93e1ea54f8a85daf9b81f575d4d7f83fac702c | |
parent | 28d2dd19e10d5d58d11f6319ae70a30251be1ef1 (diff) | |
download | keystone-9beb3a58011596af5c704e3930a0f01d67f5c845.tar.gz |
Properly handle octet (byte) strings when converting LDAP responses
If LDAP returns a UUID as an octet string the LDAP driver will fail to
convert it to something meaningful. The error usually looks something
like:
ID attribute objectGUID not found in LDAP object
Microsoft AD's `objectGUID` parameter is stored and transmitted as an
octet string [0]. If you attempt to use the `objectGUID` to generate
user or group IDs, you'll get an HTTP 404 because keystone can't decode
it properly. This is unfortunate because `objectGUID` are a fixed
length, UUID format, and ideal for generating IDs in keystone. As
opposed to using the object's CN, which is variable length, and can
generate hashes that are larger than keystone's database table limit for
user IDs.
[0] https://docs.microsoft.com/en-us/windows/win32/ad/reading-an-objectampaposs-objectguid-and-creating-a-string-representation-of-the-guid
Conflicts:
keystone/identity/backends/ldap/common.py
Due to python3 string detection differences between ussuri and
train.
Change-Id: Id80b17bdff015e10340e636102576b7435bd564f
Closes-Bug: 1889936
(cherry picked from commit 8bf222ac5d390e25d306d35f69bd958b18bee4d8)
(cherry picked from commit d5870f69c12c034dd97b164345e85e6259ee7abe)
-rw-r--r-- | keystone/identity/backends/ldap/common.py | 12 | ||||
-rw-r--r-- | keystone/tests/unit/identity/backends/test_ldap_common.py | 14 | ||||
-rw-r--r-- | releasenotes/notes/bug-1889936-78d6853b5212b8f1.yaml | 5 |
3 files changed, 30 insertions, 1 deletions
diff --git a/keystone/identity/backends/ldap/common.py b/keystone/identity/backends/ldap/common.py index cef0d9bdf..05da67509 100644 --- a/keystone/identity/backends/ldap/common.py +++ b/keystone/identity/backends/ldap/common.py @@ -18,6 +18,7 @@ import functools import os.path import re import sys +import uuid import weakref import ldap.controls @@ -95,7 +96,16 @@ def utf8_decode(value): :raises UnicodeDecodeError: for invalid UTF-8 encoding """ if isinstance(value, six.binary_type): - return _utf8_decoder(value)[0] + try: + return _utf8_decoder(value)[0] + except UnicodeDecodeError: + # NOTE(lbragstad): We could be dealing with a UUID in byte form, + # which some LDAP implementations use. + uuid_byte_string_length = 16 + if len(value) == uuid_byte_string_length: + return six.text_type(uuid.UUID(bytes_le=value)) + else: + raise return six.text_type(value) diff --git a/keystone/tests/unit/identity/backends/test_ldap_common.py b/keystone/tests/unit/identity/backends/test_ldap_common.py index e464a8a14..2a0d9ab28 100644 --- a/keystone/tests/unit/identity/backends/test_ldap_common.py +++ b/keystone/tests/unit/identity/backends/test_ldap_common.py @@ -520,6 +520,20 @@ class CommonLdapTestCase(unit.BaseTestCase): # The user name should still be a string value. self.assertEqual(user_name, py_result[0][1]['user_name'][0]) + def test_user_id_attribute_is_uuid_in_byte_form(self): + results = [( + 'cn=alice,dc=example,dc=com', + { + 'cn': [b'cn=alice'], + 'objectGUID': [b'\xdd\xd8Rt\xee]bA\x8e(\xe39\x0b\xe1\xf8\xe8'], + 'email': [uuid.uuid4().hex], + 'sn': [uuid.uuid4().hex] + } + )] + py_result = common_ldap.convert_ldap_result(results) + exp_object_guid = '7452d8dd-5dee-4162-8e28-e3390be1f8e8' + self.assertEqual(exp_object_guid, py_result[0][1]['objectGUID'][0]) + class LDAPFilterQueryCompositionTest(unit.BaseTestCase): """These test cases test LDAP filter generation.""" diff --git a/releasenotes/notes/bug-1889936-78d6853b5212b8f1.yaml b/releasenotes/notes/bug-1889936-78d6853b5212b8f1.yaml new file mode 100644 index 000000000..de96b27f7 --- /dev/null +++ b/releasenotes/notes/bug-1889936-78d6853b5212b8f1.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + [`bug 1889936 <https://bugs.launchpad.net/keystone/+bug/1889936>`_] + Properly decode octet strings, or byte arrays, returned from LDAP. |