diff options
-rw-r--r-- | API.txt | 2 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | ipalib/plugins/dns.py | 18 | ||||
-rw-r--r-- | ipalib/util.py | 29 | ||||
-rw-r--r-- | ipaserver/install/bindinstance.py | 7 | ||||
-rw-r--r-- | ipaserver/install/plugins/dns.py | 4 | ||||
-rw-r--r-- | tests/test_xmlrpc/test_dns_plugin.py | 12 |
7 files changed, 60 insertions, 14 deletions
@@ -1014,7 +1014,7 @@ option: Int('idnssoaexpire', attribute=True, autofill=True, cli_name='expire', d option: Int('idnssoaminimum', attribute=True, autofill=True, cli_name='minimum', default=3600, maxvalue=10800, minvalue=0, multivalue=False, required=True) option: Int('dnsttl', attribute=True, cli_name='ttl', multivalue=False, required=False) option: StrEnum('dnsclass', attribute=True, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS')) -option: Str('idnsupdatepolicy', attribute=True, cli_name='update_policy', multivalue=False, required=False) +option: Str('idnsupdatepolicy', attribute=True, autofill=True, cli_name='update_policy', multivalue=False, required=False) option: Bool('idnsallowdynupdate', attribute=True, autofill=True, cli_name='dynamic_update', default=False, multivalue=False, required=False) option: Str('idnsallowquery', attribute=True, autofill=True, cli_name='allow_query', default=u'any;', multivalue=False, required=False) option: Str('idnsallowtransfer', attribute=True, autofill=True, cli_name='allow_transfer', default=u'none;', multivalue=False, required=False) @@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000 # # ######################################################## IPA_API_VERSION_MAJOR=2 -IPA_API_VERSION_MINOR=37 +IPA_API_VERSION_MINOR=38 diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py index 1bf754272..a48262794 100644 --- a/ipalib/plugins/dns.py +++ b/ipalib/plugins/dns.py @@ -32,7 +32,8 @@ from ipalib.parameters import Flag, Bool, Int, Decimal, Str, StrEnum, Any from ipalib.plugins.baseldap import * from ipalib import _, ngettext from ipalib.util import (validate_zonemgr, normalize_zonemgr, - validate_hostname, validate_dns_label, validate_domain_name) + validate_hostname, validate_dns_label, validate_domain_name, + get_dns_forward_zone_update_policy, get_dns_reverse_zone_update_policy) from ipapython.ipautil import valid_ip, CheckedIPAddress, is_host_resolvable from ldap import explode_dn @@ -75,8 +76,11 @@ EXAMPLES: --admin-email=admin@example.com Modify the zone to allow dynamic updates for hosts own records in realm EXAMPLE.COM: - ipa dnszone-mod example.com --dynamic-update=TRUE \\ - --update-policy="grant EXAMPLE.COM krb5-self * A; grant EXAMPLE.COM krb5-self * AAAA;" + ipa dnszone-mod example.com --dynamic-update=TRUE + + This is the equivalent of: + ipa dnszone-mod example.com --dynamic-update=TRUE \\ + --update-policy="grant EXAMPLE.COM krb5-self * A; grant EXAMPLE.COM krb5-self * AAAA; grant EXAMPLE.COM krb5-self * SSHFP;" Modify the zone to allow zone transfers for local network only: ipa dnszone-mod example.com --allow-transfer=10.0.0.0/8 @@ -1510,6 +1514,12 @@ def dns_container_exists(ldap): return False return True +def default_zone_update_policy(zone): + if zone_is_reverse(zone): + return get_dns_reverse_zone_update_policy(api.env.realm, zone) + else: + return get_dns_forward_zone_update_policy(api.env.realm) + class dnszone(LDAPObject): """ DNS Zone, container for resource records. @@ -1611,6 +1621,8 @@ class dnszone(LDAPObject): cli_name='update_policy', label=_('BIND update policy'), doc=_('BIND update policy'), + default_from=lambda idnsname: default_zone_update_policy(idnsname), + autofill=True ), Bool('idnszoneactive?', cli_name='zone_active', diff --git a/ipalib/util.py b/ipalib/util.py index 50da74327..039ffb06d 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -427,11 +427,11 @@ def parse_time_duration(value): return duration -def gen_dns_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')): +def get_dns_forward_zone_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')): """ - Generate update policy for a DNS zone (idnsUpdatePolicy attribute). Bind - uses this policy to grant/reject access for client machines trying to - dynamically update their records. + Generate update policy for a forward DNS zone (idnsUpdatePolicy + attribute). Bind uses this policy to grant/reject access for client + machines trying to dynamically update their records. :param realm: A realm of the of the client :param rrtypes: A list of resource records types that client shall be @@ -445,6 +445,27 @@ def gen_dns_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')): return policy +def get_dns_reverse_zone_update_policy(realm, reverse_zone, rrtypes=('PTR',)): + """ + Generate update policy for a reverse DNS zone (idnsUpdatePolicy + attribute). Bind uses this policy to grant/reject access for client + machines trying to dynamically update their records. + + :param realm: A realm of the of the client + :param reverse_zone: Name of the actual zone. All clients with IPs in this + sub-domain will be allowed to perform changes + :param rrtypes: A list of resource records types that client shall be + allowed to update + """ + policy_element = "grant %(realm)s krb5-subdomain %(zone)s %(rrtype)s" + policies = [ policy_element \ + % dict(realm=realm, zone=reverse_zone, rrtype=rrtype) \ + for rrtype in rrtypes ] + policy = "; ".join(policies) + policy += ";" + + return policy + def validate_rdn_param(ugettext, value): try: rdn = RDN(value) diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index caac8b4f2..24415556c 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -32,7 +32,8 @@ from ipapython import sysrestore from ipapython import ipautil from ipalib.constants import DNS_ZONE_REFRESH from ipalib.parameters import IA5Str -from ipalib.util import validate_zonemgr, normalize_zonemgr, gen_dns_update_policy +from ipalib.util import (validate_zonemgr, normalize_zonemgr, + get_dns_forward_zone_update_policy, get_dns_reverse_zone_update_policy) from ipapython.ipa_log_manager import * import ipalib @@ -185,7 +186,7 @@ def read_reverse_zone(default, ip_address): def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_address=None, update_policy=None): if update_policy is None: - update_policy = gen_dns_update_policy(api.env.realm) + update_policy = get_dns_forward_zone_update_policy(api.env.realm) if zonemgr is None: zonemgr = 'hostmaster.%s' % name @@ -229,7 +230,7 @@ def add_reverse_zone(zone, ns_hostname=None, ns_ip_address=None, ns_replicas=[], update_policy=None, dns_backup=None): zone = normalize_zone(zone) if update_policy is None: - update_policy = "grant %s krb5-subdomain %s PTR;" % (api.env.realm, zone) + update_policy = get_dns_reverse_zone_update_policy(api.env.realm, zone) if ns_hostname is None: # automatically retrieve list of DNS masters diff --git a/ipaserver/install/plugins/dns.py b/ipaserver/install/plugins/dns.py index 928ecc06e..29b71dd9d 100644 --- a/ipaserver/install/plugins/dns.py +++ b/ipaserver/install/plugins/dns.py @@ -70,9 +70,9 @@ class update_dnszones(PostUpdate): # do not open zone transfers by default update['idnsallowtransfer'] = u'none;' - old_policy = util.gen_dns_update_policy(api.env.realm, ('A', 'AAAA')) + old_policy = util.get_dns_forward_zone_update_policy(api.env.realm, ('A', 'AAAA')) if zone.get('idnsupdatepolicy', [''])[0] == old_policy: - update['idnsupdatepolicy'] = util.gen_dns_update_policy(\ + update['idnsupdatepolicy'] = util.get_dns_forward_zone_update_policy(\ api.env.realm) if update: diff --git a/tests/test_xmlrpc/test_dns_plugin.py b/tests/test_xmlrpc/test_dns_plugin.py index 532961039..ab1d4f0be 100644 --- a/tests/test_xmlrpc/test_dns_plugin.py +++ b/tests/test_xmlrpc/test_dns_plugin.py @@ -145,6 +145,10 @@ class test_dns(Declarative): 'idnssoaexpire': [fuzzy_digits], 'idnssoaminimum': [fuzzy_digits], 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' + u'grant %(realm)s krb5-self * AAAA; ' + u'grant %(realm)s krb5-self * SSHFP;' + % dict(realm=api.env.realm)], 'idnsallowtransfer': [u'none;'], 'idnsallowquery': [u'any;'], 'objectclass': [u'top', u'idnsrecord', u'idnszone'], @@ -202,6 +206,10 @@ class test_dns(Declarative): 'idnssoaexpire': [fuzzy_digits], 'idnssoaminimum': [fuzzy_digits], 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' + u'grant %(realm)s krb5-self * AAAA; ' + u'grant %(realm)s krb5-self * SSHFP;' + % dict(realm=api.env.realm)], 'idnsallowtransfer': [u'none;'], 'idnsallowquery': [u'any;'], 'objectclass': [u'top', u'idnsrecord', u'idnszone'], @@ -293,6 +301,8 @@ class test_dns(Declarative): 'idnssoaexpire': [fuzzy_digits], 'idnssoaminimum': [fuzzy_digits], 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' + % dict(realm=api.env.realm, zone=revdnszone1)], 'idnsallowtransfer': [u'none;'], 'idnsallowquery': [u'any;'], 'objectclass': [u'top', u'idnsrecord', u'idnszone'], @@ -929,6 +939,8 @@ class test_dns(Declarative): 'idnssoaexpire': [fuzzy_digits], 'idnssoaminimum': [fuzzy_digits], 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' + % dict(realm=api.env.realm, zone=revdnszone1)], 'idnsallowtransfer': [u'none;'], 'idnsallowquery': [u'any;'], 'objectclass': [u'top', u'idnsrecord', u'idnszone'], |