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))
class sudorule_remove_option(LDAPQuery): __doc__ = _('Remove an option from Sudo Rule.') takes_options = (Str( 'ipasudoopt', cli_name='sudooption', label=_('Sudo Option'), ), ) 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 except KeyError: raise errors.AttrValueNotFound(attr='ipasudoopt', value=options['ipasudoopt'])
def test_delete_the_number_again(self, user): """ Try deleting the number again for user """ user.ensure_exists() update = u'301-555-1212' command = user.make_update_command( dict(delattr=u'telephoneNumber='+update)) with raises_exact(errors.AttrValueNotFound( attr=u'telephonenumber', value=update)): command()
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) associateddomain = entry_attrs.get('associateddomain') add_domain = entry_attrs.get('add_domain') del_domain = entry_attrs.get('del_domain') force = options.get('force') current_domain = self.api.env.domain # User specified the list of domains explicitly if associateddomain: if add_domain or del_domain: raise errors.MutuallyExclusiveError(reason=_( "The --domain option cannot be used together " "with --add-domain or --del-domain. Use --domain " "to specify the whole realm domain list explicitly, " "to add/remove individual domains, use " "--add-domain/del-domain.")) # Make sure our domain is included in the list if current_domain not in associateddomain: raise errors.ValidationError( name='realmdomain list', error=_("IPA server domain cannot be omitted")) # Validate that each domain satisfies the requirements # for realmdomain self.validate_domains(domains=associateddomain, force=force) return dn # If --add-domain or --del-domain options were provided, read # the curent list from LDAP, modify it, and write the changes back domains = ldap.get_entry(dn)['associateddomain'] if add_domain: self.validate_domains(domains=[add_domain], force=force) del entry_attrs['add_domain'] domains.append(add_domain) if del_domain: if del_domain == current_domain: raise errors.ValidationError( name='del_domain', error=_("IPA server domain cannot be deleted")) del entry_attrs['del_domain'] try: domains.remove(del_domain) except ValueError: raise errors.AttrValueNotFound(attr='associateddomain', value=del_domain) entry_attrs['associateddomain'] = domains return dn
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) associateddomain = entry_attrs.get('associateddomain') add_domain = entry_attrs.get('add_domain') del_domain = entry_attrs.get('del_domain') force = options.get('force') if associateddomain: if add_domain or del_domain: raise errors.MutuallyExclusiveError(reason=_( "you cannot specify the --domain option together with --add-domain or --del-domain" )) if get_domain_name() not in associateddomain: raise errors.ValidationError( name='domain', error=_("cannot delete domain of IPA server")) if not force: bad_domains = [ d for d in associateddomain if not has_soa_or_ns_record(d) ] if bad_domains: bad_domains = ', '.join(bad_domains) raise errors.ValidationError( name='domain', error=_("no SOA or NS records found for domains: %s" % bad_domains)) return dn # If --add-domain or --del-domain options were provided, read # the curent list from LDAP, modify it, and write the changes back domains = ldap.get_entry(dn)['associateddomain'] if add_domain: if not force and not has_soa_or_ns_record(add_domain): raise errors.ValidationError( name='add_domain', error=_("no SOA or NS records found for domain %s" % add_domain)) del entry_attrs['add_domain'] domains.append(add_domain) if del_domain: if del_domain == get_domain_name(): raise errors.ValidationError( name='del_domain', error=_("cannot delete domain of IPA server")) del entry_attrs['del_domain'] try: domains.remove(del_domain) except ValueError: raise errors.AttrValueNotFound(attr='associateddomain', value=del_domain) entry_attrs['associateddomain'] = domains return dn
def test_set_and_del_value_and_del_missing_one(self, user): """ Set and delete one value, plus try deleting a missing one """ command = user.make_command( 'config_mod', **dict( delattr=[u'ipaCustomFields=See Also,seealso,false', u'ipaCustomFields=Country,c,false'], addattr=u'ipaCustomFields=See Also,seealso,false') ) with raises_exact(errors.AttrValueNotFound( attr='ipacustomfields', value='Country,c,false')): command()
def test_delete_nonexistent_datetime(self, user): """ Delete a datetime data type that isn't in the entry """ user.ensure_exists() expdate = u'20220210144006Z' bad_expdate = u'20280210144006Z' user.update( dict(setattr=u'krbpasswordexpiration=' + expdate), dict(krbpasswordexpiration=[ datetime.strptime(expdate, LDAP_GENERALIZED_TIME_FORMAT) ], setattr='') ) command = user.make_update_command( dict(delattr=u'krbpasswordexpiration=' + bad_expdate), ) with raises_exact(errors.AttrValueNotFound( attr='krbpasswordexpiration', value=bad_expdate)): command()
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
def test_add_and_delete_DN(self, user, manager): """ Delete a DN data type """ user.ensure_exists() manager.ensure_exists() user.update( dict(setattr=u'manager=manager'), dict(manager=['manager'], setattr='') ) command = user.make_update_command( dict(delattr=u'manager=manager'), ) # Setting works because the user plugin knows the container # to convert a string to a DN. Passing in just the uid we # don't have the context in ldap.decode() to know the entry # type so `ipa user-mod someuser --delattr manager=foo` will # fail. with raises_exact(errors.AttrValueNotFound( attr='manager', value='manager')): command()
class test_realmdomains(Declarative): # Make sure your environment has sound DNS configuration where # the IPA domain has either NS or SOA record. Check your resolver # if getting errors with the realmdomains_mod cleanup command. cleanup_commands = [ ('realmdomains_mod', [], {'associateddomain': [our_domain]}), ] tests = [ dict( desc='Retrieve realm domains', command=('realmdomains_show', [], {}), expected=dict( value=None, summary=None, result=dict( dn=dn, associateddomain=[our_domain], ), ), ), dict( desc='Retrieve realm domains - print all attributes', command=('realmdomains_show', [], {'all': True}), expected=dict( value=None, summary=None, result=dict( dn=dn, associateddomain=[our_domain], cn=[cn], objectclass=objectclasses.realmdomains, aci=[ u'(targetattr = "associateddomain || cn || ' u'createtimestamp || entryusn || ' u'modifytimestamp || objectclass")' u'(targetfilter = "(objectclass=domainrelatedobject)")' u'(version 3.0;acl ' u'"permission:System: Read Realm Domains";' u'allow (compare,read,search) ' u'userdn = "ldap:///all";)', u'(targetattr = "associateddomain")' u'(targetfilter = "(objectclass=domainrelatedobject)")' u'(version 3.0;acl ' u'"permission:System: Modify Realm Domains";' u'allow (write) groupdn = "ldap:///%s";)' % DN('cn=System: Modify Realm Domains', api.env.container_permission, api.env.basedn), ], ), ), ), dict( desc='Replace list of realm domains with "%s"' % [our_domain, new_domain_1], command=('realmdomains_mod', [], {'associateddomain': [our_domain, new_domain_1], 'force':True}), expected=dict( value=None, summary=None, messages=({u'message': u"The _kerberos TXT record from domain " "example1.com could not be created (%s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please create the record " "manually, containing the following value: " "'%s'" % (new_domain_1, api.env.realm), u'code': 13011, u'type': u'warning', u'name': u'KerberosTXTRecordCreationFailure', u'data': { u'domain': new_domain_1, u'realm': api.env.realm, u'error': (u"%s.: DNS zone not found" % new_domain_1), }}, ), result=dict( associateddomain=[our_domain, new_domain_1], ), ), ), dict( desc='Add domain "%s" to list' % new_domain_2, command=('realmdomains_mod', [], {'add_domain': new_domain_2, 'force': True}), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_1, new_domain_2], ), messages=({u'message': u"The _kerberos TXT record from domain " "%(domain)s could not be created (%(domain)s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please create the record " "manually, containing the following value: " "'%(realm)s'" % dict(domain=new_domain_2, realm=api.env.realm), u'code': 13011, u'type': u'warning', u'name': u'KerberosTXTRecordCreationFailure', u'data': { u'domain': new_domain_2, u'realm': api.env.realm, u'error': (u"%s.: DNS zone not found" % new_domain_2), }}, ), ), ), dict( desc='Delete domain "%s" from list' % new_domain_2, command=('realmdomains_mod', [], {'del_domain': new_domain_2}), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_1], ), messages=({u'message': u"The _kerberos TXT record from domain " "%(domain)s could not be removed (%(domain)s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please remove the record " "manually." % dict(domain=new_domain_2), u'code': 13012, u'type': u'warning', u'name': u'KerberosTXTRecordDeletionFailure', u'data': { u'domain': new_domain_2, u'error': (u"%s.: DNS zone not found" % new_domain_2), }}, ), ), ), dict( desc='Add domain "%s" and delete domain "%s"' % (new_domain_2, new_domain_1), command=('realmdomains_mod', [], {'add_domain': new_domain_2, 'del_domain': new_domain_1, 'force': True}), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_2], ), messages=({u'message': u"The _kerberos TXT record from domain " "%(domain)s could not be created (%(domain)s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please create the record " "manually, containing the following value: " "'%(realm)s'" % dict(domain=new_domain_2, realm=api.env.realm), u'code': 13011, u'type': u'warning', u'name': u'KerberosTXTRecordCreationFailure', u'data': { u'domain': new_domain_2, u'realm': api.env.realm, u'error': (u"%s.: DNS zone not found" % new_domain_2), }}, {u'message': u"The _kerberos TXT record from domain " "%(domain)s could not be removed (%(domain)s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please remove the record " "manually." % dict(domain=new_domain_1), u'code': 13012, u'type': u'warning', u'name': u'KerberosTXTRecordDeletionFailure', u'data': { u'domain': new_domain_1, u'error': (u"%s.: DNS zone not found" % new_domain_1), }}, ), ), ), dict( desc='Try to specify --domain and --add-domain options together', command=('realmdomains_mod', [], { 'associateddomain': [our_domain, new_domain_1], 'add_domain': new_domain_1, }), expected=errors.MutuallyExclusiveError( reason='The --domain option cannot be used together with --add-domain or --del-domain. Use --domain to specify the whole realm domain list explicitly, to add/remove individual domains, use --add-domain/del-domain.'), ), dict( desc='Try to replace list of realm domains with a list without our domain', command=('realmdomains_mod', [], {'associateddomain': [new_domain_1]}), expected=errors.ValidationError( name='realmdomain list', error='IPA server domain cannot be omitted'), ), dict( desc='Try to replace list of realm domains with a list with an invalid domain "%s"' % bad_domain, command=('realmdomains_mod', [], {'associateddomain': [our_domain, bad_domain]}), expected=errors.ValidationError( name='domain', error='DNS zone for each realmdomain must contain SOA or NS records. No records found for: %s' % bad_domain), ), dict( desc='Try to add an invalid domain "%s"' % bad_domain, command=('realmdomains_mod', [], {'add_domain': bad_domain}), expected=errors.ValidationError( name='domain', error='DNS zone for each realmdomain must contain SOA or NS records. No records found for: %s' % bad_domain), ), dict( desc='Try to delete our domain', command=('realmdomains_mod', [], {'del_domain': our_domain}), expected=errors.ValidationError( name='del_domain', error='IPA server domain cannot be deleted'), ), dict( desc='Try to delete domain which is not in list', command=('realmdomains_mod', [], {'del_domain': new_domain_1}), expected=errors.AttrValueNotFound( attr='associateddomain', value=new_domain_1), ), dict( desc='Add an invalid domain "%s" with --force option' % bad_domain, command=('realmdomains_mod', [], {'add_domain': bad_domain, 'force': True}), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_2, bad_domain], ), messages=({u'message': u"The _kerberos TXT record from domain " "%(domain)s could not be created (%(domain)s.: " "DNS zone not found).\nThis can happen if the zone " "is not managed by IPA. Please create the record " "manually, containing the following value: " "'%(realm)s'" % dict(domain=bad_domain, realm=api.env.realm), u'code': 13011, u'type': u'warning', u'name': u'KerberosTXTRecordCreationFailure', u'data': { u'domain': bad_domain, u'realm': api.env.realm, u'error': (u"%s.: DNS zone not found" % bad_domain), }}, ), ), ), dict( desc='Add a single label domain {}'.format(sl_domain), command=('realmdomains_mod', [], {'add_domain': sl_domain}), expected=errors.ValidationError( name='add_domain', error='single label domains are not supported' ), ) ]
class test_realmdomains(Declarative): cleanup_commands = [ ('realmdomains_mod', [], { 'associateddomain': [our_domain] }), ] tests = [ dict( desc='Retrieve realm domains', command=('realmdomains_show', [], {}), expected=dict( value=None, summary=None, result=dict( dn=dn, associateddomain=[our_domain], ), ), ), dict( desc='Retrieve realm domains - print all attributes', command=('realmdomains_show', [], { 'all': True }), expected=dict( value=None, summary=None, result=dict( dn=dn, associateddomain=[our_domain], cn=[cn], objectclass=objectclasses.realmdomains, aci=[ u'(targetattr = "associateddomain || cn || ' u'createtimestamp || entryusn || ' u'modifytimestamp || objectclass")' u'(targetfilter = "(objectclass=domainrelatedobject)")' u'(version 3.0;acl ' u'"permission:System: Read Realm Domains";' u'allow (compare,read,search) ' u'userdn = "ldap:///all";)', u'(targetattr = "associateddomain")' u'(targetfilter = "(objectclass=domainrelatedobject)")' u'(version 3.0;acl ' u'"permission:System: Modify Realm Domains";' u'allow (write) groupdn = "ldap:///%s";)' % DN('cn=System: Modify Realm Domains', api.env.container_permission, api.env.basedn), ], ), ), ), dict( desc='Replace list of realm domains with "%s"' % [our_domain, new_domain_1], command=('realmdomains_mod', [], { 'associateddomain': [our_domain, new_domain_1] }), expected=dict( value=None, summary=None, result=dict(associateddomain=[our_domain, new_domain_1], ), ), ), dict( desc='Add domain "%s" to list' % new_domain_2, command=('realmdomains_mod', [], { 'add_domain': new_domain_2 }), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_1, new_domain_2], ), ), ), dict( desc='Delete domain "%s" from list' % new_domain_2, command=('realmdomains_mod', [], { 'del_domain': new_domain_2 }), expected=dict( value=None, summary=None, result=dict(associateddomain=[our_domain, new_domain_1], ), ), ), dict( desc='Add domain "%s" and delete domain "%s"' % (new_domain_2, new_domain_1), command=('realmdomains_mod', [], { 'add_domain': new_domain_2, 'del_domain': new_domain_1 }), expected=dict( value=None, summary=None, result=dict(associateddomain=[our_domain, new_domain_2], ), ), ), dict( desc='Try to specify --domain and --add-domain options together', command=('realmdomains_mod', [], { 'associateddomain': [our_domain, new_domain_1], 'add_domain': new_domain_1, }), expected=errors.MutuallyExclusiveError( reason= 'you cannot specify the --domain option together with --add-domain or --del-domain' ), ), dict( desc= 'Try to replace list of realm domains with a list without our domain', command=('realmdomains_mod', [], { 'associateddomain': [new_domain_1] }), expected=errors.ValidationError( name='domain', error='cannot delete domain of IPA server'), ), dict( desc= 'Try to replace list of realm domains with a list with an invalid domain "%s"' % bad_domain, command=('realmdomains_mod', [], { 'associateddomain': [our_domain, bad_domain] }), expected=errors.ValidationError( name='domain', error='no SOA or NS records found for domains: %s' % bad_domain), ), dict( desc='Try to add an invalid domain "%s"' % bad_domain, command=('realmdomains_mod', [], { 'add_domain': bad_domain }), expected=errors.ValidationError( name='add_domain', error='no SOA or NS records found for domain %s' % bad_domain), ), dict( desc='Try to delete our domain', command=('realmdomains_mod', [], { 'del_domain': our_domain }), expected=errors.ValidationError( name='del_domain', error='cannot delete domain of IPA server'), ), dict( desc='Try to delete domain which is not in list', command=('realmdomains_mod', [], { 'del_domain': new_domain_1 }), expected=errors.AttrValueNotFound(attr='associateddomain', value=new_domain_1), ), dict( desc='Add an invalid domain "%s" with --force option' % bad_domain, command=('realmdomains_mod', [], { 'add_domain': bad_domain, 'force': True }), expected=dict( value=None, summary=None, result=dict( associateddomain=[our_domain, new_domain_2, bad_domain], ), ), ), ]
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=dict( gecos=[u'Test User1'], givenname=[u'Test'], homedirectory=[u'/home/tuser1'], krbprincipalname=[u'tuser1@' + api.env.realm], loginshell=[u'/bin/sh'], objectclass=objectclasses.user, sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'%s@%s' % (user1, api.env.domain)], displayname=[u'Test User1'], 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'), api.env.basedn) ], memberof_group=[u'ipausers'], dn=DN(('uid', 'tuser1'), ('cn', 'users'), ('cn', 'accounts'), api.env.basedn), has_keytab=False, has_password=False, ), ), ), dict( desc='Change givenname, add mail %r' % user1, command=('user_mod', [user1], dict(setattr=(u'givenname=Finkle', u'[email protected]'))), expected=dict( result=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**'], memberof_group=[u'ipausers'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'410-555-1212', u'301-555-1212'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'301-555-1212'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[ u'301-555-1212', u'202-888-9833', u'703-555-1212' ], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833', u'703-555-1212'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'301-555-1212', u'703-555-1212'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[ u'703-555-1212', u'301-555-1212', u'202-888-9833' ], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Fred'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833'], nsaccountlock=False, has_keytab=False, has_password=False, ), summary=u'Modified user "tuser1"', value=user1, ), ), dict( desc='Lock %r using setattr' % user1, command=('user_mod', [user1], dict(setattr=u'nsaccountlock=TrUe')), expected=dict( result=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833'], nsaccountlock=True, has_keytab=False, has_password=False, ), 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=dict( givenname=[u'Finkle'], homedirectory=[u'/home/tuser1'], loginshell=[u'/bin/sh'], sn=[u'User1'], uid=[user1], uidnumber=[fuzzy_digits], gidnumber=[fuzzy_digits], mail=[u'*****@*****.**', u'*****@*****.**'], memberof_group=[u'ipausers'], telephonenumber=[u'202-888-9833'], nsaccountlock=False, has_keytab=False, has_password=False, ), 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=''), ), ]
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=''), ), ]