Enable support for posixGroups in LDAP

Support LDAP backends using POSIX goups

Change-Id: Iaaf022bfdcbd26b3a29c84ff60a033f65a60302b
Closes-Bug: 1526462
This commit is contained in:
Alexander Makarov 2015-12-16 17:11:36 +03:00 committed by Brant Knudson
parent 8d7d49edaf
commit 449f1f2bde
5 changed files with 84 additions and 5 deletions

View File

@ -785,6 +785,11 @@ FILE_OPTIONS = {
help='End user auth connection pool size.'),
cfg.IntOpt('auth_pool_connection_lifetime', default=60,
help='End user auth connection lifetime in seconds.'),
cfg.BoolOpt('group_members_are_ids', default=False,
help='If the members of the group objectclass are user '
'IDs rather than DNs, set this to true. This is the '
'case when using posixGroup as the group '
'objectclass and OpenDirectory.'),
],
'auth': [
cfg.ListOpt('methods', default=_DEFAULT_AUTH_METHODS,

View File

@ -187,15 +187,19 @@ class Identity(identity.IdentityDriverV8):
def list_users_in_group(self, group_id, hints):
users = []
for user_dn in self.group.list_group_users(group_id):
user_id = self.user._dn_to_id(user_dn)
for user_key in self.group.list_group_users(group_id):
if self.conf.ldap.group_members_are_ids:
user_id = user_key
else:
user_id = self.user._dn_to_id(user_key)
try:
users.append(self.user.get_filtered(user_id))
except exception.UserNotFound:
LOG.debug(("Group member '%(user_dn)s' not found in"
LOG.debug(("Group member '%(user_key)s' not found in"
" '%(group_id)s'. The user should be removed"
" from the group. The user will be ignored."),
dict(user_dn=user_dn, group_id=group_id))
dict(user_key=user_key, group_id=group_id))
return users
def check_user_in_group(self, user_id, group_id):

View File

@ -68,7 +68,13 @@ def _internal_attr(attr_name, value_or_values):
if dn == 'cn=Doe\\, John,ou=Users,cn=example,cn=com':
return 'CN=Doe\\2C John,OU=Users,CN=example,CN=com'
dn = ldap.dn.str2dn(core.utf8_encode(dn))
try:
dn = ldap.dn.str2dn(core.utf8_encode(dn))
except ldap.DECODING_ERROR:
# NOTE(amakarov): In case of IDs instead of DNs in group members
# they must be handled as regular values.
return normalize_value(dn)
norm = []
for part in dn:
name, val, i = part[0]

View File

@ -2109,6 +2109,64 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
self.assertEqual(exp_filter, m.call_args[0][2])
class LDAPPosixGroupsTest(unit.TestCase):
def setUp(self):
super(LDAPPosixGroupsTest, self).setUp()
self.useFixture(ldapdb.LDAPDatabase())
self.useFixture(database.Database())
self.load_backends()
self.load_fixtures(default_fixtures)
_assert_backends(self, identity='ldap')
def load_fixtures(self, fixtures):
# Override super impl since need to create group container.
create_group_container(self.identity_api)
super(LDAPPosixGroupsTest, self).load_fixtures(fixtures)
def config_overrides(self):
super(LDAPPosixGroupsTest, self).config_overrides()
self.config_fixture.config(group='identity', driver='ldap')
self.config_fixture.config(group='ldap', group_members_are_ids=True,
group_member_attribute='memberUID')
def config_files(self):
config_files = super(LDAPPosixGroupsTest, self).config_files()
config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def _get_domain_fixture(self):
"""Domains in LDAP are read-only, so just return the static one."""
return self.resource_api.get_domain(CONF.identity.default_domain_id)
def test_posix_member_id(self):
domain = self._get_domain_fixture()
new_group = unit.new_group_ref(domain_id=domain['id'])
new_group = self.identity_api.create_group(new_group)
# Make sure we get an empty list back on a new group, not an error.
user_refs = self.identity_api.list_users_in_group(new_group['id'])
self.assertEqual([], user_refs)
# Make sure we get the correct users back once they have been added
# to the group.
new_user = unit.new_user_ref(domain_id=domain['id'])
new_user = self.identity_api.create_user(new_user)
# NOTE(amakarov): Create the group directly using LDAP operations
# rather than going through the manager.
group_api = self.identity_api.driver.group
group_ref = group_api.get(new_group['id'])
mod = (ldap.MOD_ADD, group_api.member_attribute, new_user['id'])
conn = group_api.get_connection()
conn.modify_s(group_ref['dn'], [mod])
user_refs = self.identity_api.list_users_in_group(new_group['id'])
self.assertIn(new_user['id'], (x['id'] for x in user_refs))
class LdapIdentityWithMapping(
BaseLDAPIdentity, unit.SQLDriverOverrides, unit.TestCase):
"""Class to test mapping of default LDAP backend.

View File

@ -0,0 +1,6 @@
---
fixes:
- >
[`bug 1526462 <https://bugs.launchpad.net/keystone/+bug/1526462>`_]
Support for posixGroups with OpenDirectory and UNIX when using
the LDAP identity driver.