def _enable_sid(self, ldap, options): # the user must have the Replication Administrators privilege privilege = 'Replication Administrators' if not principal_has_privilege(self.api, context.principal, privilege): raise errors.ACIError( info=_("not allowed to enable SID generation")) # NetBIOS name is either taken from options or generated try: netbios_name, reset_netbios_name = set_and_check_netbios_name( options.get('netbios_name', None), True, self.api) except ScriptError: raise errors.ValidationError( name="NetBIOS name", error=_('Up to 15 characters and only uppercase ASCII letters' ', digits and dashes are allowed. Empty string is ' 'not allowed.')) _ret = 0 _stdout = '' _stderr = '' dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) method_options = [] if options.get('add_sids', False): method_options.extend(["--add-sids"]) method_options.extend(["--netbios-name", netbios_name]) if reset_netbios_name: method_options.append("--reset-netbios-name") # Dbus definition expects up to 10 arguments method_options.extend([''] * (10 - len(method_options))) try: bus = dbus.SystemBus() obj = bus.get_object('org.freeipa.server', '/', follow_name_owner_changes=True) server = dbus.Interface(obj, 'org.freeipa.server') _ret, _stdout, _stderr = server.config_enable_sid(*method_options) except dbus.DBusException as e: logger.error( 'Failed to call org.freeipa.server.config_enable_sid.' 'DBus exception is %s', str(e)) raise errors.ExecutionError(message=_('Failed to call DBus')) # The oddjob restarts dirsrv, we need to re-establish the conn if self.api.Backend.ldap2.isconnected(): self.api.Backend.ldap2.disconnect() self.api.Backend.ldap2.connect(ccache=context.ccache_name) if _ret != 0: logger.error("Helper config_enable_sid return code is %d", _ret) raise errors.ExecutionError( message=_('Configuration of SID failed. ' 'See details in the error log'))
def new_session_id(self, max_retries=5): ''' Returns a new *unique* session id. See `generate_session_id()` for how the session id's are formulated. The scope of the uniqueness of the id is limited to id's generated by this instance of the `SessionManager` and session id's currently stored in the memcache instance. :parameters: max_retries Maximum number of attempts to produce a unique id. :returns: Unique session id as a string. ''' n_retries = 0 while n_retries < max_retries: session_id = super(MemcacheSessionManager, self).new_session_id(max_retries) session_data = self.get_session_data(session_id) if session_data is None: break n_retries += 1 if n_retries >= max_retries: self.error( 'could not allocate unique new session_id, %d retries exhausted', n_retries) raise errors.ExecutionError( message=_('could not allocate unique new session_id')) return session_id
def new_session_id(self, max_retries=5): ''' Returns a new *unique* session id. See `generate_session_id()` for how the session id's are formulated. The scope of the uniqueness of the id is limited to id's generated by this instance of the `SessionManager`. :parameters: max_retries Maximum number of attempts to produce a unique id. :returns: Unique session id as a string. ''' n_retries = 0 while n_retries < max_retries: session_id = self.generate_session_id() if not session_id in self.generated_session_ids: break n_retries += 1 if n_retries >= max_retries: self.error( 'could not allocate unique new session_id, %d retries exhausted', n_retries) raise errors.ExecutionError( message=_('could not allocate unique new session_id')) self.generated_session_ids.add(session_id) return session_id
def _preserve_user(self, pkey, delete_container, **options): assert isinstance(delete_container, DN) dn = self.obj.get_either_dn(pkey, **options) delete_dn = DN(dn[0], delete_container) ldap = self.obj.backend logger.debug("preserve move %s -> %s", dn, delete_dn) if dn.endswith(delete_container): raise errors.ExecutionError( _('%s: user is already preserved' % pkey) ) # Check that this value is a Active user try: original_entry_attrs = self._exc_wrapper( pkey, options, ldap.get_entry)(dn, ['dn']) except errors.NotFound: raise self.obj.handle_not_found(pkey) for callback in self.get_callbacks('pre'): dn = callback(self, ldap, dn, pkey, **options) assert isinstance(dn, DN) # start to move the entry to Delete container self._exc_wrapper(pkey, options, ldap.move_entry)(dn, delete_dn, del_old=True) # Then clear the credential attributes attrs_to_clear = ['krbPrincipalKey', 'krbLastPwdChange', 'krbPasswordExpiration', 'userPassword'] entry_attrs = self._exc_wrapper(pkey, options, ldap.get_entry)( delete_dn, attrs_to_clear) clearedCredential = False for attr in attrs_to_clear: if attr.lower() in entry_attrs: del entry_attrs[attr] clearedCredential = True if clearedCredential: self._exc_wrapper(pkey, options, ldap.update_entry)(entry_attrs) # Then restore some original entry attributes attrs_to_restore = ['secretary', 'managedby', 'manager', 'ipauniqueid', 'uidnumber', 'gidnumber', 'passwordHistory'] entry_attrs = self._exc_wrapper( pkey, options, ldap.get_entry)(delete_dn, attrs_to_restore) restoreAttr = False for attr in attrs_to_restore: if ((attr.lower() in original_entry_attrs) and not (attr.lower() in entry_attrs)): restoreAttr = True entry_attrs[attr.lower()] = original_entry_attrs[attr.lower()] if restoreAttr: self._exc_wrapper(pkey, options, ldap.update_entry)(entry_attrs)
def fail(self, *args, **kwargs): assert args == (1, 2) assert kwargs == dict(a=1, b=2) raise errors.ExecutionError('failure')
def fail(self, *args, **kwargs): """Raise an error""" raise errors.ExecutionError('failure')
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) attrs_list.append('objectclass') try: old_attrs = ldap.get_entry(dn, ['*']) except errors.NotFound: raise self.obj.handle_not_found(*keys) if old_attrs['iparangetype'][0] == 'ipa-local': raise errors.ExecutionError( message=_('This command can not be used to change ID ' 'allocation for local IPA domain. Run ' '`ipa help idrange` for more information')) is_set = lambda x: (x in entry_attrs) and (entry_attrs[x] is not None) in_updated_attrs = lambda x:\ (x in entry_attrs and entry_attrs[x] is not None) or\ (x not in entry_attrs and x in old_attrs and old_attrs[x] is not None) # This needs to stay in options since there is no # ipanttrusteddomainname attribute in LDAP if 'ipanttrusteddomainname' in options: if is_set('ipanttrusteddomainsid'): raise errors.ValidationError( name='ID Range setup', error=_('Options dom-sid and dom-name ' 'cannot be used together')) sid = self.obj.get_trusted_domain_sid_from_name( options['ipanttrusteddomainname']) # we translate the name into sid so further validation can rely # on ipanttrusteddomainsid attribute only if sid is not None: entry_attrs['ipanttrusteddomainsid'] = sid else: raise errors.ValidationError( name='ID Range setup', error=_('SID for the specified trusted domain name could ' 'not be found. Please specify the SID directly ' 'using dom-sid option.')) if in_updated_attrs('ipanttrusteddomainsid'): if in_updated_attrs('ipasecondarybaserid'): raise errors.ValidationError( name='ID Range setup', error=_('Options dom-sid and secondary-rid-base cannot ' 'be used together')) range_type = old_attrs['iparangetype'][0] if range_type == u'ipa-ad-trust': if not in_updated_attrs('ipabaserid'): raise errors.ValidationError( name='ID Range setup', error=_('Options dom-sid and rid-base must ' 'be used together')) elif (range_type == u'ipa-ad-trust-posix' and 'ipabaserid' in entry_attrs): if entry_attrs['ipabaserid'] is None: entry_attrs['ipabaserid'] = 0 elif entry_attrs['ipabaserid'] != 0: raise errors.ValidationError( name='ID Range setup', error=_('Option rid-base must not be used when IPA ' 'range type is ipa-ad-trust-posix')) if is_set('ipanttrusteddomainsid'): # Validate SID as the one of trusted domains # perform this check only if the attribute was changed self.obj.validate_trusted_domain_sid( entry_attrs['ipanttrusteddomainsid']) # Add trusted AD domain range object class, if it wasn't there if not 'ipatrustedaddomainrange' in old_attrs['objectclass']: entry_attrs['objectclass'].append('ipatrustedaddomainrange') else: # secondary base rid must be set if and only if base rid is set if in_updated_attrs('ipasecondarybaserid') !=\ in_updated_attrs('ipabaserid'): raise errors.ValidationError( name='ID Range setup', error=_('Options secondary-rid-base and rid-base must ' 'be used together')) # ensure that primary and secondary rid ranges do not overlap if all( in_updated_attrs(base) for base in ('ipabaserid', 'ipasecondarybaserid')): # make sure we are working with updated attributes rid_range_attributes = ('ipabaserid', 'ipasecondarybaserid', 'ipaidrangesize') updated_values = dict() for attr in rid_range_attributes: if is_set(attr): updated_values[attr] = entry_attrs[attr] else: updated_values[attr] = int(old_attrs[attr][0]) if self.obj.are_rid_ranges_overlapping( updated_values['ipabaserid'], updated_values['ipasecondarybaserid'], updated_values['ipaidrangesize']): raise errors.ValidationError( name='ID Range setup', error=_("Primary RID range and secondary RID range" " cannot overlap")) # check whether ids are in modified range old_base_id = int(old_attrs.get('ipabaseid', [0])[0]) old_range_size = int(old_attrs.get('ipaidrangesize', [0])[0]) new_base_id = entry_attrs.get('ipabaseid') if new_base_id is not None: new_base_id = int(new_base_id) new_range_size = entry_attrs.get('ipaidrangesize') if new_range_size is not None: new_range_size = int(new_range_size) self.obj.check_ids_in_modified_range(old_base_id, old_range_size, new_base_id, new_range_size) return dn
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, ), ), ]