Patches attached.

Ticket: https://fedorahosted.org/freeipa/ticket/4149

There is a bug in bind-dyndb-ldap (or worse in dirsrv), which cause the named service is stopped after deleting zone.
Bug ticket: https://fedorahosted.org/bind-dyndb-ldap/ticket/138

--
Martin Basti

From 9ed12420bf52a2d2dab1f8cc4f1f6b1b5f86a801 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Fri, 22 Aug 2014 17:11:22 +0200
Subject: [PATCH 1/2] Fix DNS plugin to allow to add root zone

Ticket: https://fedorahosted.org/freeipa/ticket/4149
---
 ipalib/plugins/dns.py | 53 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 24b303d8405aa3b4a6e0474e75d0e46e6949860d..9c8d09856a57f12b0ff1a52c8f0277f7abb29cdd 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -1783,17 +1783,21 @@ class DNSZoneBase(LDAPObject):
         zone = keys[-1]
         assert isinstance(zone, DNSName)
         assert zone.is_absolute()
-        zone = zone.ToASCII()
+        zone_a = zone.ToASCII()
+
+        # special case when zone is the root zone ('.')
+        if zone == DNSName.root:
+            return super(DNSZoneBase, self).get_dn(zone_a, **options)
 
         # try first relative name, a new zone has to be added as absolute
         # otherwise ObjectViolation is raised
-        zone = zone[:-1]
-        dn = super(DNSZoneBase, self).get_dn(zone, **options)
+        zone_a = zone_a[:-1]
+        dn = super(DNSZoneBase, self).get_dn(zone_a, **options)
         try:
             self.backend.get_entry(dn, [''])
         except errors.NotFound:
-            zone = u"%s." % zone
-            dn = super(DNSZoneBase, self).get_dn(zone, **options)
+            zone_a = u"%s." % zone_a
+            dn = super(DNSZoneBase, self).get_dn(zone_a, **options)
 
         return dn
 
@@ -1825,6 +1829,8 @@ class DNSZoneBase(LDAPObject):
         try:
             api.Command['permission_del'](permission_name, force=True)
         except errors.NotFound, e:
+            if zone == DNSName.root:  # special case root zone
+                raise
             # compatibility, older IPA versions which allows to create zone
             # without absolute zone name
             permission_name_rel = self.permission_name(
@@ -1988,20 +1994,21 @@ class DNSZoneBase_add_permission(LDAPQuery):
         permission_name = self.obj.permission_name(keys[-1])
 
         # compatibility with older IPA versions which allows relative zonenames
-        permission_name_rel = self.obj.permission_name(
-            keys[-1].relativize(DNSName.root)
-        )
-        try:
-            api.Object['permission'].get_dn_if_exists(permission_name_rel)
-        except errors.NotFound:
-            pass
-        else:
-            # permission exists without absolute domain name
-            raise errors.DuplicateEntry(
-                message=_('permission "%(value)s" already exists') % {
-                        'value': permission_name
-                }
+        if keys[-1] != DNSName.root:  # special case root zone
+            permission_name_rel = self.obj.permission_name(
+                keys[-1].relativize(DNSName.root)
             )
+            try:
+                api.Object['permission'].get_dn_if_exists(permission_name_rel)
+            except errors.NotFound:
+                pass
+            else:
+                # permission exists without absolute domain name
+                raise errors.DuplicateEntry(
+                    message=_('permission "%(value)s" already exists') % {
+                            'value': permission_name
+                    }
+                )
 
         permission = api.Command['permission_add_noaci'](permission_name,
                          ipapermissiontype=u'SYSTEM'
@@ -2417,12 +2424,14 @@ class dnszone_add(DNSZoneBase_add):
                                nameserver_ip_address)
 
         # Add entry to realmdomains
-        # except for our own domain, forwarded zones and reverse zones
+        # except for our own domain, forward zones, reverse zones and root zone
         zone = keys[0]
 
         if (zone != DNSName(api.env.domain).make_absolute()
             and not options.get('idnsforwarders')
-            and not zone.is_reverse()):
+            and not zone.is_reverse()
+            and zone != DNSName.root
+        ):
             try:
                 api.Command['realmdomains_mod'](add_domain=unicode(zone),
                                                 force=True)
@@ -2444,11 +2453,11 @@ class dnszone_del(DNSZoneBase_del):
         super(dnszone_del, self).post_callback(ldap, dn, *keys, **options)
 
         # Delete entry from realmdomains
-        # except for our own domain
+        # except for our own domain, and root zone
         zone = keys[0].make_absolute()
 
         if (zone != DNSName(api.env.domain).make_absolute() and
-                not zone.is_reverse()
+                not zone.is_reverse() and zone != DNSName.root
         ):
             try:
                 api.Command['realmdomains_mod'](del_domain=unicode(zone),
-- 
1.8.3.1

From 1e9150d63da3c5c7f1d82ce722e85449a9915661 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Mon, 25 Aug 2014 12:48:32 +0200
Subject: [PATCH 2/2] DNS test: allow '.' as zone name

https://fedorahosted.org/freeipa/ticket/4149
---
 ipatests/test_xmlrpc/test_dns_plugin.py | 103 ++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/ipatests/test_xmlrpc/test_dns_plugin.py b/ipatests/test_xmlrpc/test_dns_plugin.py
index 4085871ec4ebe2e03e6fee2460f159da2c3bf855..9eca2c3697e40bd42f86231c39c2e80e841d9864 100644
--- a/ipatests/test_xmlrpc/test_dns_plugin.py
+++ b/ipatests/test_xmlrpc/test_dns_plugin.py
@@ -3697,3 +3697,106 @@ class test_dns(Declarative):
         ),
 
     ]
+
+
+zone_root = u'.'
+zone_root_dnsname = DNSName(zone_root)
+zone_root_ip = u'172.16.29.222'
+zone_root_dn = DN(('idnsname',zone_root), api.env.container_dns, api.env.basedn)
+zone_root_ns = u'ns'
+zone_root_ns_dnsname = DNSName(zone_root_ns)
+zone_root_ns_dn = DN(('idnsname', zone_root_ns), zone_root_dn)
+zone_root_rname = u'root.example.com.'
+zone_root_rname_dnsname = DNSName(zone_root_rname)
+zone_root_permission = u'Manage DNS zone %s' % zone_root
+zone_root_permission_dn = DN(('cn',zone_root_permission),
+                            api.env.container_permission,api.env.basedn)
+
+class test_root_zone(Declarative):
+
+    @classmethod
+    def setUpClass(cls):
+        super(test_root_zone, cls).setUpClass()
+
+        if not api.Backend.rpcclient.isconnected():
+            api.Backend.rpcclient.connect(fallback=False)
+        try:
+            api.Command['dnszone_add'](zone1,
+               idnssoamname = zone1_ns,
+               idnssoarname = zone1_rname,
+               force = True,
+               )
+            api.Command['dnszone_del'](zone1)
+        except errors.NotFound:
+            raise nose.SkipTest('DNS is not configured')
+        except errors.DuplicateEntry:
+            pass
+
+    cleanup_commands = [
+        ('dnszone_del', [zone_root, ],
+            {'continue': True}),
+        ('permission_del', [zone_root_permission, ], {'force': True}
+        ),
+    ]
+
+    tests = [
+
+        dict(
+            desc='Create zone %r' % zone_root,
+            command=(
+                'dnszone_add', [zone_root], {
+                    'idnssoamname': zone_root_ns,
+                    'idnssoarname': zone_root_rname,
+                    'ip_address' : zone_root_ip,
+                }
+            ),
+            expected={
+                'value': zone_root_dnsname,
+                'summary': None,
+                'result': {
+                    'dn': zone_root_dn,
+                    'idnsname': [zone_root_dnsname],
+                    'idnszoneactive': [u'TRUE'],
+                    'idnssoamname': [zone_root_ns_dnsname],
+                    'nsrecord': [zone_root_ns],
+                    'idnssoarname': [zone_root_rname_dnsname],
+                    'idnssoaserial': [fuzzy_digits],
+                    'idnssoarefresh': [fuzzy_digits],
+                    'idnssoaretry': [fuzzy_digits],
+                    'idnssoaexpire': [fuzzy_digits],
+                    'idnssoaminimum': [fuzzy_digits],
+                    'idnsallowdynupdate': [u'FALSE'],
+                    'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; '
+                                         u'grant %(realm)s krb5-self * AAAA; '
+                                         u'grant %(realm)s krb5-self * SSHFP;'
+                                         % dict(realm=api.env.realm)],
+                    'idnsallowtransfer': [u'none;'],
+                    'idnsallowquery': [u'any;'],
+                    'objectclass': objectclasses.dnszone,
+                },
+            },
+        ),
+
+        dict(
+            desc='Add per-zone permission for zone %r' % zone_root,
+            command=(
+                'dnszone_add_permission', [zone_root], {}
+            ),
+            expected=dict(
+                result=True,
+                value=zone_root_permission,
+                summary=u'Added system permission "%s"' % zone_root_permission,
+            ),
+        ),
+
+        dict(
+            desc='Delete zone %r' % zone_root,
+            command=('dnszone_del', [zone_root], {}),
+            expected={
+                'value': [zone_root_dnsname],
+                'summary': u'Deleted DNS zone "%s"' % zone_root,
+                'result': {'failed': []},
+            },
+        ),
+
+    ]
-- 
1.8.3.1

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

Reply via email to