User ids that begin with 0 cannot authenticate through ldap

Currently, in the ldap2py function, several fields are attempted
to be converted to python friendly types.

In doing so, an attempt to convert a field to int() is attempted,
but in some cases, a user id may begin with a 0. When the user
attempts to authenticate, they will be rejected since any additional
query will use the id without the 0 in front.

Closes-Bug: #1396763

Change-Id: I1e2436b845e534f6cdb0398b5cca17d8502b905f
This commit is contained in:
Steve Martinelli 2014-11-26 14:12:01 -05:00
parent 2355f3a85e
commit 474271683f
2 changed files with 70 additions and 10 deletions

View File

@ -107,16 +107,9 @@ def py2ldap(val):
return six.text_type(val)
def ldap2py(val):
"""Convert an LDAP formatted value to Python type used by OpenStack.
def enabled2py(val):
"""Similar to ldap2py, only useful for the enabled attribute."""
Virtually all LDAP values are stored as UTF-8 encoded strings.
OpenStack prefers values which are Python types, e.g. unicode,
boolean, integer, etc.
:param val: LDAP formatted value
:returns: val converted to preferred Python type
"""
try:
return LDAP_VALUES[val]
except KeyError:
@ -128,6 +121,23 @@ def ldap2py(val):
return utf8_decode(val)
def ldap2py(val):
"""Convert an LDAP formatted value to Python type used by OpenStack.
Virtually all LDAP values are stored as UTF-8 encoded strings.
OpenStack prefers values which are Python types, e.g. unicode,
boolean, etc.
:param val: LDAP formatted value
:returns: val converted to preferred Python type
"""
try:
return LDAP_VALUES[val]
except KeyError:
pass
return utf8_decode(val)
def convert_ldap_result(ldap_result):
"""Convert LDAP search result to Python types used by OpenStack.
@ -157,7 +167,8 @@ def convert_ldap_result(ldap_result):
for kind, values in six.iteritems(attrs):
try:
ldap_attrs[kind] = [ldap2py(x) for x in values]
val2py = enabled2py if kind == 'enabled' else ldap2py
ldap_attrs[kind] = [val2py(x) for x in values]
except UnicodeDecodeError:
LOG.debug('Unable to decode value for attribute %s', kind)

View File

@ -435,3 +435,52 @@ class CommonLdapTestCase(tests.BaseTestCase):
result_unicode = ks_ldap.utf8_decode(100)
self.assertEqual(u'100', result_unicode)
def test_user_id_begins_with_0(self):
user_id = '0123456'
result = [(
'cn=dummy,dc=example,dc=com',
{
'user_id': [user_id],
'enabled': ['TRUE']
}
), ]
py_result = ks_ldap.convert_ldap_result(result)
# The user id should be 0123456, and the enabled
# flag should be True
self.assertIs(py_result[0][1]['enabled'][0], True)
self.assertEqual(user_id, py_result[0][1]['user_id'][0])
def test_user_id_begins_with_0_and_enabled_bit_mask(self):
user_id = '0123456'
bitmask = '225'
expected_bitmask = 225
result = [(
'cn=dummy,dc=example,dc=com',
{
'user_id': [user_id],
'enabled': [bitmask]
}
), ]
py_result = ks_ldap.convert_ldap_result(result)
# The user id should be 0123456, and the enabled
# flag should be 225
self.assertEqual(expected_bitmask, py_result[0][1]['enabled'][0])
self.assertEqual(user_id, py_result[0][1]['user_id'][0])
def test_user_id_and_bitmask_begins_with_0(self):
user_id = '0123456'
bitmask = '0225'
expected_bitmask = 225
result = [(
'cn=dummy,dc=example,dc=com',
{
'user_id': [user_id],
'enabled': [bitmask]
}
), ]
py_result = ks_ldap.convert_ldap_result(result)
# The user id should be 0123456, and the enabled
# flag should be 225, the 0 is dropped.
self.assertEqual(expected_bitmask, py_result[0][1]['enabled'][0])
self.assertEqual(user_id, py_result[0][1]['user_id'][0])