def pre_callback(self, ldap, dn, *keys, **options): filters = [ ldap.make_filter_from_attr(attr, dn) for attr in ('memberallowcmd', 'memberdenycmd') ] filter = ldap.combine_filters(filters, ldap.MATCH_ANY) filter = ldap.combine_filters( (filter, ldap.make_filter_from_attr('objectClass', 'ipasudorule')), ldap.MATCH_ALL) dependent_sudorules = [] try: entries, _truncated = ldap.find_entries( filter, ['cn'], base_dn=DN(api.env.container_sudorule, api.env.basedn)) except errors.NotFound: pass else: for entry_attrs in entries: [cn] = entry_attrs['cn'] dependent_sudorules.append(cn) if dependent_sudorules: raise errors.DependentEntry( key=keys[0], label='sudorule', dependent=', '.join(dependent_sudorules)) return dn
def pre_callback(self, ldap, dn, *keys, **options): assert isinstance(dn, DN) kw = dict(seealso=keys[0]) _entries = api.Command.selinuxusermap_find(None, **kw) if _entries['count']: raise errors.DependentEntry(key=keys[0], label=self.api.Object['selinuxusermap'].label_singular, dependent=_entries['result'][0]['cn'][0]) return dn
def test_del_dependent_sudocmd_sudorule_deny(self, sudocmd1, sudorule1): """ Try to delete sudocmd that is in sudorule deny list """ sudocmd1.ensure_exists() command = sudocmd1.make_delete_command() with raises_exact( errors.DependentEntry(key=sudocmd1.cmd, label='sudorule', dependent=sudorule1)): command()
def pre_callback(self, ldap, dn, *keys, **options): try: old_attrs = ldap.get_entry(dn, ['ipabaseid', 'ipaidrangesize', 'ipanttrusteddomainsid']) except errors.NotFound: raise self.obj.handle_not_found(*keys) # Check whether we leave any object with id in deleted range old_base_id = int(old_attrs.get('ipabaseid', [0])[0]) old_range_size = int(old_attrs.get('ipaidrangesize', [0])[0]) self.obj.check_ids_in_modified_range( old_base_id, old_range_size, 0, 0) # Check whether the range does not belong to the active trust range_sid = old_attrs.get('ipanttrusteddomainsid') if range_sid is not None: # Search for trusted domain with SID specified in the ID range entry range_sid = range_sid[0] domain_filter=('(&(objectclass=ipaNTTrustedDomain)' '(ipanttrusteddomainsid=%s))' % range_sid) try: trust_domains, _truncated = ldap.find_entries( base_dn=DN(api.env.container_trusts, api.env.basedn), filter=domain_filter) except errors.NotFound: pass else: # If there's an entry, it means that there's active domain # of a trust that this range belongs to, so raise a # DependentEntry error raise errors.DependentEntry( label='Active Trust domain', key=keys[0], dependent=trust_domains[0].dn[0].value) return dn
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_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'], ), ), ), ]
class test_range(Declarative): mockldap = None @pytest.fixture(autouse=True, scope="class") def range_setup(self, request, declarative_setup): cls = request.cls def fin(): cls.mockldap = MockLDAP() cls.mockldap.del_entry(domain2_dn) cls.mockldap.del_entry(domain3_dn) cls.mockldap.del_entry(domain4_dn) cls.mockldap.del_entry(domain5_dn) cls.mockldap.del_entry(domain6_dn) cls.mockldap.del_entry(domain7_dn) cls.mockldap.del_entry(domain1range1_dn) cls.mockldap.del_entry(domain2range1_dn) cls.mockldap.del_entry(domain2range2_dn) cls.mockldap.del_entry(domain3range1_dn) cls.mockldap.del_entry(domain3range2_dn) cls.mockldap.del_entry(domain4range1_dn) cls.mockldap.del_entry(domain5range1_dn) cls.mockldap.del_entry(domain5range2_dn) cls.mockldap.del_entry(domain6range1_dn) cls.mockldap.del_entry(domain7range1_dn) cls.mockldap.del_entry(trust_container_dn) cls.mockldap.del_entry(trust_local_dn) cls.mockldap.del_entry(smb_cont_dn) cls.mockldap.unbind() fin() cls.mockldap = MockLDAP() cls.mockldap.add_entry(trust_container_dn, trust_container_add) cls.mockldap.add_entry(smb_cont_dn, smb_cont_add) cls.mockldap.add_entry(trust_local_dn, trust_local_add) cls.mockldap.add_entry(domain2_dn, domain2_add) cls.mockldap.add_entry(domain3_dn, domain3_add) cls.mockldap.add_entry(domain4_dn, domain4_add) cls.mockldap.add_entry(domain5_dn, domain5_add) cls.mockldap.add_entry(domain6_dn, domain6_add) cls.mockldap.add_entry(domain7_dn, domain7_add) cls.mockldap.add_entry(domain1range1_dn, domain1range1_add) cls.mockldap.add_entry(domain2range1_dn, domain2range1_add) cls.mockldap.add_entry(domain2range2_dn, domain2range2_add) cls.mockldap.add_entry(domain3range1_dn, domain3range1_add) cls.mockldap.add_entry(domain3range2_dn, domain3range2_add) cls.mockldap.add_entry(domain4range1_dn, domain4range1_add) cls.mockldap.add_entry(domain5range1_dn, domain5range1_add) cls.mockldap.add_entry(domain5range2_dn, domain5range2_add) cls.mockldap.add_entry(domain6range1_dn, domain6range1_add) cls.mockldap.unbind() request.addfinalizer(fin) cleanup_commands = [ ('idrange_del', [ testrange1, testrange2, testrange3, testrange4, testrange5, testrange6, testrange7, testrange8, testrange9 ], { 'continue': True }), ('user_del', [user1], {}), ('group_del', [group1], {}), ] # Basic tests. tests = [ dict( desc='Create ID range %r' % (testrange1), command=('idrange_add', [testrange1], dict(ipabaseid=testrange1_base_id, ipaidrangesize=testrange1_size, ipabaserid=testrange1_base_rid, ipasecondarybaserid=testrange1_secondary_base_rid)), expected=dict( result=dict( dn=DN(('cn', testrange1), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange1], objectclass=[u'ipaIDrange', u'ipadomainidrange'], ipabaseid=[unicode(testrange1_base_id)], ipabaserid=[unicode(testrange1_base_rid)], ipasecondarybaserid=[ unicode(testrange1_secondary_base_rid) ], ipaidrangesize=[unicode(testrange1_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange1, summary=u'Added ID range "%s"' % (testrange1), ), ), dict( desc='Retrieve ID range %r' % (testrange1), command=('idrange_show', [testrange1], dict()), expected=dict( result=dict( dn=DN(('cn', testrange1), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange1], ipabaseid=[unicode(testrange1_base_id)], ipabaserid=[unicode(testrange1_base_rid)], ipasecondarybaserid=[ unicode(testrange1_secondary_base_rid) ], ipaidrangesize=[unicode(testrange1_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange1, summary=None, ), ), # Checks for modifications leaving objects outside of the range. dict( desc='Create user %r in ID range %r' % (user1, testrange1), command=('user_add', [user1], dict(givenname=u'Test', sn=u'User1', uidnumber=user1_uid)), expected=dict( value=user1, summary=u'Added user "%s"' % user1, result=get_user_result( user1, u'Test', u'User1', 'add', uidnumber=[unicode(user1_uid)], gidnumber=[unicode(user1_uid)], ), ), ), dict( desc='Create group %r in ID range %r' % (group1, testrange1), command=('group_add', [group1], dict(description=u'Test desc 1', gidnumber=group1_gid)), expected=dict( value=group1, summary=u'Added group "%s"' % group1, result=dict( cn=[group1], description=[u'Test desc 1'], gidnumber=[unicode(group1_gid)], objectclass=objectclasses.group + [u'posixgroup'], ipauniqueid=[fuzzy_uuid], dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), ), ), ), dict( desc='Try to modify ID range %r to get out bounds object #1' % (testrange1), command=('idrange_mod', [testrange1], dict(ipabaseid=user1_uid + 1)), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR), ), dict( desc='Try to modify ID range %r to get out bounds object #2' % (testrange1), command=('idrange_mod', [testrange1], dict(ipaidrangesize=100)), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR), ), dict( desc='Try to modify ID range %r to get out bounds object #3' % (testrange1), command=('idrange_mod', [testrange1], dict(ipabaseid=100, ipaidrangesize=100)), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR), ), dict(desc='Modify ID range %r' % (testrange1), command=('idrange_mod', [testrange1], dict(ipaidrangesize=90000)), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR)), dict( desc='Try to delete ID range %r with active IDs inside it' % testrange1, command=('idrange_del', [testrange1], {}), expected=errors.ValidationError( name='ipabaseid,ipaidrangesize', error=u'range modification leaving objects with ID out of the' u' defined range is not allowed'), ), dict( desc='Delete user %r' % user1, command=('user_del', [user1], {}), expected=dict( result=dict(failed=[]), value=[user1], summary=u'Deleted user "%s"' % user1, ), ), dict( desc='Delete group %r' % group1, command=('group_del', [group1], {}), expected=dict( result=dict(failed=[]), value=[group1], summary=u'Deleted group "%s"' % group1, ), ), # Framework validation: mod local idrange with auto-private-groups # is prohibited dict(desc=('Try to modify local range %r with --auto-private-groups' % (testrange1)), command=('idrange_mod', [testrange1], dict(ipaautoprivategroups='true')), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR)), dict( desc='Delete ID range %r' % testrange1, command=('idrange_del', [testrange1], {}), expected=dict( result=dict(failed=[]), value=[testrange1], summary=u'Deleted ID range "%s"' % testrange1, ), ), # Tests for overlapping local ranges. dict( desc='Create ID range %r' % (testrange2), command=('idrange_add', [testrange2], dict(ipabaseid=testrange2_base_id, ipaidrangesize=testrange2_size, ipabaserid=testrange2_base_rid, ipasecondarybaserid=testrange2_secondary_base_rid)), expected=dict( result=dict( dn=DN(('cn', testrange2), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange2], objectclass=[u'ipaIDrange', u'ipadomainidrange'], ipabaseid=[unicode(testrange2_base_id)], ipabaserid=[unicode(testrange2_base_rid)], ipasecondarybaserid=[ unicode(testrange2_secondary_base_rid) ], ipaidrangesize=[unicode(testrange2_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange2, summary=u'Added ID range "%s"' % (testrange2), ), ), dict( desc= 'Try to modify ID range %r so that its rid ranges are overlapping themselves' % (testrange2), command=('idrange_mod', [testrange2], dict(ipabaserid=(testrange2_secondary_base_rid))), expected=errors.ExecutionError(message=IPA_LOCAL_RANGE_MOD_ERR), ), dict( desc='Try to create ID range %r with overlapping rid range' % (testrange3), command=('idrange_add', [testrange3], dict(ipabaseid=testrange3_base_id, ipaidrangesize=testrange3_size, ipabaserid=testrange3_base_rid, ipasecondarybaserid=testrange3_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New primary rid range overlaps with existing primary rid range.' ), ), dict( desc= 'Try to create ID range %r with overlapping secondary rid range' % (testrange4), command=('idrange_add', [testrange4], dict(ipabaseid=testrange4_base_id, ipaidrangesize=testrange4_size, ipabaserid=testrange4_base_rid, ipasecondarybaserid=testrange4_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New secondary rid range overlaps with existing secondary rid range.' ), ), dict( desc= 'Try to create ID range %r with primary range overlapping secondary rid range' % (testrange5), command=('idrange_add', [testrange5], dict(ipabaseid=testrange5_base_id, ipaidrangesize=testrange5_size, ipabaserid=testrange5_base_rid, ipasecondarybaserid=testrange5_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New primary rid range overlaps with existing secondary rid range.' ), ), dict( desc='Try to create ID range %r with overlapping id range' % (testrange6), command=('idrange_add', [testrange6], dict(ipabaseid=testrange6_base_id, ipaidrangesize=testrange6_size, ipabaserid=testrange6_base_rid, ipasecondarybaserid=testrange6_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), dict( desc= 'Try to create ID range %r with rid ranges overlapping themselves' % (testrange7), command=('idrange_add', [testrange7], dict(ipabaseid=testrange7_base_id, ipaidrangesize=testrange7_size, ipabaserid=testrange7_base_rid, ipasecondarybaserid=testrange7_secondary_base_rid)), expected=errors.ValidationError( name='ID Range setup', error='Primary RID range and secondary RID range cannot overlap' ), ), dict( desc='Delete ID range %r' % testrange2, command=('idrange_del', [testrange2], {}), expected=dict( result=dict(failed=[]), value=[testrange2], summary=u'Deleted ID range "%s"' % testrange2, ), ), # Testing framework validation: --dom-sid/--dom-name and secondary RID # base cannot be used together dict( desc='Create ID range %r' % (testrange8), command=('idrange_add', [testrange8], dict(ipabaseid=testrange8_base_id, ipaidrangesize=testrange8_size, ipabaserid=testrange8_base_rid, ipasecondarybaserid=testrange8_secondary_base_rid, ipanttrusteddomainsid=domain1_sid)), expected=errors.ValidationError( name='ID Range setup', error='Options dom-sid/dom-name and ' 'secondary-rid-base cannot be used together'), ), # Testing framework validation: --auto-private-groups is prohibited # with ipa-local range dict( desc='Local ID range %r with auto-private-groups' % (testrange8), command=('idrange_add', [testrange8], dict(ipabaseid=testrange8_base_id, ipaidrangesize=testrange8_size, ipaautoprivategroups='true')), expected=errors.ValidationError( name='ID Range setup', error='IPA Range type must be one of ipa-ad-trust ' 'or ipa-ad-trust-posix when ' 'auto-private-groups is specified'), ), # Testing framework validation: --rid-base is prohibited with ipa-ad-posix dict( desc='Try to create ipa-ad-trust-posix ID range %r with base RID' % (domain7range1), command=('idrange_add', [domain7range1], dict(ipabaseid=domain7range1_base_id, ipaidrangesize=domain7range1_size, ipabaserid=domain7range1_base_rid, iparangetype=domain7range1_type, ipanttrusteddomainsid=domain7_sid)), expected=errors.ValidationError( name='ID Range setup', error='Option rid-base must not be used when IPA range ' 'type is ipa-ad-trust-posix'), ), # Testing framework validation: --auto-private-groups can only be # one of true, false, hybrid dict( desc=('Create ID range %r with bogus --auto-private-groups' % (domain7range1)), command=('idrange_add', [domain7range1], dict(ipabaseid=domain7range1_base_id, ipaidrangesize=domain7range1_size, iparangetype=domain7range1_type, ipanttrusteddomainsid=domain7_sid, ipaautoprivategroups='bogus')), expected=errors.ValidationError( name='auto_private_groups', error="must be one of 'true', 'false', 'hybrid'"), ), dict( desc='Create ID range %r' % (domain7range1), command=('idrange_add', [domain7range1], dict(ipabaseid=domain7range1_base_id, ipaidrangesize=domain7range1_size, iparangetype=domain7range1_type, ipanttrusteddomainsid=domain7_sid)), expected=dict( result=dict( dn=unicode(domain7range1_dn), cn=[domain7range1], objectclass=[u'ipaIDrange', u'ipatrustedaddomainrange'], ipabaseid=[unicode(domain7range1_base_id)], ipaidrangesize=[unicode(domain7range1_size)], ipanttrusteddomainsid=[unicode(domain7_sid)], iparangetyperaw=[u'ipa-ad-trust-posix'], iparangetype=[ u'Active Directory trust range with POSIX attributes' ], ), value=unicode(domain7range1), summary=u'Added ID range "%s"' % (domain7range1), ), ), dict( desc='Try to modify ipa-ad-trust-posix ID range %r with base RID' % (domain7range1), command=('idrange_mod', [domain7range1], dict(ipabaserid=domain7range1_base_rid)), expected=errors.ValidationError( name='ID Range setup', error='Option rid-base must not be used when IPA range ' 'type is ipa-ad-trust-posix'), ), # Testing prohibition of deletion of ranges belonging to active # trusted domains. dict( desc='Delete non-active AD trusted range %r' % domain1range1, command=('idrange_del', [domain1range1], {}), expected=dict( result=dict(failed=[]), value=[domain1range1], summary=u'Deleted ID range "%s"' % domain1range1, ), ), dict( desc='Try to delete active AD trusted range %r' % domain2range1, command=('idrange_del', [domain2range1], {}), expected=errors.DependentEntry(label='Active Trust domain', key=domain2range1, dependent=domain2), ), # Testing base range overlaps for ranges of different types and # different domains # - Base range overlaps # 1. ipa-ad-trust-posix type ranges from the same forest can overlap # on base ranges, use domain3range1 and domain3range2 dict( desc=('Modify ipa-ad-trust-posix range %r to overlap on base range' ' with posix range from the same domain' % (domain3range2)), command=('idrange_mod', [domain3range2], dict(ipabaseid=domain3range1_base_id)), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain3range2).to_dict(), ), result=dict( cn=[domain3range2], ipabaseid=[unicode(domain3range1_base_id)], ipaidrangesize=[unicode(domain3range2_size)], ipanttrusteddomainsid=[unicode(domain3_sid)], iparangetyperaw=[u'ipa-ad-trust-posix'], iparangetype=[ u'Active Directory trust range with POSIX ' 'attributes' ], ), value=domain3range2, summary=u'Modified ID range "%s"' % (domain3range2), ), ), # 2. ipa-ad-trust-posix type ranges from different forests cannot # overlap on base ranges, use domain3range1 and domain4range1 dict( desc=('Modify ipa-ad-trust-posix range %r to overlap on base range' ' with posix range from different domain' % (domain3range1)), command=('idrange_mod', [domain3range1], dict(ipabaseid=domain4range1_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # 3. ipa-ad-trust ranges from same forest cannot overlap on base ranges, # use domain5range1 and domain5range2 dict( desc=('Modify ipa-ad-trust range %r to overlap on base range' ' with posix range from the same domain' % (domain5range1)), command=('idrange_mod', [domain5range1], dict(ipabaseid=domain5range2_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # 4. ipa-ad-trust ranges from different forests cannot overlap on base # ranges, use domain5range1 and domain6range1 dict( desc=('Modify ipa-ad-trust range %r to overlap on base range' ' with posix range from different domain' % (domain5range1)), command=('idrange_mod', [domain5range1], dict(ipabaseid=domain6range1_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # - RID range overlaps # 1. Overlaps on base RID ranges are allowed for ranges from different # domains, use domain2range1 and domain5range1 dict( desc=('Modify ipa-ad-trust range %r to overlap on base RID' ' range with nonposix range from different domain' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipabaserid=domain5range1_base_rid)), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain2range1).to_dict(), ), result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), # 2. ipa-ad-trust ranges from the same forest cannot overlap on base # RID ranges, use domain5range1 and domain5range2 dict( desc=('Modify ipa-ad-trust range %r to overlap on base RID range' ' with range from the same domain' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipabaserid=domain2range2_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info='New primary rid range overlaps with existing primary rid ' 'range.'), ), dict( desc=('Modify ipa-ad-trust range %r with --auto-private-groups=' 'true' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipaautoprivategroups='true')), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain2range1).to_dict(), ), result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], ipaautoprivategroups=[u'true'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), dict( desc=('Modify ipa-ad-trust range %r with --auto-private-groups=' 'false' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipaautoprivategroups='false')), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain2range1).to_dict(), ), result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], ipaautoprivategroups=[u'false'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), dict( desc=('Modify ipa-ad-trust range %r with --auto-private-groups=' 'hybrid' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipaautoprivategroups='hybrid')), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain2range1).to_dict(), ), result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], ipaautoprivategroups=[u'hybrid'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), dict( desc=('Modify ipa-ad-trust range %r with --auto-private-groups=' '<empty>' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipaautoprivategroups='')), expected=dict( messages=(messages.ServiceRestartRequired( service=services.knownservices['sssd'].systemd_name, server=domain2range1).to_dict(), ), result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), # Test for bug 6404 # if dom-name is empty, add should not fail dict( desc='Create ID range %r' % (testrange9), command=('idrange_add', [testrange9], dict(ipanttrusteddomainname=None, ipabaseid=testrange9_base_id, ipaidrangesize=testrange9_size, ipabaserid=testrange9_base_rid, ipasecondarybaserid=testrange9_secondary_base_rid)), expected=dict( result=dict( dn=DN(('cn', testrange9), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange9], objectclass=[u'ipaIDrange', u'ipadomainidrange'], ipabaseid=[unicode(testrange9_base_id)], ipabaserid=[unicode(testrange9_base_rid)], ipasecondarybaserid=[ unicode(testrange9_secondary_base_rid) ], ipaidrangesize=[unicode(testrange9_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange9, summary=u'Added ID range "%s"' % (testrange9), ), ), dict( desc='Delete ID range %r' % testrange9, command=('idrange_del', [testrange9], {}), expected=dict( result=dict(failed=[]), value=[testrange9], summary=u'Deleted ID range "%s"' % testrange9, ), ), ]
class test_range(Declarative): @classmethod def setup_class(cls): super(test_range, cls).setup_class() cls.teardown_class() cls.mockldap = MockLDAP() cls.mockldap.add_entry(trust_container_dn, trust_container_add) cls.mockldap.add_entry(smb_cont_dn, smb_cont_add) cls.mockldap.add_entry(trust_local_dn, trust_local_add) cls.mockldap.add_entry(domain2_dn, domain2_add) cls.mockldap.add_entry(domain3_dn, domain3_add) cls.mockldap.add_entry(domain4_dn, domain4_add) cls.mockldap.add_entry(domain5_dn, domain5_add) cls.mockldap.add_entry(domain6_dn, domain6_add) cls.mockldap.add_entry(domain7_dn, domain7_add) cls.mockldap.add_entry(domain1range1_dn, domain1range1_add) cls.mockldap.add_entry(domain2range1_dn, domain2range1_add) cls.mockldap.add_entry(domain2range2_dn, domain2range2_add) cls.mockldap.add_entry(domain3range1_dn, domain3range1_add) cls.mockldap.add_entry(domain3range2_dn, domain3range2_add) cls.mockldap.add_entry(domain4range1_dn, domain4range1_add) cls.mockldap.add_entry(domain5range1_dn, domain5range1_add) cls.mockldap.add_entry(domain5range2_dn, domain5range2_add) cls.mockldap.add_entry(domain6range1_dn, domain6range1_add) cls.mockldap.unbind() @classmethod def teardown_class(cls): cls.mockldap = MockLDAP() cls.mockldap.del_entry(domain2_dn) cls.mockldap.del_entry(domain3_dn) cls.mockldap.del_entry(domain4_dn) cls.mockldap.del_entry(domain5_dn) cls.mockldap.del_entry(domain6_dn) cls.mockldap.del_entry(domain7_dn) cls.mockldap.del_entry(domain1range1_dn) cls.mockldap.del_entry(domain2range1_dn) cls.mockldap.del_entry(domain2range2_dn) cls.mockldap.del_entry(domain3range1_dn) cls.mockldap.del_entry(domain3range2_dn) cls.mockldap.del_entry(domain4range1_dn) cls.mockldap.del_entry(domain5range1_dn) cls.mockldap.del_entry(domain5range2_dn) cls.mockldap.del_entry(domain6range1_dn) cls.mockldap.del_entry(domain7range1_dn) cls.mockldap.del_entry(trust_container_dn) cls.mockldap.del_entry(trust_local_dn) cls.mockldap.del_entry(smb_cont_dn) cls.mockldap.unbind() cleanup_commands = [ ('idrange_del', [ testrange1, testrange2, testrange3, testrange4, testrange5, testrange6, testrange7, testrange8 ], { 'continue': True }), ('user_del', [user1], {}), ('group_del', [group1], {}), ] # Basic tests. tests = [ dict( desc='Create ID range %r' % (testrange1), command=('idrange_add', [testrange1], dict(ipabaseid=testrange1_base_id, ipaidrangesize=testrange1_size, ipabaserid=testrange1_base_rid, ipasecondarybaserid=testrange1_secondary_base_rid)), expected=dict( result=dict( dn=DN(('cn', testrange1), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange1], objectclass=[u'ipaIDrange', u'ipadomainidrange'], ipabaseid=[unicode(testrange1_base_id)], ipabaserid=[unicode(testrange1_base_rid)], ipasecondarybaserid=[ unicode(testrange1_secondary_base_rid) ], ipaidrangesize=[unicode(testrange1_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange1, summary=u'Added ID range "%s"' % (testrange1), ), ), dict( desc='Retrieve ID range %r' % (testrange1), command=('idrange_show', [testrange1], dict()), expected=dict( result=dict( dn=DN(('cn', testrange1), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange1], ipabaseid=[unicode(testrange1_base_id)], ipabaserid=[unicode(testrange1_base_rid)], ipasecondarybaserid=[ unicode(testrange1_secondary_base_rid) ], ipaidrangesize=[unicode(testrange1_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange1, summary=None, ), ), # Checks for modifications leaving objects outside of the range. dict( desc='Create user %r in ID range %r' % (user1, testrange1), command=('user_add', [user1], dict(givenname=u'Test', sn=u'User1', uidnumber=user1_uid)), expected=dict( value=user1, summary=u'Added user "%s"' % user1, result=get_user_result( user1, u'Test', u'User1', 'add', uidnumber=[unicode(user1_uid)], gidnumber=[unicode(user1_uid)], ), ), ), dict( desc='Create group %r in ID range %r' % (group1, testrange1), command=('group_add', [group1], dict(description=u'Test desc 1', gidnumber=group1_gid)), expected=dict( value=group1, summary=u'Added group "%s"' % group1, result=dict( cn=[group1], description=[u'Test desc 1'], gidnumber=[unicode(group1_gid)], objectclass=objectclasses.group + [u'posixgroup'], ipauniqueid=[fuzzy_uuid], dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), ), ), ), dict( desc='Try to modify ID range %r to get out bounds object #1' % (testrange1), command=('idrange_mod', [testrange1], dict(ipabaseid=user1_uid + 1)), expected=errors.ValidationError( name='ipabaseid,ipaidrangesize', error=u'range modification leaving objects with ID out of the' u' defined range is not allowed'), ), dict( desc='Try to modify ID range %r to get out bounds object #2' % (testrange1), command=('idrange_mod', [testrange1], dict(ipaidrangesize=100)), expected=errors.ValidationError( name='ipabaseid,ipaidrangesize', error=u'range modification leaving objects with ID out of the' u' defined range is not allowed'), ), dict( desc='Try to modify ID range %r to get out bounds object #3' % (testrange1), command=('idrange_mod', [testrange1], dict(ipabaseid=100, ipaidrangesize=100)), expected=errors.ValidationError( name='ipabaseid,ipaidrangesize', error=u'range modification leaving objects with ID out of the' u' defined range is not allowed'), ), dict( desc='Modify ID range %r' % (testrange1), command=('idrange_mod', [testrange1], dict(ipaidrangesize=90000)), expected=dict( result=dict( cn=[testrange1], ipabaseid=[unicode(testrange1_base_id)], ipabaserid=[unicode(testrange1_base_rid)], ipasecondarybaserid=[ unicode(testrange1_secondary_base_rid) ], ipaidrangesize=[u'90000'], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange1, summary=u'Modified ID range "%s"' % (testrange1), ), ), dict( desc='Try to delete ID range %r with active IDs inside it' % testrange1, command=('idrange_del', [testrange1], {}), expected=errors.ValidationError( name='ipabaseid,ipaidrangesize', error=u'range modification leaving objects with ID out of the' u' defined range is not allowed'), ), dict( desc='Delete user %r' % user1, command=('user_del', [user1], {}), expected=dict( result=dict(failed=[]), value=[user1], summary=u'Deleted user "%s"' % user1, ), ), dict( desc='Delete group %r' % group1, command=('group_del', [group1], {}), expected=dict( result=dict(failed=[]), value=[group1], summary=u'Deleted group "%s"' % group1, ), ), dict( desc='Delete ID range %r' % testrange1, command=('idrange_del', [testrange1], {}), expected=dict( result=dict(failed=[]), value=[testrange1], summary=u'Deleted ID range "%s"' % testrange1, ), ), # Tests for overlapping local ranges. dict( desc='Create ID range %r' % (testrange2), command=('idrange_add', [testrange2], dict(ipabaseid=testrange2_base_id, ipaidrangesize=testrange2_size, ipabaserid=testrange2_base_rid, ipasecondarybaserid=testrange2_secondary_base_rid)), expected=dict( result=dict( dn=DN(('cn', testrange2), ('cn', 'ranges'), ('cn', 'etc'), api.env.basedn), cn=[testrange2], objectclass=[u'ipaIDrange', u'ipadomainidrange'], ipabaseid=[unicode(testrange2_base_id)], ipabaserid=[unicode(testrange2_base_rid)], ipasecondarybaserid=[ unicode(testrange2_secondary_base_rid) ], ipaidrangesize=[unicode(testrange2_size)], iparangetyperaw=[u'ipa-local'], iparangetype=[u'local domain range'], ), value=testrange2, summary=u'Added ID range "%s"' % (testrange2), ), ), dict( desc= 'Try to modify ID range %r so that its rid ranges are overlapping themselves' % (testrange2), command=('idrange_mod', [testrange2], dict(ipabaserid=(testrange2_secondary_base_rid))), expected=errors.ValidationError( name='ID Range setup', error='Primary RID range and secondary RID range cannot overlap' ), ), dict( desc='Try to create ID range %r with overlapping rid range' % (testrange3), command=('idrange_add', [testrange3], dict(ipabaseid=testrange3_base_id, ipaidrangesize=testrange3_size, ipabaserid=testrange3_base_rid, ipasecondarybaserid=testrange3_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New primary rid range overlaps with existing primary rid range.' ), ), dict( desc= 'Try to create ID range %r with overlapping secondary rid range' % (testrange4), command=('idrange_add', [testrange4], dict(ipabaseid=testrange4_base_id, ipaidrangesize=testrange4_size, ipabaserid=testrange4_base_rid, ipasecondarybaserid=testrange4_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New secondary rid range overlaps with existing secondary rid range.' ), ), dict( desc= 'Try to create ID range %r with primary range overlapping secondary rid range' % (testrange5), command=('idrange_add', [testrange5], dict(ipabaseid=testrange5_base_id, ipaidrangesize=testrange5_size, ipabaserid=testrange5_base_rid, ipasecondarybaserid=testrange5_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info= 'New primary rid range overlaps with existing secondary rid range.' ), ), dict( desc='Try to create ID range %r with overlapping id range' % (testrange6), command=('idrange_add', [testrange6], dict(ipabaseid=testrange6_base_id, ipaidrangesize=testrange6_size, ipabaserid=testrange6_base_rid, ipasecondarybaserid=testrange6_secondary_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), dict( desc= 'Try to create ID range %r with rid ranges overlapping themselves' % (testrange7), command=('idrange_add', [testrange7], dict(ipabaseid=testrange7_base_id, ipaidrangesize=testrange7_size, ipabaserid=testrange7_base_rid, ipasecondarybaserid=testrange7_secondary_base_rid)), expected=errors.ValidationError( name='ID Range setup', error='Primary RID range and secondary RID range cannot overlap' ), ), dict( desc='Delete ID range %r' % testrange2, command=('idrange_del', [testrange2], {}), expected=dict( result=dict(failed=[]), value=[testrange2], summary=u'Deleted ID range "%s"' % testrange2, ), ), # Testing framework validation: --dom-sid/--dom-name and secondary RID # base cannot be used together dict( desc='Create ID range %r' % (testrange8), command=('idrange_add', [testrange8], dict(ipabaseid=testrange8_base_id, ipaidrangesize=testrange8_size, ipabaserid=testrange8_base_rid, ipasecondarybaserid=testrange8_secondary_base_rid, ipanttrusteddomainsid=domain1_sid)), expected=errors.ValidationError( name='ID Range setup', error='Options dom-sid/dom-name and ' 'secondary-rid-base cannot be used together'), ), # Testing framework validation: --rid-base is prohibited with ipa-ad-posix dict( desc='Try to create ipa-ad-trust-posix ID range %r with base RID' % (domain7range1), command=('idrange_add', [domain7range1], dict(ipabaseid=domain7range1_base_id, ipaidrangesize=domain7range1_size, ipabaserid=domain7range1_base_rid, iparangetype=domain7range1_type, ipanttrusteddomainsid=domain7_sid)), expected=errors.ValidationError( name='ID Range setup', error='Option rid-base must not be used when IPA range ' 'type is ipa-ad-trust-posix'), ), dict( desc='Create ID range %r' % (domain7range1), command=('idrange_add', [domain7range1], dict(ipabaseid=domain7range1_base_id, ipaidrangesize=domain7range1_size, iparangetype=domain7range1_type, ipanttrusteddomainsid=domain7_sid)), expected=dict( result=dict( dn=unicode(domain7range1_dn), cn=[domain7range1], objectclass=[u'ipaIDrange', u'ipatrustedaddomainrange'], ipabaseid=[unicode(domain7range1_base_id)], ipaidrangesize=[unicode(domain7range1_size)], ipanttrusteddomainsid=[unicode(domain7_sid)], iparangetyperaw=[u'ipa-ad-trust-posix'], iparangetype=[ u'Active Directory trust range with POSIX attributes' ], ), value=unicode(domain7range1), summary=u'Added ID range "%s"' % (domain7range1), ), ), dict( desc='Try to modify ipa-ad-trust-posix ID range %r with base RID' % (domain7range1), command=('idrange_mod', [domain7range1], dict(ipabaserid=domain7range1_base_rid)), expected=errors.ValidationError( name='ID Range setup', error='Option rid-base must not be used when IPA range ' 'type is ipa-ad-trust-posix'), ), # Testing prohibition of deletion of ranges belonging to active # trusted domains. dict( desc='Delete non-active AD trusted range %r' % domain1range1, command=('idrange_del', [domain1range1], {}), expected=dict( result=dict(failed=[]), value=[domain1range1], summary=u'Deleted ID range "%s"' % domain1range1, ), ), dict( desc='Try to delete active AD trusted range %r' % domain2range1, command=('idrange_del', [domain2range1], {}), expected=errors.DependentEntry(label='Active Trust domain', key=domain2range1, dependent=domain2), ), # Testing base range overlaps for ranges of different types and # different domains # - Base range overlaps # 1. ipa-ad-trust-posix type ranges from the same forest can overlap # on base ranges, use domain3range1 and domain3range2 dict( desc=('Modify ipa-ad-trust-posix range %r to overlap on base range' ' with posix range from the same domain' % (domain3range2)), command=('idrange_mod', [domain3range2], dict(ipabaseid=domain3range1_base_id)), expected=dict( result=dict( cn=[domain3range2], ipabaseid=[unicode(domain3range1_base_id)], ipaidrangesize=[unicode(domain3range2_size)], ipanttrusteddomainsid=[unicode(domain3_sid)], iparangetyperaw=[u'ipa-ad-trust-posix'], iparangetype=[ u'Active Directory trust range with POSIX ' 'attributes' ], ), value=domain3range2, summary=u'Modified ID range "%s"' % (domain3range2), ), ), # 2. ipa-ad-trust-posix type ranges from different forests cannot # overlap on base ranges, use domain3range1 and domain4range1 dict( desc=('Modify ipa-ad-trust-posix range %r to overlap on base range' ' with posix range from different domain' % (domain3range1)), command=('idrange_mod', [domain3range1], dict(ipabaseid=domain4range1_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # 3. ipa-ad-trust ranges from same forest cannot overlap on base ranges, # use domain5range1 and domain5range2 dict( desc=('Modify ipa-ad-trust range %r to overlap on base range' ' with posix range from the same domain' % (domain5range1)), command=('idrange_mod', [domain5range1], dict(ipabaseid=domain5range2_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # 4. ipa-ad-trust ranges from different forests cannot overlap on base # ranges, use domain5range1 and domain6range1 dict( desc=('Modify ipa-ad-trust range %r to overlap on base range' ' with posix range from different domain' % (domain5range1)), command=('idrange_mod', [domain5range1], dict(ipabaseid=domain6range1_base_id)), expected=errors.DatabaseError( desc='Constraint violation', info='New base range overlaps with existing base range.'), ), # - RID range overlaps # 1. Overlaps on base RID ranges are allowed for ranges from different # domains, use domain2range1 and domain5range1 dict( desc=('Modify ipa-ad-trust range %r to overlap on base RID' ' range with nonposix range from different domain' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipabaserid=domain5range1_base_rid)), expected=dict( result=dict( cn=[domain2range1], ipabaseid=[unicode(domain2range1_base_id)], ipabaserid=[unicode(domain5range1_base_rid)], ipaidrangesize=[unicode(domain2range1_size)], ipanttrusteddomainsid=[unicode(domain2_sid)], iparangetyperaw=[u'ipa-ad-trust'], iparangetype=[u'Active Directory domain range'], ), value=domain2range1, summary=u'Modified ID range "%s"' % (domain2range1), ), ), # 2. ipa-ad-trust ranges from the same forest cannot overlap on base # RID ranges, use domain5range1 and domain5range2 dict( desc=('Modify ipa-ad-trust range %r to overlap on base RID range' ' with range from the same domain' % (domain2range1)), command=('idrange_mod', [domain2range1], dict(ipabaserid=domain2range2_base_rid)), expected=errors.DatabaseError( desc='Constraint violation', info='New primary rid range overlaps with existing primary rid ' 'range.'), ), ]