https://fedorahosted.org/freeipa/ticket/5087
--
David Kupka
From 4ee9794a8d857e5a71f12b8fd05d337bbb4b062a Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Thu, 2 Jul 2015 15:10:40 +0200
Subject: [PATCH] dns: do not add (forward)zone if it is already resolvable.

Check if the zone user wants to add is already resolvable and refuse to
create it if yes. --skip-overlap-check and --force options suppress this check.

https://fedorahosted.org/freeipa/ticket/5087
---
 ipalib/plugins/dns.py | 38 +++++++++++++++++++++++++++++++++-----
 ipapython/ipautil.py  |  9 +++++++++
 2 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 512a653c3cc8ee641debec0d20f58e17eff08266..4e7b72628930c5be340ac37c08f1e45654e80c9e 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -50,7 +50,7 @@ from ipalib.util import (normalize_zonemgr,
                          validate_dnssec_zone_forwarder_step1,
                          validate_dnssec_zone_forwarder_step2)
 
-from ipapython.ipautil import CheckedIPAddress, is_host_resolvable
+from ipapython.ipautil import CheckedIPAddress, is_host_resolvable, is_zone_resolvable, zone_nameservers
 from ipapython.dnsutil import DNSName
 
 __doc__ = _("""
@@ -2101,11 +2101,25 @@ class DNSZoneBase(LDAPObject):
 
 class DNSZoneBase_add(LDAPCreate):
 
+    takes_options = LDAPCreate.takes_options + (
+        Flag('force',
+             label=_('Force'),
+             doc=_('Force DNS zone creation.')
+        ),
+        Flag('skip_overlap_check',
+             doc=_('Force DNS zone creation even if it will overlap with '
+                   'existing zone.')
+        ),
+    )
+
     has_output_params = LDAPCreate.has_output_params + dnszone_output_params
 
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
+        if options['force']:
+            options['skip_overlap_check'] = True
+
         try:
             entry = ldap.get_entry(dn)
         except errors.NotFound:
@@ -2120,6 +2134,17 @@ class DNSZoneBase_add(LDAPCreate):
 
         entry_attrs['idnszoneactive'] = 'TRUE'
 
+        zone = keys[-1]
+        if not options['skip_overlap_check']:
+            if is_zone_resolvable(zone):
+                ns = zone_nameservers(zone)
+                if ns:
+                    msg = _(u"DNS zone {0} already exists and is handled "
+                            "by server(s): {1}".format(zone, ', '.join(ns)))
+                else:
+                    msg = _(u"DNS zone {0} already exists".format(zone))
+                raise errors.DuplicateEntry(message=msg)
+
         return dn
 
 
@@ -2673,9 +2698,9 @@ class dnszone_add(DNSZoneBase_add):
     __doc__ = _('Create new DNS zone (SOA record).')
 
     takes_options = DNSZoneBase_add.takes_options + (
-        Flag('force',
-             label=_('Force'),
-             doc=_('Force DNS zone creation even if nameserver is not resolvable.'),
+        Flag('skip_nameserver_check',
+             doc=_('Force DNS zone creation even if nameserver is not '
+                   'resolvable.')
         ),
 
         # Deprecated
@@ -2699,6 +2724,9 @@ class dnszone_add(DNSZoneBase_add):
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
+        if options['force']:
+            options['skip_nameserver_check'] = True
+
         dn = super(dnszone_add, self).pre_callback(
             ldap, dn, entry_attrs, attrs_list, *keys, **options)
 
@@ -2713,7 +2741,7 @@ class dnszone_add(DNSZoneBase_add):
                     error=_("Nameserver for reverse zone cannot be a relative DNS name"))
 
             # verify if user specified server is resolvable
-            if not options['force']:
+            if not options['skip_nameserver_check']:
                 check_ns_rec_resolvable(keys[0], entry_attrs['idnssoamname'])
             # show warning about --name-server option
             context.show_warning_nameserver_option = True
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 88e89706b8e2aa6dea80809510d88bceaa836e85..6bfba377c54a96ea197be7f7c8f633e433429db3 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -923,6 +923,15 @@ def host_exists(host):
     else:
         return True
 
+def is_zone_resolvable(zone):
+    return resolver.zone_for_name(zone) == zone
+
+def zone_nameservers(zone):
+        try:
+            return [ns.to_text() for ns in resolver.query(zone, 'NS')]
+        except DNSException:
+            return []
+
 def get_ipa_basedn(conn):
     """
     Get base DN of IPA suffix in given LDAP server.
-- 
2.4.3

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to