示例#1
0
def __discover_config(discover_server=True):
    servers = []
    try:
        if not config.default_domain:
            # try once with REALM -> domain
            domain = str(config.default_realm).lower()
            name = "_ldap._tcp." + domain

            try:
                servers = query_srv(name)
            except DNSException:
                # try cycling on domain components of FQDN
                # pylint: disable=ipa-forbidden-import
                from ipalib.constants import FQDN
                # pylint: enable=ipa-forbidden-import
                try:
                    domain = dns.name.from_text(FQDN)
                except DNSException:
                    return False

                while True:
                    domain = domain.parent()

                    if str(domain) == '.':
                        return False
                    name = "_ldap._tcp.%s" % domain
                    try:
                        servers = query_srv(name)
                        break
                    except DNSException:
                        pass

            config.default_domain = str(domain).rstrip(".")

        if discover_server:
            if not servers:
                name = "_ldap._tcp.%s." % config.default_domain
                try:
                    servers = query_srv(name)
                except DNSException:
                    pass

            for server in servers:
                hostname = str(server.target).rstrip(".")
                config.default_server.append(hostname)

    except Exception:
        pass
    return None
示例#2
0
    def get_url_list(self, rpc_uri):
        """
        Create a list of urls consisting of the available IPA servers.
        """
        # the configured URL defines what we use for the discovered servers
        (_scheme, _netloc, path, _params, _query,
         _fragment) = urllib.parse.urlparse(rpc_uri)
        servers = []
        name = '_ldap._tcp.%s.' % self.env.domain

        try:
            answers = query_srv(name)
        except DNSException:
            answers = []

        for answer in answers:
            server = str(answer.target).rstrip(".")
            servers.append('https://%s%s' %
                           (ipautil.format_netloc(server), path))

        # make sure the configured master server is there just once and
        # it is the first one.
        if rpc_uri in servers:
            servers.remove(rpc_uri)
        servers.insert(0, rpc_uri)

        return servers
示例#3
0
文件: rpc.py 项目: stlaz/freeipa
    def get_url_list(self, rpc_uri):
        """
        Create a list of urls consisting of the available IPA servers.
        """
        # the configured URL defines what we use for the discovered servers
        (_scheme, _netloc, path, _params, _query, _fragment
            ) = urllib.parse.urlparse(rpc_uri)
        servers = []
        name = '_ldap._tcp.%s.' % self.env.domain

        try:
            answers = query_srv(name)
        except DNSException:
            answers = []

        for answer in answers:
            server = str(answer.target).rstrip(".")
            servers.append('https://%s%s' % (ipautil.format_netloc(server), path))

        # make sure the configured master server is there just once and
        # it is the first one.
        if rpc_uri in servers:
            servers.remove(rpc_uri)
        servers.insert(0, rpc_uri)

        return servers
示例#4
0
    def ipadns_search_srv(self,
                          domain,
                          srv_record_name,
                          default_port,
                          break_on_first=True):
        """
        Search for SRV records in given domain. When no record is found,
        en empty list is returned

        :param domain: Search domain name
        :param srv_record_name: SRV record name, e.g. "_ldap._tcp"
        :param default_port: When default_port is not None, it is being
                    checked with the port in SRV record and if they don't
                    match, the port from SRV record is appended to
                    found hostname in this format: "hostname:port"
        :param break_on_first: break on the first find and return just one
                    entry
        """
        servers = []

        qname = '%s.%s' % (srv_record_name, domain)

        logger.debug("Search DNS for SRV record of %s", qname)

        try:
            answers = query_srv(qname)
        except DNSException as e:
            logger.debug("DNS record not found: %s", e.__class__.__name__)
            answers = []

        for answer in answers:
            logger.debug("DNS record found: %s", answer)
            server = str(answer.target).rstrip(".")
            if not server:
                logger.debug("Cannot parse the hostname from SRV record: %s",
                             answer)
                continue
            if default_port is not None and answer.port != default_port:
                server = "%s:%s" % (server, str(answer.port))
            servers.append(server)
            if break_on_first:
                break

        return servers
示例#5
0
    def ipadns_search_srv(self, domain, srv_record_name, default_port,
                          break_on_first=True):
        """
        Search for SRV records in given domain. When no record is found,
        en empty list is returned

        :param domain: Search domain name
        :param srv_record_name: SRV record name, e.g. "_ldap._tcp"
        :param default_port: When default_port is not None, it is being
                    checked with the port in SRV record and if they don't
                    match, the port from SRV record is appended to
                    found hostname in this format: "hostname:port"
        :param break_on_first: break on the first find and return just one
                    entry
        """
        servers = []
        qname = '%s.%s' % (srv_record_name, domain)

        logger.debug("Search DNS for SRV record of %s", qname)

        try:
            answers = query_srv(qname)
        except DNSException as e:
            logger.debug("DNS record not found: %s", e.__class__.__name__)
            answers = []

        for answer in answers:
            logger.debug("DNS record found: %s", answer)
            server = str(answer.target).rstrip(".")
            if not server:
                logger.debug("Cannot parse the hostname from SRV record: %s",
                             answer)
                continue
            if default_port is not None and answer.port != default_port:
                server = "%s:%s" % (server, str(answer.port))
            servers.append(server)
            if break_on_first:
                break

        return servers
示例#6
0
    def check(self):
        # pylint: disable=import-outside-toplevel
        from ipapython.dnsutil import query_srv
        from ipaserver.dns_data_management import IPASystemRecords
        # pylint: enable=import-outside-toplevel

        system_records = IPASystemRecords(api)
        base_records = system_records.get_base_records()

        # collect the list of expected values
        txt_rec = dict()
        srv_rec = dict()
        uri_rec = dict()
        a_rec = list()
        aaaa_rec = list()

        for name, node in base_records.items():
            for rdataset in node:
                for rd in rdataset:
                    if rd.rdtype == rdatatype.SRV:
                        if name.ToASCII() in srv_rec:
                            srv_rec[name.ToASCII()].append(rd.target.to_text())
                        else:
                            srv_rec[name.ToASCII()] = [rd.target.to_text()]
                    elif rd.rdtype == rdatatype.TXT:
                        if name.ToASCII() in txt_rec:
                            txt_rec[name.ToASCII()].append(rd.to_text())
                        else:
                            txt_rec[name.ToASCII()] = [rd.to_text()]
                    elif rd.rdtype == rdatatype.A:
                        a_rec.append(rd.to_text())
                    elif rd.rdtype == rdatatype.AAAA:
                        aaaa_rec.append(rd.to_text())
                    elif rd.rdtype == rdatatype.URI:
                        if name.ToASCII() in uri_rec:
                            uri_rec[name.ToASCII()].append(
                                rd.target.decode('utf-8')
                            )
                        else:
                            uri_rec[name.ToASCII()] = [
                                rd.target.decode('utf-8')
                            ]
                    else:
                        logger.error("Unhandled rdtype %d", rd.rdtype)

        # For each SRV record that IPA thinks it should have, do a DNS
        # lookup of it and ensure that DNS has the same set of values
        # that IPA thinks it should.
        for srv, hosts in srv_rec.items():
            logger.debug("Search DNS for SRV record of %s", srv)
            try:
                answers = query_srv(srv)
            except DNSException as e:
                logger.debug("DNS record not found: %s", e.__class__.__name__)
                answers = []
            for answer in answers:
                logger.debug("DNS record found: %s", answer)
                try:
                    hosts.remove(answer.target.to_text())
                    yield Result(
                         self, constants.SUCCESS,
                         key=self.srv_to_name(srv, answer.target.to_text()))
                except ValueError:
                    yield Result(
                        self, constants.WARNING,
                        msg='Unexpected SRV entry in DNS',
                        key=self.srv_to_name(srv, answer.target.to_text()))
            for host in hosts:
                yield Result(
                    self, constants.WARNING,
                    msg='Expected SRV record missing',
                    key=self.srv_to_name(srv, host))

        for uri, hosts in uri_rec.items():
            logger.debug("Search DNS for URI record of %s", uri)
            answers = query_uri(uri)
            for answer in answers:
                logger.debug("DNS record found: %s", answer)
                try:
                    hosts.remove(answer.target.decode('utf-8'))
                    yield Result(
                         self, constants.SUCCESS,
                         key=self.uri_to_name(
                             uri, answer.target.decode('utf-8')
                         )
                    )
                except ValueError:
                    yield Result(
                        self, constants.WARNING,
                        msg='Unexpected URI entry in DNS',
                        key=self.uri_to_name(
                            uri, answer.target.decode('utf-8')
                        )
                    )
            for host in hosts:
                yield Result(
                    self, constants.WARNING,
                    msg='Expected URI record missing',
                    key=self.uri_to_name(uri, host)
                )

        for txt, realms in txt_rec.items():
            logger.debug("Search DNS for TXT record of %s", txt)
            try:
                answers = resolve(txt, rdatatype.TXT)
            except DNSException as e:
                logger.debug("DNS record not found: %s", e.__class__.__name__)
                answers = []

            for answer in answers:
                logger.debug("DNS record found: %s", answer)
                realm = answer.to_text()
                try:
                    realms.remove(realm)
                    yield Result(self, constants.SUCCESS,
                                 key=realm)
                except ValueError:
                    yield Result(self, constants.WARNING,
                                 key=realm,
                                 msg='expected realm missing')

        if a_rec:
            # Look up the ipa-ca records
            qname = "ipa-ca." + api.env.domain + "."
            logger.debug("Search DNS for A record of %s", qname)
            try:
                answers = resolve(qname, rdatatype.A)
            except DNSException as e:
                logger.debug("DNS record not found: %s", e.__class__.__name__)
                answers = []

            for answer in answers:
                logger.debug("DNS record found: %s", answer)
                ipaddr = answer.to_text()
                try:
                    yield Result(self, constants.SUCCESS,
                                 key=ipaddr)
                except ValueError:
                    yield Result(self, constants.WARNING,
                                 key=ipaddr,
                                 msg='expected ipa-ca IPv4 address missing')

            ca_count = 0
            for server in system_records.servers_data:
                master = system_records.servers_data.get(server)
                if 'CA server' in master.get('roles'):
                    ca_count += 1

            if len(answers) != ca_count:
                yield Result(
                    self, constants.WARNING,
                    key='ca_count_a_rec',
                    msg='Got {count} ipa-ca A records, expected {expected}',
                    count=len(answers),
                    expected=ca_count)

        if aaaa_rec:
            # Look up the ipa-ca records
            qname = "ipa-ca." + api.env.domain + "."
            logger.debug("Search DNS for AAAA record of %s", qname)
            try:
                answers = resolve(qname, rdatatype.AAAA)
            except DNSException as e:
                logger.debug("DNS record not found: %s", e.__class__.__name__)
                answers = []

            for answer in answers:
                logger.debug("DNS record found: %s", answer)
                ipaddr = answer.to_text()
                try:
                    yield Result(self, constants.SUCCESS,
                                 key=ipaddr)
                except ValueError:
                    yield Result(self, constants.WARNING,
                                 key=ipaddr,
                                 msg='expected ipa-ca IPv6 address missing')

            ca_count = 0
            for server in system_records.servers_data:
                master = system_records.servers_data.get(server)
                if 'CA server' in master.get('roles'):
                    ca_count += 1

            if len(answers) != ca_count:
                yield Result(
                    self, constants.WARNING,
                    key='ca_count_aaaa_rec',
                    msg='Got {count} ipa-ca AAAA records, expected {expected}',
                    count=len(answers),
                    expected=ca_count)