On 27.5.2011 16:49, Jan Cholasta wrote:
On 20.5.2011 20:29, Jan Cholasta wrote:
On 12.5.2011 14:47, Jan Cholasta wrote:


Rewrote host.py so that it doesn't use get_reverse_zone from
ipaserver.bindinstance (which fixes the pylint errors).

Honza


Patch updated. Requires patch 18.1.


Another update, requires patch 18.3.

Honza


Updated, requires 18.4.

--
Jan Cholasta
>From 43acc55fc0acc45746cb2605a730974c74ae0c94 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 27 May 2011 20:29:33 +0200
Subject: [PATCH] Honor netmask in DNS reverse zone setup.

ticket 910
---
 install/tools/ipa-dns-install     |    3 +-
 install/tools/ipa-replica-install |    6 +++-
 install/tools/ipa-replica-prepare |   34 ++++++++++++++++++++----
 install/tools/ipa-server-install  |    3 +-
 ipalib/plugins/host.py            |   45 ++++++++++++++++++++------------
 ipaserver/install/bindinstance.py |   52 ++++++++++++++++++++++++-------------
 6 files changed, 98 insertions(+), 45 deletions(-)

diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index e837919..91edcca 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -113,6 +113,7 @@ def main():
             sys.exit("Unable to resolve IP address for host name")
         else:
             ip_address = read_ip_address(api.env.host, fstore)
+    ip_prefixlen = ip_address.prefixlen
     ip_address = str(ip_address)
     logging.debug("will use ip_address: %s\n", ip_address)
 
@@ -158,7 +159,7 @@ def main():
         create_reverse = not options.no_reverse
     elif not options.no_reverse:
         create_reverse = bindinstance.create_reverse()
-    bind.setup(api.env.host, ip_address, api.env.realm, api.env.domain, dns_forwarders, conf_ntp, create_reverse, zonemgr=options.zonemgr)
+    bind.setup(api.env.host, ip_address, ip_prefixlen, api.env.realm, api.env.domain, dns_forwarders, conf_ntp, create_reverse, zonemgr=options.zonemgr)
 
     if bind.dm_password:
         api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=bind.dm_password)
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 6df5123..2848366 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -272,6 +272,7 @@ def install_bind(config, options):
         sys.exit("Unable to resolve IP address for host name")
     ip = installutils.parse_ip_address(ip_address)
     ip_address = str(ip)
+    ip_prefixlen = ip.prefixlen
 
     create_reverse = True
     if options.unattended:
@@ -285,7 +286,7 @@ def install_bind(config, options):
             # specified, ask the user
             create_reverse = bindinstance.create_reverse()
 
-    bind.setup(config.host_name, ip_address, config.realm_name,
+    bind.setup(config.host_name, ip_address, ip_prefixlen, config.realm_name,
                config.domain_name, forwarders, options.conf_ntp, create_reverse)
     bind.create_instance()
 
@@ -309,8 +310,9 @@ def install_dns_records(config, options):
         sys.exit("Unable to resolve IP address for host name")
     ip = installutils.parse_ip_address(ip_address)
     ip_address = str(ip)
+    ip_prefixlen = ip.prefixlen
 
-    bind.add_master_dns_records(config.host_name, ip_address,
+    bind.add_master_dns_records(config.host_name, ip_address, ip_prefixlen,
                                 config.realm_name, config.domain_name,
                                 options.conf_ntp)
 
diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index 21f30f0..2765e4a 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -27,7 +27,7 @@ import krbV
 
 from ipapython import ipautil
 from ipaserver.install import bindinstance, dsinstance, installutils, certs
-from ipaserver.install.bindinstance import add_zone, add_reverse_zone, add_rr, add_ptr_rr
+from ipaserver.install.bindinstance import add_zone, add_reverse_zone, add_fwd_rr, add_ptr_rr, dns_zone_exists
 from ipaserver.install.replication import check_replication_plugin, enable_replication_version_checking
 from ipaserver.install.installutils import resolve_host
 from ipaserver.plugins.ldap2 import ldap2
@@ -426,12 +426,34 @@ def main():
         name = domain.pop(0)
         domain = ".".join(domain)
 
-        ip_address = str(options.ip_address)
+        ip = options.ip_address
+        ip_address = str(ip)
+        ip_prefixlen = ip.prefixlen
+
+        if ip.defaultnet:
+            revzone = ip.reverse_dns
+            if ip.version == 4:
+                prefix = 32
+                dec = 8
+            elif ip.version == 6:
+                prefix = 128
+                dec = 4
+
+            while prefix > 0:
+                dummy, dot, revzone = revzone.partition('.')
+                prefix = prefix - dec
+                if dns_zone_exists(revzone):
+                    break
+
+            if prefix > 0:
+                ip_prefixlen = prefix
+            else:
+                ns_ip_address = resolve_host(api.env.host)
+                add_reverse_zone(ip_address, ip_prefixlen, ns_ip_address)
+
         zone = add_zone(domain, nsaddr=ip_address)
-        add_rr(zone, name, "A", ip_address)
-        ns_ip_address = resolve_host(api.env.host)
-        add_reverse_zone(ip_address, ns_ip_address)
-        add_ptr_rr(ip_address, replica_fqdn)
+        add_fwd_rr(zone, name, ip_address)
+        add_ptr_rr(ip_address, ip_prefixlen, replica_fqdn)
 
 try:
     if not os.geteuid()==0:
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index e36d5af..23e495e 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -622,6 +622,7 @@ def main():
         ip = read_ip_address(host_name, fstore)
         logging.debug("read ip_address: %s\n" % str(ip))
     ip_address = str(ip)
+    ip_prefixlen = ip.prefixlen
 
     print "The IPA Master Server will be configured with"
     print "Hostname:    " + host_name
@@ -892,7 +893,7 @@ def main():
                 # specified, ask the user
                 create_reverse = bindinstance.create_reverse()
 
-    bind.setup(host_name, ip_address, realm_name, domain_name, dns_forwarders, options.conf_ntp, create_reverse, zonemgr=options.zonemgr)
+    bind.setup(host_name, ip_address, ip_prefixlen, realm_name, domain_name, dns_forwarders, options.conf_ntp, create_reverse, zonemgr=options.zonemgr)
     if options.setup_dns:
         api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dm_password)
 
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 52830de..4947986 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -91,8 +91,6 @@ from ipalib import _, ngettext
 from ipalib import x509
 from ipapython.ipautil import ipa_generate_password
 from ipalib.request import context
-if api.env.context in ['lite', 'server']:
-    from ipaserver.install.bindinstance import get_reverse_zone
 import base64
 import nss.nss as nss
 import netaddr
@@ -111,16 +109,37 @@ def is_forward_record(zone, str_address):
     if addr.version == 4:
         result = api.Command['dnsrecord_find'](zone, arecord=str_address)
     elif addr.version == 6:
-        result = api.Command['dnsrecord_find'](zone, aaarecord=str_address)
+        result = api.Command['dnsrecord_find'](zone, aaaarecord=str_address)
     else:
         raise ValueError('Invalid address family')
 
     return result['count'] > 0
 
+def get_reverse_zone(ipaddr):
+    ip = netaddr.IPAddress(ipaddr)
+    revdns = unicode(ip.reverse_dns)
+
+    revzone = u''
+
+    result = api.Command['dnszone_find']()['result']
+    for zone in result:
+        zonename = zone['idnsname'][0]
+        if revdns.endswith(zonename) and len(zonename) > len(revzone):
+            revzone = zonename
+
+    if len(revzone) == 0:
+        raise errors.NotFound(
+            reason=_('DNS reverse zone for IP address %(addr)s not found') % dict(addr=ipaddr)
+        )
+
+    revname = revdns[:-len(revzone)-1]
+
+    return revzone, revname
+
 def remove_fwd_ptr(ipaddr, host, domain, recordtype):
     api.log.debug('deleting ipaddr %s' % ipaddr)
-    revzone, revname = get_reverse_zone(ipaddr)
     try:
+        revzone, revname = get_reverse_zone(ipaddr)
         delkw = { 'ptrrecord' : "%s.%s." % (host, domain) }
         api.Command['dnsrecord_del'](revzone, revname, **delkw)
     except errors.NotFound:
@@ -321,19 +340,9 @@ class host_add(LDAPCreate):
                     reason=_('DNS zone %(zone)s not found') % dict(zone=domain)
                 )
             if not options.get('no_reverse', False):
-                # we prefer lookup of the IP through the reverse zone
-                revzone, revname = get_reverse_zone(options['ip_address'])
-                # Verify that our reverse zone exists
-                match = False
-                for zone in result:
-                    if revzone == zone['idnsname'][0]:
-                        match = True
-                        break
-                if not match:
-                    raise errors.NotFound(
-                        reason=_('Reverse DNS zone %(zone)s not found') % dict(zone=revzone)
-                    )
                 try:
+                    # we prefer lookup of the IP through the reverse zone
+                    revzone, revname = get_reverse_zone(options['ip_address'])
                     reverse = api.Command['dnsrecord_find'](revzone, idnsname=revname)
                     if reverse['count'] > 0:
                         raise errors.DuplicateEntry(message=u'This IP address is already assigned.')
@@ -381,10 +390,12 @@ class host_add(LDAPCreate):
                 add_forward_record(domain, parts[0], options['ip_address'])
 
                 if not options.get('no_reverse', False):
-                    revzone, revname = get_reverse_zone(options['ip_address'])
                     try:
+                        revzone, revname = get_reverse_zone(options['ip_address'])
                         addkw = { 'ptrrecord' : keys[-1]+'.' }
                         api.Command['dnsrecord_add'](revzone, revname, **addkw)
+                    except errors.NotFound:
+                        pass
                     except errors.EmptyModlist:
                         # the entry already exists and matches
                         pass
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index fa27451..fc6519d 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -98,16 +98,20 @@ def dns_container_exists(fqdn, suffix):
 
     return ret
 
-def get_reverse_zone(ip_address_str):
+def get_reverse_zone(ip_address_str, ip_prefixlen):
     ip = netaddr.IPAddress(ip_address_str)
+    items = ip.reverse_dns.split('.')
+
     if ip.version == 4:
-        name, dot, zone = ip.reverse_dns.partition('.')
+        pos = 4 - ip_prefixlen / 8
     elif ip.version == 6:
-        name = '.'.join(ip.reverse_dns.split('.')[:8])
-        zone = '.'.join(ip.reverse_dns.split('.')[8:])
+        pos = 32 - ip_prefixlen / 4
     else:
         raise ValueError('Bad address format?')
 
+    name = '.'.join(items[:pos])
+    zone = '.'.join(items[pos:])
+
     return unicode(zone), unicode(name)
 
 def dns_zone_exists(name):
@@ -138,8 +142,8 @@ def add_zone(name, zonemgr=None, dns_backup=None, nsaddr=None, update_policy=Non
     add_rr(name, "@", "NS", api.env.host+'.', dns_backup, force=True)
     return name
 
-def add_reverse_zone(ip_address, ns_ip_address, update_policy=None, dns_backup=None):
-    zone, name = get_reverse_zone(ip_address)
+def add_reverse_zone(ip_address, ip_prefixlen, ns_ip_address, update_policy=None, dns_backup=None):
+    zone, name = get_reverse_zone(ip_address, ip_prefixlen)
     if not update_policy:
         update_policy = "grant %s krb5-subdomain %s. PTR;" % (api.env.realm, zone)
     try:
@@ -172,8 +176,8 @@ def add_fwd_rr(zone, host, ip_address):
     elif addr.version == 6:
         add_rr(zone, host, "AAAA", ip_address)
 
-def add_ptr_rr(ip_address, fqdn, dns_backup=None):
-    zone, name = get_reverse_zone(ip_address)
+def add_ptr_rr(ip_address, ip_prefixlen, fqdn, dns_backup=None):
+    zone, name = get_reverse_zone(ip_address, ip_prefixlen)
     add_rr(zone, name, "PTR", fqdn+".", dns_backup)
 
 def del_rr(zone, name, type, rdata):
@@ -249,6 +253,7 @@ class BindInstance(service.Service):
         self.domain = None
         self.host = None
         self.ip_address = None
+        self.ip_prefixlen = None
         self.realm = None
         self.forwarders = None
         self.sub_dict = None
@@ -259,10 +264,11 @@ class BindInstance(service.Service):
         else:
             self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
 
-    def setup(self, fqdn, ip_address, realm_name, domain_name, forwarders, ntp, create_reverse, named_user="named", zonemgr=None):
+    def setup(self, fqdn, ip_address, ip_prefixlen, realm_name, domain_name, forwarders, ntp, create_reverse, named_user="named", zonemgr=None):
         self.named_user = named_user
         self.fqdn = fqdn
         self.ip_address = ip_address
+        self.ip_prefixlen = ip_prefixlen
         self.realm = realm_name
         self.domain = domain_name
         self.forwarders = forwarders
@@ -390,11 +396,11 @@ class BindInstance(service.Service):
 
         # Add forward and reverse records to self
         add_fwd_rr(zone, self.host, self.ip_address)
-        if dns_zone_exists(get_reverse_zone(self.ip_address)[0]):
-            add_ptr_rr(self.ip_address, self.fqdn)
+        if dns_zone_exists(get_reverse_zone(self.ip_address, self.ip_prefixlen)[0]):
+            add_ptr_rr(self.ip_address, self.ip_prefixlen, self.fqdn)
 
     def __setup_reverse_zone(self):
-        add_reverse_zone(self.ip_address, self.ip_address,
+        add_reverse_zone(self.ip_address, self.ip_prefixlen, self.ip_address,
                 dns_backup=self.dns_backup)
 
     def __setup_principal(self):
@@ -451,10 +457,11 @@ class BindInstance(service.Service):
         resolv_fd.write(resolv_txt)
         resolv_fd.close()
 
-    def add_master_dns_records(self, fqdn, ip_address,
+    def add_master_dns_records(self, fqdn, ip_address, ip_prefixlen,
                                realm_name, domain_name, ntp=False):
         self.fqdn = fqdn
         self.ip_address = ip_address
+        self.ip_prefixlen = ip_prefixlen
         self.realm = realm_name
         self.domain = domain_name
         self.host = fqdn.split(".")[0]
@@ -483,16 +490,25 @@ class BindInstance(service.Service):
         for (record, type, rdata) in resource_records:
             del_rr(zone, record, type, rdata)
 
-        areclist = get_rr(zone, host, "A")
-        if len(areclist) != 0:
-            for rdata in areclist:
-                del_rr(zone, host, "A", rdata)
+        areclist = [("A", x) for x in get_rr(zone, host, "A")] + [("AAAA", x) for x in get_rr(zone, host, "AAAA")]
+        for (type, rdata) in areclist:
+            del_rr(zone, host, type, rdata)
+
+            ip = netaddr.IPAddress(rdata)
+            rzone = ip.reverse_dns
+            record = ''
+
+            while True:
+                part, dot, rzone = rzone.partition('.')
+                if len(rzone) == 0:
+                    break
+                record = (record + '.' + part).lstrip('.')
 
-                rzone, record = get_reverse_zone(rdata)
                 if dns_zone_exists(rzone):
                     del_rr(rzone, record, "PTR", fqdn+".")
                     # remove also master NS record from the reverse zone
                     del_rr(rzone, "@", "NS", fqdn+".")
+                    break
 
 
     def uninstall(self):
-- 
1.7.4.4

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

Reply via email to