Example #1
0
    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()
Example #2
0
    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)
Example #3
0
    def __init__(self, api_instance, domain_data):
        self.api = api_instance

        self.domain = self.api.env.domain
        self.domain_data = domain_data
        self.masters_base = DN(self.api.env.container_masters,
                               self.api.env.basedn)

        self.test_master_dn = DN(('cn', self.api.env.host),
                                 self.api.env.container_masters,
                                 self.api.env.basedn)

        self.ldap = MockLDAP()

        self.existing_masters = {
            m['cn'][0]
            for m in self.api.Command.server_find(
                u'', sizelimit=0, pkey_only=True, no_members=True, raw=True)
            ['result']
        }

        self.existing_attributes = self._check_test_host_attributes()
Example #4
0
def trusted_domain():
    """Fixture providing mocked AD trust entries

    The fixture yields after creating a mock of AD trust
    entries in the directory server. After the test, the entries
    are deleted from the directory.
    """

    trusted_dom = TRUSTED_DOMAIN_MOCK

    # Write the changes
    with mocked_trust_containers(), MockLDAP() as ldap:
        ldap.add_entry(trusted_dom['dn'], trusted_dom['ldif'])
        yield trusted_dom
        ldap.del_entry(trusted_dom['dn'])
Example #5
0
def trusted_domain_with_suffix():
    """Fixture providing mocked AD trust entries

    The fixture yields after creating a mock of AD trust
    entries in the directory server. After the test, the entries
    are deleted from the directory.
    """
    trusted_dom = copy.deepcopy(TRUSTED_DOMAIN_MOCK)

    trusted_dom['ldif']['ipaNTAdditionalSuffixes'] = (encode_mockldap_value(
        trusted_dom['name']))

    # Write the changes
    with mocked_trust_containers(), MockLDAP() as ldap:
        ldap.add_entry(trusted_dom['dn'], trusted_dom['ldif'])
        yield trusted_dom
        ldap.del_entry(trusted_dom['dn'])
Example #6
0
    def test_adding_alias_adds_canonical_name(self, krbalias_user):
        """Test adding alias on an entry without canonical name"""
        krbalias_user.ensure_exists()

        user_krb_principal = krbalias_user.attrs['krbprincipalname'][0]

        # Delete all values of krbcanonicalname from an LDAP entry
        dn = str(krbalias_user.dn)
        modlist = [(ldap.MOD_DELETE, 'krbcanonicalname', None)]

        with MockLDAP() as ldapconn:
            ldapconn.mod_entry(dn, modlist)

        # add new user principal alias
        krbalias_user.add_principal(u'krbalias_principal_canonical')

        # verify that the previous principal name is now krbcanonicalname
        cmd = krbalias_user.make_retrieve_command()

        new_canonical_name = cmd()['result']['krbcanonicalname'][0]
        assert new_canonical_name == user_krb_principal
Example #7
0
    def __init__(self, api_instance, domain_data):
        self.api = api_instance

        self.domain = self.api.env.domain
        self.domain_data = domain_data
        self.masters_base = DN(
            self.api.env.container_masters, self.api.env.basedn)

        self.test_master_dn = DN(
            ('cn', self.api.env.host), self.api.env.container_masters,
            self.api.env.basedn)

        self.ldap = MockLDAP()

        self.existing_masters = {
            m['cn'][0] for m in self.api.Command.server_find(
                u'', sizelimit=0,
                pkey_only=True,
                no_members=True,
                raw=True)['result']}

        self.existing_attributes = self._check_test_host_attributes()
Example #8
0
        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()
Example #9
0
class MockMasterTopology(object):
    """
    object that will set up and tear down entries in LDAP backend to mimic
    a presence of real IPA masters with services running on them.
    """

    ipamaster_services = [u'KDC', u'HTTP', u'KPASSWD']

    def __init__(self, api_instance, domain_data):
        self.api = api_instance

        self.domain = self.api.env.domain
        self.domain_data = domain_data
        self.masters_base = DN(
            self.api.env.container_masters, self.api.env.basedn)

        self.test_master_dn = DN(
            ('cn', self.api.env.host), self.api.env.container_masters,
            self.api.env.basedn)

        self.ldap = MockLDAP()

        self.existing_masters = {
            m['cn'][0] for m in self.api.Command.server_find(
                u'', sizelimit=0,
                pkey_only=True,
                no_members=True,
                raw=True)['result']}

        self.existing_attributes = self._check_test_host_attributes()

    def iter_domain_data(self):
        MasterData = namedtuple('MasterData',
                                ['dn', 'fqdn', 'services', 'attrs'])
        for name in self.domain_data:
            fqdn = self.get_fqdn(name)
            master_dn = self.get_master_dn(name)
            master_services = self.domain_data[name].get('services', {})

            master_attributes = self.domain_data[name].get('attributes', {})

            yield MasterData(
                dn=master_dn,
                fqdn=fqdn,
                services=master_services,
                attrs=master_attributes
            )

    def get_fqdn(self, name):
        return '.'.join([name, self.domain])

    def get_master_dn(self, name):
        return DN(('cn', self.get_fqdn(name)), self.masters_base)

    def get_service_dn(self, name, master_dn):
        return DN(('cn', name), master_dn)

    def _add_host_entry(self, fqdn):
        self.api.Command.host_add(fqdn, force=True)
        self.api.Command.hostgroup_add_member(u'ipaservers', host=fqdn)

    def _del_host_entry(self, fqdn):
        try:
            self.api.Command.host_del(fqdn)
        except errors.NotFound:
            pass

    def _add_service_entry(self, service, fqdn):
        return self.api.Command.service_add(
            '/'.join([service, fqdn]),
            force=True
        )

    def _del_service_entry(self, service, fqdn):
        try:
            self.api.Command.service_del(
                '/'.join([service, fqdn]),
            )
        except errors.NotFound:
            pass

    def _add_svc_entries(self, master_dn, svc_desc):
        self._add_ipamaster_services(master_dn)
        for name in svc_desc:
            svc_dn = self.get_service_dn(name, master_dn)
            svc_mods = svc_desc[name]

            self.ldap.add_entry(
                str(svc_dn),
                _make_service_entry_mods(
                    enabled=svc_mods['enabled'],
                    other_config=svc_mods.get('config', None)))

    def _remove_svc_master_entries(self, master_dn):
        try:
            entries = self.ldap.connection.search_s(
                str(master_dn), ldap.SCOPE_SUBTREE
            )
        except ldap.NO_SUCH_OBJECT:
            return

        if entries:
            entries.sort(key=lambda x: len(x[0]), reverse=True)
            for entry_dn, attrs in entries:
                self.ldap.del_entry(str(entry_dn))

    def _add_ipamaster_services(self, master_dn):
        """
        add all the service entries which are part of the IPA Master role
        """
        for svc_name in self.ipamaster_services:
            svc_dn = self.get_service_dn(svc_name, master_dn)
            self.ldap.add_entry(str(svc_dn), _make_service_entry_mods())

    def _add_members(self, dn, fqdn, member_attrs):
        entry, attrs = self.ldap.connection.search_s(
            str(dn), ldap.SCOPE_SUBTREE)[0]
        mods = []
        value = attrs.get('member', [])
        mod_op = ldap.MOD_REPLACE
        if not value:
            mod_op = ldap.MOD_ADD

        for a in member_attrs:

            if a == 'host':
                value.append(
                    str(self.api.Object.host.get_dn(fqdn)))
            else:
                result = self._add_service_entry(a, fqdn)['result']
                value.append(str(result['dn']))

        mods.append(
            (mod_op, 'member', value)
        )

        self.ldap.connection.modify_s(str(dn), mods)

    def _remove_members(self, dn, fqdn, member_attrs):
        entry, attrs = self.ldap.connection.search_s(
            str(dn), ldap.SCOPE_SUBTREE)[0]
        mods = []
        for a in member_attrs:
            value = set(attrs.get('member', []))
            if not value:
                continue

            if a == 'host':
                try:
                    value.remove(
                        str(self.api.Object.host.get_dn(fqdn)))
                except KeyError:
                    pass
            else:
                try:
                    value.remove(
                        str(self.api.Object.service.get_dn(
                            '/'.join([a, fqdn]))))
                except KeyError:
                    pass
                self._del_service_entry(a, fqdn)

        mods.append(
            (ldap.MOD_REPLACE, 'member', list(value))
        )

        try:
            self.ldap.connection.modify_s(str(dn), mods)
        except (ldap.NO_SUCH_OBJECT, ldap.NO_SUCH_ATTRIBUTE):
            pass

    def _check_test_host_attributes(self):
        existing_attributes = set()

        for service, value, attr_name in (
                ('CA', 'caRenewalMaster', 'ca renewal master'),
                ('DNSSEC', 'DNSSecKeyMaster', 'dnssec key master')):

            svc_dn = DN(('cn', service), self.test_master_dn)
            try:
                svc_entry = self.api.Backend.ldap2.get_entry(svc_dn)
            except errors.NotFound:
                continue
            else:
                config_string_val = svc_entry.get('ipaConfigString', [])

                if value in config_string_val:
                    existing_attributes.add(attr_name)

        return existing_attributes

    def _remove_ca_renewal_master(self):
        if 'ca renewal master' not in self.existing_attributes:
            return

        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)

        config_string_val = ca_entry.get('ipaConfigString', [])
        try:
            config_string_val.remove('caRenewalMaster')
        except KeyError:
            return

        ca_entry.update({'ipaConfigString': config_string_val})
        self.api.Backend.ldap2.update_entry(ca_entry)

    def _restore_ca_renewal_master(self):
        if 'ca renewal master' not in self.existing_attributes:
            return

        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)

        config_string_val = ca_entry.get('ipaConfigString', [])
        config_string_val.append('caRenewalMaster')

        ca_entry.update({'ipaConfigString': config_string_val})
        self.api.Backend.ldap2.update_entry(ca_entry)

    def setup_data(self):
        self._remove_ca_renewal_master()
        for master_data in self.iter_domain_data():
            # create host
            self._add_host_entry(master_data.fqdn)

            # create master
            self.ldap.add_entry(
                str(master_data.dn), _make_master_entry_mods(
                    ca='CA' in master_data.services))

            # now add service entries
            self._add_svc_entries(master_data.dn, master_data.services)

            # optionally add some attributes required e.g. by AD trust roles
            for entry_dn, attrs in master_data.attrs.items():
                if 'member' in attrs:
                    self._add_members(
                        entry_dn,
                        master_data.fqdn,
                        attrs['member']
                    )

    def teardown_data(self):
        self._restore_ca_renewal_master()
        for master_data in self.iter_domain_data():
            # first remove the master entries and service containers
            self._remove_svc_master_entries(master_data.dn)

            # optionally clean up leftover attributes
            for entry_dn, attrs in master_data.attrs.items():
                if 'member' in attrs:
                    self._remove_members(
                        entry_dn,
                        master_data.fqdn,
                        attrs['member'],
                    )

            # finally remove host entry
            self._del_host_entry(master_data.fqdn)
Example #10
0
class MockMasterTopology(object):
    """
    object that will set up and tear down entries in LDAP backend to mimic
    a presence of real IPA masters with services running on them.
    """

    ipamaster_services = [u'KDC', u'HTTP', u'KPASSWD']

    def __init__(self, api_instance, domain_data):
        self.api = api_instance

        self.domain = self.api.env.domain
        self.domain_data = domain_data
        self.masters_base = DN(self.api.env.container_masters,
                               self.api.env.basedn)

        self.test_master_dn = DN(('cn', self.api.env.host),
                                 self.api.env.container_masters,
                                 self.api.env.basedn)

        self.ldap = MockLDAP()

        self.existing_masters = {
            m['cn'][0]
            for m in self.api.Command.server_find(
                u'', sizelimit=0, pkey_only=True, no_members=True, raw=True)
            ['result']
        }

        self.existing_attributes = self._check_test_host_attributes()

    def iter_domain_data(self):
        MasterData = namedtuple('MasterData',
                                ['dn', 'fqdn', 'services', 'attrs'])
        for name in self.domain_data:
            fqdn = self.get_fqdn(name)
            master_dn = self.get_master_dn(name)
            master_services = self.domain_data[name].get('services', {})

            master_attributes = self.domain_data[name].get('attributes', {})

            yield MasterData(dn=master_dn,
                             fqdn=fqdn,
                             services=master_services,
                             attrs=master_attributes)

    def get_fqdn(self, name):
        return '.'.join([name, self.domain])

    def get_master_dn(self, name):
        return DN(('cn', self.get_fqdn(name)), self.masters_base)

    def get_service_dn(self, name, master_dn):
        return DN(('cn', name), master_dn)

    def _add_host_entry(self, fqdn):
        self.api.Command.host_add(fqdn, force=True)
        self.api.Command.hostgroup_add_member(u'ipaservers', host=fqdn)

    def _del_host_entry(self, fqdn):
        try:
            self.api.Command.host_del(fqdn)
        except errors.NotFound:
            pass

    def _add_service_entry(self, service, fqdn):
        return self.api.Command.service_add('/'.join([service, fqdn]),
                                            force=True)

    def _del_service_entry(self, service, fqdn):
        try:
            self.api.Command.service_del('/'.join([service, fqdn]), )
        except errors.NotFound:
            pass

    def _add_svc_entries(self, master_dn, svc_desc):
        self._add_ipamaster_services(master_dn)
        for name in svc_desc:
            svc_dn = self.get_service_dn(name, master_dn)
            svc_mods = svc_desc[name]

            self.ldap.add_entry(
                str(svc_dn),
                _make_service_entry_mods(enabled=svc_mods['enabled'],
                                         other_config=svc_mods.get(
                                             'config', None)))

    def _remove_svc_master_entries(self, master_dn):
        try:
            entries = self.ldap.connection.search_s(str(master_dn),
                                                    ldap.SCOPE_SUBTREE)
        except ldap.NO_SUCH_OBJECT:
            return

        if entries:
            entries.sort(key=lambda x: len(x[0]), reverse=True)
            for entry_dn, _attrs in entries:
                self.ldap.del_entry(str(entry_dn))

    def _add_ipamaster_services(self, master_dn):
        """
        add all the service entries which are part of the IPA Master role
        """
        for svc_name in self.ipamaster_services:
            svc_dn = self.get_service_dn(svc_name, master_dn)
            self.ldap.add_entry(str(svc_dn), _make_service_entry_mods())

    def _add_members(self, dn, fqdn, member_attrs):
        _entry, attrs = self.ldap.connection.search_s(str(dn),
                                                      ldap.SCOPE_SUBTREE)[0]
        mods = []
        value = attrs.get('member', [])
        mod_op = ldap.MOD_REPLACE
        if not value:
            mod_op = ldap.MOD_ADD

        for a in member_attrs:

            if a == 'host':
                value.append(str(self.api.Object.host.get_dn(fqdn)))
            else:
                result = self._add_service_entry(a, fqdn)['result']
                value.append(str(result['dn']))

        mods.append((mod_op, 'member', value))

        self.ldap.connection.modify_s(str(dn), mods)

    def _remove_members(self, dn, fqdn, member_attrs):
        _entry, attrs = self.ldap.connection.search_s(str(dn),
                                                      ldap.SCOPE_SUBTREE)[0]
        mods = []
        for a in member_attrs:
            value = set(attrs.get('member', []))
            if not value:
                continue

            if a == 'host':
                try:
                    value.remove(str(self.api.Object.host.get_dn(fqdn)))
                except KeyError:
                    pass
            else:
                try:
                    value.remove(
                        str(self.api.Object.service.get_dn('/'.join([a,
                                                                     fqdn]))))
                except KeyError:
                    pass
                self._del_service_entry(a, fqdn)

        mods.append((ldap.MOD_REPLACE, 'member', list(value)))

        try:
            self.ldap.connection.modify_s(str(dn), mods)
        except (ldap.NO_SUCH_OBJECT, ldap.NO_SUCH_ATTRIBUTE):
            pass

    def _check_test_host_attributes(self):
        existing_attributes = set()

        for service, value, attr_name in (('CA', 'caRenewalMaster',
                                           'ca renewal master'),
                                          ('DNSSEC', 'DNSSecKeyMaster',
                                           'dnssec key master')):

            svc_dn = DN(('cn', service), self.test_master_dn)
            try:
                svc_entry = self.api.Backend.ldap2.get_entry(svc_dn)
            except errors.NotFound:
                continue
            else:
                config_string_val = svc_entry.get('ipaConfigString', [])

                if value in config_string_val:
                    existing_attributes.add(attr_name)

        return existing_attributes

    def _remove_ca_renewal_master(self):
        if 'ca renewal master' not in self.existing_attributes:
            return

        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)

        config_string_val = ca_entry.get('ipaConfigString', [])
        try:
            config_string_val.remove('caRenewalMaster')
        except KeyError:
            return

        ca_entry.update({'ipaConfigString': config_string_val})
        self.api.Backend.ldap2.update_entry(ca_entry)

    def _restore_ca_renewal_master(self):
        if 'ca renewal master' not in self.existing_attributes:
            return

        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)

        config_string_val = ca_entry.get('ipaConfigString', [])
        config_string_val.append('caRenewalMaster')

        ca_entry.update({'ipaConfigString': config_string_val})
        self.api.Backend.ldap2.update_entry(ca_entry)

    def setup_data(self):
        self._remove_ca_renewal_master()
        for master_data in self.iter_domain_data():
            # create host
            self._add_host_entry(master_data.fqdn)

            # create master
            self.ldap.add_entry(
                str(master_data.dn),
                _make_master_entry_mods(ca='CA' in master_data.services))

            # now add service entries
            self._add_svc_entries(master_data.dn, master_data.services)

            # optionally add some attributes required e.g. by AD trust roles
            for entry_dn, attrs in master_data.attrs.items():
                if 'member' in attrs:
                    self._add_members(entry_dn, master_data.fqdn,
                                      attrs['member'])

    def teardown_data(self):
        self._restore_ca_renewal_master()
        for master_data in self.iter_domain_data():
            # first remove the master entries and service containers
            self._remove_svc_master_entries(master_data.dn)

            # optionally clean up leftover attributes
            for entry_dn, attrs in master_data.attrs.items():
                if 'member' in attrs:
                    self._remove_members(
                        entry_dn,
                        master_data.fqdn,
                        attrs['member'],
                    )

            # finally remove host entry
            self._del_host_entry(master_data.fqdn)
Example #11
0
def remove_mock_trust_containers():
    with MockLDAP() as ldap:
        ldap.del_entry(trust_container_dn)
        ldap.del_entry(smb_cont_dn)
Example #12
0
def create_mock_trust_containers():
    with MockLDAP() as ldap:
        ldap.add_entry(trust_container_dn, trust_container_add)
        ldap.add_entry(smb_cont_dn, smb_cont_add)