Example #1
0
 def test_rename_to_same_value(self, idp):
     """ Try to rename idp to the same value """
     idp.ensure_exists()
     command = idp.make_update_command(updates=dict(setattr=('cn=%s' %
                                                             idp.cn)))
     with raises_exact(errors.EmptyModlist()):
         command()
Example #2
0
 def test_rename_to_the_same_value(self, user):
     """ Try to rename user to the same value """
     user.ensure_exists()
     command = user.make_update_command(updates=dict(setattr=(u'uid=%s' %
                                                              user.uid)))
     with raises_exact(errors.EmptyModlist()):
         command()
Example #3
0
    def execute(self, cn, **options):
        ldap = self.obj.backend

        dn = self.obj.get_dn(cn)

        if not options['ipasudoopt'].strip():
            raise errors.EmptyModlist()

        entry_attrs = ldap.get_entry(dn, ['ipasudoopt'])

        try:
            if options['ipasudoopt'] in entry_attrs['ipasudoopt']:
                entry_attrs.setdefault('ipasudoopt',
                                       []).remove(options['ipasudoopt'])
                ldap.update_entry(entry_attrs)
            else:
                raise errors.AttrValueNotFound(attr='ipasudoopt',
                                               value=options['ipasudoopt'])
        except ValueError:
            pass
        except KeyError:
            raise errors.AttrValueNotFound(attr='ipasudoopt',
                                           value=options['ipasudoopt'])
        except errors.NotFound:
            raise self.obj.handle_not_found(cn)

        attrs_list = self.obj.default_attributes
        entry_attrs = ldap.get_entry(dn, attrs_list)

        self.obj.get_indirect_members(entry_attrs, attrs_list)
        self.obj.convert_attribute_members(entry_attrs, [cn], **options)

        entry_attrs = entry_to_dict(entry_attrs, **options)

        return dict(result=entry_attrs, value=pkey_to_value(cn, options))
Example #4
0
    def execute(self, cn, **options):
        ldap = self.obj.backend

        dn = self.obj.get_dn(cn)

        if len(options.get('ipasudoopt', [])) == 0:
            raise errors.EmptyModlist()
        entry_attrs = ldap.get_entry(dn, ['ipasudoopt'])

        try:
            entry_attrs.setdefault('ipasudoopt', [])
            for option in options['ipasudoopt']:
                if option not in entry_attrs['ipasudoopt']:
                    entry_attrs['ipasudoopt'].append(option)
                else:
                    raise errors.DuplicateEntry
        except KeyError:
            entry_attrs.setdefault('ipasudoopt',
                                   []).append(options['ipasudoopt'])
        try:
            ldap.update_entry(entry_attrs)
        except errors.EmptyModlist:
            pass
        except errors.NotFound:
            raise self.obj.handle_not_found(cn)

        attrs_list = self.obj.default_attributes
        entry_attrs = ldap.get_entry(dn, attrs_list)

        self.obj.get_indirect_members(entry_attrs, attrs_list)
        self.obj.convert_attribute_members(entry_attrs, [cn], **options)

        entry_attrs = entry_to_dict(entry_attrs, **options)

        return dict(result=entry_attrs, value=pkey_to_value(cn, options))
Example #5
0
    def execute(self, cn, **options):
        ldap = self.obj.backend

        dn = self.obj.get_dn(cn)

        if not options['ipasudoopt'].strip():
            raise errors.EmptyModlist()
        entry_attrs = ldap.get_entry(dn, ['ipasudoopt'])

        try:
            if options['ipasudoopt'] not in entry_attrs['ipasudoopt']:
                entry_attrs.setdefault('ipasudoopt', []).append(
                    options['ipasudoopt'])
            else:
                raise errors.DuplicateEntry
        except KeyError:
            entry_attrs.setdefault('ipasudoopt', []).append(
                options['ipasudoopt'])
        try:
            ldap.update_entry(entry_attrs)
        except errors.EmptyModlist:
            pass
        except errors.NotFound:
            self.obj.handle_not_found(cn)

        attrs_list = self.obj.default_attributes
        entry_attrs = ldap.get_entry(dn, attrs_list)

        entry_attrs = entry_to_dict(entry_attrs, **options)

        return dict(result=entry_attrs, value=pkey_to_value(cn, options))
Example #6
0
    def execute(self, *keys, **options):
        ldap = self.obj.backend

        dn = self.obj.get_dn(*keys, **options)
        assert isinstance(dn, DN)

        newdn = None
        if options and 'ingroup' in options:
            group = options['ingroup']
            if group:
                newdn = DN(('cn', keys[0]),('cn', group)) + self.obj.container_dn + self.obj.api.env.basedn
            else:
                newdn = DN(('cn', keys[0])) + self.obj.container_dn + self.obj.api.env.basedn

        else:
            raise errors.EmptyModlist()


        ldap.move_entry(dn, newdn)
        entry_attrs = ldap.get_entry(newdn)
        if group:
            entry_attrs['ingroup'] = group
        else:
            entry_attrs['ingroup'] = '--none--'
            
        entry_attrs = entry_to_dict(entry_attrs, **options)
        entry_attrs['dn'] = newdn
        
        pkey = keys[-1]

        return dict(result=entry_attrs, value=pkey_to_value(pkey, options))
Example #7
0
class test_pwpolicy_mod_cospriority(Declarative):
    """Tests for cospriority modifications"""
    cleanup_commands = [
        ('pwpolicy_del', [u'ipausers'], {}),
    ]

    tests = [
        dict(
            desc='Create a password policy',
            command=('pwpolicy_add', [u'ipausers'],
                     dict(
                         krbmaxpwdlife=90,
                         krbminpwdlife=1,
                         krbpwdhistorylength=10,
                         krbpwdmindiffchars=3,
                         krbpwdminlength=8,
                         cospriority=10,
                     )),
            expected=dict(
                result=dict(
                    cn=[u'ipausers'],
                    cospriority=[u'10'],
                    dn=DN('cn=ipausers', ('cn', api.env.realm), 'cn=kerberos',
                          api.env.basedn),
                    krbmaxpwdlife=[u'90'],
                    krbminpwdlife=[u'1'],
                    krbpwdhistorylength=[u'10'],
                    krbpwdmindiffchars=[u'3'],
                    krbpwdminlength=[u'8'],
                    objectclass=objectclasses.pwpolicy,
                ),
                summary=None,
                value=u'ipausers',
            ),
        ),
        dict(
            # https://fedorahosted.org/freeipa/ticket/4309
            desc="Try no-op modification of password policy's cospriority",
            command=('pwpolicy_mod', [u'ipausers'], dict(cospriority=10, )),
            expected=errors.EmptyModlist(),
        ),
        dict(
            desc="Modify the password policy's cospriority",
            command=('pwpolicy_mod', [u'ipausers'], dict(cospriority=20, )),
            expected=dict(
                result=dict(
                    cn=[u'ipausers'],
                    cospriority=[u'20'],
                    krbmaxpwdlife=[u'90'],
                    krbminpwdlife=[u'1'],
                    krbpwdhistorylength=[u'10'],
                    krbpwdmindiffchars=[u'3'],
                    krbpwdminlength=[u'8'],
                ),
                summary=None,
                value=u'ipausers',
            ),
        ),
    ]
Example #8
0
def group_mod_fas_precb(self, ldap, dn, entry_attrs, *keys, **options):
    """Add fasgroup object class
    """
    if options.get("fasgroup", False):
        old_entry_attrs = ldap.get_entry(dn, ["objectclass"])
        if "fasgroup" in old_entry_attrs["objectclass"]:
            raise errors.EmptyModlist(
                message=_("This is already a FAS group")
            )
        old_entry_attrs["objectclass"].append("fasgroup")
        entry_attrs["objectclass"] = old_entry_attrs["objectclass"]
    return dn
Example #9
0
    def execute(self, aciname, **kw):
        aciprefix = kw['aciprefix']
        ldap = self.api.Backend.ldap2

        entry = ldap.get_entry(self.api.env.basedn, ['aci'])

        acis = _convert_strings_to_acis(entry.get('aci', []))
        aci = _find_aci_by_name(acis, aciprefix, aciname)

        # The strategy here is to convert the ACI we're updating back into
        # a series of keywords. Then we replace any keywords that have been
        # updated and convert that back into an ACI and write it out.
        oldkw = _aci_to_kw(ldap, aci)
        newkw = deepcopy(oldkw)
        if newkw.get('selfaci', False):
            # selfaci is set in aci_to_kw to True only if the target is self
            kw['selfaci'] = True
        newkw.update(kw)
        for acikw in (oldkw, newkw):
            acikw.pop('aciname', None)

        # _make_aci is what is run in aci_add and validates the input.
        # Do this before we delete the existing ACI.
        newaci = _make_aci(ldap, None, aciname, newkw)
        if aci.isequal(newaci):
            raise errors.EmptyModlist()

        self.api.Command['aci_del'](aciname, aciprefix=aciprefix)

        try:
            result = self.api.Command['aci_add'](aciname, **newkw)['result']
        except Exception as e:
            # ACI could not be added, try to restore the old deleted ACI and
            # report the ADD error back to user
            try:
                self.api.Command['aci_add'](aciname, **oldkw)
            except Exception:
                pass
            raise e

        if kw.get('raw', False):
            result = dict(aci=unicode(newaci))
        else:
            result = _aci_to_kw(ldap, newaci)
        return dict(
            result=result,
            value=pkey_to_value(aciname, kw),
        )
Example #10
0
    def execute(self, cn, **options):
        ldap = self.obj.backend

        dn = self.obj.get_dn(cn)

        if not options['ipasudoopt'].strip():
            raise errors.EmptyModlist()
        (dn, entry_attrs) = ldap.get_entry(dn, ['ipasudoopt'])
        try:
            if options['ipasudoopt'] in entry_attrs['ipasudoopt']:
                entry_attrs.setdefault('ipasudoopt',
                                       []).remove(options['ipasudoopt'])
                ldap.update_entry(dn, entry_attrs)
            else:
                raise errors.AttrValueNotFound(attr='ipasudoopt',
                                               value=options['ipasudoopt'])
        except ValueError, e:
            pass
Example #11
0
 def test_remove_empty_location_from_user(self, user):
     """ Try to "remove" empty location from user """
     user.ensure_exists()
     command = user.make_update_command(dict(l=None))
     with raises_exact(errors.EmptyModlist()):
         command()
Example #12
0
class test_config(Declarative):

    cleanup_commands = []

    tests = [
        dict(
            desc='Try to add an unrelated objectclass to ipauserobjectclasses',
            command=('config_mod', [],
                     dict(addattr=u'ipauserobjectclasses=ipahost')),
            expected=dict(
                result=lambda d: 'ipahost' in d['ipauserobjectclasses'],
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Remove the unrelated objectclass from ipauserobjectclasses',
            command=('config_mod', [],
                     dict(delattr=u'ipauserobjectclasses=ipahost')),
            expected=dict(
                result=lambda d: 'ipahost' not in d['ipauserobjectclasses'],
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Try to remove ipausersearchfields',
            command=
            ('config_mod', [],
             dict(
                 delattr=
                 u'ipausersearchfields=uid,givenname,sn,telephonenumber,ou,title'
             )),
            expected=errors.RequirementError(name='usersearch'),
        ),
        dict(
            desc='Add uppercased attribute to ipausersearchfields',
            command=(
                'config_mod', [],
                dict(
                    ipausersearchfields=
                    u'uid,givenname,sn,telephonenumber,ou,title,Description')),
            expected=dict(
                result=lambda d:
                (d['ipausersearchfields'] ==
                 (u'uid,givenname,sn,telephonenumber,ou,title,description', )),
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Remove uppercased attribute from ipausersearchfields',
            command=('config_mod', [],
                     dict(ipausersearchfields=
                          u'uid,givenname,sn,telephonenumber,ou,title', )),
            expected=dict(
                result=lambda d:
                (d['ipausersearchfields'] ==
                 (u'uid,givenname,sn,telephonenumber,ou,title', )),
                value=None,
                summary=None,
            ),
        ),
        dict(
            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'),
        ),
        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 {}, where max level '
                '{}'.format(platformconstants.SELINUX_MLS_REGEX,
                            platformconstants.SELINUX_MLS_MAX)),
        ),
        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'),
        ),
        dict(
            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'),
        ),
        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'baduser')),
            expected=errors.ValidationError(
                name='ipaselinuxusermaporder',
                error='SELinux user \'baduser\' is not valid: Invalid MLS '
                'value, must match {}, where max level {}'.format(
                    platformconstants.SELINUX_MLS_REGEX,
                    platformconstants.SELINUX_MLS_MAX)),
        ),
        dict(
            desc='Try to set new selinux order and invalid default user',
            command=('config_mod', [],
                     dict(ipaselinuxusermaporder=u'foo:s0',
                          ipaselinuxusermapdefault=u'unknown_u:s0')),
            expected=errors.ValidationError(
                name='ipaselinuxusermapdefault',
                error='SELinux user map default user not in order list'),
        ),
        dict(
            desc='Set user auth type',
            command=('config_mod', [], dict(ipauserauthtype=u'password')),
            expected=dict(
                result=lambda d: d['ipauserauthtype'] == (u'password', ),
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Check user auth type',
            command=('config_show', [], {}),
            expected=dict(
                result=lambda d: d['ipauserauthtype'] == (u'password', ),
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Unset user auth type',
            command=('config_mod', [], dict(ipauserauthtype=None)),
            expected=dict(
                result=lambda d: 'ipauserauthtype' not in d,
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Set maximum username length higher than limit of 255',
            command=('config_mod', [], dict(ipamaxusernamelength=256)),
            expected=errors.ValidationError(name='maxusername',
                                            error='can be at most 255'),
        ),
        dict(
            desc='Set maximum username length equal to limit 255',
            command=('config_mod', [], dict(ipamaxusernamelength=255)),
            expected=dict(
                result=lambda d: d['ipamaxusernamelength'] == (u'255', ),
                value=None,
                summary=None,
            ),
        ),

        # Cleanup after previous test - returns max username length to 32
        dict(
            desc='Return maximum username length to default value',
            command=('config_mod', [], dict(ipamaxusernamelength=32)),
            expected=dict(
                result=lambda d: d['ipamaxusernamelength'] == (u'32', ),
                value=None,
                summary=None,
            ),
        ),
        dict(
            desc='Check if domain resolution order does not accept SLD',
            command=('config_mod', [], {
                'ipadomainresolutionorder':
                u'{domain}:{sl_domain}'.format(domain=domain,
                                               sl_domain=sl_domain)
            }),
            expected=errors.ValidationError(
                name=u'ipadomainresolutionorder',
                error=(u"Invalid domain name '{}': "
                       "single label domains are not supported"
                       ).format(sl_domain),
            ),
        ),
        dict(
            desc='Set the number of search records to -1 (unlimited)',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'-1',
                },
            ),
            expected={
                'result': lambda d: d['ipasearchrecordslimit'] == (u'-1', ),
                'summary': None,
                'value': None,
            },
        ),
        dict(
            desc='Set the number of search records to greater than 10',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'100',
                },
            ),
            expected={
                'result': lambda d: d['ipasearchrecordslimit'] == (u'100', ),
                'summary': None,
                'value': None,
            },
        ),
        dict(
            desc='Set the number of search records to lower than -1',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'-10',
                },
            ),
            expected=errors.ValidationError(
                name=u'searchrecordslimit',
                error=u'must be at least 10',
            ),
        ),
        dict(
            desc='Set the number of search records to lower than 10',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'1',
                },
            ),
            expected=errors.ValidationError(
                name=u'searchrecordslimit',
                error=u'must be at least 10',
            ),
        ),
        dict(
            desc='Set the number of search records to zero (unlimited)',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'0',
                },
            ),
            expected={
                'result': lambda d: d['ipasearchrecordslimit'] == (u'-1', ),
                'summary': None,
                'value': None,
            },
        ),
        dict(
            desc='Set the number of search records back to 100',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'100',
                },
            ),
            expected={
                'result': lambda d: d['ipasearchrecordslimit'] == (u'100', ),
                'summary': None,
                'value': None,
            },
        ),
        dict(
            desc='Set the value to the already set value, no modifications',
            command=(
                'config_mod',
                [],
                {
                    'ipasearchrecordslimit': u'100',
                },
            ),
            expected=errors.EmptyModlist(),
        ),
    ]
Example #13
0
class test_attr(Declarative):

    cleanup_commands = [
        ('user_del', [user1], {}),
    ]

    tests = [
        dict(
            desc='Try to add user %r with single-value attribute set via '
            'option and --addattr' % user1,
            command=('user_add', [user1],
                     dict(givenname=u'Test', sn=u'User1',
                          addattr=u'sn=User2')),
            expected=errors.OnlyOneValueAllowed(attr='sn'),
        ),
        dict(
            desc='Create %r' % user1,
            command=('user_add', [user1],
                     dict(givenname=u'Test', sn=u'User1', setattr=None)),
            expected=dict(
                value=user1,
                summary=u'Added user "tuser1"',
                result=get_user_result(user1, u'Test', u'User1', 'add'),
            ),
        ),
        dict(
            desc='Change givenname, add mail %r' % user1,
            command=('user_mod', [user1],
                     dict(setattr=(u'givenname=Finkle',
                                   u'[email protected]'))),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Add another mail %r' % user1,
            command=('user_mod', [user1],
                     dict(addattr=u'[email protected]')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Add two phone numbers at once %r' % user1,
            command=('user_mod', [user1],
                     dict(setattr=u'telephoneNumber=410-555-1212',
                          addattr=u'telephoneNumber=301-555-1212')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'410-555-1212', u'301-555-1212'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Go from two phone numbers to one %r' % user1,
            command=('user_mod', [user1],
                     dict(setattr=u'telephoneNumber=301-555-1212')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'301-555-1212'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Add two more phone numbers %r' % user1,
            command=('user_mod', [user1],
                     dict(addattr=(u'telephoneNumber=703-555-1212',
                                   u'telephoneNumber=202-888-9833'))),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[
                        u'301-555-1212', u'703-555-1212', u'202-888-9833'
                    ],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Delete one phone number for %r' % user1,
            command=('user_mod', [user1],
                     dict(delattr=u'telephoneNumber=301-555-1212')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'703-555-1212', u'202-888-9833'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(desc='Try deleting the number again for %r' % user1,
             command=('user_mod', [user1],
                      dict(delattr=u'telephoneNumber=301-555-1212')),
             expected=errors.AttrValueNotFound(attr=u'telephonenumber',
                                               value=u'301-555-1212')),
        dict(
            desc='Add and delete one phone number for %r' % user1,
            command=('user_mod', [user1],
                     dict(addattr=u'telephoneNumber=301-555-1212',
                          delattr=u'telephoneNumber=202-888-9833')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'703-555-1212', u'301-555-1212'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Add and delete the same phone number for %r' % user1,
            command=('user_mod', [user1],
                     dict(addattr=(u'telephoneNumber=301-555-1212',
                                   u'telephoneNumber=202-888-9833'),
                          delattr=u'telephoneNumber=301-555-1212')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[
                        u'703-555-1212', u'301-555-1212', u'202-888-9833'
                    ],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Set and delete a phone number for %r' % user1,
            command=('user_mod', [user1],
                     dict(setattr=(u'telephoneNumber=301-555-1212',
                                   u'telephoneNumber=202-888-9833'),
                          delattr=u'telephoneNumber=301-555-1212')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'202-888-9833'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Try setting givenname to None with setattr in %r' % user1,
            command=('user_mod', [user1], dict(setattr=(u'givenname='))),
            expected=errors.RequirementError(name='givenname'),
        ),
        dict(
            desc='Try setting givenname to None with option in %r' % user1,
            command=('user_mod', [user1], dict(givenname=None)),
            expected=errors.RequirementError(name='first'),
        ),
        dict(
            desc='Make sure setting givenname works with option in %r' % user1,
            command=('user_mod', [user1], dict(givenname=u'Fred')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Fred',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'202-888-9833'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Make sure setting givenname works with setattr in %r' %
            user1,
            command=('user_mod', [user1], dict(setattr=u'givenname=Finkle')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'202-888-9833'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Try to "remove" empty location from %r' % user1,
            command=('user_mod', [user1], dict(l=None)),
            expected=errors.EmptyModlist(),
        ),
        dict(
            desc='Lock %r using setattr' % user1,
            command=('user_mod', [user1], dict(setattr=u'nsaccountlock=TrUe')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'202-888-9833'],
                    nsaccountlock=True,
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Unlock %r using addattr&delattr' % user1,
            command=('user_mod', [user1],
                     dict(addattr=u'nsaccountlock=FaLsE',
                          delattr=u'nsaccountlock=TRUE')),
            expected=dict(
                result=get_user_result(
                    user1,
                    u'Finkle',
                    u'User1',
                    'mod',
                    mail=[u'*****@*****.**', u'*****@*****.**'],
                    telephonenumber=[u'202-888-9833'],
                ),
                summary=u'Modified user "tuser1"',
                value=user1,
            ),
        ),
        dict(
            desc='Try adding a new group search fields config entry',
            command=('config_mod', [],
                     dict(addattr=u'ipagroupsearchfields=newattr')),
            expected=errors.OnlyOneValueAllowed(attr='ipagroupsearchfields'),
        ),
        dict(
            desc='Try adding a new cert subject base config entry',
            command=('config_mod', [],
                     dict(addattr=u'ipacertificatesubjectbase=0=DOMAIN.COM')),
            expected=errors.ValidationError(
                name='ipacertificatesubjectbase',
                error='attribute is not configurable'),
        ),
        dict(
            desc='Try deleting a required config entry',
            command=('config_mod', [],
                     dict(delattr=u'ipasearchrecordslimit=100')),
            expected=errors.RequirementError(name='ipasearchrecordslimit'),
        ),
        dict(
            desc='Try setting nonexistent attribute',
            command=('config_mod', [], dict(setattr=u'invalid_attr=false')),
            expected=errors.ObjectclassViolation(
                info='attribute "invalid_attr" not allowed'),
        ),
        dict(
            desc='Try setting out-of-range krbpwdmaxfailure',
            command=('pwpolicy_mod', [], dict(setattr=u'krbpwdmaxfailure=-1')),
            expected=errors.ValidationError(name='krbpwdmaxfailure',
                                            error='must be at least 0'),
        ),
        dict(
            desc='Try setting out-of-range maxfail',
            command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'-1')),
            expected=errors.ValidationError(name='maxfail',
                                            error='must be at least 0'),
        ),
        dict(
            desc='Try setting non-numeric krbpwdmaxfailure',
            command=('pwpolicy_mod', [],
                     dict(setattr=u'krbpwdmaxfailure=abc')),
            expected=errors.ConversionError(name='krbpwdmaxfailure',
                                            error='must be an integer'),
        ),
        dict(
            desc='Try setting non-numeric maxfail',
            command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'abc')),
            expected=errors.ConversionError(name='maxfail',
                                            error='must be an integer'),
        ),
        dict(
            desc='Try deleting bogus attribute',
            command=('config_mod', [], dict(delattr=u'bogusattribute=xyz')),
            expected=errors.ValidationError(
                name='bogusattribute',
                error='No such attribute on this entry'),
        ),
        dict(
            desc='Try deleting empty attribute',
            command=('config_mod', [],
                     dict(delattr=u'ipaCustomFields=See Also,seealso,false')),
            expected=errors.ValidationError(
                name='ipacustomfields',
                error='No such attribute on this entry'),
        ),
        dict(
            desc='Set and delete one value, plus try deleting a missing one',
            command=('config_mod', [],
                     dict(delattr=[
                         u'ipaCustomFields=See Also,seealso,false',
                         u'ipaCustomFields=Country,c,false'
                     ],
                          addattr=u'ipaCustomFields=See Also,seealso,false')),
            expected=errors.AttrValueNotFound(attr='ipacustomfields',
                                              value='Country,c,false'),
        ),
        dict(
            desc='Try to delete an operational attribute with --delattr',
            command=('config_mod', [],
                     dict(delattr=u'creatorsName=cn=directory manager')),
            expected=errors.DatabaseError(
                desc='Server is unwilling to perform', info=''),
        ),
    ]