Add support for external group members

When using ipaExternalGroup/ipaExternalMember attributes it is
possible to add group members which don't exist in IPA database.
This is primarily is required for AD trusts support and therefore
validation is accepting only secure identifier (SID) format.

https://fedorahosted.org/freeipa/ticket/2664
This commit is contained in:
Alexander Bokovoy
2012-06-20 16:08:33 +03:00
committed by Martin Kosek
parent 52f69aaa8a
commit a6ff85f425
11 changed files with 358 additions and 29 deletions

View File

@@ -45,6 +45,8 @@ group = [
u'ipaobject',
]
externalgroup = group + [u'ipaexternalgroup']
host = [
u'ipasshhost',
u'ipaSshGroupOfPubKeys',

View File

@@ -28,11 +28,18 @@ from ipalib.dn import *
group1 = u'testgroup1'
group2 = u'testgroup2'
group3 = u'testgroup3'
renamedgroup1 = u'testgroup'
user1 = u'tuser1'
invalidgroup1=u'+tgroup1'
# When adding external SID member to a group we can't test
# it fully due to possibly missing Samba 4 python bindings
# and/or not configured AD trusts. Thus, we'll use incorrect
# SID value to merely test that proper exceptions are raised
external_sid1=u'S-1-1-123456-789-1'
def get_group_dn(cn):
return DN(('cn', cn), api.env.container_group, api.env.basedn)
@@ -40,6 +47,7 @@ class test_group(Declarative):
cleanup_commands = [
('group_del', [group1], {}),
('group_del', [group2], {}),
('group_del', [group3], {}),
('user_del', [user1], {}),
]
@@ -373,6 +381,63 @@ class test_group(Declarative):
),
),
###############
# test external SID members for group3:
dict(
desc='Create external %r' % group3,
command=(
'group_add', [group3], dict(description=u'Test desc 3',external=True)
),
expected=dict(
value=group3,
summary=u'Added group "testgroup3"',
result=dict(
cn=[group3],
description=[u'Test desc 3'],
objectclass=objectclasses.externalgroup,
ipauniqueid=[fuzzy_uuid],
dn=lambda x: DN(x) == get_group_dn(group3),
),
),
),
dict(
desc='Convert posix group %r to support external membership' % (group2),
command=(
'group_mod', [group2], dict(external=True)
),
expected=errors.PosixGroupViolation(),
),
dict(
desc='Convert external members group %r to posix' % (group3),
command=(
'group_mod', [group3], dict(posix=True)
),
expected=errors.ExternalGroupViolation(),
),
dict(
desc='Add external member %r to %r' % (external_sid1, group3),
command=(
'group_add_member', [group3], dict(ipaexternalmember=external_sid1)
),
expected=lambda x, output: type(x) == errors.ValidationError or type(x) == errors.NotFound,
),
dict(
desc='Remove group %r with external membership' % (group3),
command=('group_del', [group3], {}),
expected=dict(
result=dict(failed=u''),
value=group3,
summary=u'Deleted group "testgroup3"',
),
),
###############

View File

@@ -1059,7 +1059,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipahomesrootdir=u'/other-home'),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(
@@ -1107,7 +1107,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipahomesrootdir=u'/home'),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(
@@ -1125,7 +1125,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipadefaultloginshell=u'/usr/bin/ipython'),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(
@@ -1172,7 +1172,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipadefaultloginshell=u'/bin/sh'),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(
@@ -1245,7 +1245,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipadefaultprimarygroup=group1),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(
@@ -1328,7 +1328,7 @@ class test_user(Declarative):
command=(
'config_mod', [], dict(ipadefaultprimarygroup=u'ipausers'),
),
expected=lambda x: True,
expected=lambda x, output: x is None,
),
dict(

View File

@@ -260,6 +260,8 @@ class Declarative(XMLRPC_test):
raise nose.SkipTest('%r not in api.Command' % cmd)
if isinstance(expected, errors.PublicError):
self.check_exception(nice, cmd, args, options, expected)
elif hasattr(expected, '__call__'):
self.check_callable(nice, cmd, args, options, expected)
else:
self.check_output(nice, cmd, args, options, expected, extra_check)
@@ -285,6 +287,18 @@ class Declarative(XMLRPC_test):
# For now just compare the strings
assert_deepequal(expected.strerror, e.strerror)
def check_callable(self, nice, cmd, args, options, expected):
output = dict()
e = None
try:
output = api.Command[cmd](*args, **options)
except StandardError, e:
pass
if not expected(e, output):
raise AssertionError(
UNEXPECTED % (cmd, args, options, e.__class__.__name__, e)
)
def check_output(self, nice, cmd, args, options, expected, extra_check):
got = api.Command[cmd](*args, **options)
assert_deepequal(expected, got, nice)