summaryrefslogtreecommitdiffstats
path: root/ipalib/plugins/dns.py
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2013-04-02 11:58:31 +0200
committerMartin Kosek <mkosek@redhat.com>2013-04-02 17:11:52 +0200
commit42c401a87795fe3a2067155460ae276ad2d3e360 (patch)
tree586986c6caabd4a5ed8b72789baee6230b69f692 /ipalib/plugins/dns.py
parent81be28d6bd49cad19d41a572b0d09c6fe9663359 (diff)
downloadfreeipa-42c401a87795fe3a2067155460ae276ad2d3e360.tar.gz
freeipa-42c401a87795fe3a2067155460ae276ad2d3e360.tar.xz
freeipa-42c401a87795fe3a2067155460ae276ad2d3e360.zip
Improve CNAME record validation
Refactor DNS RR conflict validator so that it is better extensible in the future. Also check that there is only one CNAME defined for a DNS record. PTR+CNAME record combination is no longer allowed as we found out it does not make sense to have this combination. https://fedorahosted.org/freeipa/ticket/3450
Diffstat (limited to 'ipalib/plugins/dns.py')
-rw-r--r--ipalib/plugins/dns.py43
1 files changed, 27 insertions, 16 deletions
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index dabab8405..7d9956504 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -2269,23 +2269,34 @@ class dnsrecord(LDAPObject):
def check_record_type_collisions(self, old_entry, entry_attrs):
# Test that only allowed combination of record types was created
- attrs = set(attr for attr in entry_attrs.keys() if attr in _record_attributes
- and entry_attrs[attr])
- attrs.update(attr for attr in old_entry.keys() if attr not in entry_attrs)
+ rrattrs = {}
+ if old_entry is not None:
+ old_rrattrs = dict((key, value) for key, value in old_entry.iteritems()
+ if key in self.params and
+ isinstance(self.params[key], DNSRecord))
+ rrattrs.update(old_rrattrs)
+ new_rrattrs = dict((key, value) for key, value in entry_attrs.iteritems()
+ if key in self.params and
+ isinstance(self.params[key], DNSRecord))
+ rrattrs.update(new_rrattrs)
+
+ # CNAME record validation
try:
- attrs.remove('cnamerecord')
+ cnames = rrattrs['cnamerecord']
except KeyError:
- rec_has_cname = False
+ pass
else:
- rec_has_cname = True
- # CNAME and PTR record combination is allowed
- attrs.discard('ptrrecord')
- rec_has_other_types = True if attrs else False
-
- if rec_has_cname and rec_has_other_types:
- raise errors.ValidationError(name='cnamerecord',
- error=_('CNAME record is not allowed to coexist with any other '
- 'records except PTR'))
+ if cnames is not None:
+ if len(cnames) > 1:
+ raise errors.ValidationError(name='cnamerecord',
+ error=_('only one CNAME record is allowed per name '
+ '(RFC 2136, section 1.1.5)'))
+ if any(rrvalue is not None
+ and rrattr != 'cnamerecord'
+ for rrattr, rrvalue in rrattrs.iteritems()):
+ raise errors.ValidationError(name='cnamerecord',
+ error=_('CNAME record is not allowed to coexist '
+ 'with any other record (RFC 1034, section 3.6.2)'))
api.register(dnsrecord)
@@ -2435,7 +2446,7 @@ class dnsrecord_add(LDAPCreate):
try:
(dn_, old_entry) = ldap.get_entry(dn, _record_attributes)
except errors.NotFound:
- pass
+ old_entry = None
else:
for attr in entry_attrs.keys():
if attr not in _record_attributes:
@@ -2448,7 +2459,7 @@ class dnsrecord_add(LDAPCreate):
vals = list(entry_attrs[attr])
entry_attrs[attr] = list(set(old_entry.get(attr, []) + vals))
- self.obj.check_record_type_collisions(old_entry, entry_attrs)
+ self.obj.check_record_type_collisions(old_entry, entry_attrs)
return dn
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):