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
--
Jan Cholasta
>From d131dd9ea659bb1cc21aa2146b14a0832c45e42a Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 27 May 2011 13:52:07 +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 | 32 +++++++++++++++++++---
install/tools/ipa-server-install | 3 +-
ipalib/plugins/host.py | 45 ++++++++++++++++++++------------
ipaserver/install/bindinstance.py | 52 ++++++++++++++++++++++++-------------
6 files changed, 97 insertions(+), 44 deletions(-)
diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index 491585b..d41a476 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -138,6 +138,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)
@@ -183,7 +184,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 2727fa6..65b5536 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -287,6 +287,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:
@@ -300,7 +301,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()
@@ -324,8 +325,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 f54436d..69ebd4a 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.plugins.ldap2 import ldap2
from ipapython import version
@@ -425,11 +425,33 @@ 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:
+ add_reverse_zone(ip_address, ip_prefixlen)
+
zone = add_zone(domain, nsaddr=ip_address)
- add_rr(zone, name, "A", ip_address)
- add_reverse_zone(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 4a93802..5a09d40 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -644,6 +644,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
@@ -914,7 +915,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 3208688..2bdbf56 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, update_policy=None, dns_backup=None):
- zone, name = get_reverse_zone(ip_address)
+def add_reverse_zone(ip_address, ip_prefixlen, 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, dns_backup=self.dns_backup)
+ add_reverse_zone(self.ip_address, self.ip_prefixlen, dns_backup=self.dns_backup)
def __setup_principal(self):
dns_principal = "DNS/" + self.fqdn + "@" + self.realm
@@ -450,10 +456,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]
@@ -482,16 +489,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