https://fedorahosted.org/freeipa/ticket/2845

--
PetrĀ³
From 4bb93410e99864d334f25ce2b2dfbf5ec8d84946 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 4 Sep 2012 03:47:43 -0400
Subject: [PATCH] Check direct/reverse hostname/address resolution in
 ipa-replica-install

Forward and reverse resolution of the newly created replica is already
checked via get_host_name (which calls verify_fqdn).
Add the same check for the existing master.

Additionally, if DNS is installed on the remote host, check forward
and reverse resolution of both replicas using that DNS only
(ignoring /etc/hosts). These checks give only warnings and, in interactive
installs, a "Continue?" prompt.

https://fedorahosted.org/freeipa/ticket/2845
---
 install/tools/ipa-replica-install | 102 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index d7baf9c05794d95472091059cb96c54cf00bfc41..7b561054fed158b776005e46a038a1f6439bc576 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -25,6 +25,10 @@ import os, pwd, shutil
 import grp
 from optparse import OptionGroup
 
+import dns.resolver
+import dns.reversename
+import dns.exception
+
 from ipapython import ipautil
 
 from ipaserver.install import dsinstance, installutils, krbinstance, service
@@ -277,6 +281,86 @@ def check_bind():
         print "Aborting installation"
         sys.exit(1)
 
+
+def check_dns_resolution(host_name, dns_server):
+    """Check forward and reverse resolution of host_name using dns_server
+    """
+    # Point the resolver at specified DNS server
+    server_ips = list(
+            a[4][0] for a in socket.getaddrinfo(dns_server, None))
+    resolver = dns.resolver.Resolver()
+    resolver.nameservers = server_ips
+
+    root_logger.debug('Search DNS server %s (%s) for %s',
+        dns_server, server_ips, host_name)
+
+    # Get IP addresses of host_name
+    addresses = set()
+    for rtype in 'A', 'AAAA':
+        try:
+            result = resolver.query(host_name, rtype)
+        except dns.exception.DNSException:
+            rrset = []
+        else:
+            rrset = result.rrset
+        if rrset:
+            addresses.update(r.address for r in result.rrset)
+
+    if not addresses:
+        root_logger.error(
+            'Could not resolve hostname %s using DNS. '
+            'Clients may not function properly. '
+            'Please check your DNS setup. '
+            '(Note that this check queries IPA DNS directly and '
+            'ignores /etc/hosts.)',
+            host_name)
+        return False
+
+    no_errors = True
+
+    # Check each of the IP addresses
+    checked = set()
+    for address in addresses:
+        if address in checked:
+            continue
+        checked.add(address)
+        try:
+            root_logger.debug('Check reverse address %s (%s)',
+                address, host_name)
+            revname = dns.reversename.from_address(address)
+            rrset = resolver.query(revname, 'PTR').rrset
+        except Exception, e:
+            root_logger.debug('Check failed: %s %s', type(e).__name__, e)
+            root_logger.error(
+                'Reverse DNS resolution of address %s (%s) failed. '
+                'Clients may not function properly. '
+                'Please check your DNS setup. '
+                '(Note that this check queries IPA DNS directly and '
+                'ignores /etc/hosts.)',
+                address, host_name)
+            no_errors = False
+        else:
+            host_name_obj = dns.name.from_text(host_name)
+            if rrset:
+                names = [r.target.to_text() for r in rrset]
+            else:
+                names = []
+            root_logger.debug(
+                'Address %s resolves to: %s. ', address, ', '.join(names))
+            if not rrset or not any(
+                    r.target == host_name_obj for r in rrset):
+                root_logger.error(
+                    'The IP address %s of host %s resolves to: %s. '
+                    'Clients may not function properly. '
+                    'Please check your DNS setup. '
+                    '(Note that this check queries IPA DNS directly and '
+                    'ignores /etc/hosts.)',
+                    address, host_name, ', '.join(names))
+                no_errors = False
+
+    return no_errors
+
+
 def main():
     ipaservices.check_selinux_status()
     safe_options, options, filename = parse_options()
@@ -346,6 +430,7 @@ def main():
     config.dir = dir
     config.setup_ca = options.setup_ca
 
+    installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
 
     # check connection
     if not options.skip_conncheck:
@@ -418,6 +503,23 @@ def main():
             found = True
         except errors.NotFound:
             pass
+
+        # If remote host has DNS, check forward/reverse resolution
+        try:
+            entry = conn.find_entries(u'cn=dns', base_dn=DN(api.env.basedn))
+        except errors.NotFound:
+            pass
+        else:
+            master = config.master_host_name
+            if not options.no_host_dns:
+                resolution_ok = (
+                    check_dns_resolution(master, master) and
+                    check_dns_resolution(config.host_name, master))
+                root_logger.debug('Check forward/reverse DNS resolution')
+                if not resolution_ok and not options.unattended:
+                    if not ipautil.user_input("Continue?", False):
+                        sys.exit(0)
+
         try:
             (agreement_cn, agreement_dn) = replman.agreement_dn(host)
             entry = conn.get_entry(agreement_dn, ['*'])
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to