summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2012-01-13 11:34:04 -0500
committerMartin Kosek <mkosek@redhat.com>2012-01-18 10:03:05 +0100
commit4c4888190b78b0a4e58471235550d1709ef7e329 (patch)
tree74f73b8f0d5ee6d187a21d7f5a446a87c999ec82
parentbb854cedd62e69f0a5b570b7a669dbb3dab3b0a7 (diff)
downloadfreeipa-4c4888190b78b0a4e58471235550d1709ef7e329.tar.gz
freeipa-4c4888190b78b0a4e58471235550d1709ef7e329.tar.xz
freeipa-4c4888190b78b0a4e58471235550d1709ef7e329.zip
In sudo when the category is all do not allow members, and vice versa.
This is what we already do in the HBAC plugin, this ports it to Sudo. If a category (user, host, etc) is u'all' then we don't allow individual members be added. Conversely if there are members we don't allow the category be set to u'all'. https://fedorahosted.org/freeipa/ticket/1440
-rw-r--r--ipalib/plugins/hbacrule.py11
-rw-r--r--ipalib/plugins/sudorule.py75
-rw-r--r--tests/test_xmlrpc/test_sudorule_plugin.py98
3 files changed, 177 insertions, 7 deletions
diff --git a/ipalib/plugins/hbacrule.py b/ipalib/plugins/hbacrule.py
index 92b656d66..0fa44a590 100644
--- a/ipalib/plugins/hbacrule.py
+++ b/ipalib/plugins/hbacrule.py
@@ -96,10 +96,13 @@ def is_all(options, attribute):
"""
See if options[attribute] is lower-case 'all' in a safe way.
"""
- if attribute in options and \
- options[attribute] is not None and \
- options[attribute].lower() == 'all':
- return True
+ if attribute in options and options[attribute] is not None:
+ if type(options[attribute]) in (list, tuple):
+ value = options[attribute][0].lower()
+ else:
+ value = options[attribute].lower()
+ if value == 'all':
+ return True
else:
return False
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index 65a1d8541..df395ead2 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -20,6 +20,7 @@
from ipalib import api, errors
from ipalib import Str, StrEnum
from ipalib.plugins.baseldap import *
+from ipalib.plugins.hbacrule import is_all
from ipalib import _, ngettext
__doc__ = _("""
@@ -77,6 +78,8 @@ class sudorule(LDAPObject):
'description', 'usercategory', 'hostcategory',
'cmdcategory', 'memberuser', 'memberhost',
'memberallowcmd', 'memberdenycmd', 'ipasudoopt',
+ 'ipasudorunas', 'ipasudorunasgroup',
+ 'ipasudorunasusercategory', 'ipasudorunasgroupcategory',
]
uuid_attribute = 'ipauniqueid'
rdn_attribute = 'ipauniqueid'
@@ -232,6 +235,25 @@ class sudorule_mod(LDAPUpdate):
__doc__ = _('Modify Sudo Rule.')
msg_summary = _('Modified Sudo Rule "%(value)s"')
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+
+ if is_all(options, 'usercategory') and 'memberuser' in _entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_("user category cannot be set to 'all' while there are users"))
+ if is_all(options, 'hostcategory') and 'memberhost' in _entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_("host category cannot be set to 'all' while there are hosts"))
+ if is_all(options, 'cmdcategory') and ('memberallowcmd' or
+ 'memberdenywcmd') in _entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_("command category cannot be set to 'all' while there are allow or deny commands"))
+ if is_all(options, 'ipasudorunasusercategory') and 'ipasudorunas' in _entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_("user runAs category cannot be set to 'all' while there are users"))
+ if is_all(options, 'ipasudorunasgroupcategory') and 'ipasudorunasgroup' in _entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_("group runAs category cannot be set to 'all' while there are groups"))
+
+ return dn
api.register(sudorule_mod)
@@ -306,6 +328,16 @@ class sudorule_add_allow_command(LDAPAddMember):
member_attributes = ['memberallowcmd']
member_count_out = ('%i object added.', '%i objects added.')
+ def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'cmdcategory'):
+ raise errors.MutuallyExclusiveError(reason=_("commands cannot be added when command category='all'"))
+
+ return dn
+
api.register(sudorule_add_allow_command)
@@ -324,6 +356,15 @@ class sudorule_add_deny_command(LDAPAddMember):
member_attributes = ['memberdenycmd']
member_count_out = ('%i object added.', '%i objects added.')
+ def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'cmdcategory'):
+ raise errors.MutuallyExclusiveError(reason=_("commands cannot be added when command category='all'"))
+ return dn
+
api.register(sudorule_add_deny_command)
@@ -342,6 +383,15 @@ class sudorule_add_user(LDAPAddMember):
member_attributes = ['memberuser']
member_count_out = ('%i object added.', '%i objects added.')
+ def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'usercategory'):
+ raise errors.MutuallyExclusiveError(reason=_("users cannot be added when user category='all'"))
+ return dn
+
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
completed_external = 0
# Sift through the user failures. We assume that these are all
@@ -410,6 +460,15 @@ class sudorule_add_host(LDAPAddMember):
member_attributes = ['memberhost']
member_count_out = ('%i object added.', '%i objects added.')
+ def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'hostcategory'):
+ raise errors.MutuallyExclusiveError(reason=_("hosts cannot be added when host category='all'"))
+ return dn
+
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
completed_external = 0
# Sift through the host failures. We assume that these are all
@@ -485,6 +544,14 @@ class sudorule_add_runasuser(LDAPAddMember):
return False
return True
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'ipasudorunasusercategory') or \
+ is_all(_entry_attrs, 'ipasudorunasgroupcategory'):
+ raise errors.MutuallyExclusiveError(reason=_("users cannot be added when runAs user or runAs group category='all'"))
+
if 'user' in options:
for name in options['user']:
if not check_validity(name):
@@ -575,6 +642,14 @@ class sudorule_add_runasgroup(LDAPAddMember):
return False
return True
+ try:
+ (_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(_entry_attrs, 'ipasudorunasusercategory') or \
+ is_all(_entry_attrs, 'ipasudorunasgroupcategory'):
+ raise errors.MutuallyExclusiveError(reason=_("users cannot be added when runAs user or runAs group category='all'"))
+
if 'group' in options:
for name in options['group']:
if not check_validity(name):
diff --git a/tests/test_xmlrpc/test_sudorule_plugin.py b/tests/test_xmlrpc/test_sudorule_plugin.py
index 88e31c72c..07d23c3d2 100644
--- a/tests/test_xmlrpc/test_sudorule_plugin.py
+++ b/tests/test_xmlrpc/test_sudorule_plugin.py
@@ -47,7 +47,7 @@ class test_sudorule(XMLRPC_test):
test_denycommand = u'/usr/bin/testdenysudocmd1'
test_runasuser = u'manager'
test_runasgroup = u'manager'
- test_catagory = u'all'
+ test_category = u'all'
test_option = u'authenticate'
def test_0_sudorule_add(self):
@@ -520,7 +520,99 @@ class test_sudorule(XMLRPC_test):
assert 'memberdenycmd_sudocmd' not in entry
assert 'memberdenycmd_sudocmdgroup' not in entry
- def test_c_sudorule_clear_testing_data(self):
+ def test_c_sudorule_exclusiveuser(self):
+ """
+ Test adding a user to an Sudo rule when usercat='all'
+ """
+ api.Command['sudorule_mod'](self.rule_name, usercategory=u'all')
+ try:
+ api.Command['sudorule_add_user'](self.rule_name, users='admin')
+ except errors.MutuallyExclusiveError:
+ pass
+ api.Command['sudorule_mod'](self.rule_name, usercategory=u'')
+
+ def test_d_sudorule_exclusiveuser(self):
+ """
+ Test setting usercat='all' in an Sudo rule when there are users
+ """
+ api.Command['sudorule_add_user'](self.rule_name, users='admin')
+ try:
+ api.Command['sudorule_mod'](self.rule_name, usercategory=u'all')
+ except errors.MutuallyExclusiveError:
+ pass
+ finally:
+ api.Command['sudorule_remove_user'](self.rule_name, users='admin')
+
+ def test_e_sudorule_exclusivehost(self):
+ """
+ Test adding a host to an Sudo rule when hostcat='all'
+ """
+ api.Command['sudorule_mod'](self.rule_name, hostcategory=u'all')
+ try:
+ api.Command['sudorule_add_host'](self.rule_name, host=self.test_host)
+ except errors.MutuallyExclusiveError:
+ pass
+ api.Command['sudorule_mod'](self.rule_name, hostcategory=u'')
+
+ def test_f_sudorule_exclusivehost(self):
+ """
+ Test setting hostcat='all' in an Sudo rule when there are hosts
+ """
+ api.Command['sudorule_add_host'](self.rule_name, host=self.test_host)
+ try:
+ api.Command['sudorule_mod'](self.rule_name, hostcategory=u'all')
+ except errors.MutuallyExclusiveError:
+ pass
+ finally:
+ api.Command['sudorule_remove_host'](self.rule_name, host=self.test_host)
+
+ def test_g_sudorule_exclusivecommand(self):
+ """
+ Test adding a command to an Sudo rule when cmdcategory='all'
+ """
+ api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'all')
+ try:
+ api.Command['sudorule_add_allow_command'](self.rule_name, sudocmd=self.test_command)
+ except errors.MutuallyExclusiveError:
+ pass
+ api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'')
+
+ def test_h_sudorule_exclusivecommand(self):
+ """
+ Test setting cmdcategory='all' in an Sudo rule when there are commands
+ """
+ api.Command['sudorule_add_allow_command'](self.rule_name, sudocmd=self.test_command)
+ try:
+ api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'all')
+ except errors.MutuallyExclusiveError:
+ pass
+ finally:
+ api.Command['sudorule_remove_allow_command'](self.rule_name, sudocmd=self.test_command)
+
+ def test_i_sudorule_exclusiverunas(self):
+ """
+ Test adding a runasuser to an Sudo rule when ipasudorunasusercategory='all'
+ """
+ api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'all')
+ try:
+ api.Command['sudorule_add_runasuser'](self.rule_name, sudocmd=self.test_user)
+ except errors.MutuallyExclusiveError:
+ pass
+ api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'')
+
+ def test_j_sudorule_exclusiverunas(self):
+ """
+ Test setting ipasudorunasusercategory='all' in an Sudo rule when there are runas users
+ """
+ api.Command['sudorule_add_runasuser'](self.rule_name, user=self.test_user)
+ try:
+ api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'all')
+ except errors.MutuallyExclusiveError:
+ pass
+ finally:
+ api.Command['sudorule_remove_runasuser'](self.rule_name, user=self.test_command)
+
+ def test_k_sudorule_clear_testing_data(self):
"""
Clear data for Sudo rule plugin testing.
"""
@@ -534,7 +626,7 @@ class test_sudorule(XMLRPC_test):
api.Command['sudocmdgroup_del'](self.test_sudodenycmdgroup)
- def test_f_sudorule_del(self):
+ def test_l_sudorule_del(self):
"""
Test deleting a Sudo rule using `xmlrpc.sudorule_del`.
"""