def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) entry_attrs.setdefault('nisdomainname', self.api.env.domain) try: test_dn = self.obj.get_dn(keys[-1]) (test_dn_, netgroup) = ldap.get_entry(test_dn, ['objectclass']) if 'mepManagedEntry' in netgroup.get('objectclass', []): raise errors.DuplicateEntry( message=unicode(self.msg_collision % keys[-1])) else: self.obj.handle_duplicate_entry(*keys) except errors.NotFound: pass try: # when enabled, a managed netgroup is created for every hostgroup # make sure that we don't create a collision if the plugin is # (temporarily) disabled api.Object['hostgroup'].get_dn_if_exists(keys[-1]) raise errors.DuplicateEntry(message=unicode(self.msg_collision % keys[-1])) except errors.NotFound: pass return dn
def _check_conflict(self, ldap, dn, entry, operation): """Check for conflicting login and email address The stageuser_activate plugin does not modrdn the stage user to active user. Instead it first creates a new active user DN and then deletes the stage user DN. All uniqueness plugins have to exclude stage user area and FAS has to manually check for conflicts. """ unique_attrs = ["uid", "krbprincipalname", "krbcanonicalname", "mail"] if operation == "add": attr_filters = ldap.make_filter( {attr: entry[attr] for attr in unique_attrs}, rules=ldap.MATCH_ANY) elif operation == "mod": entry["uid"] = dn["uid"] attr_filters = ldap.make_filter( {attr: entry[attr] for attr in unique_attrs if attr in entry}, rules=ldap.MATCH_ANY, ) else: raise ValueError(operation) objcls_filters = ldap.make_filter( {"objectclass": ["posixaccount", "inetOrgPerson"]}, rules=ldap.MATCH_ANY, ) filters = ldap.combine_filters([objcls_filters, attr_filters], rules=ldap.MATCH_ALL) try: res, truncated = ldap.find_entries( filters, unique_attrs, base_dn=self.api.env.basedn, scope=ldap.SCOPE_SUBTREE, ) except errors.NotFound: pass else: for conflict_entry in res: if conflict_entry.dn == dn: # skip own entry continue if "mail" in entry: raise errors.DuplicateEntry(message=_( "Login '%(user)s' or email address '%(mail)s' are " "already registered.") % { "user": entry["uid"], "mail": ", ".join(entry["mail"]) }) else: # mod operation raise errors.DuplicateEntry( message=_("Login '%(user)s' is already registered.") % {"user": entry["uid"]})
def handle_duplicate_entry(self, *keys): pkey = keys[-1] key = pkey.split(self.rdn_separator)[0] info = self.rdn_separator.join(pkey.split(self.rdn_separator)[1:]) if info: raise errors.DuplicateEntry(message=self.already_exists_msg % { 'key': key, 'info': info, }) else: raise errors.DuplicateEntry(message=self.key_already_exists_msg % { 'key': key, })
def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options): ca_enabled_check() if not ldap.can_add(dn[1:]): raise errors.ACIError( info=_("Insufficient 'add' privilege for entry '%s'.") % dn) # check for name collision before creating CA in Dogtag try: api.Object.ca.get_dn_if_exists(keys[-1]) self.obj.handle_duplicate_entry(*keys) except errors.NotFound: pass # check for subject collision before creating CA in Dogtag result = api.Command.ca_find(ipacasubjectdn=options['ipacasubjectdn']) if result['count'] > 0: raise errors.DuplicateEntry( message=_("Subject DN is already used by CA '%s'") % result['result'][0]['cn'][0]) # Create the CA in Dogtag. with self.api.Backend.ra_lightweight_ca as ca_api: resp = ca_api.create_ca(options['ipacasubjectdn']) entry['ipacaid'] = [resp['id']] entry['ipacaissuerdn'] = [resp['issuerDN']] # In the event that the issued certificate's subject DN # differs from what was requested, record the actual DN. # entry['ipacasubjectdn'] = [resp['dn']] return dn
def test_create_duplicate(self, user_profile): msg = u'Certificate Profile with name "{}" already exists' user_profile.ensure_exists() command = user_profile.make_create_command() with raises_exact( errors.DuplicateEntry(message=msg.format(user_profile.name))): command()
def test_create_duplicate(self, stageduser): stageduser.ensure_exists() command = stageduser.make_create_command() with raises_exact(errors.DuplicateEntry( message=u'stage user with name "%s" already exists' % stageduser.uid)): command()
def test_active_same_as_preserved(self, user4, user5): user4.ensure_missing() user5.make_preserved_user() command = user4.make_create_command() with raises_exact(errors.DuplicateEntry( message=u'user with name "%s" already exists' % user4.uid)): command() user5.delete()
def test_create_duplicate(self, host): host.ensure_exists() command = host.make_create_command(force=True) with raises_exact( errors.DuplicateEntry( message=u'host with name "%s" already exists' % host.fqdn)): command()
def test_create_duplicate(self, location): location.ensure_exists() command = location.make_create_command() with raises_exact( errors.DuplicateEntry( message=u'location with name "%s" already exists' % location.idnsname)): command()
def test_create_duplicates(self, sudocmd1, sudocmd2): """ Try to create duplicate sudocmds """ sudocmd1.ensure_exists() sudocmd2.ensure_exists() command1 = sudocmd1.make_create_command() command2 = sudocmd2.make_create_command() with raises_exact( errors.DuplicateEntry( message=u'sudo command with name "%s" already exists' % sudocmd1.cmd)): command1() with raises_exact( errors.DuplicateEntry( message=u'sudo command with name "%s" already exists' % sudocmd2.cmd)): command2()
def test_create_duplicate_hostgroup(self, hostgroup): """ Try to create duplicate hostgroup """ hostgroup.ensure_exists() command = hostgroup.make_create_command() with raises_exact(errors.DuplicateEntry( message=u'host group with name "%s" already exists' % hostgroup.cn)): command()
def test_create_duplicate(self, user): """ Try to create second user with the same name """ user.ensure_exists() command = user.make_create_command() with raises_exact( errors.DuplicateEntry( message=u'user with name "%s" already exists' % user.uid)): command()
def test_create_duplicate_to_nonposix(self, group): """ Try to create a duplicate non-posix group """ group.ensure_exists() command = group.make_create_command() with raises_exact(errors.DuplicateEntry( message=u'group with name "%s" already exists' % group.cn)): command()
def test_create_duplicate(self, sudocmdgroup1): """ Try to create duplicate sudocmdgroup """ sudocmdgroup1.ensure_exists() command = sudocmdgroup1.make_create_command() with raises_exact( errors.DuplicateEntry( message=u'sudo command group ' + u'with name "%s" already exists' % sudocmdgroup1.cn)): command()
def test_staged_same_as_preserved(self, user5, stageduser4): user5.make_preserved_user() stageduser4.create() # can be created command = stageduser4.make_activate_command() with raises_exact( errors.DuplicateEntry(message=u'This entry already exists')): command() # cannot be activated user5.delete() stageduser4.delete()
def test_staged_same_as_active(self, user4, stageduser4): user4.ensure_exists() stageduser4.create() # can be created command = stageduser4.make_activate_command() with raises_exact(errors.DuplicateEntry( message=u'active user with name "%s" already exists' % user4.uid)): command() # cannot be activated user4.delete() stageduser4.delete()
def handle_duplicate_entry(self, *keys): if hasattr(context, "subid_owner_dn"): uid = context.subid_owner_dn[0].value msg = _( '%(oname)s with with name "%(pkey)s" or for user "%(uid)s" ' "already exists.") % { "uid": uid, "pkey": keys[-1] if keys else "", "oname": self.object_name, } raise errors.DuplicateEntry(message=msg) from None else: super().handle_duplicate_entry(*keys)
def test_active_same_as_staged(self, user4, stageduser4): user4.ensure_missing() stageduser4.ensure_exists() command = user4.make_create_command() result = command() user4.track_create() user4.check_create(result) # can be created command = stageduser4.make_activate_command() with raises_exact(errors.DuplicateEntry( message=u'active user with name "%s" already exists' % user4.uid)): command() # cannot be activated
def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options): ca_enabled_check(self.api) if not ldap.can_add(dn[1:]): raise errors.ACIError( info=_("Insufficient 'add' privilege for entry '%s'.") % dn) # check that DN only includes standard naming attributes dn_attrs = { ava.attr.lower() for rdn in options['ipacasubjectdn'] for ava in rdn } x509_attrs = { attr.lower() for attr in six.viewvalues(ATTR_NAME_BY_OID) } unknown_attrs = dn_attrs - x509_attrs if len(unknown_attrs) > 0: raise errors.ValidationError( name=_("Subject DN"), error=_("Unrecognized attributes: %(attrs)s") % dict(attrs=", ".join(unknown_attrs)) ) # check for name collision before creating CA in Dogtag try: api.Object.ca.get_dn_if_exists(keys[-1]) self.obj.handle_duplicate_entry(*keys) except errors.NotFound: pass # check for subject collision before creating CA in Dogtag result = api.Command.ca_find(ipacasubjectdn=options['ipacasubjectdn']) if result['count'] > 0: raise errors.DuplicateEntry(message=_( "Subject DN is already used by CA '%s'" ) % result['result'][0]['cn'][0]) # Create the CA in Dogtag. with self.api.Backend.ra_lightweight_ca as ca_api: resp = ca_api.create_ca(options['ipacasubjectdn']) entry['ipacaid'] = [resp['id']] entry['ipacaissuerdn'] = [resp['issuerDN']] # In the event that the issued certificate's subject DN # differs from what was requested, record the actual DN. # entry['ipacasubjectdn'] = [resp['dn']] return dn
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) try: # check duplicity with hostgroups first to provide proper error api.Object['hostgroup'].get_dn_if_exists(keys[-1]) self.obj.handle_duplicate_entry(*keys) except errors.NotFound: pass try: # when enabled, a managed netgroup is created for every hostgroup # make sure that the netgroup can be created api.Object['netgroup'].get_dn_if_exists(keys[-1]) raise errors.DuplicateEntry(message=unicode(_( u'netgroup with name "%s" already exists. ' u'Hostgroups and netgroups share a common namespace' ) % keys[-1])) except errors.NotFound: pass return dn
def _group_exc_callback(ldap, dn, entry_attrs, exc, options): assert isinstance(dn, DN) if isinstance(exc, errors.DuplicateEntry): if options.get('groupoverwritegid', False) and \ entry_attrs.get('gidnumber') is not None: try: new_entry_attrs = {'gidnumber': entry_attrs['gidnumber']} ldap.update_entry(dn, new_entry_attrs) except errors.EmptyModlist: # no change to the GID pass # mark as success return elif not options.get('groupoverwritegid', False) and \ entry_attrs.get('gidnumber') is not None: msg = unicode(exc) # add information about possibility to overwrite GID msg = msg + unicode(_('. Check GID of the existing group. ' \ 'Use --group-overwrite-gid option to overwrite the GID')) raise errors.DuplicateEntry(message=msg) raise exc
def execute(self, aciname, **kw): 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, kw['aciprefix'], aciname) for a in acis: prefix, _name = _parse_aci_name(a.name) if _make_aci_name(prefix, kw['newname']) == a.name: raise errors.DuplicateEntry() # 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. newkw = _aci_to_kw(ldap, aci) if 'selfaci' in newkw and newkw['selfaci'] == True: # selfaci is set in aci_to_kw to True only if the target is self kw['selfaci'] = True if 'aciname' in newkw: del newkw['aciname'] # _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, kw['newname'], newkw) self.api.Command['aci_del'](aciname, aciprefix=kw['aciprefix']) result = self.api.Command['aci_add'](kw['newname'], **newkw)['result'] 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(kw['newname'], kw), )
def execute(self, aciname, **kw): """ Execute the aci-create operation. Returns the entry as it will be created in LDAP. :param aciname: The name of the ACI being added. :param kw: Keyword arguments for the other LDAP attributes. """ assert 'aciname' not in kw ldap = self.api.Backend.ldap2 newaci = _make_aci(ldap, None, aciname, kw) entry = ldap.get_entry(self.api.env.basedn, ['aci']) acis = _convert_strings_to_acis(entry.get('aci', [])) for a in acis: # FIXME: add check for permission_group = permission_group if a.isequal(newaci) or newaci.name == a.name: raise errors.DuplicateEntry() newaci_str = unicode(newaci) entry.setdefault('aci', []).append(newaci_str) if not kw.get('test', False): ldap.update_entry(entry) if kw.get('raw', False): result = dict(aci=unicode(newaci_str)) else: result = _aci_to_kw(ldap, newaci, kw.get('test', False)) return dict( result=result, value=pkey_to_value(aciname, kw), )
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) if not self.obj.check_system(ldap, dn, *keys): raise errors.ACIError( info=_('A SYSTEM permission may not be modified')) # check if permission is in LDAP try: (dn, attrs) = ldap.get_entry(dn, attrs_list, normalize=self.obj.normalize_dn) except errors.NotFound: self.obj.handle_not_found(*keys) # when renaming permission, check if the target permission does not # exists already. Then, make changes to underlying ACI if 'rename' in options: if options['rename']: try: try: new_dn = EditableDN(dn) new_dn[0][ 'cn'] # assure the first RDN has cn as it's type except (IndexError, KeyError), e: raise ValueError( "expected dn starting with 'cn=' but got '%s'" % dn) new_dn[0].value = options['rename'] (new_dn, attrs) = ldap.get_entry(new_dn, attrs_list, normalize=self.obj.normalize_dn) raise errors.DuplicateEntry() except errors.NotFound: pass # permission may be renamed, continue
class test_selinuxusermap(Declarative): cleanup_commands = [ ('selinuxusermap_del', [rule1], {}), ('group_del', [group1], {}), ('user_del', [user1], {}), ('host_del', [host1], {}), ('hbacrule_del', [hbacrule1], {}), ('hbacrule_del', [hbacrule2], {}), ] tests = [ dict( desc='Try to retrieve non-existent %r' % rule1, command=('selinuxusermap_show', [rule1], {}), expected=errors.NotFound( reason=u'%s: SELinux User Map rule not found' % rule1), ), dict( desc='Try to update non-existent %r' % rule1, command=('selinuxusermap_mod', [rule1], dict(description=u'Foo')), expected=errors.NotFound( reason=u'%s: SELinux User Map rule not found' % rule1), ), dict( desc='Try to delete non-existent %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=errors.NotFound( reason=u'%s: SELinux User Map rule not found' % rule1), ), dict( desc='Create rule %r' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1) ), expected=dict( value=rule1, summary=u'Added SELinux User Map "%s"' % rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], objectclass=objectclasses.selinuxusermap, ipauniqueid=[fuzzy_uuid], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ), ), dict( desc='Try to create duplicate %r' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1) ), expected=errors.DuplicateEntry(message=u'SELinux User Map rule ' + u'with name "%s" already exists' % rule1), ), dict( desc='Retrieve rule %r' % rule1, command=('selinuxusermap_show', [rule1], {}), expected=dict( value=rule1, summary=None, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ), ), dict( desc='Update rule %r' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(ipaselinuxuser=selinuxuser2) ), expected=dict( result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], ), summary=u'Modified SELinux User Map "%s"' % rule1, value=rule1, ), ), dict( desc='Retrieve %r to verify update' % rule1, command=('selinuxusermap_show', [rule1], {}), expected=dict( value=rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), summary=None, ), ), dict( desc='Search for rule %r' % rule1, command=('selinuxusermap_find', [], dict(cn=rule1)), expected=dict( count=1, truncated=False, result=[ dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ], summary=u'1 SELinux User Map matched', ), ), ############### # Create additional entries needed for testing dict( desc='Create %r' % user1, command=( 'user_add', [], dict(givenname=u'Test', sn=u'User1') ), expected=dict( value=user1, summary=u'Added user "%s"' % user1, result=get_user_result(user1, u'Test', u'User1', 'add'), ), ), dict( desc='Create group %r' % group1, command=( 'group_add', [group1], dict(description=u'Test desc 1') ), expected=dict( value=group1, summary=u'Added group "%s"' % group1, result=dict( cn=[group1], description=[u'Test desc 1'], gidnumber=[fuzzy_digits], objectclass=objectclasses.group + [u'posixgroup'], ipauniqueid=[fuzzy_uuid], dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), ), ), ), dict( desc='Add member %r to %r' % (user1, group1), command=( 'group_add_member', [group1], dict(user=user1) ), expected=dict( completed=1, failed=dict( member=dict( group=tuple(), user=tuple(), ), ), result={ 'dn': DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), 'member_user': (user1,), 'gidnumber': [fuzzy_digits], 'cn': [group1], 'description': [u'Test desc 1'], }, ), ), dict( desc='Create host %r' % host1, command=('host_add', [host1], dict( description=u'Test host 1', l=u'Undisclosed location 1', force=True, ), ), expected=dict( value=host1, summary=u'Added host "%s"' % host1, result=dict( dn=hostdn1, fqdn=[host1], description=[u'Test host 1'], l=[u'Undisclosed location 1'], krbprincipalname=[u'host/%s@%s' % (host1, api.env.realm)], krbcanonicalname=[u'host/%s@%s' % (host1, api.env.realm)], objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[host1], has_keytab=False, has_password=False, ), ), ), dict( desc='Create HBAC rule %r' % hbacrule1, command=( 'hbacrule_add', [hbacrule1], {} ), expected=dict( value=hbacrule1, summary=u'Added HBAC rule "%s"' % hbacrule1, result=dict( cn=[hbacrule1], objectclass=objectclasses.hbacrule, ipauniqueid=[fuzzy_uuid], accessruletype=[u'allow'], ipaenabledflag=[u'TRUE'], dn=fuzzy_hbacruledn, ), ), ), dict( desc='Create HBAC rule %r' % hbacrule2, command=( 'hbacrule_add', [hbacrule2], {} ), expected=dict( value=hbacrule2, summary=u'Added HBAC rule "%s"' % hbacrule2, result=dict( cn=[hbacrule2], objectclass=objectclasses.hbacrule, ipauniqueid=[fuzzy_uuid], accessruletype=[u'allow'], ipaenabledflag=[u'TRUE'], dn=fuzzy_hbacruledn, ), ), ), ############### # Fill out rule with members and/or pointers to HBAC rules dict( desc='Add user to %r' % rule1, command=('selinuxusermap_add_user', [rule1], dict(user=user1)), expected=dict( failed=dict(memberuser=dict(group=[], user=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], memberuser_user=[user1], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Add non-existent user to %r' % rule1, command=('selinuxusermap_add_user', [rule1], dict(user=u'notfound')), expected=dict( failed=dict( memberuser=dict(group=[], user=[(u'notfound', u'no such entry')]) ), completed=0, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], memberuser_user=[user1], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Remove user from %r' % rule1, command=('selinuxusermap_remove_user', [rule1], dict(user=user1)), expected=dict( failed=dict(memberuser=dict(group=[], user=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Remove non-existent user to %r' % rule1, command=('selinuxusermap_remove_user', [rule1], dict(user=u'notfound')), expected=dict( failed=dict( memberuser=dict(group=[], user=[(u'notfound', u'This entry is not a member')] ) ), completed=0, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Add group to %r' % rule1, command=('selinuxusermap_add_user', [rule1], dict(group=group1)), expected=dict( failed=dict(memberuser=dict(group=[], user=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], memberuser_group=[group1], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Add host to %r' % rule1, command=('selinuxusermap_add_host', [rule1], dict(host=host1)), expected=dict( failed=dict(memberhost=dict(hostgroup=[], host=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], memberhost_host=[host1], memberuser_group=[group1], dn=fuzzy_selinuxusermapdn, ), ) ), ############### # Test enabling and disabling dict( desc='Disable %r' % rule1, command=('selinuxusermap_disable', [rule1], {}), expected=dict( result=True, value=rule1, summary=u'Disabled SELinux User Map "%s"' % rule1, ) ), dict( desc='Disable %r again' % rule1, command=('selinuxusermap_disable', [rule1], {}), expected=errors.AlreadyInactive(), ), dict( desc='Enable %r' % rule1, command=('selinuxusermap_enable', [rule1], {}), expected=dict( result=True, value=rule1, summary=u'Enabled SELinux User Map "%s"' % rule1, ) ), dict( desc='Re-enable %r again' % rule1, command=('selinuxusermap_enable', [rule1], {}), expected=errors.AlreadyActive(), ), # Point to an HBAC Rule dict( desc='Add an HBAC rule to %r that has other members' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Remove host from %r' % rule1, command=('selinuxusermap_remove_host', [rule1], dict(host=host1)), expected=dict( failed=dict(memberhost=dict(hostgroup=[], host=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], memberuser_group=[group1], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Remove group from %r' % rule1, command=('selinuxusermap_remove_user', [rule1], dict(group=group1)), expected=dict( failed=dict(memberuser=dict(group=[], user=[])), completed=1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ) ), dict( desc='Add non-existent HBAC rule to %r' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(seealso=u'notfound') ), expected=errors.NotFound( reason=u'HBAC rule notfound not found'), ), dict( desc='Add an HBAC rule to %r' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) ), expected=dict( result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser2], ipaenabledflag=[u'TRUE'], seealso=hbacrule1, ), summary=u'Modified SELinux User Map "%s"' % rule1, value=rule1, ), ), dict( desc='Add user to %r that has HBAC' % rule1, command=('selinuxusermap_add_user', [rule1], dict(user=user1)), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Add host to %r that has HBAC' % rule1, command=('selinuxusermap_add_host', [rule1], dict(host=host1)), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Try to delete HBAC rule pointed to by %r' % rule1, command=('hbacrule_del', [hbacrule1], {}), expected=errors.DependentEntry(key=hbacrule1, label=u'SELinux User Map', dependent=rule1) ), # This tests selinuxusermap-find --hbacrule=<foo> returns an # exact match dict( desc='Try to delete similarly named HBAC rule %r' % hbacrule2, command=('hbacrule_del', [hbacrule2], {}), expected=dict( result=dict(failed=[]), value=[hbacrule2], summary=u'Deleted HBAC rule "%s"' % hbacrule2, ) ), # Test clean up dict( desc='Delete %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=dict( result=dict(failed=[]), value=[rule1], summary=u'Deleted SELinux User Map "%s"' % rule1, ) ), dict( desc='Try to delete non-existent %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=errors.NotFound( reason=u'%s: SELinux User Map rule not found' % rule1), ), # Some negative tests dict( desc='Create rule with unknown user %r' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'notfound:s0:c0') ), expected=errors.NotFound(reason=u'SELinux user notfound:s0:c0 ' + u'not found in ordering list (in config)'), ), dict( desc='Create rule with invalid user bad+user', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'bad+user') ), expected=errors.ValidationError( name='selinuxuser', error=u'Invalid SELinux user name, only a-Z, _ ' 'and . are allowed' ), ), dict( desc='Create rule with invalid MCS xguest_u:s999', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s999') ), expected=errors.ValidationError(name='selinuxuser', error=u'Invalid MLS value, must match s[0-15](-s[0-15])'), ), dict( desc='Create rule with invalid MLS xguest_u:s0:p88', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s0:p88') ), expected=errors.ValidationError(name='selinuxuser', error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' + u'and/or c[0-1023]-c[0-c0123]'), ), dict( desc='Create rule with invalid MLS xguest_u:s0:c0.c1028', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'xguest_u:s0-s0:c0.c1028') ), expected=errors.ValidationError(name='selinuxuser', error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' + u'and/or c[0-1023]-c[0-c0123]'), ), dict( desc='Create rule with invalid user via setattr', command=( 'selinuxusermap_mod', [rule1], dict(setattr=u'ipaselinuxuser=deny') ), expected=errors.ValidationError(name='ipaselinuxuser', error=u'Invalid MLS value, must match s[0-15](-s[0-15])'), ), dict( desc='Create rule with both --hbacrule and --usercat set', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1, usercategory=u'all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Create rule with both --hbacrule and --hostcat set', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1, hostcategory=u'all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Create rule with both --hbacrule ' 'and --usercat set via setattr', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1, setattr=u'usercategory=all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Create rule with both --hbacrule ' 'and --hostcat set via setattr', command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1, setattr=u'hostcategory=all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Create rule %r with --hbacrule' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1) ), expected=dict( value=rule1, summary=u'Added SELinux User Map "%s"' % rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], objectclass=objectclasses.selinuxusermap, ipauniqueid=[fuzzy_uuid], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, seealso=hbacrule1 ), ), ), dict( desc='Add an --usercat to %r that has HBAC set' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(usercategory=u'all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Add an --hostcat to %r that has HBAC set' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(hostcategory=u'all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Add an usercat via setattr to %r that has HBAC set' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(setattr=u'usercategory=all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Add an hostcat via setattr to %r that has HBAC set' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(setattr=u'hostcategory=all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Delete %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=dict( result=dict(failed=[]), value=[rule1], summary=u'Deleted SELinux User Map "%s"' % rule1, ) ), dict( desc='Create rule %r with usercat and hostcat set' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, usercategory=u'all', hostcategory=u'all') ), expected=dict( value=rule1, summary=u'Added SELinux User Map "%s"' % rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], objectclass=objectclasses.selinuxusermap, ipauniqueid=[fuzzy_uuid], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, usercategory=[u'all'], hostcategory=[u'all'] ), ), ), dict( desc='Add HBAC rule to %r that has usercat and hostcat' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Delete %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=dict( result=dict(failed=[]), value=[rule1], summary=u'Deleted SELinux User Map "%s"' % rule1, ) ), dict( desc='Create rule %r' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1) ), expected=dict( value=rule1, summary=u'Added SELinux User Map "%s"' % rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], objectclass=objectclasses.selinuxusermap, ipauniqueid=[fuzzy_uuid], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, ), ), ), dict( desc='Add HBAC rule, hostcat and usercat to %r' % rule1, command=( 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1, usercategory=u'all', hostcategory=u'all') ), expected=errors.MutuallyExclusiveError( reason=u'HBAC rule and local members cannot both be set'), ), dict( desc='Delete %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=dict( result=dict(failed=[]), value=[rule1], summary=u'Deleted SELinux User Map "%s"' % rule1, ) ), dict( desc='Create rule %r with ' '--setattr=seealso=<allow_all rule DN>' % rule1, command=( 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=selinuxuser1, setattr=u'seealso=%s' % allow_all_rule_dn) ), expected=dict( value=rule1, summary=u'Added SELinux User Map "%s"' % rule1, result=dict( cn=[rule1], ipaselinuxuser=[selinuxuser1], objectclass=objectclasses.selinuxusermap, ipauniqueid=[fuzzy_uuid], ipaenabledflag=[u'TRUE'], dn=fuzzy_selinuxusermapdn, seealso=u'allow_all', ), ), ), dict( desc='Delete %r' % rule1, command=('selinuxusermap_del', [rule1], {}), expected=dict( result=dict(failed=[]), value=[rule1], summary=u'Deleted SELinux User Map "%s"' % rule1, ) ), ]
class test_raduisproxy(Declarative): cleanup_commands = [ ('radiusproxy_del', [radius1], {}), ('user_del', [user1], {}), ] tests = [ dict( desc='Try to retrieve non-existent %r' % radius1, command=('radiusproxy_show', [radius1], {}), expected=errors.NotFound( reason=u'%s: RADIUS proxy server not found' % radius1), ), dict( desc='Try to update non-existent %r' % radius1, command=('radiusproxy_mod', [radius1], {}), expected=errors.NotFound( reason=_('%s: RADIUS proxy server not found') % radius1), ), dict( desc='Try to delete non-existent %r' % radius1, command=('radiusproxy_del', [radius1], {}), expected=errors.NotFound( reason=_('%s: RADIUS proxy server not found') % radius1), ), dict( desc='Try to add multiple radius proxy server %r' % radius1, command=('radiusproxy_add', [radius1], dict( ipatokenradiusserver=radius1_fqdn, addattr=u'ipatokenradiusserver=radius1_fqdn', ipatokenradiussecret=password1, ), ), expected=errors.OnlyOneValueAllowed(attr='ipatokenradiusserver') ), dict( desc='Create %r' % radius1, command=('radiusproxy_add', [radius1], dict( ipatokenradiusserver=radius1_fqdn, ipatokenradiussecret=password1, ), ), expected=dict( value=radius1, summary=u'Added RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], dn=radius1_dn, ipatokenradiussecret=[password1_bytes], ipatokenradiusserver=[radius1_fqdn], objectclass=objectclasses.radiusproxy, ), ), ), dict( desc='Try to create duplicate %r' % radius1, command=('radiusproxy_add', [radius1], dict( ipatokenradiusserver=radius1_fqdn, ipatokenradiussecret=password1, ), ), expected=errors.DuplicateEntry(message=_('RADIUS proxy server ' 'with name "%s" already exists') % radius1), ), dict( desc='Retrieve %r' % radius1, command=('radiusproxy_show', [radius1], {}), expected=dict( value=radius1, summary=None, result=dict( cn=[radius1], dn=radius1_dn, ipatokenradiusserver=[radius1_fqdn], ), ), ), dict( desc='Retrieve %r with all=True' % radius1, command=('radiusproxy_show', [radius1], dict(all=True)), expected=dict( value=radius1, summary=None, result=dict( cn=[radius1], dn=radius1_dn, ipatokenradiussecret=[password1_bytes], ipatokenradiusserver=[radius1_fqdn], objectclass=objectclasses.radiusproxy, ), ), ), ] + [ dict( desc='Set timeout of %s to %s (valid)' % (radius1, num), command=('radiusproxy_mod', [radius1], dict(ipatokenradiustimeout=num)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ipatokenradiustimeout=[unicode(num)], ), ), ) for num in (1, 100) ] + [ dict( desc='Set timeout of %s to 0 (invalid)' % radius1, command=('radiusproxy_mod', [radius1], dict(ipatokenradiustimeout=0)), expected=errors.ValidationError( name='timeout', error=_('must be at least 1')), ), dict( desc='Unset timeout of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(ipatokenradiustimeout=None)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ), ), ), ] + [ dict( desc='Set retries of %s to %s (valid)' % (radius1, num), command=('radiusproxy_mod', [radius1], dict(ipatokenradiusretries=num)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ipatokenradiusretries=[unicode(num)], ), ), ) for num in (0, 4, 10) ] + [ dict( desc='Set retries of %s to %s (invalid)' % (radius1, num), command=('radiusproxy_mod', [radius1], dict(ipatokenradiusretries=num)), expected=errors.ValidationError( name='retries', error=reason), ) for num, reason in ((-1, 'must be at least 0'), (11, 'can be at most 10'), (100, 'can be at most 10')) ] + [ dict( desc='Unset retries of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(ipatokenradiusretries=None)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ), ), ), ] + [ dict( desc='Set server string of %s to %s (valid)' % (radius1, fqdn), command=('radiusproxy_mod', [radius1], dict(ipatokenradiusserver=fqdn)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[fqdn], ), ), ) for fqdn in (radius1_fqdn + u':12345', radius1_fqdn) ] + [ dict( desc='Set server string of %s to %s (invalid)' % (radius1, fqdn), command=('radiusproxy_mod', [radius1], dict(ipatokenradiusserver=fqdn)), expected=errors.ValidationError(name='ipatokenradiusserver', error=error), ) for fqdn, error in ( (radius1_fqdn + u':0x5a', 'invalid port number'), (radius1_fqdn + u':1:2:3', "only letters, numbers, '_', '-' are allowed. DNS label may not " "start or end with '-'"), (u'bogus', 'not fully qualified'), ) ] + [ dict( desc='Try to unset server string of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(ipatokenradiusserver=None)), expected=errors.RequirementError(name='server'), ), dict( desc='Set userattr of %s to %s (valid)' % (radius1, u'cn'), command=('radiusproxy_mod', [radius1], dict(ipatokenusermapattribute=u'cn')), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ipatokenusermapattribute=[u'cn'], ), ), ), dict( desc='Set userattr of %s to %s (invalid)' % (radius1, u'$%^&*'), command=('radiusproxy_mod', [radius1], dict(ipatokenusermapattribute=u'$%^&*')), expected=errors.ValidationError(name='ipatokenusermapattribute', error=u'invalid attribute name'), ), dict( desc='Unset userattr of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(ipatokenusermapattribute=None)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ), ), ), dict( desc='Set desc of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(description=u'a virtual radius server')), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], description=[u'a virtual radius server'], ), ), ), dict( desc='Unset desc of %s' % radius1, command=('radiusproxy_mod', [radius1], dict(description=None)), expected=dict( value=radius1, summary=u'Modified RADIUS proxy server "%s"' % radius1, result=dict( cn=[radius1], ipatokenradiusserver=[radius1_fqdn], ), ), ), dict( desc='Create "%s"' % user1, command=( 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') ), expected=dict( value=user1, summary=u'Added user "%s"' % user1, result=get_user_result(user1, u'Test', u'User1', 'add'), ), ), dict( desc='Set radiusconfiglink of %r' % user1, command=('user_mod', [user1], dict(ipatokenradiusconfiglink=radius1,)), expected=dict( result=get_user_result(user1, u'Test', u'User1', 'mod', ipatokenradiusconfiglink=[radius1]), value=user1, summary='Modified user "%s"' % user1, ), ), dict( desc='Retrieve %r to verify %s is output' % (radius1, user1), command=('radiusproxy_show', [radius1], {}), expected=dict( value=radius1, summary=None, result=dict( cn=[radius1], dn=radius1_dn, ipatokenradiusserver=[radius1_fqdn], ), ), ), dict( desc='Retrieve %r to verify %s is output' % (user1, radius1), command=('user_show', [user1], {}), expected=dict( value=user1, summary=None, result=get_user_result(user1, u'Test', u'User1', 'show', ipatokenradiusconfiglink=[radius1]), ), ), dict( desc='Delete %r' % radius1, command=('radiusproxy_del', [radius1], {}), expected=dict( value=[radius1], summary=u'Deleted RADIUS proxy server "%s"' % radius1, result=dict(failed=[]), ), ), dict( desc='Retrieve %s to verify link is deleted' % user1, command=('user_show', [user1], {}), expected=dict( value=user1, summary=None, result=get_user_result(user1, u'Test', u'User1', 'show'), ), ), ]
def forward(self, *args, **options): """ The basic idea is to read the master file and create all the maps we need, then read each map file and add all the keys for the map. """ location = self.api.Command['automountlocation_show'](args[0]) result = { 'maps': [], 'keys': [], 'skipped': [], 'duplicatekeys': [], 'duplicatemaps': [] } maps = {} master = self.__read_mapfile(args[1]) for m in master: if m.startswith('#'): continue m = m.rstrip() if m.startswith('+'): result['skipped'].append([m, args[1]]) continue if len(m) == 0: continue am = m.split(None) if len(am) < 2: continue if am[1].startswith('/'): mapfile = am[1].replace('"', '') am[1] = os.path.basename(am[1]) maps[am[1]] = mapfile info = ' '.join(am[1:]) # Add a new key to the auto.master map for the new map file try: api.Command['automountkey_add'](args[0], u'auto.master', automountkey=unicode(am[0]), automountinformation=unicode( ' '.join(am[1:]))) result['keys'].append([am[0], u'auto.master']) except errors.DuplicateEntry as e: if unicode(am[0]) in DEFAULT_KEYS: # ignore conflict when the key was pre-created by the framework pass elif options.get('continue', False): result['duplicatekeys'].append(am[0]) pass else: raise errors.DuplicateEntry( message=_('key %(key)s already exists') % dict(key=am[0])) # Add the new map if not am[1].startswith('-'): try: api.Command['automountmap_add'](args[0], unicode(am[1])) result['maps'].append(am[1]) except errors.DuplicateEntry as e: if unicode(am[1]) in DEFAULT_MAPS: # ignore conflict when the map was pre-created by the framework pass elif options.get('continue', False): result['duplicatemaps'].append(am[0]) pass else: raise errors.DuplicateEntry( message=_('map %(map)s already exists') % dict(map=am[1])) except errors.DuplicateEntry: # This means the same map is used on several mount points. pass # Now iterate over the map files and add the keys. To handle # continuation lines I'll make a pass through it to skip comments # etc and also to combine lines. for m in maps: map = self.__read_mapfile(maps[m]) lines = [] cont = '' for x in map: if x.startswith('#'): continue x = x.rstrip() if x.startswith('+'): result['skipped'].append([m, maps[m]]) continue if len(x) == 0: continue if x.endswith("\\"): cont = cont + x[:-1] + ' ' else: lines.append(cont + x) cont = '' for x in lines: am = x.split(None) key = unicode(am[0].replace('"', '')) try: api.Command['automountkey_add']( args[0], unicode(m), automountkey=key, automountinformation=unicode(' '.join(am[1:]))) result['keys'].append([key, m]) except errors.DuplicateEntry as e: if options.get('continue', False): result['duplicatekeys'].append(am[0]) pass else: raise e return dict(result=result)
class test_old_permission(Declarative): default_version = u'2.65' cleanup_commands = [ ('permission_del', [permission1], {}), ('permission_del', [permission2], {}), ('permission_del', [permission3], {}), ('privilege_del', [privilege1], {}), ] tests = [ dict( desc='Try to retrieve non-existent %r' % permission1, command=('permission_show', [permission1], {}), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Try to update non-existent %r' % permission1, command=('permission_mod', [permission1], dict(permissions=u'all')), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Try to delete non-existent %r' % permission1, command=('permission_del', [permission1], {}), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Search for non-existent %r' % permission1, command=('permission_find', [permission1], {}), expected=dict( count=0, truncated=False, summary=u'0 permissions matched', result=[], ), ), dict( desc='Create %r' % permission1, command=( 'permission_add', [permission1], dict( type=u'user', permissions=u'write', ) ), expected=dict( value=permission1, summary=u'Added permission "%s"' % permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, type=u'user', permissions=[u'write'], ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Try to create duplicate %r' % permission1, command=( 'permission_add', [permission1], dict( type=u'user', permissions=u'write', ), ), expected=errors.DuplicateEntry( message='permission with name "%s" already exists' % permission1), ), dict( desc='Create %r' % privilege1, command=('privilege_add', [privilege1], dict(description=u'privilege desc. 1') ), expected=dict( value=privilege1, summary=u'Added privilege "%s"' % privilege1, result=dict( dn=privilege1_dn, cn=[privilege1], description=[u'privilege desc. 1'], objectclass=objectclasses.privilege, ), ), ), dict( desc='Add permission %r to privilege %r' % (permission1, privilege1), command=('privilege_add_permission', [privilege1], dict(permission=permission1) ), expected=dict( completed=1, failed=dict( member=dict( permission=[], ), ), result={ 'dn': privilege1_dn, 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1], 'objectclass': objectclasses.privilege, } ), ), dict( desc='Retrieve %r' % permission1, command=('permission_show', [permission1], {}), expected=dict( value=permission1, summary=None, result={ 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ), ), dict( desc='Retrieve %r with --raw' % permission1, command=('permission_show', [permission1], {'raw' : True}), expected=dict( value=permission1, summary=None, result={ 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member': [privilege1_dn], 'aci': [u'(targetfilter = "(objectclass=posixaccount)")'+ u'(version 3.0;acl "permission:testperm";' + u'allow (write) ' + u'groupdn = "ldap:///%s";)' % DN( ('cn', 'testperm'), ('cn', 'permissions'), ('cn', 'pbac'), api.env.basedn)], 'ipapermright': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'ipapermtargetfilter': [u'(objectclass=posixaccount)'], 'ipapermlocation': [users_dn], }, ), ), dict( desc='Search for %r' % permission1, command=('permission_find', [permission1], {}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), dict( desc='Search for %r using --name' % permission1, command=('permission_find', [], {'cn': permission1}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), dict( desc='Search for non-existence permission using --name', command=('permission_find', [], {'cn': u'notfound'}), expected=dict( count=0, truncated=False, summary=u'0 permissions matched', result=[], ), ), dict( desc='Search for %r' % privilege1, command=('permission_find', [privilege1], {}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), dict( desc='Search for %r with --raw' % permission1, command=('permission_find', [permission1], {'raw' : True}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member': [privilege1_dn], 'aci': [u'(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:testperm";allow (write) groupdn = "ldap:///%s";)' % \ DN(('cn', 'testperm'), ('cn', 'permissions'), ('cn', 'pbac'), api.env.basedn)], 'ipapermright': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'ipapermtargetfilter': [u'(objectclass=posixaccount)'], 'ipapermlocation': [users_dn], }, ], ), ), dict( desc='Create %r' % permission2, command=( 'permission_add', [permission2], dict( type=u'user', permissions=u'write', setattr=u'owner=cn=test', addattr=u'owner=cn=test2', ) ), expected=dict( value=permission2, summary=u'Added permission "%s"' % permission2, result=dict( dn=permission2_dn, cn=[permission2], objectclass=objectclasses.permission, type=u'user', permissions=[u'write'], owner=[u'cn=test', u'cn=test2'], ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Search for %r' % permission1, command=('permission_find', [permission1], {}), expected=dict( count=2, truncated=False, summary=u'2 permissions matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, { 'dn': permission2_dn, 'cn': [permission2], 'objectclass': objectclasses.permission, 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), dict( desc='Search for %r with --pkey-only' % permission1, command=('permission_find', [permission1], {'pkey_only' : True}), expected=dict( count=2, truncated=False, summary=u'2 permissions matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], }, { 'dn': permission2_dn, 'cn': [permission2], }, ], ), ), dict( desc='Search by ACI attribute with --pkey-only', command=('permission_find', [], {'pkey_only': True, 'attrs': [u'krbminpwdlife']}), expected=dict( count=2, truncated=False, summary=u'2 permissions matched', result=[ { 'dn': DN(('cn', 'System: Modify Group Password Policy'), api.env.container_permission, api.env.basedn), 'cn': [u'System: Modify Group Password Policy'], }, { 'dn': DN(('cn', 'System: Read Group Password Policy'), api.env.container_permission, api.env.basedn), 'cn': [u'System: Read Group Password Policy'], }, ], ), ), dict( desc='Search for %r' % privilege1, command=('privilege_find', [privilege1], {}), expected=dict( count=1, truncated=False, summary=u'1 privilege matched', result=[ { 'dn': privilege1_dn, 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1], }, ], ), ), dict( desc='Search for %r with a limit of 1 (truncated)' % permission1, command=('permission_find', [permission1], dict(sizelimit=1)), expected=dict( count=1, truncated=True, summary=u'1 permission matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), dict( desc='Search for %r with a limit of 2' % permission1, command=('permission_find', [permission1], dict(sizelimit=2)), expected=dict( count=2, truncated=False, summary=u'2 permissions matched', result=[ { 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, { 'dn': permission2_dn, 'cn': [permission2], 'objectclass': objectclasses.permission, 'type': u'user', 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ], ), ), # This tests setting truncated to True in the post_callback of # permission_find(). The return order in LDAP is not guaranteed # so do not check the actual entry. dict( desc='Search for permissions by attr with a limit of 1 (truncated)', command=('permission_find', [u'Modify'], dict(attrs=u'ipaenabledflag', sizelimit=1)), expected=dict( count=1, truncated=True, summary=u'1 permission matched', result=[lambda res: DN(res['dn']).endswith(DN(api.env.container_permission, api.env.basedn)) and 'ipapermission' in res['objectclass']], ), ), dict( desc='Update %r' % permission1, command=( 'permission_mod', [permission1], dict( permissions=u'read', memberof=u'ipausers', setattr=u'owner=cn=other-test', addattr=u'owner=cn=other-test2', ) ), expected=dict( value=permission1, summary=u'Modified permission "%s"' % permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, member_privilege=[privilege1], type=u'user', permissions=[u'read'], memberof=u'ipausers', owner=[u'cn=other-test', u'cn=other-test2'], ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Retrieve %r to verify update' % permission1, command=('permission_show', [permission1], {}), expected=dict( value=permission1, summary=None, result={ 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'read'], 'memberof': u'ipausers', 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ), ), dict( desc='Try to rename %r to existing permission %r' % (permission1, permission2), command=( 'permission_mod', [permission1], dict(rename=permission2, permissions=u'all',) ), expected=errors.DuplicateEntry(), ), dict( desc='Try to rename %r to empty name' % (permission1), command=( 'permission_mod', [permission1], dict(rename=u'', permissions=u'all',) ), expected=errors.ValidationError(name='rename', error=u'New name can not be empty'), ), dict( desc='Check integrity of original permission %r' % permission1, command=('permission_show', [permission1], {}), expected=dict( value=permission1, summary=None, result={ 'dn': permission1_dn, 'cn': [permission1], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'read'], 'memberof': u'ipausers', 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ), ), dict( desc='Rename %r to permission %r' % (permission1, permission1_renamed), command=( 'permission_mod', [permission1], dict(rename=permission1_renamed, permissions= u'all',) ), expected=dict( value=permission1, summary=u'Modified permission "%s"' % permission1, result={ 'dn': permission1_renamed_dn, 'cn': [permission1_renamed], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'all'], 'memberof': u'ipausers', 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ), ), dict( desc='Rename %r to permission %r' % (permission1_renamed, permission1_renamed_ucase), command=( 'permission_mod', [permission1_renamed], dict(rename=permission1_renamed_ucase, permissions= u'write',) ), expected=dict( value=permission1_renamed, summary=u'Modified permission "%s"' % permission1_renamed, result={ 'dn': permission1_renamed_ucase_dn, 'cn': [permission1_renamed_ucase], 'objectclass': objectclasses.permission, 'member_privilege': [privilege1], 'type': u'user', 'permissions': [u'write'], 'memberof': u'ipausers', 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], 'subtree': u'ldap:///%s' % users_dn, }, ), ), dict( desc='Change %r to a subtree type' % permission1_renamed_ucase, command=( 'permission_mod', [permission1_renamed_ucase], dict(subtree=u'ldap:///%s' % DN(('cn', 'accounts'), api.env.basedn), type=None) ), expected=dict( value=permission1_renamed_ucase, summary=u'Modified permission "%s"' % permission1_renamed_ucase, result=dict( dn=permission1_renamed_ucase_dn, cn=[permission1_renamed_ucase], objectclass=objectclasses.permission, member_privilege=[privilege1], subtree=u'ldap:///%s' % DN(('cn', 'accounts'), api.env.basedn), permissions=[u'write'], memberof=u'ipausers', ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], ), ), ), dict( desc='Search for %r using --subtree' % permission1, command=('permission_find', [], {'subtree': u'ldap:///%s' % DN(('cn', 'accounts'), api.env.basedn)}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn':permission1_renamed_ucase_dn, 'cn':[permission1_renamed_ucase], 'objectclass': objectclasses.permission, 'member_privilege':[privilege1], 'subtree':u'ldap:///%s' % DN(('cn', 'accounts'), api.env.basedn), 'permissions':[u'write'], 'memberof':u'ipausers', 'ipapermbindruletype': [u'permission'], 'ipapermissiontype': [u'V2', u'SYSTEM'], }, ], ), ), dict( desc='Search using nonexistent --subtree', command=('permission_find', [], {'subtree': u'ldap:///foo=bar'}), expected=dict( count=0, truncated=False, summary=u'0 permissions matched', result=[], ), ), dict( desc='Search using --targetgroup', command=('permission_find', [], {'targetgroup': u'ipausers'}), expected=dict( count=1, truncated=False, summary=u'1 permission matched', result=[ { 'dn': DN(('cn', 'System: Add User to default group'), api.env.container_permission, api.env.basedn), 'cn': [u'System: Add User to default group'], 'objectclass': objectclasses.permission, 'member_privilege': [u'User Administrators'], 'attrs': [u'member'], 'targetgroup': u'ipausers', 'memberindirect_role': [u'User Administrator'], 'permissions': [u'write'], 'ipapermbindruletype': [u'permission'], 'ipapermtarget': [DN('cn=ipausers', groups_dn)], 'subtree': u'ldap:///%s' % groups_dn, 'ipapermdefaultattr': [u'member'], 'ipapermissiontype': [u'V2', u'MANAGED', u'SYSTEM'], } ], ), ), dict( desc='Delete %r' % permission1_renamed_ucase, command=('permission_del', [permission1_renamed_ucase], {}), expected=dict( result=dict(failed=u''), value=permission1_renamed_ucase, summary=u'Deleted permission "%s"' % permission1_renamed_ucase, ) ), dict( desc='Try to delete non-existent %r' % permission1, command=('permission_del', [permission1], {}), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Try to retrieve non-existent %r' % permission1, command=('permission_show', [permission1], {}), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Try to update non-existent %r' % permission1, command=('permission_mod', [permission1], dict(rename=u'Foo')), expected=errors.NotFound( reason=u'%s: permission not found' % permission1), ), dict( desc='Delete %r' % permission2, command=('permission_del', [permission2], {}), expected=dict( result=dict(failed=u''), value=permission2, summary=u'Deleted permission "%s"' % permission2, ) ), dict( desc='Search for %r' % permission1, command=('permission_find', [permission1], {}), expected=dict( count=0, truncated=False, summary=u'0 permissions matched', result=[], ), ), dict( desc='Delete %r' % privilege1, command=('privilege_del', [privilege1], {}), expected=dict( result=dict(failed=u''), value=privilege1, summary=u'Deleted privilege "%s"' % privilege1, ) ), dict( desc='Try to create permission %r with non-existing memberof' % permission1, command=( 'permission_add', [permission1], dict( memberof=u'nonexisting', permissions=u'write', ) ), expected=errors.NotFound(reason=u'nonexisting: group not found'), ), dict( desc='Create memberof permission %r' % permission1, command=( 'permission_add', [permission1], dict( memberof=u'editors', permissions=u'write', type=u'user', ) ), expected=dict( value=permission1, summary=u'Added permission "%s"' % permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, memberof=u'editors', permissions=[u'write'], type=u'user', ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Try to update non-existent memberof of %r' % permission1, command=('permission_mod', [permission1], dict( memberof=u'nonexisting')), expected=errors.NotFound(reason=u'nonexisting: group not found'), ), dict( desc='Update memberof permission %r' % permission1, command=( 'permission_mod', [permission1], dict( memberof=u'admins', ) ), expected=dict( value=permission1, summary=u'Modified permission "%s"' % permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, memberof=u'admins', permissions=[u'write'], type=u'user', ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Unset memberof of permission %r' % permission1, command=( 'permission_mod', [permission1], dict( memberof=None, ) ), expected=dict( summary=u'Modified permission "%s"' % permission1, value=permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, permissions=[u'write'], type=u'user', ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Delete %r' % permission1, command=('permission_del', [permission1], {}), expected=dict( result=dict(failed=u''), value=permission1, summary=u'Deleted permission "%s"' % permission1, ) ), dict( desc='Create targetgroup permission %r' % permission1, command=( 'permission_add', [permission1], dict( targetgroup=u'editors', permissions=u'write', ) ), expected=dict( value=permission1, summary=u'Added permission "%s"' % permission1, result=dict( dn=permission1_dn, cn=[permission1], objectclass=objectclasses.permission, targetgroup=u'editors', permissions=[u'write'], ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], ipapermtarget=[DN('cn=editors', groups_dn)], subtree=u'ldap:///%s' % api.env.basedn, ), ), ), dict( desc='Try to create invalid %r' % invalid_permission1, command=('permission_add', [invalid_permission1], dict( type=u'user', permissions=u'write', )), expected=errors.ValidationError(name='name', error='May only contain letters, numbers, -, _, ., and space'), ), dict( desc='Create %r' % permission3, command=( 'permission_add', [permission3], dict( type=u'user', permissions=u'write', attrs=[u'cn'] ) ), expected=dict( value=permission3, summary=u'Added permission "%s"' % permission3, result=dict( dn=permission3_dn, cn=[permission3], objectclass=objectclasses.permission, type=u'user', permissions=[u'write'], attrs=(u'cn',), ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Retrieve %r with --all --rights' % permission3, command=('permission_show', [permission3], {'all' : True, 'rights' : True}), expected=dict( value=permission3, summary=None, result=dict( dn=permission3_dn, cn=[permission3], objectclass=objectclasses.permission, type=u'user', attrs=(u'cn',), ipapermincludedattr=[u'cn'], permissions=[u'write'], attributelevelrights=permission3_attributelevelrights, ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], ipapermtargetfilter=[u'(objectclass=posixaccount)'], subtree=u'ldap:///%s' % users_dn, ), ), ), dict( desc='Modify %r with --all -rights' % permission3, command=('permission_mod', [permission3], {'all' : True, 'rights': True, 'attrs':[u'cn',u'uid']}), expected=dict( value=permission3, summary=u'Modified permission "%s"' % permission3, result=dict( dn=permission3_dn, cn=[permission3], objectclass=objectclasses.permission, type=u'user', attrs=(u'cn',u'uid'), ipapermincludedattr=[u'cn', u'uid'], permissions=[u'write'], attributelevelrights=permission3_attributelevelrights, ipapermbindruletype=[u'permission'], ipapermissiontype=[u'V2', u'SYSTEM'], ipapermtargetfilter=[u'(objectclass=posixaccount)'], subtree=u'ldap:///%s' % users_dn, ), ), ), ]
def execute(self, *args, **options): ldap = self.obj.backend staging_dn = self.obj.get_dn(*args, **options) assert isinstance(staging_dn, DN) # retrieve the current entry try: entry_attrs = self._exc_wrapper(args, options, ldap.get_entry)(staging_dn, ['*']) except errors.NotFound: raise self.obj.handle_not_found(*args) entry_attrs = dict((k.lower(), v) for (k, v) in entry_attrs.items()) # Check it does not exist an active entry with the same RDN active_dn = DN(staging_dn[0], api.env.container_user, api.env.basedn) try: self._exc_wrapper(args, options, ldap.get_entry)(active_dn, ['dn']) raise errors.DuplicateEntry( message=_('active user with name "%(user)s" already exists') % dict(user=args[-1])) except errors.NotFound: pass # Check the original entry is valid self._check_validy(staging_dn, entry_attrs) # Time to build the new entry result_entry = {'dn': active_dn} new_entry_attrs = self.__dict_new_entry() for (attr, values) in entry_attrs.items(): self.__merge_values(args, options, entry_attrs, new_entry_attrs, attr) result_entry[attr] = values # Allow Managed entry plugin to do its work if 'description' in new_entry_attrs and NO_UPG_MAGIC in new_entry_attrs[ 'description']: new_entry_attrs['description'].remove(NO_UPG_MAGIC) if result_entry['description'] == NO_UPG_MAGIC: del result_entry['description'] for (k, v) in new_entry_attrs.items(): logger.debug("new entry: k=%r and v=%r)", k, v) self._build_new_entry(ldap, staging_dn, entry_attrs, new_entry_attrs) # Add the Active entry entry = ldap.make_entry(active_dn, new_entry_attrs) self._exc_wrapper(args, options, ldap.add_entry)(entry) # Now delete the Staging entry try: self._exc_wrapper(args, options, ldap.delete_entry)(staging_dn) except BaseException: try: logger.error( "Fail to delete the Staging user after " "activating it %s ", staging_dn) self._exc_wrapper(args, options, ldap.delete_entry)(active_dn) except Exception: logger.error( "Fail to cleanup activation. The user remains " "active %s", active_dn) raise # add the user we just created into the default primary group config = ldap.get_ipa_config() def_primary_group = config.get('ipadefaultprimarygroup') group_dn = self.api.Object['group'].get_dn(def_primary_group) # if the user is already a member of default primary group, # do not raise error # this can happen if automember rule or default group is set try: ldap.add_entry_to_group(active_dn, group_dn) except errors.AlreadyGroupMember: pass # Now retrieve the activated entry result = self.api.Command.user_show( args[-1], all=options.get('all', False), raw=options.get('raw', False), version=options.get('version'), ) result['summary'] = unicode( _('Stage user %s activated' % staging_dn[0].value)) return result
class test_sudocmd(Declarative): cleanup_commands = [ ('sudocmd_del', [sudocmd1], {}), ('sudocmd_del', [sudocmd1_camelcase], {}), ('sudorule_del', [sudorule1], {}), ] tests = [ dict( desc='Try to retrieve non-existent %r' % sudocmd1, command=('sudocmd_show', [sudocmd1], {}), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Try to update non-existent %r' % sudocmd1, command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Try to delete non-existent %r' % sudocmd1, command=('sudocmd_del', [sudocmd1], {}), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Create %r' % sudocmd1, command=( 'sudocmd_add', [sudocmd1], dict(description=u'Test sudo command 1', ), ), expected=dict( value=sudocmd1, summary=u'Added Sudo Command "%s"' % sudocmd1, result=dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1], description=[u'Test sudo command 1'], objectclass=objectclasses.sudocmd, ipauniqueid=[fuzzy_uuid], ), ), ), dict( desc='Create %r' % sudocmd1_camelcase, command=( 'sudocmd_add', [sudocmd1_camelcase], dict(description=u'Test sudo command 2', ), ), expected=dict( value=sudocmd1_camelcase, summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase, result=dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1_camelcase], description=[u'Test sudo command 2'], objectclass=objectclasses.sudocmd, ipauniqueid=[fuzzy_uuid], ), ), ), dict( desc='Try to create duplicate %r' % sudocmd1, command=( 'sudocmd_add', [sudocmd1], dict(description=u'Test sudo command 1', ), ), expected=errors.DuplicateEntry( message=u'sudo command with ' + u'name "%s" already exists' % sudocmd1), ), dict( desc='Try to create duplicate %r' % sudocmd1_camelcase, command=( 'sudocmd_add', [sudocmd1_camelcase], dict(description=u'Test sudo command 2', ), ), expected=errors.DuplicateEntry( message=u'sudo command with ' + u'name "%s" already exists' % sudocmd1_camelcase), ), dict( desc='Retrieve %r' % sudocmd1, command=('sudocmd_show', [sudocmd1], {}), expected=dict( value=sudocmd1, summary=None, result=dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1], description=[u'Test sudo command 1'], ), ), ), dict( desc='Search for %r' % sudocmd1, command=('sudocmd_find', [sudocmd1], {}), expected=dict( count=1, truncated=False, summary=u'1 Sudo Command matched', result=[ dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1], description=[u'Test sudo command 1'], ), ], ), ), dict( desc='Search for %r' % sudocmd1_camelcase, command=('sudocmd_find', [sudocmd1_camelcase], {}), expected=dict( count=1, truncated=False, summary=u'1 Sudo Command matched', result=[ dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1_camelcase], description=[u'Test sudo command 2'], ), ], ), ), dict( desc='Update %r' % sudocmd1, command=('sudocmd_mod', [sudocmd1], dict(description=u'Updated sudo command 1')), expected=dict( value=sudocmd1, summary=u'Modified Sudo Command "%s"' % sudocmd1, result=dict( sudocmd=[sudocmd1], description=[u'Updated sudo command 1'], ), ), ), dict( desc='Retrieve %r to verify update' % sudocmd1, command=('sudocmd_show', [sudocmd1], {}), expected=dict( value=sudocmd1, summary=None, result=dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1], description=[u'Updated sudo command 1'], ), ), ), dict( desc='Create %r' % sudorule1, command=('sudorule_add', [sudorule1], {}), expected=lambda e, result: True, ), dict( desc='Add %r to %r allow list' % (sudocmd1, sudorule1), command=('sudorule_add_allow_command', [sudorule1], dict(sudocmd=sudocmd1)), expected=dict( completed=1, failed=dict(memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), result=lambda result: True, ), ), dict( desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), command=('sudocmd_del', [sudocmd1], {}), expected=errors.DependentEntry(key=sudocmd1, label='sudorule', dependent=sudorule1), ), dict( desc='Remove %r from %r' % (sudocmd1, sudorule1), command=('sudorule_remove_allow_command', [sudorule1], dict(sudocmd=sudocmd1)), expected=dict( completed=1, failed=dict(memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), result=lambda result: True, ), ), dict( desc='Add %r to %r deny list' % (sudocmd1, sudorule1), command=('sudorule_add_deny_command', [sudorule1], dict(sudocmd=sudocmd1)), expected=dict( completed=1, failed=dict(memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), result=lambda result: True, ), ), dict( desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), command=('sudocmd_del', [sudocmd1], {}), expected=errors.DependentEntry(key=sudocmd1, label='sudorule', dependent=sudorule1), ), dict( desc='Remove %r from %r' % (sudocmd1, sudorule1), command=('sudorule_remove_deny_command', [sudorule1], dict(sudocmd=sudocmd1)), expected=dict( completed=1, failed=dict(memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), result=lambda result: True, ), ), dict( desc='Delete %r' % sudocmd1, command=('sudocmd_del', [sudocmd1], {}), expected=dict( value=[sudocmd1], summary=u'Deleted Sudo Command "%s"' % sudocmd1, result=dict(failed=[]), ), ), dict( desc='Try to retrieve non-existent %r' % sudocmd1, command=('sudocmd_show', [sudocmd1], {}), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Try to update non-existent %r' % sudocmd1, command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Try to delete non-existent %r' % sudocmd1, command=('sudocmd_del', [sudocmd1], {}), expected=errors.NotFound(reason=u'%s: sudo command not found' % sudocmd1), ), dict( desc='Retrieve %r' % sudocmd1_camelcase, command=('sudocmd_show', [sudocmd1_camelcase], {}), expected=dict( value=sudocmd1_camelcase, summary=None, result=dict( dn=fuzzy_sudocmddn, sudocmd=[sudocmd1_camelcase], description=[u'Test sudo command 2'], ), ), ), ]