On Thu, 2014-06-19 at 18:37 +0200, Martin Basti wrote:
> On Fri, 2014-06-13 at 09:55 +0200, Martin Basti wrote:
> > On Thu, 2014-06-12 at 16:20 +0200, Martin Basti wrote:
> > > On Thu, 2014-06-12 at 13:17 +0200, Petr Vobornik wrote:
> > > > On 9.6.2014 17:28, Martin Basti wrote:
> > > > > Ticket: https://fedorahosted.org/freeipa/ticket/4328
> > > > >
> > > > > Petr please make the WebUI patch review (0062) :-)
> > > > >
> > > > > Patches attached.
> > > > >
> > > > 
> > > > Patch #0059: LGTM
> > > > 
> > > > Patch #0060:
> > > > 
> > > > 1. Please add `pattern_errmsg` to `salt` part of nsec3param. Otherwise 
> > > > you get general "Text does not match field pattern" error message in 
> > > > Web UI.
> > > > 
> > > I will add the message.
> > > 
> > > > 2. Could be in one if:
> > > > +            if nsec3params is not None:
> > > > +                if len(nsec3params) > 1:
> > > > 
> > > > Maybe I'm missing something. But why does the dns plugin code use 
> > > > following all over the place:
> > > > 
> > > >          try:
> > > >              nsec3params = rrattrs['nsec3paramrecord']
> > > >          except KeyError:
> > > >              pass
> > > >          else:
> > > >              if nsec3params is not None:
> > > > 
> > > > instead of:
> > > > 
> > > >      nsec3params = rrattrs.get('nsec3paramrecord')
> > > >      if nsec3params is not None:
> > > > 
> > > > btw you use both patterns in the patch.
> > > I will use shorten form, I wrote it in the same way as the other code in
> > > the block was written, that's why.
> > > 
> > > > 
> > > > Patch #0061: ACK
> > > > 
> > > > 
> > > > Patch #0062:
> > > > 
> > > > 3. Why are there the idnafsdbrec1 variables?
> > > > 
> > > It was replace for NSEC records, which are not supported anymore.
> > > Now I realize, there is wrong description, so the idnafsbrec1 variable
> > > is not needed.
> > > I will remove it.
> > > 
> > > > 4. related to ^^:
> > > > ./ipatests/test_xmlrpc/test_dns_plugin.py:199:33: E231 missing 
> > > > whitespace after ','
> > > > 
> > > > 
> > > > Patch #0063: LGTM
> > > > IDK if they work because I'm experiencing some weird issues with 
> > > > xmlrpc_tests in general.
> > > I had troubles only with permission tests, but all DNS test worked fine 
> > > for me.
> > > 
> > > Thank you for review.
> > > 
> > Updated patches attached.
> > 
> > _______________________________________________
> > Freeipa-devel mailing list
> > Freeipa-devel@redhat.com
> > https://www.redhat.com/mailman/listinfo/freeipa-devel
> 
> Rebased patches attached
> _______________________________________________
> Freeipa-devel mailing list
> Freeipa-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/freeipa-devel

Updated patch attached, fixed missing update permission
-- 
Martin^2 Basti
>From 87ee296b5f90d35605df65f96e6274e89f864d22 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Tue, 3 Jun 2014 11:21:10 +0200
Subject: [PATCH 2/5] DNSSEC: added NSEC3PARAM record type

Ticket: https://fedorahosted.org/freeipa/ticket/4328
---
 ACI.txt                     |  4 ++--
 API.txt                     | 12 ++++++++--
 VERSION                     |  4 ++--
 install/share/60ipadns.ldif |  3 ++-
 install/share/dns.ldif      |  2 +-
 ipalib/plugins/dns.py       | 54 ++++++++++++++++++++++++++++++++++++++++-----
 6 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/ACI.txt b/ACI.txt
index cd19fb90fdd0ac1947393aabfd667e46a6f015fc..d3bcef17ea83c9ec6234a741bd9c6294b845a322 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -23,11 +23,11 @@ aci: (targetattr = "idnsallowsyncptr || idnsforwarders || idnsforwardpolicy || i
 dn: cn=System: Add DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example
 aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Add DNS Entries";allow (add) groupdn = "ldap:///cn=System: Add DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=System: Read DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsrecord || nxtrecord || objectclass || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || txtrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Read DNS Entries";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || objectclass || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || txtrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Read DNS Entries";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=System: Remove DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example
 aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Remove DNS Entries";allow (delete) groupdn = "ldap:///cn=System: Remove DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsrecord || nxtrecord || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || txtrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Update DNS Entries";allow (write) groupdn = "ldap:///cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || txtrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example";)(version 3.0;acl "permission:System: Update DNS Entries";allow (write) groupdn = "ldap:///cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=System: Read Group Membership,cn=permissions,cn=pbac,dc=ipa,dc=example
 aci: (targetattr = "member || memberhost || memberof || memberuid || memberuser")(targetfilter = "(objectclass=ipausergroup)")(version 3.0;acl "permission:System: Read Group Membership";allow (compare,read,search) userdn = "ldap:///all";;)
 dn: cn=System: Read Groups,cn=permissions,cn=pbac,dc=ipa,dc=example
diff --git a/API.txt b/API.txt
index 2af0a824aa4256891d0caaaa4b0b61611a0d81e3..5a542a452aa21c7ece9eabcff7cc7ccf4af83da4 100644
--- a/API.txt
+++ b/API.txt
@@ -799,7 +799,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: dnsrecord_add
-args: 2,92,3
+args: 2,96,3
 arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
 arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
 option: Str('a6_part_data', attribute=False, cli_name='a6_data', multivalue=False, option_group=u'A6 Record', required=False)
@@ -866,6 +866,10 @@ option: Str('naptr_part_replacement', attribute=False, cli_name='naptr_replaceme
 option: Str('naptr_part_service', attribute=False, cli_name='naptr_service', multivalue=False, option_group=u'NAPTR Record', required=False)
 option: NAPTRRecord('naptrrecord', attribute=True, cli_name='naptr_rec', csv=True, multivalue=True, option_group=u'NAPTR Record', required=False)
 option: DNSNameParam('ns_part_hostname', attribute=False, cli_name='ns_hostname', multivalue=False, option_group=u'NS Record', required=False)
+option: Int('nsec3param_part_algorithm', attribute=False, cli_name='nsec3param_algorithm', maxvalue=255, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Int('nsec3param_part_flags', attribute=False, cli_name='nsec3param_flags', default=0, maxvalue=255, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Int('nsec3param_part_iterations', attribute=False, cli_name='nsec3param_iterations', maxvalue=65535, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Str('nsec3param_part_salt', attribute=False, cli_name='nsec3param_salt', default=u'-', minlength=1, multivalue=False, option_group=u'NSEC3PARAM Record', pattern='^([0-9a-fA-F]+|-)$', required=False)
 option: NSEC3PARAMRecord('nsec3paramrecord', attribute=True, cli_name='nsec3param_rec', csv=True, multivalue=True, option_group=u'NSEC3PARAM Record', required=False)
 option: NSEC3Record('nsec3record', attribute=True, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=u'NSEC3 Record', required=False)
 option: NSECRecord('nsecrecord', attribute=True, cli_name='nsec_rec', csv=True, multivalue=True, option_group=u'NSEC Record', required=False)
@@ -1005,7 +1009,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: dnsrecord_mod
-args: 2,92,3
+args: 2,96,3
 arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
 arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('a6_part_data', attribute=False, autofill=False, cli_name='a6_data', multivalue=False, option_group=u'A6 Record', required=False)
@@ -1070,6 +1074,10 @@ option: Str('naptr_part_replacement', attribute=False, autofill=False, cli_name=
 option: Str('naptr_part_service', attribute=False, autofill=False, cli_name='naptr_service', multivalue=False, option_group=u'NAPTR Record', required=False)
 option: NAPTRRecord('naptrrecord', attribute=True, autofill=False, cli_name='naptr_rec', csv=True, multivalue=True, option_group=u'NAPTR Record', required=False)
 option: DNSNameParam('ns_part_hostname', attribute=False, autofill=False, cli_name='ns_hostname', multivalue=False, option_group=u'NS Record', required=False)
+option: Int('nsec3param_part_algorithm', attribute=False, autofill=False, cli_name='nsec3param_algorithm', maxvalue=255, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Int('nsec3param_part_flags', attribute=False, autofill=False, cli_name='nsec3param_flags', default=0, maxvalue=255, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Int('nsec3param_part_iterations', attribute=False, autofill=False, cli_name='nsec3param_iterations', maxvalue=65535, minvalue=0, multivalue=False, option_group=u'NSEC3PARAM Record', required=False)
+option: Str('nsec3param_part_salt', attribute=False, autofill=False, cli_name='nsec3param_salt', default=u'-', minlength=1, multivalue=False, option_group=u'NSEC3PARAM Record', pattern='^([0-9a-fA-F]+|-)$', required=False)
 option: NSEC3PARAMRecord('nsec3paramrecord', attribute=True, autofill=False, cli_name='nsec3param_rec', csv=True, multivalue=True, option_group=u'NSEC3PARAM Record', required=False)
 option: NSEC3Record('nsec3record', attribute=True, autofill=False, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=u'NSEC3 Record', required=False)
 option: NSECRecord('nsecrecord', attribute=True, autofill=False, cli_name='nsec_rec', csv=True, multivalue=True, option_group=u'NSEC Record', required=False)
diff --git a/VERSION b/VERSION
index 77324e7fb68c1b6912e4198045a5f5e81b6419eb..04dc4ae9e8aaf575f01ce92f3173e3f0098799dd 100644
--- a/VERSION
+++ b/VERSION
@@ -89,5 +89,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=91
-# Last change: mbasti - Removed records: SIG, NSEC, KEY, RRSIG
+IPA_API_VERSION_MINOR=92
+# Last change: mbasti - New record type added: NSEC3PARAM
diff --git a/install/share/60ipadns.ldif b/install/share/60ipadns.ldif
index 724524ea7e3c2709642798a13854d79d2af2e7fd..190be11d702b3c8994a0b2c46252e4b41f1b450b 100644
--- a/install/share/60ipadns.ldif
+++ b/install/share/60ipadns.ldif
@@ -26,6 +26,7 @@ attributeTypes: (1.3.6.1.4.1.2428.20.1.43 NAME 'dSRecord' DESC 'Delegation Signe
 attributeTypes: (1.3.6.1.4.1.2428.20.1.44 NAME 'sSHFPRecord' DESC 'SSH Key Fingerprint, draft-ietf-secsh-dns-05.txt' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 attributeTypes: (1.3.6.1.4.1.2428.20.1.46 NAME 'rRSIGRecord' DESC 'RRSIG, RFC 3755' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 attributeTypes: (1.3.6.1.4.1.2428.20.1.47 NAME 'nSECRecord' DESC 'NSEC, RFC 3755' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+attributeTypes: (1.3.6.1.4.1.2428.20.1.51 NAME 'nSEC3PARAMRecord' DESC 'RFC 5155' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
 attributeTypes: (0.9.2342.19200300.100.1.26 NAME 'aRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 attributeTypes: (0.9.2342.19200300.100.1.29 NAME 'nSRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 attributeTypes: (0.9.2342.19200300.100.1.31 NAME 'cNAMERecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
@@ -50,7 +51,7 @@ attributeTypes: ( 2.16.840.1.113730.3.8.5.15 NAME 'idnsForwarders' DESC 'list of
 attributeTypes: ( 2.16.840.1.113730.3.8.5.16 NAME 'idnsZoneRefresh' DESC 'zone refresh interval' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'IPA v2' )
 attributeTypes: ( 2.16.840.1.113730.3.8.5.17 NAME 'idnsPersistentSearch' DESC 'allow persistent searches' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'IPA v2' )
 attributeTypes: ( 2.16.840.1.113730.3.8.5.18 NAME 'idnsSecInlineSigning' DESC 'allow inline DNSSEC signing' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'IPA v4' )
-objectClasses: ( 2.16.840.1.113730.3.8.6.0 NAME 'idnsRecord' DESC 'dns Record, usually a host' SUP top STRUCTURAL MUST idnsName MAY ( idnsAllowDynUpdate $ dNSTTL $ dNSClass $ aRecord $ aAAARecord $ a6Record $ nSRecord $ cNAMERecord $ pTRRecord $ sRVRecord $ tXTRecord $ mXRecord $ mDRecord $ hInfoRecord $ mInfoRecord $ aFSDBRecord $ SigRecord $ KeyRecord $ LocRecord $ nXTRecord $ nAPTRRecord $ kXRecord $ certRecord $ dNameRecord $ dSRecord $ sSHFPRecord $ rRSIGRecord $ nSECRecord ) )
+objectClasses: ( 2.16.840.1.113730.3.8.6.0 NAME 'idnsRecord' DESC 'dns Record, usually a host' SUP top STRUCTURAL MUST idnsName MAY ( idnsAllowDynUpdate $ dNSTTL $ dNSClass $ aRecord $ aAAARecord $ a6Record $ nSRecord $ cNAMERecord $ pTRRecord $ sRVRecord $ tXTRecord $ mXRecord $ mDRecord $ hInfoRecord $ mInfoRecord $ aFSDBRecord $ SigRecord $ KeyRecord $ LocRecord $ nXTRecord $ nAPTRRecord $ kXRecord $ certRecord $ dNameRecord $ dSRecord $ sSHFPRecord $ rRSIGRecord $ nSECRecord $ nSEC3PARAMRecord ) )
 objectClasses: ( 2.16.840.1.113730.3.8.6.1 NAME 'idnsZone' DESC 'Zone class' SUP idnsRecord STRUCTURAL MUST ( idnsZoneActive $ idnsSOAmName $ idnsSOArName $ idnsSOAserial $ idnsSOArefresh $ idnsSOAretry $ idnsSOAexpire $ idnsSOAminimum ) MAY ( idnsUpdatePolicy $ idnsAllowQuery $ idnsAllowTransfer $ idnsAllowSyncPTR $ idnsForwardPolicy $ idnsForwarders $ idnsSecInlineSigning ) )
 objectClasses: ( 2.16.840.1.113730.3.8.6.2 NAME 'idnsConfigObject' DESC 'DNS global config options' STRUCTURAL MAY ( idnsForwardPolicy $ idnsForwarders $ idnsAllowSyncPTR $ idnsZoneRefresh $ idnsPersistentSearch ) )
 objectClasses: ( 2.16.840.1.113730.3.8.12.18 NAME 'ipaDNSZone' SUP top AUXILIARY MUST idnsName MAY managedBy X-ORIGIN 'IPA v3' )
diff --git a/install/share/dns.ldif b/install/share/dns.ldif
index a2b126714acb30b9a6283db58728fac8fe340678..73ed0dc4762f0ffc70e35678c58b5e6581be3b53 100644
--- a/install/share/dns.ldif
+++ b/install/share/dns.ldif
@@ -7,7 +7,7 @@ cn: dns
 aci: (targetattr = "*")(version 3.0; acl "Allow read access"; allow (read,search,compare) groupdn = "ldap:///cn=Read DNS Entries,cn=permissions,cn=pbac,$SUFFIX" or userattr = "parent[0,1].managedby#GROUPDN";)
 aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX";)(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)
 aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX";)(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)
-aci: (targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX";)(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
+aci: (targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || nsec3paramrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX";)(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
 
 dn: cn=DNS Administrators,cn=privileges,cn=pbac,$SUFFIX
 changetype: add
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 2b6d37e93898cde279f7f207ab2b6941b82b3326..98b3c8244c8b81e9914d13b30cebb618238fce5c 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -1225,7 +1225,34 @@ class NSEC3Record(DNSRecord):
 class NSEC3PARAMRecord(DNSRecord):
     rrtype = 'NSEC3PARAM'
     rfc = 5155
-    supported = False
+    parts = (
+        Int('algorithm',
+            label=_('Algorithm'),
+            minvalue=0,
+            maxvalue=255,
+            ),
+        Int('flags',
+            label=_('Flags'),
+            minvalue=0,
+            maxvalue=255,
+            default=0,
+            ),
+        Int('iterations',
+            label=_('Iterations'),
+            minvalue=0,
+            maxvalue=65535,
+            ),
+        Str('salt',
+            label=_('Salt'),
+            doc=_('A hexadecimal salt value. Requires hexadecimal digits '
+                  'or hyphen ("-") if no salt is required'),
+            minlength=1,
+            default=u'-',  # no salt
+            pattern=r'^([0-9a-fA-F]+|-)$',
+            pattern_errmsg=u'only hexadecimal digits or single hyphen ("-") '
+                           u'are allowed'
+            ),
+    )
 
 def _validate_naptr_flags(ugettext, flags):
     allowed_flags = u'SAUP'
@@ -2063,8 +2090,9 @@ class dnszone(DNSZoneBase):
                 'idnssoaserial', 'idnsupdatepolicy', 'idnszoneactive',
                 'keyrecord', 'kxrecord', 'locrecord', 'managedby', 'mdrecord',
                 'minforecord', 'mxrecord', 'naptrrecord', 'nsecrecord',
-                'nsrecord', 'nxtrecord', 'ptrrecord', 'rrsigrecord',
-                'sigrecord', 'srvrecord', 'sshfprecord', 'txtrecord',
+                'nsec3paramrecord', 'nsrecord', 'nxtrecord', 'ptrrecord',
+                'rrsigrecord', 'sigrecord', 'srvrecord', 'sshfprecord',
+                'txtrecord',
             },
             'replaces_system': ['Read DNS Entries'],
             'default_privileges': {'DNS Administrators', 'DNS Servers'},
@@ -2095,8 +2123,9 @@ class dnszone(DNSZoneBase):
                 'idnssoaserial', 'idnsupdatepolicy', 'idnszoneactive',
                 'keyrecord', 'kxrecord', 'locrecord', 'managedby', 'mdrecord',
                 'minforecord', 'mxrecord', 'naptrrecord', 'nsecrecord',
-                'nsrecord', 'nxtrecord', 'ptrrecord', 'rrsigrecord',
-                'sigrecord', 'srvrecord', 'sshfprecord', 'txtrecord',
+                'nsec3paramrecord', 'nsrecord', 'nxtrecord', 'ptrrecord',
+                'rrsigrecord', 'sigrecord', 'srvrecord', 'sshfprecord',
+                'txtrecord',
             },
             'replaces': [
                 '(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX";)(version 3.0;acl "permission:update dns entries";allow (write) groupdn = "ldap:///cn=update dns entries,cn=permissions,cn=pbac,$SUFFIX";)',
@@ -2405,6 +2434,13 @@ class dnsrecord(LDAPObject):
         for nsrecord in nsrecords:
             check_ns_rec_resolvable(keys[0], DNSName(nsrecord))
 
+    def _nsec3paramrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        assert isinstance(dn, DN)
+        nsec3paramrecord = entry_attrs.get('nsec3paramrecord')
+        if nsec3paramrecord and not self.is_pkey_zone_record(*keys):
+            raise errors.ValidationError(name='nsec3paramrecord',
+                        error=unicode(_('must be in zone record')))
+
     def _idnsname_pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
         if keys[-1].is_absolute():
@@ -2691,6 +2727,14 @@ class dnsrecord(LDAPObject):
                                   'NS record except when located in a zone root '
                                   'record (RFC 6672, section 2.3)'))
 
+        # NSEC3PARAM record validation
+        nsec3params = rrattrs.get('nsec3paramrecord')
+        if nsec3params is not None:
+            if len(nsec3params) > 1:
+                raise errors.ValidationError(name='nsec3paramrecord',
+                    error=_('Only one NSEC3PARAM record is '
+                            'allowed per zone'))
+
     def _entry2rrsets(self, entry_attrs, dns_name, dns_domain):
         '''Convert entry_attrs to a dictionary {rdtype: rrset}.
 
-- 
1.8.3.1

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

Reply via email to