summaryrefslogtreecommitdiff
path: root/keystone/identity/backends/ldap/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'keystone/identity/backends/ldap/common.py')
-rw-r--r--keystone/identity/backends/ldap/common.py44
1 files changed, 34 insertions, 10 deletions
diff --git a/keystone/identity/backends/ldap/common.py b/keystone/identity/backends/ldap/common.py
index b9becea74..f2f36718f 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)
@@ -1781,6 +1791,7 @@ class EnabledEmuMixIn(BaseLdap):
DEFAULT_GROUP_OBJECTCLASS = 'groupOfNames'
DEFAULT_MEMBER_ATTRIBUTE = 'member'
+ DEFAULT_GROUP_MEMBERS_ARE_IDS = False
def __init__(self, conf):
super(EnabledEmuMixIn, self).__init__(conf)
@@ -1797,9 +1808,11 @@ class EnabledEmuMixIn(BaseLdap):
if not self.use_group_config:
self.member_attribute = self.DEFAULT_MEMBER_ATTRIBUTE
self.group_objectclass = self.DEFAULT_GROUP_OBJECTCLASS
+ self.group_members_are_ids = self.DEFAULT_GROUP_MEMBERS_ARE_IDS
else:
self.member_attribute = conf.ldap.group_member_attribute
self.group_objectclass = conf.ldap.group_objectclass
+ self.group_members_are_ids = conf.ldap.group_members_are_ids
if not self.enabled_emulation_dn:
naming_attr_name = 'cn'
@@ -1815,10 +1828,19 @@ class EnabledEmuMixIn(BaseLdap):
naming_rdn[1])
self.enabled_emulation_naming_attr = naming_attr
- def _get_enabled(self, object_id, conn):
- dn = self._id_to_dn(object_id)
+ def _id_to_member_attribute_value(self, object_id):
+ """Convert id to value expected by member_attribute."""
+ if self.group_members_are_ids:
+ return object_id
+ return self._id_to_dn(object_id)
+
+ def _is_id_enabled(self, object_id, conn):
+ member_attr_val = self._id_to_member_attribute_value(object_id)
+ return self._is_member_enabled(member_attr_val, conn)
+
+ def _is_member_enabled(self, member_attr_val, conn):
query = '(%s=%s)' % (self.member_attribute,
- ldap.filter.escape_filter_chars(dn))
+ ldap.filter.escape_filter_chars(member_attr_val))
try:
enabled_value = conn.search_s(self.enabled_emulation_dn,
ldap.SCOPE_BASE,
@@ -1829,24 +1851,26 @@ class EnabledEmuMixIn(BaseLdap):
return bool(enabled_value)
def _add_enabled(self, object_id):
+ member_attr_val = self._id_to_member_attribute_value(object_id)
with self.get_connection() as conn:
- if not self._get_enabled(object_id, conn):
+ if not self._is_member_enabled(member_attr_val, conn):
modlist = [(ldap.MOD_ADD,
self.member_attribute,
- [self._id_to_dn(object_id)])]
+ [member_attr_val])]
try:
conn.modify_s(self.enabled_emulation_dn, modlist)
except ldap.NO_SUCH_OBJECT:
attr_list = [('objectClass', [self.group_objectclass]),
(self.member_attribute,
- [self._id_to_dn(object_id)]),
+ [member_attr_val]),
self.enabled_emulation_naming_attr]
conn.add_s(self.enabled_emulation_dn, attr_list)
def _remove_enabled(self, object_id):
+ member_attr_val = self._id_to_member_attribute_value(object_id)
modlist = [(ldap.MOD_DELETE,
self.member_attribute,
- [self._id_to_dn(object_id)])]
+ [member_attr_val])]
with self.get_connection() as conn:
try:
conn.modify_s(self.enabled_emulation_dn, modlist)
@@ -1871,7 +1895,7 @@ class EnabledEmuMixIn(BaseLdap):
ref = super(EnabledEmuMixIn, self).get(object_id, ldap_filter)
if ('enabled' not in self.attribute_ignore and
self.enabled_emulation):
- ref['enabled'] = self._get_enabled(object_id, conn)
+ ref['enabled'] = self._is_id_enabled(object_id, conn)
return ref
def get_all(self, ldap_filter=None, hints=None):
@@ -1883,7 +1907,7 @@ class EnabledEmuMixIn(BaseLdap):
if x[0] != self.enabled_emulation_dn]
with self.get_connection() as conn:
for obj_ref in obj_list:
- obj_ref['enabled'] = self._get_enabled(
+ obj_ref['enabled'] = self._is_id_enabled(
obj_ref['id'], conn)
return obj_list
else: