Dmitri Pal wrote:
Rob Crittenden wrote:
If an HBAC category is 'all' don't allow individual objects to be added.

Basically, make 'all' mutually exclusive. This makes debugging lots
easier. If say usercat='all' there is no point adding specific users
to the rule because it will always apply to everyone.

ticket 164



Comparison to 'all' should be case insensitive.
I do not know Python syntax but from general experience I assume it is a
NACK.


Using our tools the only available option is lower-case 'all':

$ ipa hbac-add test --usercat=ALL --type=allow
ipa: ERROR: invalid 'usercategory': must be one of (u'all',)

In any case, better to be robust. Updated patch attached.

rob
>From 801004392a6ea6840d5f1bf3fb471a9d5647aefe Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Wed, 15 Sep 2010 09:20:14 -0400
Subject: [PATCH] If an HBAC category is 'all' don't allow individual objects to
 be added.

Basically, make 'all' mutually exclusive. This makes debugging lots easier.
If say usercat='all' there is no point adding specific users to the rule
because it will always apply to everyone.

ticket 164
---
 ipalib/errors.py                      |   17 +++++++
 ipalib/plugins/hbac.py                |   44 +++++++++++++++++++
 tests/test_xmlrpc/test_hbac_plugin.py |   75 ++++++++++++++++++++++++++++++++-
 3 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/ipalib/errors.py b/ipalib/errors.py
index efd0d64..0d1304e 100644
--- a/ipalib/errors.py
+++ b/ipalib/errors.py
@@ -1221,6 +1221,23 @@ class CertificateOperationError(ExecutionError):
     format = _('Certificate operation cannot be completed: %(error)s')
 
 
+class MutuallyExclusiveError(ExecutionError):
+    """
+    **4302** Raised when an operation would result in setting two attributes which are mutually exlusive.
+
+    For example:
+
+    >>> raise MutuallyExclusiveError(reason=u'hosts may not be added when hostcategory=all')
+    Traceback (most recent call last):
+      ...
+    MutuallyExclusiveError: hosts may not be added when hostcategory=all
+
+    """
+
+    errno = 4302
+    format = _('%(reason)s')
+
+
 ##############################################################################
 # 5000 - 5999: Generic errors
 
diff --git a/ipalib/plugins/hbac.py b/ipalib/plugins/hbac.py
index 4d7681c..b336f6a 100644
--- a/ipalib/plugins/hbac.py
+++ b/ipalib/plugins/hbac.py
@@ -222,6 +222,22 @@ class hbac_mod(LDAPUpdate):
     Modify an HBAC rule.
     """
 
+    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+        (dn, entry_attrs) = ldap.get_entry(dn, attrs_list)
+        if 'usercategory' in options and options['usercategory'].lower() == 'all' and \
+            'memberuser' in entry_attrs:
+            raise errors.MutuallyExclusiveError(reason="user category cannot be set to 'all' while there are allowed users")
+        if 'hostcategory' in options and options['hostcategory'].lower() == 'all' and \
+            'memberhost' in entry_attrs:
+            raise errors.MutuallyExclusiveError(reason="host category cannot be set to 'all' while there are allowed hosts")
+        if 'sourcehostcategory' in options and options['sourcehostcategory'].lower() == 'all' and \
+            'sourcehost' in entry_attrs:
+            raise errors.MutuallyExclusiveError(reason="sourcehost category cannot be set to 'all' while there are allowed source hosts")
+        if 'servicecategory' in options and options['servicecategory'].lower() == 'all' and \
+            'memberservice' in entry_attrs:
+            raise errors.MutuallyExclusiveError(reason="service category cannot be set to 'all' while there are allowed services")
+        return dn
+
 api.register(hbac_mod)
 
 
@@ -373,6 +389,13 @@ class hbac_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):
+        (dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+        if 'usercategory' in entry_attrs and \
+            entry_attrs['usercategory'][0].lower() == 'all':
+            raise errors.MutuallyExclusiveError(reason="users cannot be added when user category='all'")
+        return dn
+
 api.register(hbac_add_user)
 
 
@@ -393,6 +416,13 @@ class hbac_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):
+        (dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+        if 'hostcategory' in entry_attrs and \
+            entry_attrs['hostcategory'][0].lower() == 'all':
+            raise errors.MutuallyExclusiveError(reason="hosts cannot be added when host category='all'")
+        return dn
+
 api.register(hbac_add_host)
 
 
@@ -413,6 +443,13 @@ class hbac_add_sourcehost(LDAPAddMember):
     member_attributes = ['sourcehost']
     member_count_out = ('%i object added.', '%i objects added.')
 
+    def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+        (dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+        if 'sourcehostcategory' in entry_attrs and \
+            entry_attrs['sourcehostcategory'][0].lower() == 'all':
+            raise errors.MutuallyExclusiveError(reason="source hosts cannot be added when sourcehost category='all'")
+        return dn
+
 api.register(hbac_add_sourcehost)
 
 
@@ -433,6 +470,13 @@ class hbac_add_service(LDAPAddMember):
     member_attributes = ['memberservice']
     member_count_out = ('%i object added.', '%i objects added.')
 
+    def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+        (dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
+        if 'servicecategory' in entry_attrs and \
+            entry_attrs['servicecategory'][0].lower() == 'all':
+            raise errors.MutuallyExclusiveError(reason="services cannot be added when service category='all'")
+        return dn
+
 api.register(hbac_add_service)
 
 
diff --git a/tests/test_xmlrpc/test_hbac_plugin.py b/tests/test_xmlrpc/test_hbac_plugin.py
index d908374..2405355 100644
--- a/tests/test_xmlrpc/test_hbac_plugin.py
+++ b/tests/test_xmlrpc/test_hbac_plugin.py
@@ -306,6 +306,8 @@ class test_hbac(XMLRPC_test):
         """
         Clear data for HBAC plugin testing.
         """
+        api.Command['hbac_remove_host'](self.rule_name, host=self.test_host)
+        api.Command['hbac_remove_host'](self.rule_name, hostgroup=self.test_hostgroup)
         api.Command['user_del'](self.test_user)
         api.Command['group_del'](self.test_group)
         api.Command['host_del'](self.test_host)
@@ -333,9 +335,78 @@ class test_hbac(XMLRPC_test):
          # FIXME: Should this be 'enabled' or 'TRUE'?
         assert_attr_equal(entry, 'ipaenabledflag', 'TRUE')
 
-    def test_f_hbac_del(self):
+    def test_f_hbac_exclusiveuser(self):
         """
-        Test deleting a HBAC rule using `xmlrpc.hbac_remove_sourcehost`.
+        Test adding a user to an HBAC rule when usercat='all'
+        """
+        api.Command['hbac_mod'](self.rule_name, usercategory=u'all')
+        try:
+            api.Command['hbac_add_user'](self.rule_name, users='admin')
+        except errors.MutuallyExclusiveError:
+            pass
+        api.Command['hbac_mod'](self.rule_name, usercategory=u'')
+
+    def test_g_hbac_exclusiveuser(self):
+        """
+        Test setting usercat='all' in an HBAC rule when there are users
+        """
+        api.Command['hbac_add_user'](self.rule_name, users='admin')
+        try:
+            api.Command['hbac_mod'](self.rule_name, usercategory=u'all')
+        except errors.MutuallyExclusiveError:
+            pass
+        finally:
+            api.Command['hbac_remove_user'](self.rule_name, users='admin')
+
+    def test_h_hbac_exclusivehost(self):
+        """
+        Test adding a host to an HBAC rule when hostcat='all'
+        """
+        api.Command['hbac_mod'](self.rule_name, hostcategory=u'all')
+        try:
+            api.Command['hbac_add_host'](self.rule_name, host=self.test_host)
+        except errors.MutuallyExclusiveError:
+            pass
+        api.Command['hbac_mod'](self.rule_name, hostcategory=u'')
+
+    def test_i_hbac_exclusivehost(self):
+        """
+        Test setting hostcat='all' in an HBAC rule when there are hosts
+        """
+        api.Command['hbac_add_host'](self.rule_name, host=self.test_host)
+        try:
+            api.Command['hbac_mod'](self.rule_name, hostcategory=u'all')
+        except errors.MutuallyExclusiveError:
+            pass
+        finally:
+            api.Command['hbac_remove_host'](self.rule_name, host=self.test_host)
+
+    def test_j_hbac_exclusiveservice(self):
+        """
+        Test adding a service to an HBAC rule when servicecat='all'
+        """
+        api.Command['hbac_mod'](self.rule_name, servicecategory=u'all')
+        try:
+            api.Command['hbac_add_host'](self.rule_name, hbacsvc=self.test_service)
+        except errors.MutuallyExclusiveError:
+            pass
+        api.Command['hbac_mod'](self.rule_name, servicecategory=u'')
+
+    def test_k_hbac_exclusiveservice(self):
+        """
+        Test setting servicecat='all' in an HBAC rule when there are services
+        """
+        api.Command['hbac_add_service'](self.rule_name, hbacsvc=self.test_service)
+        try:
+            api.Command['hbac_mod'](self.rule_name, servicecategory=u'all')
+        except errors.MutuallyExclusiveError:
+            pass
+        finally:
+            api.Command['hbac_remove_service'](self.rule_name, hbacsvc=self.test_service)
+
+    def test_z_hbac_del(self):
+        """
+        Test deleting a HBAC rule using `xmlrpc.hbac_del`.
         """
         assert api.Command['hbac_del'](self.rule_name)['result'] is True
         # verify that it's gone
-- 
1.7.2.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to