summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2015-11-11 07:56:48 -0800
committerNathan Kinder <nkinder@redhat.com>2015-11-13 12:27:06 -0800
commit0bce43a466aa3ee89c6c956fede2292e457146d7 (patch)
treed1a8f8430459a1b56478a9a1123ff431c53a516f
parent348130e6612afce9342ecb95093724dc16bb7206 (diff)
downloadkeystone-0bce43a466aa3ee89c6c956fede2292e457146d7.tar.gz
Remove hardcoded LDAP group schema from emulated enabled mix-in
The emulated enabled mix-in uses hard-coded LDAP schema for the group objectclass and membership attributes. This patch makes the mix-in optionally use the LDAP group configuration settings. Conflicts: keystone/common/ldap/core.py keystone/tests/unit/test_backend_ldap.py Change-Id: I5ed9d552ec140f83578398fd29e2130ebf827662 Closes-Bug: #1515302 (cherry picked from commit e465de5b44ffb1da65eab77ba7c81d1c0ced367f)
-rw-r--r--doc/source/configuration.rst12
-rw-r--r--etc/keystone.conf.sample8
-rw-r--r--keystone/common/config.py9
-rw-r--r--keystone/common/ldap/core.py31
-rw-r--r--keystone/resource/core.py1
-rw-r--r--keystone/tests/unit/test_backend_ldap.py20
6 files changed, 71 insertions, 10 deletions
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 5eff8a9cd..fb939e24b 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -1631,9 +1631,9 @@ have been created. They are enabled by setting their respective flags to True.
Then the attributes ``user_enabled_emulation_dn`` and
``project_enabled_emulation_dn`` may be set to specify how the enabled users
and projects (tenants) are selected. These attributes work by using a
-``groupOfNames`` and adding whichever users or projects (tenants) that you want
-enabled to the respective group. For example, this will mark any user who is a
-member of ``enabled_users`` as enabled:
+``groupOfNames`` entry and adding whichever users or projects (tenants) that
+you want enabled to the respective group with the ``member`` attribute. For
+example, this will mark any user who is a member of ``enabled_users`` as enabled:
.. code-block:: ini
@@ -1645,6 +1645,12 @@ The default values for user and project (tenant) enabled emulation DN is
``cn=enabled_users,$user_tree_dn`` and ``cn=enabled_tenants,$project_tree_dn``
respectively.
+If a different LDAP schema is used for group membership, it is possible to use
+the ``group_objectclass`` and ``group_member_attribute`` attributes to
+determine membership in the enabled emulation group by setting the
+``user_enabled_emulation_use_group_config`` and
+``project_enabled_emulation_use_group_config`` attributes to True.
+
Secure Connection
-----------------
diff --git a/etc/keystone.conf.sample b/etc/keystone.conf.sample
index 1c2298bf8..7b7d168ea 100644
--- a/etc/keystone.conf.sample
+++ b/etc/keystone.conf.sample
@@ -895,6 +895,10 @@
# (string value)
#user_enabled_emulation_dn = <None>
+# Use the "group_member_attribute" and "group_objectclass" settings to
+# determine membership in the emulated enabled group. (boolean value)
+#user_enabled_emulation_use_group_config = false
+
# List of additional LDAP attributes used for mapping additional attribute
# mappings for users. Attribute mapping format is <ldap_attr>:<user_attr>,
# where ldap_attr is the attribute in the LDAP entry and user_attr is the
@@ -964,6 +968,10 @@
# Deprecated group/name - [ldap]/tenant_enabled_emulation_dn
#project_enabled_emulation_dn = <None>
+# Use the "group_member_attribute" and "group_objectclass" settings to
+# determine membership in the emulated enabled group. (boolean value)
+#project_enabled_emulation_use_group_config = false
+
# Additional attribute mappings for projects. Attribute mapping format is
# <ldap_attr>:<user_attr>, where ldap_attr is the attribute in the LDAP entry
# and user_attr is the Identity API attribute. (list value)
diff --git a/keystone/common/config.py b/keystone/common/config.py
index c72502621..2e578a143 100644
--- a/keystone/common/config.py
+++ b/keystone/common/config.py
@@ -649,6 +649,10 @@ FILE_OPTIONS = {
cfg.StrOpt('user_enabled_emulation_dn',
help='DN of the group entry to hold enabled users when '
'using enabled emulation.'),
+ cfg.BoolOpt('user_enabled_emulation_use_group_config', default=False,
+ help='Use the "group_member_attribute" and '
+ '"group_objectclass" settings to determine '
+ 'membership in the emulated enabled group.'),
cfg.ListOpt('user_additional_attribute_mapping',
default=[],
help='List of additional LDAP attributes used for mapping '
@@ -724,6 +728,11 @@ FILE_OPTIONS = {
'tenant_enabled_emulation_dn', group='ldap')],
help='DN of the group entry to hold enabled projects when '
'using enabled emulation.'),
+ cfg.BoolOpt('project_enabled_emulation_use_group_config',
+ default=False,
+ help='Use the "group_member_attribute" and '
+ '"group_objectclass" settings to determine '
+ 'membership in the emulated enabled group.'),
cfg.ListOpt('project_additional_attribute_mapping',
deprecated_opts=[cfg.DeprecatedOpt(
'tenant_additional_attribute_mapping', group='ldap')],
diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py
index 8a3576b80..8a577ada0 100644
--- a/keystone/common/ldap/core.py
+++ b/keystone/common/ldap/core.py
@@ -1770,19 +1770,23 @@ class BaseLdap(object):
class EnabledEmuMixIn(BaseLdap):
"""Emulates boolean 'enabled' attribute if turned on.
- Creates groupOfNames holding all enabled objects of this class, all missing
+ Creates a group holding all enabled objects of this class, all missing
objects are considered disabled.
Options:
* $name_enabled_emulation - boolean, on/off
- * $name_enabled_emulation_dn - DN of that groupOfNames, default is
+ * $name_enabled_emulation_dn - DN of that group, default is
cn=enabled_${name}s,${tree_dn}
+ * $name_enabled_emulation_use_group_config - boolean, on/off
Where ${name}s is the plural of self.options_name ('users' or 'tenants'),
${tree_dn} is self.tree_dn.
"""
+ DEFAULT_GROUP_OBJECTCLASS = 'groupOfNames'
+ DEFAULT_MEMBER_ATTRIBUTE = 'member'
+
def __init__(self, conf):
super(EnabledEmuMixIn, self).__init__(conf)
enabled_emulation = '%s_enabled_emulation' % self.options_name
@@ -1790,6 +1794,18 @@ class EnabledEmuMixIn(BaseLdap):
enabled_emulation_dn = '%s_enabled_emulation_dn' % self.options_name
self.enabled_emulation_dn = getattr(conf.ldap, enabled_emulation_dn)
+
+ use_group_config = ('%s_enabled_emulation_use_group_config' %
+ self.options_name)
+ self.use_group_config = getattr(conf.ldap, use_group_config)
+
+ if not self.use_group_config:
+ self.member_attribute = self.DEFAULT_MEMBER_ATTRIBUTE
+ self.group_objectclass = self.DEFAULT_GROUP_OBJECTCLASS
+ else:
+ self.member_attribute = conf.ldap.group_member_attribute
+ self.group_objectclass = conf.ldap.group_objectclass
+
if not self.enabled_emulation_dn:
naming_attr_name = 'cn'
naming_attr_value = 'enabled_%ss' % self.options_name
@@ -1806,7 +1822,7 @@ class EnabledEmuMixIn(BaseLdap):
def _get_enabled(self, object_id):
dn = self._id_to_dn(object_id)
- query = '(member=%s)' % dn
+ query = '(%s=%s)' % (self.member_attribute, dn)
with self.get_connection() as conn:
try:
enabled_value = conn.search_s(self.enabled_emulation_dn,
@@ -1820,14 +1836,15 @@ class EnabledEmuMixIn(BaseLdap):
def _add_enabled(self, object_id):
if not self._get_enabled(object_id):
modlist = [(ldap.MOD_ADD,
- 'member',
+ self.member_attribute,
[self._id_to_dn(object_id)])]
with self.get_connection() as conn:
try:
conn.modify_s(self.enabled_emulation_dn, modlist)
except ldap.NO_SUCH_OBJECT:
- attr_list = [('objectClass', ['groupOfNames']),
- ('member', [self._id_to_dn(object_id)]),
+ attr_list = [('objectClass', [self.group_objectclass]),
+ (self.member_attribute,
+ [self._id_to_dn(object_id)]),
self.enabled_emulation_naming_attr]
if self.use_dumb_member:
attr_list[1][1].append(self.dumb_member)
@@ -1835,7 +1852,7 @@ class EnabledEmuMixIn(BaseLdap):
def _remove_enabled(self, object_id):
modlist = [(ldap.MOD_DELETE,
- 'member',
+ self.member_attribute,
[self._id_to_dn(object_id)])]
with self.get_connection() as conn:
try:
diff --git a/keystone/resource/core.py b/keystone/resource/core.py
index 0559b68d1..6b6150b38 100644
--- a/keystone/resource/core.py
+++ b/keystone/resource/core.py
@@ -808,6 +808,7 @@ class DomainConfigManager(manager.Manager):
'user_attribute_ignore', 'user_default_project_id_attribute',
'user_allow_create', 'user_allow_update', 'user_allow_delete',
'user_enabled_emulation', 'user_enabled_emulation_dn',
+ 'user_enabled_emulation_use_group_config',
'user_additional_attribute_mapping', 'group_tree_dn',
'group_filter', 'group_objectclass', 'group_id_attribute',
'group_name_attribute', 'group_member_attribute',
diff --git a/keystone/tests/unit/test_backend_ldap.py b/keystone/tests/unit/test_backend_ldap.py
index eca8817a1..94216e842 100644
--- a/keystone/tests/unit/test_backend_ldap.py
+++ b/keystone/tests/unit/test_backend_ldap.py
@@ -2019,6 +2019,26 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
self.skipTest(
"Enabled emulation conflicts with enabled mask")
+ def test_user_enabled_use_group_config(self):
+ self.config_fixture.config(
+ group='ldap',
+ user_enabled_emulation_use_group_config=True,
+ group_member_attribute='uniqueMember',
+ group_objectclass='groupOfUniqueNames')
+ self.clear_database()
+ self.load_backends()
+ self.load_fixtures(default_fixtures)
+
+ # Create a user and ensure they are enabled.
+ user1 = {'name': u'fäké1', 'enabled': True,
+ 'domain_id': CONF.identity.default_domain_id}
+ user_ref = self.identity_api.create_user(user1)
+ self.assertIs(True, user_ref['enabled'])
+
+ # Get a user and ensure they are enabled.
+ user_ref = self.identity_api.get_user(user_ref['id'])
+ self.assertIs(True, user_ref['enabled'])
+
def test_user_enabled_invert(self):
self.config_fixture.config(group='ldap', user_enabled_invert=True,
user_enabled_default=False)