86baa9
From 85bc681683a8a5d71b9cfaf9c70e0f388732f285 Mon Sep 17 00:00:00 2001
86baa9
From: Justin Stephenson <jstephen@redhat.com>
86baa9
Date: Wed, 27 Dec 2017 16:32:47 -0500
86baa9
Subject: [PATCH] Skip zone overlap check with auto-reverse
86baa9
86baa9
Skip the existing reverse zone overlap check during DNS installation
86baa9
when both --auto-reverse and --allow-zone-overlap arguments are
86baa9
provided.
86baa9
86baa9
https://pagure.io/freeipa/issue/7239
86baa9
86baa9
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
86baa9
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
86baa9
Reviewed-By: Christian Heimes <cheimes@redhat.com>
86baa9
---
86baa9
 ipaserver/install/bindinstance.py             | 18 ++--
86baa9
 .../test_integration/test_installation.py     | 95 +++++++++++++++++++
86baa9
 2 files changed, 105 insertions(+), 8 deletions(-)
86baa9
86baa9
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
86baa9
index 940667db9c40559d5369188395bb18f2d1eac025..4de2c6442175a64f4048a93b2006a6d5c6b2a045 100644
86baa9
--- a/ipaserver/install/bindinstance.py
86baa9
+++ b/ipaserver/install/bindinstance.py
86baa9
@@ -304,7 +304,7 @@ def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
86baa9
     return normalize_zone(zone)
86baa9
 
86baa9
 
86baa9
-def get_auto_reverse_zones(ip_addresses):
86baa9
+def get_auto_reverse_zones(ip_addresses, allow_zone_overlap=False):
86baa9
     auto_zones = []
86baa9
     for ip in ip_addresses:
86baa9
         if ipautil.reverse_record_exists(ip):
86baa9
@@ -312,12 +312,13 @@ def get_auto_reverse_zones(ip_addresses):
86baa9
             logger.info("Reverse record for IP address %s already exists", ip)
86baa9
             continue
86baa9
         default_reverse = get_reverse_zone_default(ip)
86baa9
-        try:
86baa9
-            dnsutil.check_zone_overlap(default_reverse)
86baa9
-        except ValueError:
86baa9
-            logger.info("Reverse zone %s for IP address %s already exists",
86baa9
-                        default_reverse, ip)
86baa9
-            continue
86baa9
+        if not allow_zone_overlap:
86baa9
+            try:
86baa9
+                dnsutil.check_zone_overlap(default_reverse)
86baa9
+            except ValueError:
86baa9
+                logger.info("Reverse zone %s for IP address %s already exists",
86baa9
+                            default_reverse, ip)
86baa9
+                continue
86baa9
         auto_zones.append((ip, default_reverse))
86baa9
     return auto_zones
86baa9
 
86baa9
@@ -488,7 +489,8 @@ def check_reverse_zones(ip_addresses, reverse_zones, options, unattended,
86baa9
             ips_missing_reverse.append(ip)
86baa9
 
86baa9
     # create reverse zone for IP addresses that does not have one
86baa9
-    for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse):
86baa9
+    for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse,
86baa9
+                                           options.allow_zone_overlap):
86baa9
         if options.auto_reverse:
86baa9
             logger.info("Reverse zone %s will be created", rz)
86baa9
             checked_reverse_zones.append(rz)
86baa9
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
86baa9
index 4cd8a3e33927b7522e9b2a8908a8c179daaa1280..7e6c728102e29753ec7b56cedea734dd18b8bb8c 100644
86baa9
--- a/ipatests/test_integration/test_installation.py
86baa9
+++ b/ipatests/test_integration/test_installation.py
86baa9
@@ -9,6 +9,7 @@ installed.
86baa9
 
86baa9
 from __future__ import absolute_import
86baa9
 
86baa9
+import os
86baa9
 import pytest
86baa9
 from ipalib.constants import DOMAIN_LEVEL_0
86baa9
 from ipaplatform.constants import constants
86baa9
@@ -16,9 +17,46 @@ from ipaplatform.paths import paths
86baa9
 from ipatests.pytest_ipa.integration.env_config import get_global_config
86baa9
 from ipatests.test_integration.base import IntegrationTest
86baa9
 from ipatests.pytest_ipa.integration import tasks
86baa9
+from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
86baa9
 
86baa9
 config = get_global_config()
86baa9
 
86baa9
+
86baa9
+def create_broken_resolv_conf(master):
86baa9
+    # Force a broken resolv.conf to simulate a bad response to
86baa9
+    # reverse zone lookups
86baa9
+    master.run_command([
86baa9
+        '/usr/bin/mv',
86baa9
+        paths.RESOLV_CONF,
86baa9
+        '%s.sav' % paths.RESOLV_CONF
86baa9
+    ])
86baa9
+
86baa9
+    contents = "# Set as broken by ipatests\nnameserver 127.0.0.2\n"
86baa9
+    master.put_file_contents(paths.RESOLV_CONF, contents)
86baa9
+
86baa9
+
86baa9
+def restore_resolv_conf(master):
86baa9
+    if os.path.exists('%s.sav' % paths.RESOLV_CONF):
86baa9
+        master.run_command([
86baa9
+            '/usr/bin/mv',
86baa9
+            '%s.sav' % paths.RESOLV_CONF,
86baa9
+            paths.RESOLV_CONF
86baa9
+        ])
86baa9
+
86baa9
+
86baa9
+def server_install_setup(func):
86baa9
+    def wrapped(*args):
86baa9
+        master = args[0].master
86baa9
+        create_broken_resolv_conf(master)
86baa9
+        try:
86baa9
+            func(*args)
86baa9
+        finally:
86baa9
+            tasks.uninstall_master(master, clean=False)
86baa9
+            restore_resolv_conf(master)
86baa9
+            ipa_certs_cleanup(master)
86baa9
+    return wrapped
86baa9
+
86baa9
+
86baa9
 class InstallTestBase1(IntegrationTest):
86baa9
 
86baa9
     num_replicas = 3
86baa9
@@ -226,6 +264,63 @@ class TestInstallWithCA_DNS2(InstallTestBase2):
86baa9
         super(TestInstallWithCA_DNS2, self).test_replica2_ipa_kra_install()
86baa9
 
86baa9
 
86baa9
+class TestInstallWithCA_DNS3(CALessBase):
86baa9
+    """
86baa9
+    Test an install with a bad DNS resolver configured to force a
86baa9
+    timeout trying to verify the existing zones. In the case of a reverse
86baa9
+    zone it is skipped unless --allow-zone-overlap is set regardless of
86baa9
+    the value of --auto-reverse. Confirm that --allow-zone-overlap
86baa9
+    lets the reverse zone be created.
86baa9
+
86baa9
+    ticket 7239
86baa9
+    """
86baa9
+
86baa9
+    @server_install_setup
86baa9
+    def test_number_of_zones(self):
86baa9
+        """There should be two zones: one forward, one reverse"""
86baa9
+
86baa9
+        self.create_pkcs12('ca1/server')
86baa9
+        self.prepare_cacert('ca1')
86baa9
+
86baa9
+        self.install_server(extra_args=['--allow-zone-overlap'])
86baa9
+
86baa9
+        result = self.master.run_command([
86baa9
+            'ipa', 'dnszone-find'])
86baa9
+
86baa9
+        assert "in-addr.arpa." in result.stdout_text
86baa9
+
86baa9
+        assert "returned 2" in result.stdout_text
86baa9
+
86baa9
+
86baa9
+class TestInstallWithCA_DNS4(CALessBase):
86baa9
+    """
86baa9
+    Test an install with a bad DNS resolver configured to force a
86baa9
+    timeout trying to verify the existing zones. In the case of a reverse
86baa9
+    zone it is skipped unless --allow-zone-overlap is set regardless of
86baa9
+    the value of --auto-reverse. Confirm that without --allow-reverse-zone
86baa9
+    only the forward zone is created.
86baa9
+
86baa9
+    ticket 7239
86baa9
+    """
86baa9
+
86baa9
+    @server_install_setup
86baa9
+    def test_number_of_zones(self):
86baa9
+        """There should be one zone, a forward because rev timed-out"""
86baa9
+
86baa9
+        self.create_pkcs12('ca1/server')
86baa9
+        self.prepare_cacert('ca1')
86baa9
+
86baa9
+        # no zone overlap by default
86baa9
+        self.install_server()
86baa9
+
86baa9
+        result = self.master.run_command([
86baa9
+            'ipa', 'dnszone-find'])
86baa9
+
86baa9
+        assert "in-addr.arpa." not in result.stdout_text
86baa9
+
86baa9
+        assert "returned 1" in result.stdout_text
86baa9
+
86baa9
+
86baa9
 @pytest.mark.cs_acceptance
86baa9
 class TestInstallWithCA_KRA_DNS1(InstallTestBase1):
86baa9
 
86baa9
-- 
86baa9
2.20.1
86baa9