e0ab38
From 96695bb8e414be941e07d43652516a99cfd89a24 Mon Sep 17 00:00:00 2001
e0ab38
From: Petr Spacek <pspacek@redhat.com>
e0ab38
Date: Sun, 20 Dec 2015 18:36:48 +0100
e0ab38
Subject: [PATCH] DNSSEC: ipa-dnskeysyncd: Skip zones with old DNSSEC metadata
e0ab38
 in LDAP
e0ab38
e0ab38
This filtering is useful in cases where LDAP contains DNS zones which
e0ab38
have old metadata objects and DNSSEC disabled. Such zones must be
e0ab38
ignored to prevent errors while calling dnssec-keyfromlabel or rndc.
e0ab38
e0ab38
https://fedorahosted.org/freeipa/ticket/5348
e0ab38
e0ab38
Reviewed-By: Martin Basti <mbasti@redhat.com>
e0ab38
Reviewed-By: Martin Basti <mbasti@redhat.com>
e0ab38
---
e0ab38
 ipapython/dnssec/bindmgr.py   | 16 +++++++++++++---
e0ab38
 ipapython/dnssec/keysyncer.py | 24 ++++++++++++++++++------
e0ab38
 2 files changed, 31 insertions(+), 9 deletions(-)
e0ab38
e0ab38
diff --git a/ipapython/dnssec/bindmgr.py b/ipapython/dnssec/bindmgr.py
e0ab38
index 70caaf4ee74f594c652cd82bccb8964e172bc719..d81dad940df49e79f4534c2224c10ecf192794ba 100644
e0ab38
--- a/ipapython/dnssec/bindmgr.py
e0ab38
+++ b/ipapython/dnssec/bindmgr.py
e0ab38
@@ -191,10 +191,20 @@ class BINDMgr(object):
e0ab38
 
e0ab38
         self.notify_zone(zone)
e0ab38
 
e0ab38
-    def sync(self):
e0ab38
-        """Synchronize list of zones in LDAP with BIND."""
e0ab38
+    def sync(self, dnssec_zones):
e0ab38
+        """Synchronize list of zones in LDAP with BIND.
e0ab38
+
e0ab38
+        dnssec_zones lists zones which should be processed. All other zones
e0ab38
+        will be ignored even though they were modified using ldap_event().
e0ab38
+
e0ab38
+        This filter is useful in cases where LDAP contains DNS zones which
e0ab38
+        have old metadata objects and DNSSEC disabled. Such zones must be
e0ab38
+        ignored to prevent errors while calling dnssec-keyfromlabel or rndc.
e0ab38
+        """
e0ab38
         self.log.debug('Key metadata in LDAP: %s' % self.ldap_keys)
e0ab38
-        for zone in self.modified_zones:
e0ab38
+        self.log.debug('Zones modified but skipped during bindmgr.sync: %s',
e0ab38
+                       self.modified_zones - dnssec_zones)
e0ab38
+        for zone in self.modified_zones.intersection(dnssec_zones):
e0ab38
             self.sync_zone(zone)
e0ab38
 
e0ab38
         self.modified_zones = set()
e0ab38
diff --git a/ipapython/dnssec/keysyncer.py b/ipapython/dnssec/keysyncer.py
e0ab38
index de5b5aa5f670db4c58fb92b989e181d45d887b55..5ba9baaab30b07d2f4e4ae3a3507898d08a0d6c1 100644
e0ab38
--- a/ipapython/dnssec/keysyncer.py
e0ab38
+++ b/ipapython/dnssec/keysyncer.py
e0ab38
@@ -6,6 +6,8 @@ import logging
e0ab38
 import ldap.dn
e0ab38
 import os
e0ab38
 
e0ab38
+import dns.name
e0ab38
+
e0ab38
 from ipaplatform.paths import paths
e0ab38
 from ipapython import ipautil
e0ab38
 
e0ab38
@@ -33,6 +35,7 @@ class KeySyncer(SyncReplConsumer):
e0ab38
 
e0ab38
         self.bindmgr = BINDMgr(self.api)
e0ab38
         self.init_done = False
e0ab38
+        self.dnssec_zones = set()
e0ab38
         SyncReplConsumer.__init__(self, *args, **kwargs)
e0ab38
 
e0ab38
     def _get_objclass(self, attrs):
e0ab38
@@ -112,7 +115,7 @@ class KeySyncer(SyncReplConsumer):
e0ab38
         self.ods_sync()
e0ab38
         self.hsm_replica_sync()
e0ab38
         self.hsm_master_sync()
e0ab38
-        self.bindmgr.sync()
e0ab38
+        self.bindmgr.sync(self.dnssec_zones)
e0ab38
 
e0ab38
     # idnsSecKey wrapper
e0ab38
     # Assumption: metadata points to the same key blob all the time,
e0ab38
@@ -121,23 +124,29 @@ class KeySyncer(SyncReplConsumer):
e0ab38
     def key_meta_add(self, uuid, dn, newattrs):
e0ab38
         self.hsm_replica_sync()
e0ab38
         self.bindmgr.ldap_event('add', uuid, newattrs)
e0ab38
-        self.bindmgr_sync()
e0ab38
+        self.bindmgr_sync(self.dnssec_zones)
e0ab38
 
e0ab38
     def key_meta_del(self, uuid, dn, oldattrs):
e0ab38
         self.bindmgr.ldap_event('del', uuid, oldattrs)
e0ab38
-        self.bindmgr_sync()
e0ab38
+        self.bindmgr_sync(self.dnssec_zones)
e0ab38
         self.hsm_replica_sync()
e0ab38
 
e0ab38
     def key_metadata_sync(self, uuid, dn, oldattrs, newattrs):
e0ab38
         self.bindmgr.ldap_event('mod', uuid, newattrs)
e0ab38
-        self.bindmgr_sync()
e0ab38
+        self.bindmgr_sync(self.dnssec_zones)
e0ab38
 
e0ab38
-    def bindmgr_sync(self):
e0ab38
+    def bindmgr_sync(self, dnssec_zones):
e0ab38
         if self.init_done:
e0ab38
-            self.bindmgr.sync()
e0ab38
+            self.bindmgr.sync(dnssec_zones)
e0ab38
 
e0ab38
     # idnsZone wrapper
e0ab38
     def zone_add(self, uuid, dn, newattrs):
e0ab38
+        zone = dns.name.from_text(newattrs['idnsname'][0])
e0ab38
+        if self.__is_dnssec_enabled(newattrs):
e0ab38
+            self.dnssec_zones.add(zone)
e0ab38
+        else:
e0ab38
+            self.dnssec_zones.discard(zone)
e0ab38
+
e0ab38
         if not self.ismaster:
e0ab38
             return
e0ab38
 
e0ab38
@@ -146,6 +155,9 @@ class KeySyncer(SyncReplConsumer):
e0ab38
         self.ods_sync()
e0ab38
 
e0ab38
     def zone_del(self, uuid, dn, oldattrs):
e0ab38
+        zone = dns.name.from_text(oldattrs['idnsname'][0])
e0ab38
+        self.dnssec_zones.discard(zone)
e0ab38
+
e0ab38
         if not self.ismaster:
e0ab38
             return
e0ab38
 
e0ab38
-- 
e0ab38
2.4.3
e0ab38