← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1497461] [NEW] Fernet tokens fail for some users with LDAP identity backend

 

Public bug reported:

The following bug fixed most situations where when using Fernet + LDAP identify backend.
        https://bugs.launchpad.net/keystone/+bug/1459382

However, some users have trouble, resulting in a UserNotFound exception in the logs with a UUID.  Here's the error:
2015-09-18 20:04:47.313 12979 WARNING keystone.common.wsgi [-] Could not find user: 457269632042726f776e203732363230

So the issue is this.  The user DN query + filter will return my user as:
   CN=Eric Brown 72620,OU=PAO_Users,OU=PaloAlto_California_USA,OU=NALA,OU=SITES,OU=Engineering,DC=vmware,DC=com

Therefore, I have to use CN as the user id attribute.  My user id would
therefore be "Eric Brown 72620".  The fernet token_formatters.py
attempts to convert this user id into a UUID.  And in my case that is
successful.  It results in UUID of 457269632042726f776e203732363230.  Of
course, a user id of 457269632042726f776e203732363230 doesn't exist in
LDAP, so as a result I get a UserNotFound.  So I don't understand why
the convert_uuid_bytes_to_hex is ever used in the case of LDAP backend.

For other users, the token_formatters.convert_uuid_bytes_to_hex() raises
a ValueError and everything works.  Here's an example that illustrates
the behavior

>>> import uuid
>>> uuid_obj = uuid.UUID(bytes='Eric Brown 72620')
>>> uuid_obj.hex
'457269632042726f776e203732363230'

>>> import uuid
>>> uuid_obj = uuid.UUID(bytes='Your Mama')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/uuid.py", line 144, in __init__
    raise ValueError('bytes is not a 16-char string')
ValueError: bytes is not a 16-char string


Here's the complete traceback (after adding some additional debug):

2015-09-18 20:04:47.312 12979 WARNING keystone.common.wsgi [-] EWB Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/keystone/common/wsgi.py", line 449, in __call__
    response = self.process_request(request)
  File "/usr/lib/python2.7/dist-packages/keystone/middleware/core.py", line 238, in process_request
    auth_context = self._build_auth_context(request)
  File "/usr/lib/python2.7/dist-packages/keystone/middleware/core.py", line 218, in _build_auth_context
    token_data=self.token_provider_api.validate_token(token_id))
  File "/usr/lib/python2.7/dist-packages/keystone/token/provider.py", line 198, in validate_token
    token = self._validate_token(unique_id)
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1013, in decorate
    should_cache_fn)
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 640, in get_or_create
    async_creator) as value:
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 158, in __enter__
    return self._enter()
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 98, in _enter
    generated = self._enter_create(createdtime)
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 149, in _enter_create
    created = self.creator()
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 612, in gen_value
    created_value = creator()
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1009, in creator
    return fn(*arg, **kw)
  File "/usr/lib/python2.7/dist-packages/keystone/token/provider.py", line 261, in _validate_token
    return self.driver.validate_v3_token(token_id)
  File "/usr/lib/python2.7/dist-packages/keystone/token/providers/fernet/core.py", line 258, in validate_v3_token
    audit_info=audit_ids)
  File "/usr/lib/python2.7/dist-packages/keystone/token/providers/common.py", line 441, in get_token_data
    self._populate_user(token_data, user_id, trust)
  File "/usr/lib/python2.7/dist-packages/keystone/token/providers/common.py", line 275, in _populate_user
    user_ref = self.identity_api.get_user(user_id)
  File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 342, in wrapper
    return f(self, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 353, in wrapper
    return f(self, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1013, in decorate
    should_cache_fn)
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 640, in get_or_create
    async_creator) as value:
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 158, in __enter__
    return self._enter()
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 98, in _enter
    generated = self._enter_create(createdtime)
  File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 149, in _enter_create
    created = self.creator()
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 612, in gen_value
    created_value = creator()
  File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1009, in creator
    return fn(*arg, **kw)
  File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 753, in get_user
    ref = driver.get_user(entity_id)
  File "/usr/lib/python2.7/dist-packages/keystone/identity/backends/ldap.py", line 79, in get_user
    return self.user.get_filtered(user_id)
  File "/usr/lib/python2.7/dist-packages/keystone/identity/backends/ldap.py", line 264, in get_filtered
    user = self.get(user_id)
  File "/usr/lib/python2.7/dist-packages/keystone/common/ldap/core.py", line 1859, in get
    ref = super(EnabledEmuMixIn, self).get(object_id, ldap_filter)
  File "/usr/lib/python2.7/dist-packages/keystone/common/ldap/core.py", line 1489, in get
    raise self._not_found(object_id)
UserNotFound: Could not find user: 457269632042726f776e203732363230

** Affects: keystone
     Importance: High
         Status: New


** Tags: fernet kilo-backport-potential

** Changed in: keystone
   Importance: Undecided => High

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to Keystone.
https://bugs.launchpad.net/bugs/1497461

Title:
  Fernet tokens fail for some users with LDAP identity backend

Status in Keystone:
  New

Bug description:
  The following bug fixed most situations where when using Fernet + LDAP identify backend.
          https://bugs.launchpad.net/keystone/+bug/1459382

  However, some users have trouble, resulting in a UserNotFound exception in the logs with a UUID.  Here's the error:
  2015-09-18 20:04:47.313 12979 WARNING keystone.common.wsgi [-] Could not find user: 457269632042726f776e203732363230

  So the issue is this.  The user DN query + filter will return my user as:
     CN=Eric Brown 72620,OU=PAO_Users,OU=PaloAlto_California_USA,OU=NALA,OU=SITES,OU=Engineering,DC=vmware,DC=com

  Therefore, I have to use CN as the user id attribute.  My user id
  would therefore be "Eric Brown 72620".  The fernet token_formatters.py
  attempts to convert this user id into a UUID.  And in my case that is
  successful.  It results in UUID of 457269632042726f776e203732363230.
  Of course, a user id of 457269632042726f776e203732363230 doesn't exist
  in LDAP, so as a result I get a UserNotFound.  So I don't understand
  why the convert_uuid_bytes_to_hex is ever used in the case of LDAP
  backend.

  For other users, the token_formatters.convert_uuid_bytes_to_hex()
  raises a ValueError and everything works.  Here's an example that
  illustrates the behavior

  >>> import uuid
  >>> uuid_obj = uuid.UUID(bytes='Eric Brown 72620')
  >>> uuid_obj.hex
  '457269632042726f776e203732363230'

  >>> import uuid
  >>> uuid_obj = uuid.UUID(bytes='Your Mama')
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.7/uuid.py", line 144, in __init__
      raise ValueError('bytes is not a 16-char string')
  ValueError: bytes is not a 16-char string



  Here's the complete traceback (after adding some additional debug):

  2015-09-18 20:04:47.312 12979 WARNING keystone.common.wsgi [-] EWB Traceback (most recent call last):
    File "/usr/lib/python2.7/dist-packages/keystone/common/wsgi.py", line 449, in __call__
      response = self.process_request(request)
    File "/usr/lib/python2.7/dist-packages/keystone/middleware/core.py", line 238, in process_request
      auth_context = self._build_auth_context(request)
    File "/usr/lib/python2.7/dist-packages/keystone/middleware/core.py", line 218, in _build_auth_context
      token_data=self.token_provider_api.validate_token(token_id))
    File "/usr/lib/python2.7/dist-packages/keystone/token/provider.py", line 198, in validate_token
      token = self._validate_token(unique_id)
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1013, in decorate
      should_cache_fn)
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 640, in get_or_create
      async_creator) as value:
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 158, in __enter__
      return self._enter()
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 98, in _enter
      generated = self._enter_create(createdtime)
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 149, in _enter_create
      created = self.creator()
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 612, in gen_value
      created_value = creator()
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1009, in creator
      return fn(*arg, **kw)
    File "/usr/lib/python2.7/dist-packages/keystone/token/provider.py", line 261, in _validate_token
      return self.driver.validate_v3_token(token_id)
    File "/usr/lib/python2.7/dist-packages/keystone/token/providers/fernet/core.py", line 258, in validate_v3_token
      audit_info=audit_ids)
    File "/usr/lib/python2.7/dist-packages/keystone/token/providers/common.py", line 441, in get_token_data
      self._populate_user(token_data, user_id, trust)
    File "/usr/lib/python2.7/dist-packages/keystone/token/providers/common.py", line 275, in _populate_user
      user_ref = self.identity_api.get_user(user_id)
    File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 342, in wrapper
      return f(self, *args, **kwargs)
    File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 353, in wrapper
      return f(self, *args, **kwargs)
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1013, in decorate
      should_cache_fn)
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 640, in get_or_create
      async_creator) as value:
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 158, in __enter__
      return self._enter()
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 98, in _enter
      generated = self._enter_create(createdtime)
    File "/usr/lib/python2.7/dist-packages/dogpile/core/dogpile.py", line 149, in _enter_create
      created = self.creator()
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 612, in gen_value
      created_value = creator()
    File "/usr/lib/python2.7/dist-packages/dogpile/cache/region.py", line 1009, in creator
      return fn(*arg, **kw)
    File "/usr/lib/python2.7/dist-packages/keystone/identity/core.py", line 753, in get_user
      ref = driver.get_user(entity_id)
    File "/usr/lib/python2.7/dist-packages/keystone/identity/backends/ldap.py", line 79, in get_user
      return self.user.get_filtered(user_id)
    File "/usr/lib/python2.7/dist-packages/keystone/identity/backends/ldap.py", line 264, in get_filtered
      user = self.get(user_id)
    File "/usr/lib/python2.7/dist-packages/keystone/common/ldap/core.py", line 1859, in get
      ref = super(EnabledEmuMixIn, self).get(object_id, ldap_filter)
    File "/usr/lib/python2.7/dist-packages/keystone/common/ldap/core.py", line 1489, in get
      raise self._not_found(object_id)
  UserNotFound: Could not find user: 457269632042726f776e203732363230

To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1497461/+subscriptions


Follow ups