From c04aa879436f190f82265b87255e2a7a27939975 Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Tue, 6 Jan 2015 10:36:06 +0100 Subject: [PATCH] Fix: Upgrade forwardzones zones after adding newer replica Patch fixes issue, when forwardzones has not been upgraded after adding replica >=4.0 into topology with IPA 3.x servers. Ticket: https://fedorahosted.org/freeipa/ticket/4818 Reviewed-By: Petr Spacek --- install/share/dns.ldif | 2 ++ install/updates/40-dns.update | 1 + ipaserver/install/plugins/dns.py | 65 +++++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/install/share/dns.ldif b/install/share/dns.ldif index 2c6050f8598b82e3f0e476d5bff5522f4b54e521..05f5684c385db653a049a15bf490efe0d95e4a38 100644 --- a/install/share/dns.ldif +++ b/install/share/dns.ldif @@ -2,8 +2,10 @@ dn: cn=dns,$SUFFIX changetype: add objectClass: idnsConfigObject objectClass: nsContainer +objectClass: ipaConfigObject objectClass: top cn: dns +ipaConfigString: DNSVersion 1 aci: (targetattr = "*")(version 3.0; acl "Allow read access"; allow (read,search,compare) groupdn = "ldap:///cn=Read DNS Entries,cn=permissions,cn=pbac,$SUFFIX" or userattr = "parent[0,1].managedby#GROUPDN";) aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";) aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";) diff --git a/install/updates/40-dns.update b/install/updates/40-dns.update index 00fc97fcafc98ee6ef6e0c36b2005635867287b2..251df5907217344fb7bda3adcdef0d5c79c449ab 100644 --- a/install/updates/40-dns.update +++ b/install/updates/40-dns.update @@ -2,6 +2,7 @@ # update DNS container dn: cn=dns, $SUFFIX addifexist: objectClass: idnsConfigObject +addifexist: objectClass: ipaConfigObject addifexist: aci:'(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)' addifexist: aci:'(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)' addifexist: aci:'(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders || dlvrecord || idnssecinlinesigning || nsec3paramrecord || tlsarecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)' diff --git a/ipaserver/install/plugins/dns.py b/ipaserver/install/plugins/dns.py index 62cf588d27155acb03026f69ea09ff15582d26dc..ea4aec9741e4714cacdb677bd850730462623fa7 100644 --- a/ipaserver/install/plugins/dns.py +++ b/ipaserver/install/plugins/dns.py @@ -18,6 +18,7 @@ # along with this program. If not, see . import ldap as _ldap +import re import traceback import time @@ -144,32 +145,6 @@ class update_dns_limits(PostUpdate): api.register(update_dns_limits) -class update_check_forwardzones(PreSchemaUpdate): - """ - Check if the idnsforwardzone objectclass is in LDAP schema. - If not update is required (update_to_forward_zones), set sysupgrade state - 'update_to_forward_zones' to True - """ - - def execute(self, **options): - state = sysupgrade.get_upgrade_state('dns', 'update_to_forward_zones') - if state is False: - # no upgrade is needed - return (False, False, []) - ldap = self.obj.backend - if not dns_container_exists(ldap): # No DNS installed - return (False, False, []) - result = ldap.schema.get_obj(_ldap.schema.models.ObjectClass, 'idnsforwardzone') - if result is None: - sysupgrade.set_upgrade_state('dns', 'update_to_forward_zones', True) - self.log.info('Prepared upgrade to forward zones') - else: - sysupgrade.set_upgrade_state('dns', 'update_to_forward_zones', False) - return (False, False, []) - -api.register(update_check_forwardzones) - - class update_master_to_dnsforwardzones(PostUpdate): """ Update all zones to meet requirements in the new FreeIPA versions @@ -188,10 +163,41 @@ class update_master_to_dnsforwardzones(PostUpdate): def execute(self, **options): ldap = self.obj.backend - if not sysupgrade.get_upgrade_state('dns', 'update_to_forward_zones'): - # forward zones was tranformed before, nothing to do + # check LDAP if forwardzones already uses new semantics + dns_container_dn = DN(api.env.container_dns, api.env.basedn) + try: + container_entry = ldap.get_entry(dns_container_dn) + except errors.NotFound: + # DNS container not found, nothing to upgrade return (False, False, []) + for config_option in container_entry.get("ipaConfigString", []): + matched = re.match("^DNSVersion\s+(?P\d+)$", + config_option, flags=re.I) + if matched and int(matched.group("version")) >= 1: + # forwardzones already uses new semantics, + # no upgrade is required + return (False, False, []) + + self.log.info('Updating forward zones') + # update the DNSVersion, following upgrade can be executed only once + container_entry.setdefault( + 'ipaConfigString', []).append(u"DNSVersion 1") + ldap.update_entry(container_entry) + + # Updater in IPA version from 4.0 to 4.1.2 doesn't work well, this + # should detect if update in past has been executed, and set proper + # DNSVersion into LDAP + try: + fwzones = api.Command.dnsforwardzone_find()['result'] + except errors.NotFound: + # No forwardzones found, update probably has not been executed yet + pass + else: + if fwzones: + # fwzones exist, do not execute upgrade again + return (False, False, []) + try: # raw values are required to store into ldif zones = api.Command.dnszone_find(all=True, @@ -345,9 +351,6 @@ class update_master_to_dnsforwardzones(PostUpdate): self.log.info('Zone %s was sucessfully transformed to forward zone', zone['idnsname'][0]) - - sysupgrade.set_upgrade_state('dns', 'update_to_forward_zones', False) - return (False, False, []) api.register(update_master_to_dnsforwardzones) -- 2.1.0