freeipa/tests/test_xmlrpc/test_selinuxusermap_plugin.py
Rob Crittenden dbd87af80b Fix deletion of HBAC Rules when there are SELinux user maps defined
When deleting an HBAC rule we need to ensure that an SELinux user
map isn't pointing at it. We need to take what is the cn of the HBAC
rule and see if that rule exists, then return the dn to that rule.

The search was not being done properly and wasn't enforcing uniqueness.
It could have returned partial matches as well (so tests for the
search test).

https://fedorahosted.org/freeipa/ticket/2269
2012-01-24 21:09:09 -05:00

636 lines
20 KiB
Python

# Authors:
# Rob Crittenden <rcritten@redhat.com>
#
# Copyright (C) 2011 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Test the `ipalib/plugins/selinuxusermap.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
from ipalib.dn import *
from tests.util import Fuzzy
rule1 = u'selinuxrule1'
selinuxuser1 = u'guest_u:s0'
selinuxuser2 = u'xguest_u:s0'
user1 = u'tuser1'
group1 = u'testgroup1'
host1 = u'testhost1.%s' % api.env.domain
hostdn1 = DN(('fqdn',host1),('cn','computers'),('cn','accounts'),
api.env.basedn)
hbacrule1 = u'testhbacrule1'
hbacrule2 = u'testhbacrule12'
fuzzy_selinuxusermapdn = Fuzzy(
'ipauniqueid=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12},%s,%s' % (api.env.container_selinux, api.env.basedn)
)
fuzzy_hbacruledn = Fuzzy(
'ipauniqueid=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12},%s,%s' % (api.env.container_hbac, api.env.basedn)
)
class test_selinuxusermap(Declarative):
cleanup_commands = [
('selinuxusermap_del', [rule1], {}),
('group_del', [group1], {}),
('user_del', [user1], {}),
('host_del', [host1], {}),
('hbacrule_del', [hbacrule1], {}),
('hbacrule_del', [hbacrule2], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % rule1,
command=('selinuxusermap_show', [rule1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % rule1,
command=('selinuxusermap_mod', [rule1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % rule1,
command=('selinuxusermap_del', [rule1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Create rule %r' % rule1,
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1)
),
expected=dict(
value=rule1,
summary=u'Added SELinux User Map "%s"' % rule1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser1],
objectclass=objectclasses.selinuxusermap,
ipauniqueid=[fuzzy_uuid],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
),
),
dict(
desc='Try to create duplicate %r' % rule1,
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1)
),
expected=errors.DuplicateEntry(),
),
dict(
desc='Retrieve rule %r' % rule1,
command=('selinuxusermap_show', [rule1], {}),
expected=dict(
value=rule1,
summary=None,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser1],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
),
),
dict(
desc='Update rule %r' % rule1,
command=(
'selinuxusermap_mod', [rule1], dict(ipaselinuxuser=selinuxuser2)
),
expected=dict(
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
),
summary=u'Modified SELinux User Map "%s"' % rule1,
value=rule1,
),
),
dict(
desc='Retrieve %r to verify update' % rule1,
command=('selinuxusermap_show', [rule1], {}),
expected=dict(
value=rule1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
summary=None,
),
),
dict(
desc='Search for rule %r' % rule1,
command=('selinuxusermap_find', [], dict(cn=rule1)),
expected=dict(
count=1,
truncated=False,
result=[
dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
],
summary=u'1 SELinux User Map matched',
),
),
###############
# Create additional entries needed for testing
dict(
desc='Create %r' % user1,
command=(
'user_add', [], dict(givenname=u'Test', sn=u'User1')
),
expected=dict(
value=user1,
summary=u'Added user "%s"' % user1,
result=dict(
gecos=[u'Test User1'],
givenname=[u'Test'],
homedirectory=[u'/home/%s' % user1],
krbprincipalname=[u'%s@%s' % (user1, api.env.realm)],
loginshell=[u'/bin/sh'],
objectclass=objectclasses.user,
sn=[u'User1'],
uid=[user1],
uidnumber=[fuzzy_digits],
gidnumber=[fuzzy_digits],
displayname=[u'Test User1'],
cn=[u'Test User1'],
initials=[u'TU'],
ipauniqueid=[fuzzy_uuid],
krbpwdpolicyreference=lambda x: [DN(i) for i in x] == \
[DN(('cn','global_policy'),('cn',api.env.realm),
('cn','kerberos'),api.env.basedn)],
mepmanagedentry=lambda x: [DN(i) for i in x] == \
[DN(('cn',user1),('cn','groups'),('cn','accounts'),
api.env.basedn)],
memberof_group=[u'ipausers'],
dn=lambda x: DN(x) == \
DN(('uid',user1),('cn','users'),('cn','accounts'),
api.env.basedn),
has_keytab=False,
has_password=False,
),
),
),
dict(
desc='Create group %r' % group1,
command=(
'group_add', [group1], dict(description=u'Test desc 1')
),
expected=dict(
value=group1,
summary=u'Added group "%s"' % group1,
result=dict(
cn=[group1],
description=[u'Test desc 1'],
gidnumber=[fuzzy_digits],
objectclass=objectclasses.group + [u'posixgroup'],
ipauniqueid=[fuzzy_uuid],
dn=lambda x: DN(x) == \
DN(('cn',group1),('cn','groups'),('cn','accounts'),
api.env.basedn),
),
),
),
dict(
desc='Add member %r to %r' % (user1, group1),
command=(
'group_add_member', [group1], dict(user=user1)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
group=tuple(),
user=tuple(),
),
),
result={
'dn': lambda x: DN(x) == \
DN(('cn',group1),('cn','groups'),('cn','accounts'),
api.env.basedn),
'member_user': (user1,),
'gidnumber': [fuzzy_digits],
'cn': [group1],
'description': [u'Test desc 1'],
},
),
),
dict(
desc='Create host %r' % host1,
command=('host_add', [host1],
dict(
description=u'Test host 1',
l=u'Undisclosed location 1',
force=True,
),
),
expected=dict(
value=host1,
summary=u'Added host "%s"' % host1,
result=dict(
dn=lambda x: DN(x) == hostdn1,
fqdn=[host1],
description=[u'Test host 1'],
l=[u'Undisclosed location 1'],
krbprincipalname=[u'host/%s@%s' % (host1, api.env.realm)],
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[host1],
has_keytab=False,
has_password=False,
),
),
),
dict(
desc='Create HBAC rule %r' % hbacrule1,
command=(
'hbacrule_add', [hbacrule1], {}
),
expected=dict(
value=hbacrule1,
summary=u'Added HBAC rule "%s"' % hbacrule1,
result=dict(
cn=[hbacrule1],
objectclass=objectclasses.hbacrule,
ipauniqueid=[fuzzy_uuid],
accessruletype=[u'allow'],
ipaenabledflag=[u'TRUE'],
dn=fuzzy_hbacruledn,
),
),
),
dict(
desc='Create HBAC rule %r' % hbacrule2,
command=(
'hbacrule_add', [hbacrule2], {}
),
expected=dict(
value=hbacrule2,
summary=u'Added HBAC rule "%s"' % hbacrule2,
result=dict(
cn=[hbacrule2],
objectclass=objectclasses.hbacrule,
ipauniqueid=[fuzzy_uuid],
accessruletype=[u'allow'],
ipaenabledflag=[u'TRUE'],
dn=fuzzy_hbacruledn,
),
),
),
###############
# Fill out rule with members and/or pointers to HBAC rules
dict(
desc='Add user to %r' % rule1,
command=('selinuxusermap_add_user', [rule1], dict(user=user1)),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
memberuser_user = [user1],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Add non-existent user to %r' % rule1,
command=('selinuxusermap_add_user', [rule1], dict(user=u'notfound')),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[(u'notfound', u'no such entry')])),
completed=0,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
memberuser_user = [user1],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Remove user from %r' % rule1,
command=('selinuxusermap_remove_user', [rule1], dict(user=user1)),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Remove non-existent user to %r' % rule1,
command=('selinuxusermap_remove_user', [rule1], dict(user=u'notfound')),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[(u'notfound', u'This entry is not a member')])),
completed=0,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Add group to %r' % rule1,
command=('selinuxusermap_add_user', [rule1], dict(group=group1)),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
memberuser_group = [group1],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Add host to %r' % rule1,
command=('selinuxusermap_add_host', [rule1], dict(host=host1)),
expected=dict(
failed=dict(memberhost=dict(hostgroup=[], host=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
memberhost_host = [host1],
memberuser_group = [group1],
dn=fuzzy_selinuxusermapdn,
),
)
),
###############
# Test enabling and disabling
dict(
desc='Disable %r' % rule1,
command=('selinuxusermap_disable', [rule1], {}),
expected=dict(
result=True,
value=rule1,
summary=u'Disabled SELinux User Map "%s"' % rule1,
)
),
dict(
desc='Disable %r again' % rule1,
command=('selinuxusermap_disable', [rule1], {}),
expected=errors.AlreadyInactive(),
),
dict(
desc='Enable %r' % rule1,
command=('selinuxusermap_enable', [rule1], {}),
expected=dict(
result=True,
value=rule1,
summary=u'Enabled SELinux User Map "%s"' % rule1,
)
),
dict(
desc='Re-enable %r again' % rule1,
command=('selinuxusermap_enable', [rule1], {}),
expected=errors.AlreadyActive(),
),
# Point to an HBAC Rule
dict(
desc='Add an HBAC rule to %r that has other members' % rule1,
command=(
'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1)
),
expected=errors.MutuallyExclusiveError(reason=u'cannot have both'),
),
dict(
desc='Remove host from %r' % rule1,
command=('selinuxusermap_remove_host', [rule1], dict(host=host1)),
expected=dict(
failed=dict(memberhost=dict(hostgroup=[], host=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
memberuser_group = [group1],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Remove group from %r' % rule1,
command=('selinuxusermap_remove_user', [rule1], dict(group=group1)),
expected=dict(
failed=dict(memberuser=dict(group=[], user=[])),
completed=1,
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
dn=fuzzy_selinuxusermapdn,
),
)
),
dict(
desc='Add non-existent HBAC rule to %r' % rule1,
command=(
'selinuxusermap_mod', [rule1], dict(seealso=u'notfound')
),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Add an HBAC rule to %r' % rule1,
command=(
'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1)
),
expected=dict(
result=dict(
cn=[rule1],
ipaselinuxuser=[selinuxuser2],
ipaenabledflag = [u'TRUE'],
seealso = hbacrule1,
),
summary=u'Modified SELinux User Map "%s"' % rule1,
value=rule1,
),
),
dict(
desc='Add user to %r that has HBAC' % rule1,
command=('selinuxusermap_add_user', [rule1], dict(user=user1)),
expected=errors.MutuallyExclusiveError(reason=u'cannot have both'),
),
dict(
desc='Add host to %r that has HBAC' % rule1,
command=('selinuxusermap_add_host', [rule1], dict(host=host1)),
expected=errors.MutuallyExclusiveError(reason=u'cannot have both'),
),
dict(
desc='Try to delete HBAC rule pointed to by %r' % rule1,
command=('hbacrule_del', [hbacrule1], {}),
expected=errors.DependentEntry(key=hbacrule1, label=u'SELinux User Map', dependent=rule1)
),
# This tests selinuxusermap-find --hbacrule=<foo> returns an
# exact match
dict(
desc='Try to delete similarly named HBAC rule %r' % hbacrule2,
command=('hbacrule_del', [hbacrule2], {}),
expected=dict(
result=dict(failed=u''),
value=hbacrule2,
summary=u'Deleted HBAC rule "%s"' % hbacrule2,
)
),
# Test clean up
dict(
desc='Delete %r' % rule1,
command=('selinuxusermap_del', [rule1], {}),
expected=dict(
result=dict(failed=u''),
value=rule1,
summary=u'Deleted SELinux User Map "%s"' % rule1,
)
),
dict(
desc='Try to delete non-existent %r' % rule1,
command=('selinuxusermap_del', [rule1], {}),
expected=errors.NotFound(reason='no such entry'),
),
# Some negative tests
dict(
desc='Create rule with unknown user%r' % rule1,
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'notfound')
),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Create rule with invalid user bad+user',
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'bad+user')
),
expected=errors.ValidationError(name='ipaselinuxuser', error='invalid name'),
),
dict(
desc='Create rule with invalid MCS xguest_u:s999',
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s999')
),
expected=errors.ValidationError(name='ipaselinuxuser', error='invalid name'),
),
dict(
desc='Create rule with invalid MLS xguest_u:s0:p88',
command=(
'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s0:p88')
),
expected=errors.ValidationError(name='ipaselinuxuser', error='invalid name'),
),
]