On 16.6.2011 14:31, Jan Cholasta wrote:
On 14.6.2011 20:54, Simo Sorce wrote:
On Tue, 2011-06-14 at 14:26 -0400, Rob Crittenden wrote:
Jan Cholasta wrote:
This patch enables the user to specify netmasks in the --ip-address
option of host-add. They're used for proper DNS reverse zone and PTR
record creation. Also the IP addresses are more strictly checked (just
like in the install scripts).

https://fedorahosted.org/freeipa/ticket/1234

Do we want a reverse zone created automatically when a host is added? I
think a warning that the reverse zone doesn't exist may be adequate.

A warning is preferable as we may not be controlling that reverse zone.

Simo.


Updated patch attached. NonFatalError is raised when the reverse zone is
not found.

Honza


Fixed commit message.

--
Jan Cholasta
>From 4c832c2cd81ac5e3818a1d89981b5f21e68173f5 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Tue, 14 Jun 2011 16:31:36 +0200
Subject: [PATCH] Improve IP address handling in the host-add command.

IP addresses are more strictly checked. Netmasks can be specified
and are used in DNS PTR record creation.

ticket 1234
---
 ipalib/plugins/host.py |   51 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index a602df4..178d526 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -89,7 +89,7 @@ from ipalib.plugins.dns import dns_container_exists, _record_types
 from ipalib.plugins.dns import add_forward_record
 from ipalib import _, ngettext
 from ipalib import x509
-from ipapython.ipautil import ipa_generate_password
+from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
 from ipalib.request import context
 import base64
 import nss.nss as nss
@@ -115,17 +115,30 @@ def is_forward_record(zone, str_address):
 
     return result['count'] > 0
 
-def get_reverse_zone(ipaddr):
+def get_reverse_zone(ipaddr, prefixlen=None):
     ip = netaddr.IPAddress(ipaddr)
     revdns = unicode(ip.reverse_dns)
 
-    revzone = u''
+    if prefixlen is None:
+        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
+        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
+    else:
+        if ip.version == 4:
+            pos = 4 - prefixlen / 8
+        elif ip.version == 6:
+            pos = 32 - prefixlen / 4
+        items = ip.reverse_dns.split('.')
+        revzone = u'.'.join(items[pos:])
+
+        try:
+            api.Command['dnszone_show'](revzone)
+        except errors.NotFound:
+            revzone = u''
 
     if len(revzone) == 0:
         raise errors.NotFound(
@@ -188,7 +201,9 @@ def validate_ipaddr(ugettext, ipaddr):
     """
     Verify that we have either an IPv4 or IPv6 address.
     """
-    if not util.validate_ipaddr(ipaddr):
+    try:
+        ip = CheckedIPAddress(ipaddr, match_local=False)
+    except:
         return _('invalid IP address')
     return None
 
@@ -340,17 +355,21 @@ class host_add(LDAPCreate):
                 raise errors.NotFound(
                     reason=_('DNS zone %(zone)s not found') % dict(zone=domain)
                 )
+            ip = CheckedIPAddress(options['ip_address'], match_local=False)
             if not options.get('no_reverse', False):
                 try:
+                    prefixlen = None
+                    if not ip.defaultnet:
+                        prefixlen = ip.prefixlen
                     # we prefer lookup of the IP through the reverse zone
-                    revzone, revname = get_reverse_zone(options['ip_address'])
+                    revzone, revname = get_reverse_zone(ip, prefixlen)
                     reverse = api.Command['dnsrecord_find'](revzone, idnsname=revname)
                     if reverse['count'] > 0:
                         raise errors.DuplicateEntry(message=u'This IP address is already assigned.')
                 except errors.NotFound:
                     pass
             else:
-                if is_forward_record(domain, options['ip_address']):
+                if is_forward_record(domain, unicode(ip)):
                     raise errors.DuplicateEntry(message=u'This IP address is already assigned.')
         if not options.get('force', False) and not 'ip_address' in options:
             util.validate_host_dns(self.log, keys[-1])
@@ -388,15 +407,17 @@ class host_add(LDAPCreate):
                 parts = keys[-1].split('.')
                 domain = unicode('.'.join(parts[1:]))
 
-                add_forward_record(domain, parts[0], options['ip_address'])
+                ip = CheckedIPAddress(options['ip_address'], match_local=False)
+                add_forward_record(domain, parts[0], unicode(ip))
 
                 if not options.get('no_reverse', False):
                     try:
-                        revzone, revname = get_reverse_zone(options['ip_address'])
+                        prefixlen = None
+                        if not ip.defaultnet:
+                            prefixlen = ip.prefixlen
+                        revzone, revname = get_reverse_zone(ip, prefixlen)
                         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
-- 
1.7.4.4

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

Reply via email to