On 02/06/2013 07:57 PM, Rob Crittenden wrote:
Tomas Babej wrote:
Hi,

this pair of patches improves HBAC rule handling in selinuxusermap
commands.

Patch 0031 deals with:
https://fedorahosted.org/freeipa/ticket/3349

Patch 0032 takes care of:
https://fedorahosted.org/freeipa/ticket/3348

and is to be applied on top of Patch 0031.

See commit messages for detailed info.

Tomas


ACK for patch 0032.

For patch 0031 we can't change the data type of an existing attribute. It will break backwards compatibility. Can you test with an older client to see if it cares (it may not care about the name of the type). If older clients will work then this is probably ok.

I gather that seealso detected as a DN attribute and converted into a DN class and this is blowing up the Str validator?

Yes, that was exactly the case.
rob

I added a workaround for older client versions, tested it with freeipa-client/admintools 2.2, works as expeceted. However, this only should be issue if there is older admintools package on the client than on the server.

Outline is such as follows: I added a new flag for DNParam seelalso attribute, called 'allow_malformed' that allows any string to be passed to DNParam. Its value gets wrapped in 'malformed=yes,value=<value>'. This allows to parse out the string in selinuxusermap-add/mod pre_callback out of the DN and search for the rule with such name so that it's DN gets in LDAP instead.

Updated patch attached.

Tomas
>From 7bc8d9a5743f12acbf1faad3901a7e1200000397 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Wed, 6 Feb 2013 07:04:03 -0500
Subject: [PATCH] Improve HBAC rule handling in selinuxusermap-add/mod/find

Pre-patch handling of HBAC rules in selinuxusermap commands tried
to allow the user to specify the HBAC rule using the rule's name.

However, this approach created obstacles to modifying the HBAC
rule's DN directly in LDAP (attribute 'seealso') using --setattr
or --addattr options.

This patchs removes the option for setting 'seealso' via CLI
option(named 'hbacrule') and creates a new virtual attribute
(named 'hbacrule'). If 'hbacrule' is set, rule's DN is resolved
and set to 'seealso' attribute. This allows the user to specify
the rule comfortably using its name as well as modify the entry
directly using --setattr/--addattr.

Backwards compatibility with older freeipa-admintools packages
is ensured. Setting HBAC rule via --hbacrule option using its
name, and seeting HBAC rule via --setattr=seealso using its
DN works in both older and new client versions.

https://fedorahosted.org/freeipa/ticket/3349
---
 API.txt                                         |  15 +-
 ipalib/parameters.py                            |  10 +-
 ipalib/plugins/hbacrule.py                      |   2 +-
 ipalib/plugins/selinuxusermap.py                | 139 ++++++++++++----
 tests/test_xmlrpc/test_selinuxusermap_plugin.py | 204 +++++++++++++++++++-----
 5 files changed, 288 insertions(+), 82 deletions(-)

diff --git a/API.txt b/API.txt
index 8fbfe6f5d8da44e991b8d1a36725fc6ace1f0616..ee76871d15ba30bff18e5d16858ede615b046a96 100644
--- a/API.txt
+++ b/API.txt
@@ -2607,16 +2607,17 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('value', <type 'unicode'>, None)
 command: selinuxusermap_add
-args: 1,11,3
+args: 1,12,3
 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
+option: Str('hbacrule', attribute=False, cli_name='hbacrule', multivalue=False, required=False)
 option: StrEnum('hostcategory', attribute=True, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
 option: Bool('ipaenabledflag', attribute=True, cli_name='ipaenabledflag', multivalue=False, required=False)
 option: Str('ipaselinuxuser', attribute=True, cli_name='selinuxuser', multivalue=False, required=True)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-option: Str('seealso', attribute=True, cli_name='hbacrule', multivalue=False, required=False)
+option: DNParam('seealso', attribute=True, cli_name='seealso', multivalue=False, required=False)
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: StrEnum('usercategory', attribute=True, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
 option: Str('version?', exclude='webui')
@@ -2665,17 +2666,18 @@ output: Output('result', <type 'bool'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('value', <type 'unicode'>, None)
 command: selinuxusermap_find
-args: 1,13,4
+args: 1,14,4
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('cn', attribute=True, autofill=False, cli_name='name', multivalue=False, primary_key=True, query=True, required=False)
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Str('hbacrule', attribute=False, autofill=False, cli_name='hbacrule', multivalue=False, query=True, required=False)
 option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostcat', multivalue=False, query=True, required=False, values=(u'all',))
 option: Bool('ipaenabledflag', attribute=True, autofill=False, cli_name='ipaenabledflag', multivalue=False, query=True, required=False)
 option: Str('ipaselinuxuser', attribute=True, autofill=False, cli_name='selinuxuser', multivalue=False, query=True, required=False)
 option: Flag('pkey_only?', autofill=True, default=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-option: Str('seealso', attribute=True, autofill=False, cli_name='hbacrule', multivalue=False, query=True, required=False)
+option: DNParam('seealso', attribute=True, autofill=False, cli_name='seealso', multivalue=False, query=True, required=False)
 option: Int('sizelimit?', autofill=False, minvalue=0)
 option: Int('timelimit?', autofill=False, minvalue=0)
 option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, query=True, required=False, values=(u'all',))
@@ -2685,18 +2687,19 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: selinuxusermap_mod
-args: 1,13,3
+args: 1,14,3
 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
+option: Str('hbacrule', attribute=False, autofill=False, cli_name='hbacrule', multivalue=False, required=False)
 option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
 option: Bool('ipaenabledflag', attribute=True, autofill=False, cli_name='ipaenabledflag', multivalue=False, required=False)
 option: Str('ipaselinuxuser', attribute=True, autofill=False, cli_name='selinuxuser', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Flag('rights', autofill=True, default=False)
-option: Str('seealso', attribute=True, autofill=False, cli_name='hbacrule', multivalue=False, required=False)
+option: DNParam('seealso', attribute=True, autofill=False, cli_name='seealso', multivalue=False, required=False)
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
 option: Str('version?', exclude='webui')
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index 2e26923ddc1bd14fbb04b0a4f28d79368f37552a..fe5aaea042cc926d85fbae87e0e11687c9e2af70 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -1859,12 +1859,16 @@ class DNParam(Param):
         """
         if type(value) is self.type:
             return value
-
         try:
             dn = DN(value)
         except Exception, e:
-            raise ConversionError(name=self.get_param_name(), index=index,
-                                  error=ugettext(e))
+            # this is workaround that ensures backwards compatibility
+            # in selinuxusermap.py
+            if 'allow_malformed' in self.flags:
+                dn = DN(('malformed','yes'),('value',value))
+            else:
+                raise ConversionError(name=self.get_param_name(), index=index,
+                                      error=ugettext(e))
         return dn
 
 def create_param(spec):
diff --git a/ipalib/plugins/hbacrule.py b/ipalib/plugins/hbacrule.py
index 0b1e8b83cd436fe6eaecafeefc37882c0f859be3..704f292dcb152ee322136b1e942fc525a240e646 100644
--- a/ipalib/plugins/hbacrule.py
+++ b/ipalib/plugins/hbacrule.py
@@ -246,7 +246,7 @@ class hbacrule_del(LDAPDelete):
 
     def pre_callback(self, ldap, dn, *keys, **options):
         assert isinstance(dn, DN)
-        kw = dict(seealso=keys[0])
+        kw = dict(hbacrule=keys[0])
         _entries = api.Command.selinuxusermap_find(None, **kw)
         if _entries['count']:
             raise errors.DependentEntry(key=keys[0], label=self.api.Object['selinuxusermap'].label_singular, dependent=_entries['result'][0]['cn'][0])
diff --git a/ipalib/plugins/selinuxusermap.py b/ipalib/plugins/selinuxusermap.py
index 32c55850b7d5b78f39cfae8960b8588a35b30251..8652f50747d72333834f57e463558f409e29c7dc 100644
--- a/ipalib/plugins/selinuxusermap.py
+++ b/ipalib/plugins/selinuxusermap.py
@@ -18,7 +18,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from ipalib import api, errors
-from ipalib import Str, StrEnum, Bool
+from ipalib import Str, StrEnum, Bool, DNParam
 from ipalib.plugins.baseldap import *
 from ipalib import _, ngettext
 from ipalib.plugins.hbacrule import is_all
@@ -162,11 +162,16 @@ class selinuxusermap(LDAPObject):
             cli_name='selinuxuser',
             label=_('SELinux User'),
         ),
-        Str('seealso?',
+        Str('hbacrule?',
             cli_name='hbacrule',
             label=_('HBAC Rule'),
+            flags=('virtual_attribute'),
             doc=_('HBAC Rule that defines the users, groups and hostgroups'),
         ),
+        DNParam('seealso?',
+            label=_('HBAC Rule'),
+            flags=('no_option','allow_malformed'),
+        ),
         StrEnum('usercategory?',
             cli_name='usercat',
             label=_('User category'),
@@ -205,29 +210,60 @@ class selinuxusermap(LDAPObject):
         ),
     )
 
-    def _normalize_seealso(self, seealso):
+    def _normalize_seealso(self, entry_attrs, **options):
         """
-        Given a HBAC rule name verify its existence and return the dn.
+        Given command's input, verify existence of HBAC rule and return
+        the dn. Deal with differences between client versions.
         """
-        if not seealso:
-            return None
 
+        value = None
+
+        if 'seealso' in entry_attrs:
+            # either valid DN or HBAC rule's name or invalid
+
+            # seealso can contain:
+            #   - DN from --setattr=seealso
+            #   - rule name from --hbacrule (3.1 admintools and older)
+
+            # there is a workaround in DNParam that transforms not valid
+            # DN output to malformed=yes,value=value if allow_malformed
+            # flag is set
+            if entry_attrs['seealso'].startswith(DN('malformed=yes')):
+                 # either HBAC rule's name or invalid
+                 value = entry_attrs['seealso'][1][0].value
+            else:
+                # valid DN was passed
+                return str(entry_attrs['seealso'])
+
+        elif 'hbacrule' in options:
+            # valid HBAC rule's name or invalid
+            value = options['hbacrule']
+
+        # now value contains either rule's name or something invalid
         try:
-            dn = DN(seealso)
-            return str(dn)
-        except ValueError:
+            (dn, entry_attrs) = self.backend.find_entry_by_attr(
+                self.api.Object['hbacrule'].primary_key.name,
+                value,
+                self.api.Object['hbacrule'].object_class,
+                [''],
+                self.api.Object['hbacrule'].container_dn)
+            # found the rule, return DN
+            return dn
+        except errors.NotFound:
+            # Be user-friendly and detect whether user did not try to enter
+            # the rule's DN using --hbacrule option. If that is the case,
+            # inform the user that rule's name should have been used instead.
             try:
-                (dn, entry_attrs) = self.backend.find_entry_by_attr(
-                    self.api.Object['hbacrule'].primary_key.name,
-                    seealso,
-                    self.api.Object['hbacrule'].object_class,
-                    [''],
-                    self.api.Object['hbacrule'].container_dn)
-                seealso = dn
-            except errors.NotFound:
-                raise errors.NotFound(reason=_('HBAC rule %(rule)s not found') % dict(rule=seealso))
-
-        return seealso
+                DN(value)
+                raise errors.NotFound(reason=_("It seems that you tried to "
+                    "enter the HBAC rule's DN using --hbacrule option. \n"
+                    "Please specify the rule's name instead. For editing "
+                    "DN directly, use ldapmodify or --setattr=seealso="
+                    "<rule's DN>. \n\n"
+                    "HBAC rule %s not found" % value))
+            except: # we should really catch anything here, to avoid regression
+                raise errors.NotFound(reason=_('HBAC rule %s not found'\
+                                               % value))
 
     def _convert_seealso(self, ldap, entry_attrs, **options):
         """
@@ -237,9 +273,18 @@ class selinuxusermap(LDAPObject):
             return
 
         if 'seealso' in entry_attrs:
-            (hbac_dn, hbac_attrs) = ldap.get_entry(entry_attrs['seealso'][0], ['cn'])
+            (hbac_dn, hbac_attrs) = ldap.get_entry(entry_attrs['seealso'][0],
+                                                   ['cn'])
             entry_attrs['seealso'] = hbac_attrs['cn'][0]
 
+    def check_seealso_validity(self, ldap, entry_attrs):
+         try:
+             ldap.get_entry(DN(entry_attrs['seealso']))
+         except errors.NotFound:
+             raise errors.NotFound(reason=_('HBAC rule with DN %s could not be '
+                                            'found') % entry_attrs['seealso'])
+
+
 api.register(selinuxusermap)
 
 
@@ -250,24 +295,36 @@ class selinuxusermap_add(LDAPCreate):
 
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
+
         # rules are enabled by default
         entry_attrs['ipaenabledflag'] = 'TRUE'
         validate_selinuxuser_inlist(ldap, entry_attrs['ipaselinuxuser'])
 
-        # hbacrule is not allowed when usercat or hostcat is set
-        is_to_be_set = lambda x: x in entry_attrs and entry_attrs[x] != None
+        # auxiliary functions and booleans
 
-        are_local_members_to_be_set = any(is_to_be_set(attr)
+        # entry_attrs.get(attr) evaluates to False if attr does not exist
+        # or is set to None
+        are_local_members_to_be_set = any(entry_attrs.get(attr)
                                           for attr in ('usercategory',
                                                        'hostcategory'))
 
-        is_hbacrule_to_be_set = is_to_be_set('seealso')
+        is_hbacrule_to_be_set = options.get('hbacrule') or \
+                                entry_attrs.get('seealso')
 
+        # hbacrule cannot be set both via --hbacrule and --setattr=seealso=
+        if options.get('hbacrule') and entry_attrs.get('seealso'):
+            raise errors.MutuallyExclusiveError(reason="You cannot specify "
+                "HBAC rule using both --hbacrule and --setattr. Pick one.")
+
+        # hbacrule is not allowed when usercat or hostcat is set
         if is_hbacrule_to_be_set and are_local_members_to_be_set:
             raise errors.MutuallyExclusiveError(reason=notboth_err)
 
         if is_hbacrule_to_be_set:
-            entry_attrs['seealso'] = self.obj._normalize_seealso(entry_attrs['seealso'])
+            entry_attrs['seealso'] = self.obj._normalize_seealso(entry_attrs,
+                                                                 **options)
+            # sanity check
+            self.obj.check_seealso_validity(ldap, entry_attrs)
 
         return dn
 
@@ -305,8 +362,10 @@ class selinuxusermap_mod(LDAPUpdate):
 
         # makes sure the local members and hbacrule is not set at the same time
         # memberuser or memberhost could have been set using --setattr
-        is_to_be_set = lambda x: ((x in _entry_attrs and _entry_attrs[x] != None) or \
-                                 (x in entry_attrs and entry_attrs[x] != None)) and \
+
+        # entry_attrs.get(attr) evaluates to False if attr does not exist
+        # or is set to None
+        is_to_be_set = lambda x: (_entry_attrs.get(x) or entry_attrs.get(x)) and \
                                  not is_to_be_deleted(x)
 
         are_local_members_to_be_set = any(is_to_be_set(attr)
@@ -315,13 +374,19 @@ class selinuxusermap_mod(LDAPUpdate):
                                                        'memberuser',
                                                        'memberhost'))
 
-        is_hbacrule_to_be_set = is_to_be_set('seealso')
+        is_hbacrule_to_be_set = is_to_be_set('seealso') or \
+                                options.get('hbacrule')
 
         # this can disable all modifications if hbacrule and local members were
         # set at the same time bypassing this commad, e.g. using ldapmodify
         if are_local_members_to_be_set and is_hbacrule_to_be_set:
             raise errors.MutuallyExclusiveError(reason=notboth_err)
 
+        # hbacrule cannot be set both via --hbacrule and --setattr=seealso=
+        if options.get('hbacrule') and entry_attrs.get('seealso'):
+            raise errors.MutuallyExclusiveError(reason="You cannot specify "
+                "HBAC rule using both --hbacrule and --setattr. Pick one.")
+
         if is_all(entry_attrs, 'usercategory') and 'memberuser' in entry_attrs:
             raise errors.MutuallyExclusiveError(reason="user category "
                  "cannot be set to 'all' while there are allowed users")
@@ -332,8 +397,12 @@ class selinuxusermap_mod(LDAPUpdate):
         if 'ipaselinuxuser' in entry_attrs:
             validate_selinuxuser_inlist(ldap, entry_attrs['ipaselinuxuser'])
 
-        if 'seealso' in entry_attrs:
-            entry_attrs['seealso'] = self.obj._normalize_seealso(entry_attrs['seealso'])
+        if is_hbacrule_to_be_set:
+            entry_attrs['seealso'] = self.obj._normalize_seealso(entry_attrs,
+                                                                 **options)
+            # sanity check
+            self.obj.check_seealso_validity(ldap, entry_attrs)
+
         return dn
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -353,12 +422,12 @@ class selinuxusermap_find(LDAPSearch):
 
     def execute(self, *args, **options):
         # If searching on hbacrule we need to find the uuid to search on
-        if options.get('seealso'):
-            hbacrule = options['seealso']
+        if options.get('hbacrule'):
+            hbacrule = options['hbacrule']
 
             try:
-                hbac = api.Command['hbacrule_show'](hbacrule,
-all=True)['result']
+                hbac = api.Command['hbacrule_show'](hbacrule, all=True)\
+                       ['result']
                 dn = hbac['dn']
             except errors.NotFound:
                 return dict(count=0, result=[], truncated=False)
diff --git a/tests/test_xmlrpc/test_selinuxusermap_plugin.py b/tests/test_xmlrpc/test_selinuxusermap_plugin.py
index 816e7673584cc5adba4e40de4fcc9527e19ee2b2..b12df7789a22eaab59d2773e1a0b3190a775d120 100644
--- a/tests/test_xmlrpc/test_selinuxusermap_plugin.py
+++ b/tests/test_xmlrpc/test_selinuxusermap_plugin.py
@@ -40,12 +40,16 @@ hbacrule2 = u'testhbacrule12'
 
 # Note (?i) at the beginning of the regexp is the ingnore case flag
 fuzzy_selinuxusermapdn = Fuzzy(
-    '(?i)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)
+    '(?i)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(
-    '(?i)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)
+    '(?i)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)
 )
 
+allow_all_rule_dn = api.Command['hbacrule_show'](u'allow_all')['result']['dn']
+
 class test_selinuxusermap(Declarative):
     cleanup_commands = [
         ('selinuxusermap_del', [rule1], {}),
@@ -85,7 +89,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule %r' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1)
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1)
             ),
             expected=dict(
                 value=rule1,
@@ -105,7 +111,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Try to create duplicate %r' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1)
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1)
             ),
             expected=errors.DuplicateEntry(message=u'SELinux User Map rule ' +
                 u'with name "%s" already exists' % rule1),
@@ -131,7 +139,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Update rule %r' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(ipaselinuxuser=selinuxuser2)
+                'selinuxusermap_mod',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser2)
             ),
             expected=dict(
                 result=dict(
@@ -206,9 +216,13 @@ class test_selinuxusermap(Declarative):
                     cn=[u'Test User1'],
                     initials=[u'TU'],
                     ipauniqueid=[fuzzy_uuid],
-                    krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm),
-                                              ('cn','kerberos'),api.env.basedn)],
-                    mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'),
+                    krbpwdpolicyreference=[DN(('cn','global_policy'),
+                                              ('cn',api.env.realm),
+                                              ('cn','kerberos'),
+                                              api.env.basedn)],
+                    mepmanagedentry=[DN(('cn',user1),
+                                        ('cn','groups'),
+                                        ('cn','accounts'),
                                         api.env.basedn)],
                     memberof_group=[u'ipausers'],
                     dn=DN(('uid',user1),('cn','users'),('cn','accounts'),
@@ -254,8 +268,8 @@ class test_selinuxusermap(Declarative):
                     ),
                 ),
                 result={
-                        'dn': DN(('cn',group1),('cn','groups'),('cn','accounts'),
-                                 api.env.basedn),
+                        'dn': DN(('cn',group1),('cn','groups'),
+                                 ('cn','accounts'), api.env.basedn),
                         'member_user': (user1,),
                         'gidnumber': [fuzzy_digits],
                         'cn': [group1],
@@ -354,9 +368,13 @@ class test_selinuxusermap(Declarative):
 
         dict(
             desc='Add non-existent user to %r' % rule1,
-            command=('selinuxusermap_add_user', [rule1], dict(user=u'notfound')),
+            command=('selinuxusermap_add_user',
+                     [rule1],
+                     dict(user=u'notfound')),
             expected=dict(
-                failed=dict(memberuser=dict(group=[], user=[(u'notfound', u'no such entry')])),
+                failed=dict(
+                    memberuser=dict(
+                        group=[], user=[(u'notfound', u'no such entry')])),
                 completed=0,
                 result=dict(
                     cn=[rule1],
@@ -387,9 +405,16 @@ class test_selinuxusermap(Declarative):
 
         dict(
             desc='Remove non-existent user to %r' % rule1,
-            command=('selinuxusermap_remove_user', [rule1], dict(user=u'notfound')),
+            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')])),
+                failed=dict(
+                    memberuser=dict(
+                        group=[],
+                        user=[(u'notfound', u'This entry is not a member')]
+                        )
+                    ),
                 completed=0,
                 result=dict(
                     cn=[rule1],
@@ -478,7 +503,7 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add an HBAC rule to %r that has other members' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1)
+                'selinuxusermap_mod', [rule1], dict(hbacrule=hbacrule1)
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -504,7 +529,9 @@ class test_selinuxusermap(Declarative):
 
         dict(
             desc='Remove group from %r' % rule1,
-            command=('selinuxusermap_remove_user', [rule1], dict(group=group1)),
+            command=('selinuxusermap_remove_user',
+                     [rule1],
+                     dict(group=group1)),
             expected=dict(
                 failed=dict(memberuser=dict(group=[], user=[])),
                 completed=1,
@@ -521,7 +548,7 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add non-existent HBAC rule to %r' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(seealso=u'notfound')
+                'selinuxusermap_mod', [rule1], dict(hbacrule=u'notfound')
             ),
             expected=errors.NotFound(
                 reason=u'HBAC rule notfound not found'),
@@ -531,7 +558,7 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add an HBAC rule to %r' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1)
+                'selinuxusermap_mod', [rule1], dict(hbacrule=hbacrule1)
             ),
             expected=dict(
                 result=dict(
@@ -565,7 +592,9 @@ class test_selinuxusermap(Declarative):
         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)
+            expected=errors.DependentEntry(key=hbacrule1,
+                                           label=u'SELinux User Map',
+                                           dependent=rule1)
         ),
 
 
@@ -606,10 +635,12 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with unknown user %r' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'notfound:s0:c0')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=u'notfound:s0:c0')
             ),
-            expected=errors.NotFound(reason=u'SELinux user notfound:s0:c0 not ' +
-                u'found in ordering list (in config)'),
+            expected=errors.NotFound(reason=u'SELinux user notfound:s0:c0 ' +
+                u'not found in ordering list (in config)'),
         ),
 
 
@@ -626,7 +657,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with invalid MCS xguest_u:s999',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s999')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=u'xguest_u:s999')
             ),
             expected=errors.ValidationError(name='selinuxuser',
                 error=u'Invalid MLS value, must match s[0-15](-s[0-15])'),
@@ -636,7 +669,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with invalid MLS xguest_u:s0:p88',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s0:p88')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=u'xguest_u:s0:p88')
             ),
             expected=errors.ValidationError(name='selinuxuser',
                 error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' +
@@ -647,7 +682,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with invalid MLS xguest_u:s0:c0.c1028',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s0-s0:c0.c1028')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=u'xguest_u:s0-s0:c0.c1028')
             ),
             expected=errors.ValidationError(name='selinuxuser',
                 error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' +
@@ -658,7 +695,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with invalid user via setattr',
             command=(
-                'selinuxusermap_mod', [rule1], dict(setattr=u'ipaselinuxuser=deny')
+                'selinuxusermap_mod',
+                [rule1],
+                dict(setattr=u'ipaselinuxuser=deny')
             ),
             expected=errors.ValidationError(name='ipaselinuxuser',
                 error=u'Invalid MLS value, must match s[0-15](-s[0-15])'),
@@ -667,7 +706,11 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with both --hbacrule and --usercat set',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,seealso=hbacrule1,usercategory=u'all')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     hbacrule=hbacrule1,
+                     usercategory=u'all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -676,7 +719,11 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with both --hbacrule and --hostcat set',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,seealso=hbacrule1,hostcategory=u'all')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     hbacrule=hbacrule1,
+                     hostcategory=u'all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -685,7 +732,11 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with both --hbacrule and --usercat set via setattr',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,seealso=hbacrule1,setattr=u'usercategory=all')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     hbacrule=hbacrule1,
+                     setattr=u'usercategory=all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -694,16 +745,47 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule with both --hbacrule and --hostcat set via setattr',
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,seealso=hbacrule1,setattr=u'hostcategory=all')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     hbacrule=hbacrule1,
+                     setattr=u'hostcategory=all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
         ),
 
         dict(
+            desc='Create rule with --hbacrule and --setattr=seealso set',
+            command=(
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     hbacrule=hbacrule1,
+                     setattr=u'seealso=dn=invalid')
+            ),
+            expected=errors.MutuallyExclusiveError(
+                reason=u'You cannot specify HBAC rule using both --hbacrule and --setattr. Pick one.'),
+        ),
+
+        dict(
+            desc='Create rule with --setattr=seealso set to invalid DN',
+            command=(
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     setattr=u'seealso=dn=invalid')
+            ),
+            expected=errors.NotFound(
+                reason=u'HBAC rule with DN dn=invalid could not be found'),
+        ),
+
+        dict(
             desc='Create rule %r with --hbacrule' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,seealso=hbacrule1)
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,hbacrule=hbacrule1)
             ),
             expected=dict(
                 value=rule1,
@@ -741,7 +823,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add an usercat via setattr to %r that has HBAC set' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(setattr=u'usercategory=all')
+                'selinuxusermap_mod',
+                [rule1],
+                dict(setattr=u'usercategory=all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -750,7 +834,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add an hostcat via setattr to %r that has HBAC set' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(setattr=u'hostcategory=all')
+                'selinuxusermap_mod',
+                [rule1],
+                dict(setattr=u'hostcategory=all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -769,7 +855,11 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule %r with usercat and hostcat set' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1,usercategory=u'all',hostcategory=u'all')
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     usercategory=u'all',
+                     hostcategory=u'all')
             ),
             expected=dict(
                 value=rule1,
@@ -790,7 +880,7 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add HBAC rule to %r that has usercat and hostcat' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1)
+                'selinuxusermap_mod', [rule1], dict(hbacrule=hbacrule1)
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -809,7 +899,9 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Create rule %r' % rule1,
             command=(
-                'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1)
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1)
             ),
             expected=dict(
                 value=rule1,
@@ -828,7 +920,11 @@ class test_selinuxusermap(Declarative):
         dict(
             desc='Add HBAC rule, hostcat and usercat to %r' % rule1,
             command=(
-                'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1,usercategory=u'all',hostcategory=u'all')
+                'selinuxusermap_mod',
+                [rule1],
+                dict(hbacrule=hbacrule1,
+                     usercategory=u'all',
+                     hostcategory=u'all')
             ),
             expected=errors.MutuallyExclusiveError(
                 reason=u'HBAC rule and local members cannot both be set'),
@@ -843,4 +939,38 @@ class test_selinuxusermap(Declarative):
                 summary=u'Deleted SELinux User Map "%s"' % rule1,
             )
         ),
+
+        dict(
+            desc='Create rule %r with '
+                 '--setattr=seealso=<allow_all rule DN>' % rule1,
+            command=(
+                'selinuxusermap_add',
+                [rule1],
+                dict(ipaselinuxuser=selinuxuser1,
+                     setattr=u'seealso=%s' % allow_all_rule_dn)
+            ),
+            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,
+                    seealso=u'allow_all',
+                ),
+            ),
+        ),
+
+        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,
+            )
+        ),
     ]
-- 
1.8.1

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

Reply via email to