[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Freeipa-devel] [PATCH] 16 Netgroup nisdomain and hosts validation



On 03/15/2012 08:13 AM, Martin Kosek wrote:
On Wed, 2012-03-14 at 16:54 +0100, Ondrej Hamada wrote:
On 03/09/2012 04:34 PM, Martin Kosek wrote:
On Thu, 2012-03-08 at 14:52 +0100, Ondrej Hamada wrote:
Netgroup nisdomain and hosts validation

nisdomain validation:
Added pattern to the 'nisdomain' parameter to validate the specified
nisdomain name. According to most common use cases the same patter as
for netgroup should fit. Unit-tests added.

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

hosts validation:
Added precallback to netgroup_add_member. It validates the specified
hostnames and raises ValidationError exception for invalid hostnames.
Unit-test added.

https://fedorahosted.org/freeipa/ticket/2448
I checked the host validation part and it could be improved. Issue
described in #2447 (you have switched the ticket IDs) affects all
objects that allow external hosts, users, ..., i.e. those who call
add_external_post_callback in their post_callback.

Should we fix all of these when we deal with this issue? Otherwise user
could do something like this:
# ipa sudorule-add-user foo --users=a+b
    Rule name: foo
    Enabled: TRUE
    External User: a+b

We could create a similar function called add_external_pre_callback()
and pass it attribute name and validating function (which would be
common with the linked object). It would then do the validation for all
these affected objects consistently and without redundant code.

I didn't liked much the implemented pre_callback anyway

+    def pre_callback(self, ldap, dn, found, not_found, *keys,
**options):
+        # validate entered hostnames
+        if 'host' in options:
+            invalid_hostnames=[]
+            for hostname in options['host']:
+                try:
+                    validate_hostname(hostname, False)
+                except ValueError:
+                    invalid_hostnames.append(hostname)
+            if invalid_hostnames:
+                raise errors.ValidationError(name='host',
error='hostnames:\"%s\" contain invalid characters' %
','.join(invalid_hostnames))
+        return dn

I would rather raise the ValidationError with the first invalid hostname
and tell what's wrong (function validate_hostname tells it to you). If
you go with the proposed approach, you wouldn't have to deal with
formatting error messages, you would just raise the one returned by the
validator shared with the linked LDAP object (hostname, user, ...).

Martin
external_pre_callback function seems as a good idea, but there is a
problem how to get the validators for various LDAP objects. For the
hostname we already have one in ipalib.utils, but for the uid or group
name we use only patterns specified in the parameter objects.

Below I propose solution how to use the already defined parameter
objects for validation (the only problem is that I have to assume, that
it is always the first parameter in takes_params). Do you think this is
a good approach?
I think the approach is OK, it can just be much improved in order to get
rid of the hardcoded parts. See comments below.

def add_external_pre_callback(memberattr, membertype, externalattr,
ldap, dn, found, not_found, *keys, **options):
      """
      Pre callback to validate external members.
      """
      if membertype in options:
          validator = api.Object[membertype].takes_params[0]
You can use api.Object[membertype].params[memberattr]

          for value in options[membertype]:
              try:
                  validator(value)
              except errors.ValidationError as e:
                  error_msg = e[(e.find(':')+1):]
You don't have to parse error message, you can just use e.name or
e.error right from the caught ValidationError.

                  raise errors.ValidationError(name=membertype,
error=e[e.find(':')+1:])
      return dn



nisdomain validation:
Added pattern to the 'nisdomain' parameter to validate the specified
nisdomain name. According to most common use cases the same pattern as
for netgroup should fit. Unit-tests added.

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

'add_external_pre_callback' function was created to allow validation of
all external members. Validation is based on usage of objects primary
key parameter. The 'add_external_pre_callback' fucntion has to be called
directly from in the 'pre_callback' function. This change affects
netgroup, hbacrule and sudorule commands.

Special validator is used only for hostname, the validator requires fully qualified
domain name and enables the hostnames to contain underscores.

Unit-tests added.

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

--
Regards,

Ondrej Hamada
FreeIPA team
jabber: ohama jabbim cz
IRC: ohamada

From eaf9300a5c4236835932743447c53ea430d5194d Mon Sep 17 00:00:00 2001
From: Ondrej Hamada <ohamada redhat com>
Date: Fri, 23 Mar 2012 13:16:36 +0100
Subject: [PATCH] Netgroup nisdomain and hosts validation

nisdomain validation:
Added pattern to the 'nisdomain' parameter to validate the specified
nisdomain name. According to most common use cases the same pattern as
for netgroup should fit. Unit-tests added.

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

'add_external_pre_callback' function was created to allow validation of
all external members. Validation is based on usage of objects primary
key parameter. The 'add_external_pre_callback' fucntion has to be called
directly from in the 'pre_callback' function. This change affects
netgroup, hbacrule and sudorule commands.

For hostname, the validator requires fully qualified domain name.
Hostnames may contain underscores.

Unit-tests added.

https://fedorahosted.org/freeipa/ticket/2447
---
 API.txt                                   |    6 +-
 VERSION                                   |    2 +-
 ipalib/plugins/baseldap.py                |   45 +++++++++++++++++++++-
 ipalib/plugins/hbacrule.py                |    2 +-
 ipalib/plugins/netgroup.py                |    9 ++++
 ipalib/plugins/sudorule.py                |    8 ++--
 tests/test_xmlrpc/test_hbac_plugin.py     |   13 ++++++
 tests/test_xmlrpc/test_netgroup_plugin.py |   59 ++++++++++++++++++++--------
 tests/test_xmlrpc/test_sudorule_plugin.py |   60 +++++++++++++++++++++++++++++
 9 files changed, 177 insertions(+), 27 deletions(-)

diff --git a/API.txt b/API.txt
index 363ba5a5edeb177e95cb2633b29689333f76a6be..e9eb1e1faa2c2f402e4e6055faee47530e5a8a79 100644
--- a/API.txt
+++ b/API.txt
@@ -1923,7 +1923,7 @@ command: netgroup_add
 args: 1,9,3
 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', primary_key=True, required=True)
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('nisdomainname', attribute=True, cli_name='nisdomain', multivalue=False, required=False)
+option: Str('nisdomainname', attribute=True, cli_name='nisdomain', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', required=False)
 option: StrEnum('usercategory', attribute=True, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
 option: StrEnum('hostcategory', attribute=True, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
 option: Str('setattr*', cli_name='setattr', exclude='webui')
@@ -1960,7 +1960,7 @@ args: 1,26,4
 arg: Str('criteria?', noextrawhitespace=False)
 option: Str('cn', attribute=True, autofill=False, cli_name='name', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', 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('nisdomainname', attribute=True, autofill=False, cli_name='nisdomain', multivalue=False, query=True, required=False)
+option: Str('nisdomainname', attribute=True, autofill=False, cli_name='nisdomain', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', query=True, required=False)
 option: Str('ipauniqueid', attribute=True, autofill=False, cli_name='uuid', multivalue=False, query=True, required=False)
 option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, query=True, required=False, values=(u'all',))
 option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostcat', multivalue=False, query=True, required=False, values=(u'all',))
@@ -1992,7 +1992,7 @@ command: netgroup_mod
 args: 1,11,3
 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', primary_key=True, query=True, required=True)
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('nisdomainname', attribute=True, autofill=False, cli_name='nisdomain', multivalue=False, required=False)
+option: Str('nisdomainname', attribute=True, autofill=False, cli_name='nisdomain', multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$', pattern_errmsg='may only include letters, numbers, _, -, and .', required=False)
 option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
 option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
 option: Str('setattr*', cli_name='setattr', exclude='webui')
diff --git a/VERSION b/VERSION
index 9095067296d1fda253f5cac396e48b85b9be9b70..e15d463ba5c8ad10e2fe7bc7b4fcaf83c00ac8a8 100644
--- a/VERSION
+++ b/VERSION
@@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=31
+IPA_API_VERSION_MINOR=32
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index a09e00fef748e036950e4c2caec0a49f813e4226..d05f10b217b7f44123783edc9364f2617a1bb8eb 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -33,7 +33,7 @@ from ipalib.base import NameSpace
 from ipalib.cli import to_cli, from_cli
 from ipalib import output
 from ipalib.text import _
-from ipalib.util import json_serialize
+from ipalib.util import json_serialize, validate_dns_label
 from ipalib.dn import *
 
 global_output_params = (
@@ -313,6 +313,49 @@ def wait_for_value(ldap, dn, attr, value):
 
     return entry_attrs
 
+def add_external_pre_callback(membertype, ldap, dn, keys, options):
+    """
+    Pre callback to validate external members.
+
+    This should be called by a command pre callback directly.
+
+    membertype is the type of member
+    """
+    # validate hostname with allowed underscore characters, only fqdn
+    # hostnames are allowed
+    def validate_host(hostname):
+        if len(hostname) > 255:
+            raise ValueError(_('cannot be longer that 255 characters'))
+
+        if hostname.endswith('.'):
+            hostname = hostname[:-1]
+
+        if '.' not in hostname:
+            raise ValueError(_('not fully qualified'))
+
+        hostname = hostname.split('.')
+
+        # apply DNS name validator to every name part, allow underscores
+        map(lambda label:validate_dns_label(label,True), hostname)
+
+        if not hostname[-1].isalpha():
+            # see RFC 1123
+            raise ValueError(_('top level domain label must be alphabetic'))
+
+    if membertype in options:
+        if membertype == 'host':
+            validator = validate_host
+        else:
+            validator = api.Object[membertype].primary_key
+        for value in options[membertype]:
+            try:
+                validator(value)
+            except errors.ValidationError as e:
+                raise errors.ValidationError(name=membertype, error=e.error)
+            except ValueError as e:
+                raise errors.ValidationError(name=membertype, error=e)
+    return dn
+
 def add_external_post_callback(memberattr, membertype, externalattr, ldap, completed, failed, dn, entry_attrs, *keys, **options):
     """
     Post callback to add failed members as external members.
diff --git a/ipalib/plugins/hbacrule.py b/ipalib/plugins/hbacrule.py
index 4666485569c365c9128f2dd04751a67cf71d47e1..eb5cb696eb835c717d734d31ee2c6333ac177030 100644
--- a/ipalib/plugins/hbacrule.py
+++ b/ipalib/plugins/hbacrule.py
@@ -498,7 +498,7 @@ class hbacrule_add_sourcehost(LDAPAddMember):
         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
+        return add_external_pre_callback('host', ldap, dn, keys, options)
 
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('sourcehost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 2ba154649e9d0de600aba8346e93831416e2457c..06372a59265bddea52ca4867409cbcfec0ca38c0 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -53,6 +53,11 @@ EXAMPLES:
 NETGROUP_PATTERN='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$'
 NETGROUP_PATTERN_ERRMSG='may only include letters, numbers, _, -, and .'
 
+# according to most common use cases the netgroup pattern should fit
+# also the nisdomain pattern
+NISDOMAIN_PATTERN=NETGROUP_PATTERN
+NISDOMAIN_PATTERN_ERRMSG=NETGROUP_PATTERN_ERRMSG
+
 output_params = (
         Str('memberuser_user?',
             label='Member User',
@@ -118,6 +123,8 @@ class netgroup(LDAPObject):
             doc=_('Netgroup description'),
         ),
         Str('nisdomainname?',
+            pattern=NISDOMAIN_PATTERN,
+            pattern_errmsg=NISDOMAIN_PATTERN_ERRMSG,
             cli_name='nisdomain',
             label=_('NIS domain name'),
         ),
@@ -255,6 +262,8 @@ class netgroup_add_member(LDAPAddMember):
 
     member_attributes = ['memberuser', 'memberhost', 'member']
     has_output_params = LDAPAddMember.has_output_params + output_params
+    def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+        return add_external_pre_callback('host', ldap, dn, keys, options)
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
 
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index de7a7af37e35f91505e1493f74ed770852d7cbf6..7432bc42bbb945cd0e8d25f3e320987af7fef26b 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -431,7 +431,7 @@ class sudorule_add_user(LDAPAddMember):
             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
+        return add_external_pre_callback('user', ldap, dn, keys, options)
 
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('memberuser', 'user', 'externaluser', ldap, completed, failed, dn, entry_attrs, keys, options)
@@ -464,7 +464,7 @@ class sudorule_add_host(LDAPAddMember):
             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
+        return add_external_pre_callback('host', ldap, dn, keys, options)
 
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
@@ -517,7 +517,7 @@ class sudorule_add_runasuser(LDAPAddMember):
                           error=unicode(_("RunAsUser does not accept '%(name)s' as a group name")) %
                           dict(name=name))
 
-        return dn
+        return add_external_pre_callback('user', ldap, dn, keys, options)
 
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('ipasudorunas', 'user', 'ipasudorunasextuser', ldap, completed, failed, dn, entry_attrs, keys, options)
@@ -565,7 +565,7 @@ class sudorule_add_runasgroup(LDAPAddMember):
                           error=unicode(_("RunAsGroup does not accept '%(name)s' as a group name")) %
                           dict(name=name))
 
-        return dn
+        return add_external_pre_callback('group', ldap, dn, keys, options)
 
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         return add_external_post_callback('ipasudorunasgroup', 'group', 'ipasudorunasextgroup', ldap, completed, failed, dn, entry_attrs, keys, options)
diff --git a/tests/test_xmlrpc/test_hbac_plugin.py b/tests/test_xmlrpc/test_hbac_plugin.py
index 268c8d9d2217de71a936f691e5dc1666e9afb4b1..270f768dd0ea7f9abb744af598c52769f9fa91ac 100644
--- a/tests/test_xmlrpc/test_hbac_plugin.py
+++ b/tests/test_xmlrpc/test_hbac_plugin.py
@@ -50,6 +50,8 @@ class test_hbac(XMLRPC_test):
     test_service = u'sshd'
     test_host_external = u'notfound.example.com'
 
+    test_invalid_sourcehost = u'inv+alid#srchost.nonexist.com'
+
     def test_0_hbacrule_add(self):
         """
         Test adding a new HBAC rule using `xmlrpc.hbacrule_add`.
@@ -284,6 +286,17 @@ class test_hbac(XMLRPC_test):
         assert_attr_equal(entry, 'sourcehost_host', self.test_host)
         assert_attr_equal(entry, 'sourcehost_hostgroup', self.test_hostgroup)
 
+    def test_a_hbacrule_add_invalid_sourcehost(self):
+        """
+        Test adding invalid source host to HBAC rule using `xmlrpc.hbacrule_add_host`.
+        """
+        try:
+            api.Command['hbacrule_add_sourcehost'](
+                self.rule_name, host=self.test_invalid_sourcehost, hostgroup=self.test_hostgroup
+            )
+        except errors.ValidationError:
+            pass
+
     def test_a_hbacrule_add_service(self):
         """
         Test adding service to HBAC rule using `xmlrpc.hbacrule_add_service`.
diff --git a/tests/test_xmlrpc/test_netgroup_plugin.py b/tests/test_xmlrpc/test_netgroup_plugin.py
index c40b01ad623f1566ce98f60e1254b43d539752bb..317f9be85160564f73cd27fc2986176ca97dc969 100644
--- a/tests/test_xmlrpc/test_netgroup_plugin.py
+++ b/tests/test_xmlrpc/test_netgroup_plugin.py
@@ -43,7 +43,7 @@ host1 = u'ipatesthost.%s' % api.env.domain
 host_dn1 = DN(('fqdn',host1),('cn','computers'),('cn','accounts'),
               api.env.basedn)
 
-unknown_host = u'unknown'
+unknown_host = u'unknown.host.com'
 
 hostgroup1 = u'hg1'
 hostgroup_dn1 = DN(('cn',hostgroup1),('cn','hostgroups'),('cn','accounts'),
@@ -57,6 +57,9 @@ user2 = u'pexample'
 group1 = u'testgroup'
 
 invalidnetgroup1=u'+badnetgroup'
+invalidnisdomain1=u'domain1,domain2'
+invalidnisdomain2=u'+invalidnisdomain'
+invalidhost=u'+invalid&host.nonexist.com'
 
 class test_netgroup(Declarative):
     """
@@ -106,6 +109,20 @@ class test_netgroup(Declarative):
 
 
         dict(
+            desc='Test an invalid nisdomain1 name %r' % invalidnisdomain1,
+            command=('netgroup_add', [netgroup1], dict(description=u'Test',nisdomainname=invalidnisdomain1)),
+            expected=errors.ValidationError(name='nisdomainname', error='may only include letters, numbers, _, - and .'),
+        ),
+
+
+        dict(
+            desc='Test an invalid nisdomain2 name %r' % invalidnisdomain2,
+            command=('netgroup_add', [netgroup1], dict(description=u'Test',nisdomainname=invalidnisdomain2)),
+            expected=errors.ValidationError(name='nisdomainname', error='may only include letters, numbers, _, - and .'),
+        ),
+
+
+        dict(
             desc='Create %r' % netgroup1,
             command=('netgroup_add', [netgroup1],
                 dict(description=u'Test netgroup 1')
@@ -334,6 +351,14 @@ class test_netgroup(Declarative):
 
 
         dict(
+            desc='Add invalid host %r to netgroup %r' % (invalidhost, netgroup1),
+            command=('netgroup_add_member', [netgroup1], dict(host=invalidhost)),
+            expected=errors.ValidationError(name='host',
+             error='only letters, numbers, _, and - are allowed. - must not be the DNS label character'),
+        ),
+
+
+        dict(
             desc='Add host %r to netgroup %r' % (host1, netgroup1),
             command=(
                 'netgroup_add_member', [netgroup1], dict(host=host1)
@@ -756,7 +781,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Test netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -777,7 +802,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Test netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -800,7 +825,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Test netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                     },
                 ],
             ),
@@ -824,7 +849,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Test netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                     },
                 ],
             ),
@@ -848,7 +873,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Test netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                     },
                     {
                         'dn': fuzzy_netgroupdn,
@@ -878,7 +903,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -913,7 +938,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -947,7 +972,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -980,7 +1005,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1012,7 +1037,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1043,7 +1068,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1074,7 +1099,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1105,7 +1130,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1136,7 +1161,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1167,7 +1192,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
@@ -1198,7 +1223,7 @@ class test_netgroup(Declarative):
                         'cn': [netgroup1],
                         'description': [u'Updated netgroup 1'],
                         'nisdomainname': [u'%s' % api.env.domain],
-                        'externalhost': [u'unknown'],
+                        'externalhost': [unknown_host],
                 },
             ),
         ),
diff --git a/tests/test_xmlrpc/test_sudorule_plugin.py b/tests/test_xmlrpc/test_sudorule_plugin.py
index 2a597c37bea3d621941b66c2b7bec0cf8600be28..86cb9dae544afbce9ab17bb53e0d8493de5542f5 100644
--- a/tests/test_xmlrpc/test_sudorule_plugin.py
+++ b/tests/test_xmlrpc/test_sudorule_plugin.py
@@ -53,6 +53,10 @@ class test_sudorule(XMLRPC_test):
     test_category = u'all'
     test_option = u'authenticate'
 
+    test_invalid_user = u'+invalid#user'
+    test_invalid_host = u'+invalid&host.nonexist.com'
+    test_invalid_group = u'+invalid#group'
+
     def test_0_sudorule_add(self):
         """
         Test adding a new Sudo rule using `xmlrpc.sudorule_add`.
@@ -206,6 +210,20 @@ class test_sudorule(XMLRPC_test):
         entry = ret['result']
         assert_attr_equal(entry, 'ipasudorunas_user', self.test_runasuser)
 
+    def test_a_sudorule_add_runasuser_invalid(self):
+        """
+        Test adding run as invalid user to Sudo rule using
+        `xmlrpc.sudorule_add_runasuser`.
+        """
+        try:
+            api.Command['sudorule_add_runasuser'](
+                self.rule_name, user=self.test_invalid_user
+            )
+        except errors.ValidationError:
+            pass
+        else:
+            assert False
+
     def test_b_sudorule_remove_runasuser(self):
         """
         Test removing run as user to Sudo rule using
@@ -239,6 +257,20 @@ class test_sudorule(XMLRPC_test):
         assert_attr_equal(entry, 'ipasudorunasgroup_group',
             self.test_runasgroup)
 
+    def test_a_sudorule_add_runasgroup_invalid(self):
+        """
+        Test adding run as invalid user to Sudo rule using
+        `xmlrpc.sudorule_add_runasuser`.
+        """
+        try:
+            api.Command['sudorule_add_runasgroup'](
+                self.rule_name, group=self.test_invalid_group
+            )
+        except errors.ValidationError:
+            pass
+        else:
+            assert False
+
     def test_b_sudorule_remove_runasgroup(self):
         """
         Test removing run as group to Sudo rule using
@@ -268,6 +300,20 @@ class test_sudorule(XMLRPC_test):
         entry = ret['result']
         assert_attr_equal(entry, 'externaluser', self.test_external_user)
 
+    def test_a_sudorule_add_externaluser_invalid(self):
+        """
+        Test adding an invalid external user to Sudo rule using
+        `xmlrpc.sudorule_add_user`.
+        """
+        try:
+            api.Command['sudorule_add_user'](
+                self.rule_name, user=self.test_invalid_user
+            )
+        except errors.ValidationError:
+            pass
+        else:
+            assert False
+
     def test_b_sudorule_remove_externaluser(self):
         """
         Test removing an external user from Sudo rule using
@@ -424,6 +470,20 @@ class test_sudorule(XMLRPC_test):
         entry = ret['result']
         assert_attr_equal(entry, 'externalhost', self.test_external_host)
 
+    def test_a_sudorule_add_externalhost_invalid(self):
+        """
+        Test adding an invalid external host to Sudo rule using
+        `xmlrpc.sudorule_add_host`.
+        """
+        try:
+            api.Command['sudorule_add_host'](
+                self.rule_name, host=self.test_invalid_host
+            )
+        except errors.ValidationError:
+            pass
+        else:
+            assert False
+
     def test_b_sudorule_remove_externalhost(self):
         """
         Test removing an external host from Sudo rule using
-- 
1.7.6.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]