config-mod is capable of changing default SELinux user map order
and a default SELinux user. Validate the new config values to
prevent bogus default SELinux users to be assigned to IPA users.

https://fedorahosted.org/freeipa/ticket/2993

---
Note: I removed the previous "validate" construct:
-        validate = dict(options)
-        validate.update(entry_attrs)
... as entry_attrs contains both values set via standard options and *attr.

Martin
From 296eedc7cfd258b9e5eaf4f182b1a9625f5bf1a1 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Tue, 25 Sep 2012 13:46:56 +0200
Subject: [PATCH] Validate SELinux users in config-mod

config-mod is capable of changing default SELinux user map order
and a default SELinux user. Validate the new config values to
prevent bogus default SELinux users to be assigned to IPA users.

https://fedorahosted.org/freeipa/ticket/2993
---
 ipalib/plugins/config.py                | 49 +++++++++++++++++++++------------
 tests/test_xmlrpc/test_config_plugin.py | 44 ++++++++++++++++++++++++-----
 2 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
index e02519d5759f4e4a6d6a7075fe896f8b2e69b451..1c62e0d942231fac442ee2c1f31431003c08e283 100644
--- a/ipalib/plugins/config.py
+++ b/ipalib/plugins/config.py
@@ -21,6 +21,7 @@
 from ipalib import api
 from ipalib import Bool, Int, Str, IA5Str, StrEnum, DNParam
 from ipalib.plugins.baseldap import *
+from ipalib.plugins.selinuxusermap import validate_selinuxuser
 from ipalib import _
 from ipalib.errors import ValidationError
 
@@ -258,30 +259,44 @@ class config_mod(LDAPUpdate):
                                 error=_('%(obj)s default attribute %(attr)s would not be allowed!') \
                                 % dict(obj=obj, attr=obj_attr))
 
-        # Combine the current entry and options into a single object to
-        # evaluate. This covers changes via setattr and options.
-        # Note: this is not done in a validator because we may be changing
-        #       the default user and map list at the same time and we don't
-        #       have both values in a validator.
-        validate = dict(options)
-        validate.update(entry_attrs)
-        if ('ipaselinuxusermapdefault' in validate or
-          'ipaselinuxusermaporder' in validate):
+        if ('ipaselinuxusermapdefault' in entry_attrs or
+          'ipaselinuxusermaporder' in entry_attrs):
             config = None
             failedattr = 'ipaselinuxusermaporder'
-            if 'ipaselinuxusermapdefault' in validate:
-                defaultuser = validate['ipaselinuxusermapdefault']
+
+            if 'ipaselinuxusermapdefault' in entry_attrs:
+                defaultuser = entry_attrs['ipaselinuxusermapdefault']
                 failedattr = 'ipaselinuxusermapdefault'
+
+                # validate the new default user first
+                if defaultuser is not None:
+                    error_message = validate_selinuxuser(_, defaultuser)
+
+                    if error_message:
+                        raise errors.ValidationError(name='ipaselinuxusermapdefault',
+                                error=error_message)
+
             else:
                 config = ldap.get_ipa_config()[1]
-                if 'ipaselinuxusermapdefault' in config:
-                    defaultuser = config['ipaselinuxusermapdefault'][0]
-                else:
-                    defaultuser = None
+                defaultuser = config.get('ipaselinuxusermapdefault', [None])[0]
 
-            if 'ipaselinuxusermaporder' in validate:
-                order = validate['ipaselinuxusermaporder']
+            if 'ipaselinuxusermaporder' in entry_attrs:
+                order = entry_attrs['ipaselinuxusermaporder']
                 userlist = order.split('$')
+
+                # validate the new user order first
+                for user in userlist:
+                    if not user:
+                        raise errors.ValidationError(name='ipaselinuxusermaporder',
+                                error=_('A list of SELinux users delimited by $ expected'))
+
+                    error_message = validate_selinuxuser(_, user)
+                    if error_message:
+                        error_message = _("SELinux user '%(user)s' is not "
+                                "valid: %(error)s") % dict(user=user,
+                                                          error=error_message)
+                        raise errors.ValidationError(name='ipaselinuxusermaporder',
+                                error=error_message)
             else:
                 if not config:
                     config = ldap.get_ipa_config()[1]
diff --git a/tests/test_xmlrpc/test_config_plugin.py b/tests/test_xmlrpc/test_config_plugin.py
index 6d83f047e0e647270712003d77c40f3c1014f90f..3d9a31daf38b4b8a28febee90f5812cf78538ee7 100644
--- a/tests/test_xmlrpc/test_config_plugin.py
+++ b/tests/test_xmlrpc/test_config_plugin.py
@@ -61,31 +61,61 @@ class test_config(Declarative):
         ),
 
         dict(
-            desc='Try to set invalid ipaselinuxusermapdefault',
+            desc='Try to set ipaselinuxusermapdefault not in selinux order list',
             command=('config_mod', [],
                 dict(ipaselinuxusermapdefault=u'unknown_u:s0')),
-            expected=errors.ValidationError(name='ipaselinuxusermapdefault', error='SELinux user map default user not in order list'),
+            expected=errors.ValidationError(name='ipaselinuxusermapdefault',
+                error='SELinux user map default user not in order list'),
+        ),
+
+        dict(
+            desc='Try to set invalid ipaselinuxusermapdefault',
+            command=('config_mod', [],
+                dict(ipaselinuxusermapdefault=u'foo')),
+            expected=errors.ValidationError(name='ipaselinuxusermapdefault',
+                error='Invalid MLS value, must match s[0-15](-s[0-15])'),
         ),
 
         dict(
             desc='Try to set invalid ipaselinuxusermapdefault with setattr',
             command=('config_mod', [],
                 dict(setattr=u'ipaselinuxusermapdefault=unknown_u:s0')),
-            expected=errors.ValidationError(name='ipaselinuxusermapdefault', error='SELinux user map default user not in order list'),
+            expected=errors.ValidationError(name='ipaselinuxusermapdefault',
+                error='SELinux user map default user not in order list'),
         ),
 
         dict(
-            desc='Try to set invalid ipaselinuxusermaporder',
+            desc='Try to set ipaselinuxusermaporder without ipaselinuxusermapdefault out of it',
             command=('config_mod', [],
                 dict(ipaselinuxusermaporder=u'notfound_u:s0')),
-            expected=errors.ValidationError(name='ipaselinuxusermaporder', error='SELinux user map default user not in order list'),
+            expected=errors.ValidationError(name='ipaselinuxusermaporder',
+                error='SELinux user map default user not in order list'),
+        ),
+
+        dict(
+            desc='Try to set invalid ipaselinuxusermaporder',
+            command=('config_mod', [],
+                dict(ipaselinuxusermaporder=u'$')),
+            expected=errors.ValidationError(name='ipaselinuxusermaporder',
+                error='A list of SELinux users delimited by $ expected'),
+        ),
+
+        dict(
+            desc='Try to set invalid selinux user in ipaselinuxusermaporder',
+            command=('config_mod', [],
+                dict(ipaselinuxusermaporder=u'unconfined_u:s0-s0:c0.c1023$baduser$guest_u:s0')),
+            expected=errors.ValidationError(name='ipaselinuxusermaporder',
+                error='SELinux user \'baduser\' is not valid: Invalid MLS '
+                      'value, must match s[0-15](-s[0-15])'),
         ),
 
         dict(
             desc='Try to set new selinux order and invalid default user',
             command=('config_mod', [],
-                dict(ipaselinuxusermaporder=u'$xguest_u:s0$guest_u:s0$user_u:s0-s0:c0.c1023$staff_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023', ipaselinuxusermapdefault=u'unknown_u:s0')),
-            expected=errors.ValidationError(name='ipaselinuxusermapdefault', error='SELinux user map default user not in order list'),
+                dict(ipaselinuxusermaporder=u'xguest_u:s0$guest_u:s0$user_u:s0-s0:c0.c1023$staff_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023',
+                    ipaselinuxusermapdefault=u'unknown_u:s0')),
+            expected=errors.ValidationError(name='ipaselinuxusermapdefault',
+                error='SELinux user map default user not in order list'),
         ),
 
     ]
-- 
1.7.11.4

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

Reply via email to