diff --git a/CHANGES b/CHANGES
index 4a7cadadbf3..80ac38a8b27 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,17 +1,28 @@
- --- 9.6-ESV-R4-P3 released ---
+ --- 9.8.0-P4 released ---
3124. [bug] Use an rdataset attribute flag to indicate
negative-cache records rather than using rrtype 0;
this will prevent problems when that rrtype is
used in actual DNS packets. [RT #24777]
- --- 9.6-ESV-R4-P2 released (withdrawn) ---
+ --- 9.8.0-P3 released (withdrawn) ---
+
+3126. [security] Using DNAME record to generate replacements caused
+ RPZ to exit with a assertion failure. [RT #23766]
+
+3125. [security] Using wildcard CNAME records as a replacement with
+ RPZ caused named to exit with a assertion failure.
+ [RT #24715]
3123. [security] Change #2912 exposed a latent flaw in
dns_rdataset_totext() that could cause named to
crash with an assertion failure. [RT #24777]
- --- 9.6-ESV-R4-P1 released ---
+3115. [bug] Named could fail to return requested data when
+ following a CNAME that points into the same zone.
+ [RT #2445]
+
+ --- 9.8.0-P2 released ---
3121. [security] An authoritative name server sending a negative
response containing a very large RRset could
@@ -22,22 +33,114 @@
that validated insecure without using DLV and had
DS records in the parent zone. [RT #24631]
- --- 9.6-ESV-R4 released ---
+ --- 9.8.0-P1 released ---
- --- 9.6.3 released ---
+3100. [security] Certain response policy zone configurations could
+ trigger an INSIST when receiving a query of type
+ RRSIG. [RT #24280]
+
+ --- 9.8.0 released ---
+
+3025. [bug] Fixed a possible deadlock due to zone resigning.
+ [RT #22964]
+
+3024. [func] RTT Banding removed due to minor security increase
+ but major impact on resolver latency. [RT #23310]
+
+3023. [bug] Named could be left in an inconsistent state when
+ receiving multiple AXFR response messages that were
+ not all TSIG-signed. [RT #23254]
+
+3022. [bug] Fixed rpz SERVFAILs after failed zone transfers
+ [RT #23246]
+
+3021. [bug] Change #3010 was incomplete. [RT #22296]
+
+3020. [bug] auto-dnssec failed to correctly update the zone when
+ changing the DNSKEY RRset. [RT #23232]
+
+3019. [test] Test: check apex NSEC3 records after adding DNSKEY
+ record via UPDATE. [RT #23229]
+
+ --- 9.8.0rc1 released ---
+
+3018. [bug] Named failed to check for the "none;" acl when deciding
+ if a zone may need to be re-signed. [RT #23120]
+
+3017. [doc] dnssec-keyfromlabel -I was not properly documented.
+ [RT #22887]
+
+3016. [bug] rndc usage missing '-b'. [RT #22937]
+
+3015. [port] win32: fix IN6_IS_ADDR_LINKLOCAL and
+ IN6_IS_ADDR_SITELOCAL macros. [RT #22724]
+
+3013. [bug] The DNS64 ttl was not always being set as expected.
+ [RT #23034]
+
+3012. [bug] Remove DNSKEY TTL change pairs before generating
+ signing records for any remaining DNSKEY changes.
+ [RT #22590]
+
+3011. [func] Allow setting this in named.conf using the new
+ 'resolver-query-timeout' option, which specifies a max
+ time in seconds. 0 means 'default' and anything longer
+ than 30 will be silently set to 30. [RT #22852]
+
+3010. [bug] Fixed a bug where "rndc reconfig" stopped the timer
+ for refreshing managed-keys. [RT #22296]
3009. [bug] clients-per-query code didn't work as expected with
particular query patterns. [RT #22972]
- --- 9.6.3rc1 released ---
+ --- 9.8.0b1 released ---
+
+3008. [func] Response policy zones (RPZ) support. [RT #21726]
3007. [bug] Named failed to preserve the case of domain names in
rdata which is not compressible when writing master
files. [RT #22863]
+3006. [func] Allow dynamically generated TSIG keys to be preserved
+ across restarts of named. Initially this is for
+ TSIG keys generated using GSSAPI. [RT #22639]
+
+3005. [port] Solaris: Work around the lack of
+ gsskrb5_register_acceptor_identity() by setting
+ the KRB5_KTNAME environment variable to the
+ contents of tkey-gssapi-keytab. Also fixed
+ test errors on MacOSX. [RT #22853]
+
+3004. [func] DNS64 reverse support. [RT #22769]
+
+3003. [experimental] Added update-policy match type "external",
+ enabling named to defer the decision of whether to
+ allow a dynamic update to an external daemon.
+ (Contributed by Andrew Tridgell.) [RT #22758]
+
3002. [bug] isc_mutex_init_errcheck() failed to destroy attr.
[RT #22766]
+3001. [func] Added a default trust anchor for the root zone, which
+ can be switched on by setting "dnssec-validation auto;"
+ in the named.conf options. [RT #21727]
+
+3000. [bug] More TKEY/GSS fixes:
+ - nsupdate can now get the default realm from
+ the user's Kerberos principal
+ - corrected gsstest compilation flags
+ - improved documentation
+ - fixed some NULL dereferences
+ [RT #22795]
+
+2999. [func] Add GOST support (RFC 5933). [RT #20639]
+
+2998. [func] Add isc_task_beginexclusive and isc_task_endexclusive
+ to the task api. [RT #22776]
+
+2997. [func] named -V now reports the OpenSSL and libxml2 verions
+ it was compiled against. [RT #22687]
+
2996. [security] Temporarily disable SO_ACCEPTFILTER support.
[RT #22589]
@@ -48,13 +151,52 @@
do not use threads on earlier versions. Also kill
the unproven-pthreads, mit-pthreads, and ptl2 support.
+2993. [func] Dynamically grow adb hash tables. [RT #21186]
+
+2992. [contrib] contrib/check-secure-delegation.pl: A simple tool
+ for looking at a secure delegation. [RT #22059]
+
+2991. [contrib] contrib/zone-edit.sh: A simple zone editing tool for
+ dynamic zones. [RT #22365]
+
+2990. [bug] 'dnssec-settime -S' no longer tests prepublication
+ interval validity when the interval is set to 0.
+ [RT #22761]
+
+2989. [func] Added support for writable DLZ zones. (Contributed
+ by Andrew Tridgell of the Samba project.) [RT #22629]
+
+2988. [experimental] Added a "dlopen" DLZ driver, allowing the creation
+ of external DLZ drivers that can be loaded as
+ shared objects at runtime rather than linked with
+ named. Currently this is switched on via a
+ compile-time option, "configure --with-dlz-dlopen".
+ Note: the syntax for configuring DLZ zones
+ is likely to be refined in future releases.
+ (Contributed by Andrew Tridgell of the Samba
+ project.) [RT #22629]
+
+2987. [func] Improve ease of configuring TKEY/GSS updates by
+ adding a "tkey-gssapi-keytab" option. If set,
+ updates will be allowed with any key matching
+ a principal in the specified keytab file.
+ "tkey-gssapi-credential" is no longer required
+ and is expected to be deprecated. (Contributed
+ by Andrew Tridgell of the Samba project.)
+ [RT #22629]
+
+2986. [func] Add new zone type "static-stub". It's like a stub
+ zone, but the nameserver names and/or their IP
+ addresses are statically configured. [RT #21474]
+
+2985. [bug] Add a regression test for change #2896. [RT #21324]
+
2984. [bug] Don't run MX checks when the target of the MX record
is ".". [RT #22645]
-2817. [cleanup] Removed unnecessary isc_task_endexclusive() calls.
- [RT #20768]
+2983. [bug] Include "loadkeys" in rndc help output. [RT #22493]
- --- 9.6.3b1 released ---
+ --- 9.8.0a1 released ---
2982. [bug] Reference count dst keys. dst_key_attach() can be used
increment the reference count.
@@ -63,206 +205,36 @@
always call dst_key_free() rather than setting it
to NULL on success. [RT #22672]
+2981. [func] Partial DNS64 support (AAAA synthesis). [RT #21991]
+
+2980. [bug] named didn't properly handle UPDATES that changed the
+ TTL of the NSEC3PARAM RRset. [RT #22363]
+
2979. [bug] named could deadlock during shutdown if two
"rndc stop" commands were issued at the same
time. [RT #22108]
2978. [port] hpux: look for [RT #21919]
+2977. [bug] 'nsupdate -l' report if the session key is missing.
+ [RT #21670]
+
2976. [bug] named could die on exit after negotiating a GSS-TSIG
key. [RT #22573]
-2975. [bug] rbtdb.c:cleanup_dead_nodes_callback() aquired the
+2975. [bug] rbtdb.c:cleanup_dead_nodes_callback() acquired the
wrong lock which could lead to server deadlock.
[RT #22614]
-2965. [func] Test HMAC functions using test data from RFC 2104 and
- RFC 4634. [RT #21702]
+2974. [bug] Some valid UPDATE requests could fail due to a
+ consistency check examining the existing version
+ of the zone rather than the new version resulting
+ from the UPDATE. [RT #22413]
-2960. [func] Check that named accepts non-authoritative answers.
- [RT #21594]
-
-2959. [func] Check that named starts with a missing masterfile.
- [RT #22076]
-
-2957. [bug] entropy_get() and entropy_getpseudo() failed to match
- the API for RAND_bytes() and RAND_pseudo_bytes()
- respectively. [RT #21962]
-
-2956. [port] Enable atomic operations on the PowerPC64. [RT #21899]
-
-2954. [bug] contrib: dlz_mysql_driver.c bad error handling on
- build_sqldbinstance failure. [RT #21623]
-
-2953. [bug] Silence spurious "expected covering NSEC3, got an
- exact match" message when returning a wildcard
- no data response. [RT #21744]
-
-2950. [bug] named failed to perform a SOA up to date check when
- falling back to TCP on UDP timeouts when
- ixfr-from-differences was set. [RT #21595]
-
-2946. [doc] Document the default values for the minimum and maximum
- zone refresh and retry values in the ARM. [RT #21886]
-
-2945. [doc] Update empty-zones list in ARM. [RT #21772]
-
-2944. [maint] Remove ORCHID prefix from built in empty zones.
- [RT #21772]
-
-2942. [contrib] zone2sqlite failed to setup the entropy sources.
- [RT #21610]
-
-2941. [bug] sdb and sdlz (dlz's zone database) failed to support
- DNAME at the zone apex. [RT #21610]
-
-2935. [bug] nsupdate: improve 'file not found' error message.
- [RT #21871]
-
-2934. [bug] Use ANSI C compliant shift range in lib/isc/entropy.c.
- [RT #21871]
-
-2933. [bug] 'dig +nsid' used stack memory after it went out of
- scope. This could potentially result in a unknown,
- potentially malformed, EDNS option being sent instead
- of the desired NSID option. [RT #21781]
-
-2932. [cleanup] Corrected a numbering error in the "dnssec" test.
- [RT #21597]
-
-2931. [bug] Temporarily and partially disable change 2864
- because it would cause infinite attempts of RRSIG
- queries. This is an urgent care fix; we'll
- revisit the issue and complete the fix later.
- [RT #21710]
-
-2929. [bug] Improved handling of GSS security contexts:
- - added LRU expiration for generated TSIGs
- - added the ability to use a non-default realm
- - added new "realm" keyword in nsupdate
- - limited lifetime of generated keys to 1 hour
- or the lifetime of the context (whichever is
- smaller)
- [RT #19737]
-
-2923. [bug] 'dig +trace' could drop core after "connection
- timeout". [RT #21514]
-
-2922. [contrib] Update zkt to version 1.0.
-
-2918. [maint] Add AAAA address for I.ROOT-SERVERS.NET.
-
-2916. [func] Add framework to use IPv6 in tests.
- fd92:7065:b8e:ffff::1 ... fd92:7065:b8e:ffff::7
-
-2915. [cleanup] Be smarter about which objects we attempt to compile
- based on configure options. [RT #21444]
-
-2912. [func] Windows clients don't like UPDATE responses that clear
- the zone section. [RT #20986]
-
-2911. [bug] dnssec-signzone didn't handle out of zone records well.
- [RT #21367]
-
-2910. [func] Sanity check Kerberos credentials. [RT #20986]
-
-2908. [bug] It was possible for re-signing to stop after removing
- a DNSKEY. [RT #21384]
-
-2905. [port] aix: set use_atomic=yes with native compiler.
- [RT #21402]
-
-2904. [bug] When using DLV, sub-zones of the zones in the DLV,
- could be incorrectly marked as insecure instead of
- secure leading to negative proofs failing. This was
- a unintended outcome from change 2890. [RT# 21392]
-
-2901. [port] Use AC_C_FLEXIBLE_ARRAY_MEMBER. [RT #21316]
-
-2899. [port] win32: Support linking against OpenSSL 1.0.0.
-
-2898. [bug] nslookup leaked memory when -domain=value was
- specified. [RT #21301]
-
-2894. [contrib] DLZ LDAP support now use '$' not '%'. [RT #21294]
-
-2891. [maint] Update empty-zones list to match
- draft-ietf-dnsop-default-local-zones-13. [RT# 21099]
-
-2889. [bug] Elements of the grammar where not properly reported.
- [RT #21046]
-
-2888. [bug] Only the first EDNS option was displayed. [RT #21273]
-
-2885. [bug] Improve -fno-strict-aliasing support probing in
- configure. [RT #21080]
-
-2884. [bug] Insufficient validation in dns_name_getlabelsequence().
- [RT #21283]
-
-2883. [bug] 'dig +short' failed to handle really large datasets.
- [RT #21113]
-
-2882. [bug] Remove memory context from list of active contexts
- before clearing 'magic'. [RT #21274]
-
-2881. [bug] Reduce the amount of time the rbtdb write lock
- is held when closing a version. [RT #21198]
-
-2879. [contrib] DLZ bdbhpt driver fails to close correct cursor.
- [RT #21106]
-
-2877. [bug] The validator failed to skip obviously mismatching
- RRSIGs. [RT #21138]
-
-2875. [bug] dns_time64_fromtext() could accept non digits.
- [RT #21033]
-
-2874. [bug] Cache lack of EDNS support only after the server
- successfully responds to the query using plain DNS.
- [RT #20930]
-
-2870. [maint] Add AAAA address for L.ROOT-SERVERS.NET.
-
-2868. [cleanup] Run "make clean" at the end of configure to ensure
- any changes made by configure are integrated.
- Use --with-make-clean=no to disable. [RT #20994]
-
-2867. [bug] Don't set GSS_C_SEQUENCE_FLAG as Windows DNS servers
- don't like it. [RT #20986]
-
-2866. [bug] Windows does not like the TSIG name being compressed.
- [RT #20986]
-
-2865. [bug] memset to zero event.data. [RT #20986]
-
-2864. [bug] Direct SIG/RRSIG queries were not handled correctly.
- [RT #21050]
-
-2863. [port] linux: disable IPv6 PMTUD and use network minimum MTU.
- [RT #21056]
-
-2862. [bug] nsupdate didn't default to the parent zone when
- updating DS records. [RT #20896]
-
-2859. [bug] When cancelling validation it was possible to leak
- memory. [RT #20800]
-
-2858. [bug] RTT estimates were not being adjusted on ICMP errors.
- [RT #20772]
-
-2857. [bug] named-checkconf did not fail on a bad trusted key.
- [RT #20705]
-
-2856. [bug] The size of a memory allocation was not always properly
- recorded. [RT #20927]
-
-2853. [bug] add_sigs() could run out of scratch space. [RT #21015]
-
-2851. [doc] nslookup.1, removed from the docbook
- source as it produced bad nroff. [RT #21007]
-
- --- 9.6-ESV-R3 released ---
+2973. [bug] bind.keys.h was being removed by the "make clean"
+ at the end of configure resulting in build failures
+ where there is very old version of perl installed.
+ Move it to "make maintainer-clean". [RT #22230]
2972. [bug] win32: address windows socket errors. [RT #21906]
@@ -299,13 +271,44 @@
justified character with a non zero width,
(e.g. "%-1c"). [RT #22270]
-2964. [bug] view->queryacl was being overloaded. Seperate the
- usage into view->queryacl, view->cacheacl and
- view->queryonacl. [RT #22114]
+2965. [func] Test HMAC functions using test data from RFC 2104 and
+ RFC 4634. [RT #21702]
+
+2964. [placeholder]
+
+2963. [security] The allow-query acl was being applied instead of the
+ allow-query-cache acl to cache lookups. [RT #22114]
2962. [port] win32: add more dependencies to BINDBuild.dsw.
[RT #22062]
+2961. [bug] Be still more selective about the non-authoritative
+ answers we apply change 2748 to. [RT #22074]
+
+2960. [func] Check that named accepts non-authoritative answers.
+ [RT #21594]
+
+2959. [func] Check that named starts with a missing masterfile.
+ [RT #22076]
+
+2958. [bug] named failed to start with a missing master file.
+ [RT #22076]
+
+2957. [bug] entropy_get() and entropy_getpseudo() failed to match
+ the API for RAND_bytes() and RAND_pseudo_bytes()
+ respectively. [RT #21962]
+
+2956. [port] Enable atomic operations on the PowerPC64. [RT #21899]
+
+2955. [func] Provide more detail in the recursing log. [RT #22043]
+
+2954. [bug] contrib: dlz_mysql_driver.c bad error handling on
+ build_sqldbinstance failure. [RT #21623]
+
+2953. [bug] Silence spurious "expected covering NSEC3, got an
+ exact match" message when returning a wildcard
+ no data response. [RT #21744]
+
2952. [port] win32: named-checkzone and named-checkconf failed
to initialise winsock. [RT #21932]
@@ -313,12 +316,51 @@
in a optout, delegation only zone with no secure
delegations. [RT #22007]
- --- 9.6-ESV-R2 released ---
+2950. [bug] named failed to perform a SOA up to date check when
+ falling back to TCP on UDP timeouts when
+ ixfr-from-differences was set. [RT #21595]
+
+2949. [bug] dns_view_setnewzones() contained a memory leak if
+ it was called multiple times. [RT #21942]
+
+2948. [port] MacOS: provide a mechanism to configure the test
+ interfaces at reboot. See bin/tests/system/README
+ for details.
+
+2947. [placeholder]
+
+2946. [doc] Document the default values for the minimum and maximum
+ zone refresh and retry values in the ARM. [RT #21886]
+
+2945. [doc] Update empty-zones list in ARM. [RT #21772]
+
+2944. [maint] Remove ORCHID prefix from built in empty zones.
+ [RT #21772]
+
+2943. [func] Add support to load new keys into managed zones
+ without signing immediately with "rndc loadkeys".
+ Add support to link keys with "dnssec-keygen -S"
+ and "dnssec-settime -S". [RT #21351]
+
+2942. [contrib] zone2sqlite failed to setup the entropy sources.
+ [RT #21610]
+
+2941. [bug] sdb and sdlz (dlz's zone database) failed to support
+ DNAME at the zone apex. [RT #21610]
+
+2940. [port] Remove connection aborted error message on
+ Windows. [RT #21549]
2939. [func] Check that named successfully skips NSEC3 records
that fail to match the NSEC3PARAM record currently
in use. [RT# 21868]
+2938. [bug] When generating signed responses, from a signed zone
+ that uses NSEC3, named would use a uninitialised
+ pointer if it needed to skip a NSEC3 record because
+ it didn't match the selected NSEC3PARAM record for
+ zone. [RT# 21868]
+
2937. [bug] Worked around an apparent race condition in over
memory conditions. Without this fix a DNS cache DB or
ADB could incorrectly stay in an over memory state,
@@ -336,32 +378,280 @@
likely that the bug happens only when enabling threads,
but it's not confirmed yet. [RT #21818]
+2936. [func] Improved configuration syntax and multiple-view
+ support for addzone/delzone feature (see change
+ #2930). Removed "new-zone-file" option, replaced
+ with "allow-new-zones (yes|no)". The new-zone-file
+ for each view is now created automatically, with
+ a filename generated from a hash of the view name.
+ It is no longer necessary to "include" the
+ new-zone-file in named.conf; this happens
+ automatically. Zones that were not added via
+ "rndc addzone" can no longer be removed with
+ "rndc delzone". [RT #19447]
+
+2935. [bug] nsupdate: improve 'file not found' error message.
+ [RT #21871]
+
+2934. [bug] Use ANSI C compliant shift range in lib/isc/entropy.c.
+ [RT #21871]
+
+2933. [bug] 'dig +nsid' used stack memory after it went out of
+ scope. This could potentially result in a unknown,
+ potentially malformed, EDNS option being sent instead
+ of the desired NSID option. [RT #21781]
+
+2932. [cleanup] Corrected a numbering error in the "dnssec" test.
+ [RT #21597]
+
+2931. [bug] Temporarily and partially disable change 2864
+ because it would cause infinite attempts of RRSIG
+ queries. This is an urgent care fix; we'll
+ revisit the issue and complete the fix later.
+ [RT #21710]
+
+2930. [experimental] New "rndc addzone" and "rndc delzone" commads
+ allow dynamic addition and deletion of zones.
+ To enable this feature, specify a "new-zone-file"
+ option at the view or options level in named.conf.
+ Zone configuration information for the new zones
+ will be written into that file. To make the new
+ zones persist after a restart, "include" the file
+ into named.conf in the appropriate view. (Note:
+ This feature is not yet documented, and its syntax
+ is expected to change.) [RT #19447]
+
+2929. [bug] Improved handling of GSS security contexts:
+ - added LRU expiration for generated TSIGs
+ - added the ability to use a non-default realm
+ - added new "realm" keyword in nsupdate
+ - limited lifetime of generated keys to 1 hour
+ or the lifetime of the context (whichever is
+ smaller)
+ [RT #19737]
+
+2928. [bug] Be more selective about the non-authoritative
+ answer we apply change 2748 to. [RT #21594]
+
+2927. [placeholder]
+
+2926. [placeholder]
+h
2925. [bug] Named failed to accept uncachable negative responses
from insecure zones. [RT# 21555]
+2924. [func] 'rndc secroots' dump a combined summary of the
+ current managed keys combined with trusted keys.
+ [RT #20904]
+
+2923. [bug] 'dig +trace' could drop core after "connection
+ timeout". [RT #21514]
+
+2922. [contrib] Update zkt to version 1.0.
+
2921. [bug] The resolver could attempt to destroy a fetch context
too soon. [RT #19878]
+2920. [func] Allow 'filter-aaaa-on-v4' to be applied selectively
+ to IPv4 clients. New acl 'filter-aaaa' (default any).
+
+2919. [func] Add autosign-ksk and autosign-zsk virtual time tests.
+ [RT #20840]
+
+2918. [maint] Add AAAA address for I.ROOT-SERVERS.NET.
+
+2917. [func] Virtual time test framework. [RT #20801]
+
+2916. [func] Add framework to use IPv6 in tests.
+ fd92:7065:b8e:ffff::1 ... fd92:7065:b8e:ffff::7
+
+2915. [cleanup] Be smarter about which objects we attempt to compile
+ based on configure options. [RT #21444]
+
+2914. [bug] Make the "autosign" system test more portable.
+ [RT #20997]
+
+2913. [func] Add pkcs#11 system tests. [RT #20784]
+
+2912. [func] Windows clients don't like UPDATE responses that clear
+ the zone section. [RT #20986]
+
+2911. [bug] dnssec-signzone didn't handle out of zone records well.
+ [RT #21367]
+
+2910. [func] Sanity check Kerberos credentials. [RT #20986]
+
+2909. [bug] named-checkconf -p could die if "update-policy local;"
+ was specified in named.conf. [RT #21416]
+
+2908. [bug] It was possible for re-signing to stop after removing
+ a DNSKEY. [RT #21384]
+
+2907. [bug] The export version of libdns had undefined references.
+ [RT #21444]
+
+2906. [bug] Address RFC 5011 implementation issues. [RT #20903]
+
+2905. [port] aix: set use_atomic=yes with native compiler.
+ [RT #21402]
+
+2904. [bug] When using DLV, sub-zones of the zones in the DLV,
+ could be incorrectly marked as insecure instead of
+ secure leading to negative proofs failing. This was
+ a unintended outcome from change 2890. [RT# 21392]
+
+2903. [bug] managed-keys-directory missing from namedconf.c.
+ [RT #21370]
+
+2902. [func] Add regression test for change 2897. [RT #21040]
+
+2901. [port] Use AC_C_FLEXIBLE_ARRAY_MEMBER. [RT #21316]
+
2900. [bug] The placeholder negative caching element was not
properly constructed triggering a INSIST in
dns_ncache_towire(). [RT #21346]
+2899. [port] win32: Support linking against OpenSSL 1.0.0.
+
+2898. [bug] nslookup leaked memory when -domain=value was
+ specified. [RT #21301]
+
+2897. [bug] NSEC3 chains could be left behind when transitioning
+ to insecure. [RT #21040]
+
+2896. [bug] "rndc sign" failed to properly update the zone
+ when adding a DNSKEY for publication only. [RT #21045]
+
+2895. [func] genrandom: add support for the generation of multiple
+ files. [RT #20917]
+
+2894. [contrib] DLZ LDAP support now use '$' not '%'. [RT #21294]
+
+2893. [bug] Improve managed keys support. New named.conf option
+ managed-keys-directory. [RT #20924]
+
+2892. [bug] Handle REVOKED keys better. [RT #20961]
+
+2891. [maint] Update empty-zones list to match
+ draft-ietf-dnsop-default-local-zones-13. [RT# 21099]
+
2890. [bug] Handle the introduction of new trusted-keys and
DS, DLV RRsets better. [RT #21097]
-2869. [bug] Fix arguments to dns_keytable_findnextkeynode() call.
- [RT #20877]
+2889. [bug] Elements of the grammar where not properly reported.
+ [RT #21046]
- --- 9.6-ESV-R1 released ---
+2888. [bug] Only the first EDNS option was displayed. [RT #21273]
+
+2887. [bug] Report the keytag times in UTC in the .key file,
+ local time is presented as a comment within the
+ comment. [RT #21223]
+
+2886. [bug] ctime() is not thread safe. [RT #21223]
+
+2885. [bug] Improve -fno-strict-aliasing support probing in
+ configure. [RT #21080]
+
+2884. [bug] Insufficient validation in dns_name_getlabelsequence().
+ [RT #21283]
+
+2883. [bug] 'dig +short' failed to handle really large datasets.
+ [RT #21113]
+
+2882. [bug] Remove memory context from list of active contexts
+ before clearing 'magic'. [RT #21274]
+
+2881. [bug] Reduce the amount of time the rbtdb write lock
+ is held when closing a version. [RT #21198]
+
+2880. [cleanup] Make the output of dnssec-keygen and dnssec-revoke
+ consistent. [RT #21078]
+
+2879. [contrib] DLZ bdbhpt driver fails to close correct cursor.
+ [RT #21106]
+
+2878. [func] Incrementally write the master file after performing
+ a AXFR. [RT #21010]
+
+2877. [bug] The validator failed to skip obviously mismatching
+ RRSIGs. [RT #21138]
2876. [bug] Named could return SERVFAIL for negative responses
from unsigned zones. [RT #21131]
- --- 9.6-ESV released ---
+2875. [bug] dns_time64_fromtext() could accept non digits.
+ [RT #21033]
+
+2874. [bug] Cache lack of EDNS support only after the server
+ successfully responds to the query using plain DNS.
+ [RT #20930]
+
+2873. [bug] Cancelling a dynamic update via the dns/client module
+ could trigger an assertion failure. [RT #21133]
+
+2872. [bug] Modify dns/client.c:dns_client_createx() to only
+ require one of IPv4 or IPv6 rather than both.
+ [RT #21122]
+
+2871. [bug] Type mismatch in mem_api.c between the definition and
+ the header file, causing build failure with
+ --enable-exportlib. [RT #21138]
+
+2870. [maint] Add AAAA address for L.ROOT-SERVERS.NET.
+
+2869. [bug] Fix arguments to dns_keytable_findnextkeynode() call.
+ [RT #20877]
+
+2868. [cleanup] Run "make clean" at the end of configure to ensure
+ any changes made by configure are integrated.
+ Use --with-make-clean=no to disable. [RT #20994]
+
+2867. [bug] Don't set GSS_C_SEQUENCE_FLAG as Windows DNS servers
+ don't like it. [RT #20986]
+
+2866. [bug] Windows does not like the TSIG name being compressed.
+ [RT #20986]
+
+2865. [bug] memset to zero event.data. [RT #20986]
+
+2864. [bug] Direct SIG/RRSIG queries were not handled correctly.
+ [RT #21050]
+
+2863. [port] linux: disable IPv6 PMTUD and use network minimum MTU.
+ [RT #21056]
+
+2862. [bug] nsupdate didn't default to the parent zone when
+ updating DS records. [RT #20896]
+
+2861. [doc] dnssec-settime man pages didn't correctly document the
+ inactivation time. [RT #21039]
+
+2860. [bug] named-checkconf's usage was out of date. [RT #21039]
+
+2859. [bug] When cancelling validation it was possible to leak
+ memory. [RT #20800]
+
+2858. [bug] RTT estimates were not being adjusted on ICMP errors.
+ [RT #20772]
+
+2857. [bug] named-checkconf did not fail on a bad trusted key.
+ [RT #20705]
+
+2856. [bug] The size of a memory allocation was not always properly
+ recorded. [RT #20927]
+
+2855. [func] nsupdate will now preserve the entered case of domain
+ names in update requests it sends. [RT #20928]
+
+2854. [func] dig: allow the final soa record in a axfr response to
+ be suppressed, dig +onesoa. [RT #20929]
+
+2853. [bug] add_sigs() could run out of scratch space. [RT #21015]
2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]
- --- 9.6.2 released ---
+2851. [doc] nslookup.1, removed from the docbook
+ source as it produced bad nroff. [RT #21007]
2850. [bug] If isc_heap_insert() failed due to memory shortage
the heap would have corrupted entries. [RT #20951]
@@ -369,61 +659,225 @@
2849. [bug] Don't treat errors from the xml2 library as fatal.
[RT #20945]
+2848. [doc] Moved README.dnssec, README.libdns, README.pkcs11 and
+ README.rfc5011 into the ARM. [RT #20899]
+
+2847. [cleanup] Corrected usage message in dnssec-settime. [RT #20921]
+
2846. [bug] EOF on unix domain sockets was not being handled
correctly. [RT #20731]
+2845. [bug] RFC 5011 client could crash on shutdown. [RT #20903]
+
2844. [doc] notify-delay default in ARM was wrong. It should have
been five (5) seconds.
- --- 9.6.2rc1 released ---
+2843. [func] Prevent dnssec-keygen and dnssec-keyfromlabel from
+ creating key files if there is a chance that the new
+ key ID will collide with an existing one after
+ either of the keys has been revoked. (To override
+ this in the case of dnssec-keyfromlabel, use the -y
+ option. dnssec-keygen will simply create a
+ different, non-colliding key, so an override is
+ not necessary.) [RT #20838]
-2838. [func] Backport support for SHA-2 DNSSEC algorithms,
- RSASHA256 and RSASHA512, from BIND 9.7. (This
- incorporates changes 2726 and 2738 from that
- release branch.) [RT #20871]
+2842. [func] Added "smartsign" and improved "autosign" and
+ "dnssec" regression tests. [RT #20865]
+
+2841. [bug] Change 2836 was not complete. [RT #20883]
+
+2840. [bug] Temporary fixed pkcs11-destroy usage check.
+ [RT #20760]
+
+2839. [bug] A KSK revoked by named could not be deleted.
+ [RT #20881]
+
+2838. [placeholder]
2837. [port] Prevent Linux spurious warnings about fwrite().
[RT #20812]
+2836. [bug] Keys that were scheduled to become active could
+ be delayed. [RT #20874]
+
+2835. [bug] Key inactivity dates were inadvertently stored in
+ the private key file with the outdated tag
+ "Unpublish" rather than "Inactive". This has been
+ fixed; however, any existing keys that had Inactive
+ dates set will now need to have them reset, using
+ 'dnssec-settime -I'. [RT #20868]
+
+2834. [bug] HMAC-SHA* keys that were longer than the algorithm
+ digest length were used incorrectly, leading to
+ interoperability problems with other DNS
+ implementations. This has been corrected.
+ (Note: If an oversize key is in use, and
+ compatibility is needed with an older release of
+ BIND, the new tool "isc-hmac-fixup" can convert
+ the key secret to a form that will work with all
+ versions.) [RT #20751]
+
+2833. [cleanup] Fix usage messages in dnssec-keygen and dnssec-settime.
+ [RT #20851]
+
+2832. [bug] Modify "struct stat" in lib/export/samples/nsprobe.c
+ to avoid redefinition in some OSs [RT 20831]
+
2831. [security] Do not attempt to validate or cache
out-of-bailiwick data returned with a secure
answer; it must be re-fetched from its original
source and validated in that context. [RT #20819]
+2830. [bug] Changing the OPTOUT setting could take multiple
+ passes. [RT #20813]
+
+2829. [bug] Fixed potential node inconsistency in rbtdb.c.
+ [RT #20808]
+
2828. [security] Cached CNAME or DNAME RR could be returned to clients
without DNSSEC validation. [RT #20737]
2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712]
+2826. [bug] NSEC3->NSEC transitions could fail due to a lock not
+ being released. [RT #20740]
+
2825. [bug] Changing the setting of OPTOUT in a NSEC3 chain that
was in the process of being created was not properly
recorded in the zone. [RT #20786]
+2824. [bug] "rndc sign" was not being run by the correct task.
+ [RT #20759]
+
2823. [bug] rbtdb.c:getsigningtime() was missing locks. [RT #20781]
+2822. [bug] rbtdb.c:loadnode() could return the wrong result.
+ [RT #20802]
+
+2821. [doc] Add note that named-checkconf doesn't automatically
+ read rndc.key and bind.keys [RT #20758]
+
+2820. [func] Handle read access failure of OpenSSL configuration
+ file more user friendly (PKCS#11 engine patch).
+ [RT #20668]
+
2819. [cleanup] Removed unnecessary DNS_POINTER_MAXHOPS define.
[RT #20771]
2818. [cleanup] rndc could return an incorrect error code
when a zone was not found. [RT #20767]
+2817. [cleanup] Removed unnecessary isc_task_endexclusive() calls.
+ [RT #20768]
+
+2816. [bug] previous_closest_nsec() could fail to return
+ data for NSEC3 nodes [RT #29730]
+
2815. [bug] Exclusively lock the task when freezing a zone.
[RT #19838]
2814. [func] Provide a definitive error message when a master
zone is not loaded. [RT #20757]
- --- 9.6.2b1 released ---
+2813. [bug] Better handling of unreadable DNSSEC key files.
+ [RT #20710]
+
+2812. [bug] Make sure updates can't result in a zone with
+ NSEC-only keys and NSEC3 records. [RT 20748]
+
+2811. [cleanup] Add "rndc sign" to list of commands in rndc usage
+ output. [RT #20733]
+
+2810. [doc] Clarified the process of transitioning an NSEC3 zone
+ to insecure. [RT #20746]
+
+2809. [cleanup] Restored accidentally-deleted text in usage output
+ in dnssec-settime and dnssec-revoke [RT #20739]
+
+2808. [bug] Remove the attempt to install atomic.h from lib/isc.
+ atomic.h is correctly installed by the architecture
+ specific subdirectories. [RT #20722]
+
+2807. [bug] Fixed a possible ASSERT when reconfiguring zone
+ keys. [RT #20720]
+
+ --- 9.7.0rc1 released ---
+
+2806. [bug] "rdnc sign" could delay re-signing the DNSKEY
+ when it had changed. [RT #20703]
+
+2805. [bug] Fixed namespace problems encountered when building
+ external programs using non-exported BIND9 libraries
+ (i.e., built without --enable-exportlib). [RT #20679]
+
+2804. [bug] Send notifies when a zone is signed with "rndc sign"
+ or as a result of a scheduled key change. [RT #20700]
+
+2803. [port] win32: Install named-journalprint, nsec3hash, arpaname
+ and genrandom under windows. [RT #20670]
+
+2802. [cleanup] Rename journalprint to named-journalprint. [RT #20670]
+
+2801. [func] Detect and report records that are different according
+ to DNSSEC but are semantically equal according to plain
+ DNS. Apply plain DNS comparisons rather than DNSSEC
+ comparisons when processing UPDATE requests.
+ dnssec-signzone now removes such semantically duplicate
+ records prior to signing the RRset.
+
+ named-checkzone -r {ignore|warn|fail} (default warn)
+ named-compilezone -r {ignore|warn|fail} (default warn)
+
+ named.conf: check-dup-records {ignore|warn|fail};
+
+2800. [func] Reject zones which have NS records which refer to
+ CNAMEs, DNAMEs or don't have address record (class IN
+ only). Reject UPDATEs which would cause the zone
+ to fail the above checks if committed. [RT #20678]
+
+2799. [cleanup] Changed the "secure-to-insecure" option to
+ "dnssec-secure-to-insecure", and "dnskey-ksk-only"
+ to "dnssec-dnskey-kskonly", for clarity. [RT #20586]
+
+2798. [bug] Addressed bugs in managed-keys initialization
+ and rollover. [RT #20683]
2797. [bug] Don't decrement the dispatch manager's maxbuffers.
[RT #20613]
+2796. [bug] Missing dns_rdataset_disassociate() call in
+ dns_nsec3_delnsec3sx(). [RT #20681]
+
+2795. [cleanup] Add text to differentiate "update with no effect"
+ log messages. [RT #18889]
+
+2794. [bug] Install . [RT #20677]
+
+2793. [func] Add "autosign" and "metadata" tests to the
+ automatic tests. [RT #19946]
+
+2792. [func] "filter-aaaa-on-v4" can now be set in view
+ options (if compiled in). [RT #20635]
+
+2791. [bug] The installation of isc-config.sh was broken.
+ [RT #20667]
+
2790. [bug] Handle DS queries to stub zones. [RT #20440]
2789. [bug] Fixed an INSIST in dispatch.c [RT #20576]
+2788. [bug] dnssec-signzone could sign with keys that were
+ not requested [RT #20625]
+
+2787. [bug] Spurious log message when zone keys were
+ dynamically reconfigured. [RT #20659]
+
2786. [bug] Additional could be promoted to answer. [RT #20663]
+ --- 9.7.0b3 released ---
+
+2785. [bug] Revoked keys could fail to self-sign [RT #20652]
+
2784. [bug] TC was not always being set when required glue was
dropped. [RT #20655]
@@ -433,15 +887,65 @@
2782. [port] win32: use getaddrinfo() for hostname lookups.
[RT #20650]
+2781. [bug] Inactive keys could be used for signing. [RT #20649]
+
+2780. [bug] dnssec-keygen -A none didn't properly unset the
+ activation date in all cases. [RT #20648]
+
+2779. [bug] Dynamic key revocation could fail. [RT #20644]
+
+2778. [bug] dnssec-signzone could fail when a key was revoked
+ without deleting the unrevoked version. [RT #20638]
+
2777. [contrib] DLZ MYSQL auto reconnect support discovery was wrong.
+2776. [bug] Change #2762 was not correct. [RT #20647]
+
+2775. [bug] Accept RSASHA256 and RSASHA512 as NSEC3 compatible
+ in dnssec-keyfromlabel. [RT #20643]
+
+2774. [bug] Existing cache DB wasn't being reused after
+ reconfiguration. [RT #20629]
+
+2773. [bug] In autosigned zones, the SOA could be signed
+ with the KSK. [RT #20628]
+
2772. [security] When validating, track whether pending data was from
the additional section or not and only return it if
validates as secure. [RT #20438]
+2771. [bug] dnssec-signzone: DNSKEY records could be
+ corrupted when importing from key files [RT #20624]
+
+2770. [cleanup] Add log messages to resolver.c to indicate events
+ causing FORMERR responses. [RT #20526]
+
+2769. [cleanup] Change #2742 was incomplete. [RT #19589]
+
+2768. [bug] dnssec-signzone: -S no longer implies -g [RT #20568]
+
+2767. [bug] named could crash on startup if a zone was
+ configured with auto-dnssec and there was no
+ key-directory. [RT #20615]
+
+2766. [bug] isc_socket_fdwatchpoke() should only update the
+ socketmgr state if the socket is not pending on a
+ read or write. [RT #20603]
+
2765. [bug] Skip masters for which the TSIG key cannot be found.
[RT #20595]
+2764. [bug] "rndc-confgen -a" could trigger a REQUIRE. [RT #20610]
+
+2763. [bug] "rndc sign" didn't create an NSEC chain. [RT #20591]
+
+2762. [bug] DLV validation failed with a local slave DLV zone.
+ [RT #20577]
+
+2761. [cleanup] Enable internal symbol table for backtrace only for
+ systems that are known to work. Currently, BSD
+ variants, Linux and Solaris are supported. [RT# 20202]
+
2760. [cleanup] Corrected named-compilezone usage summary. [RT #20533]
2759. [doc] Add information about .jbk/.jnw files to
@@ -454,27 +958,115 @@
2757. [bug] dig: assertion failure could occur in connect
timeout. [RT #20599]
-2755. [doc] Clarify documentation of keyset- files in
- dnssec-signzone man page. [RT #19810]
+2756. [bug] Fixed corrupt logfile message in update.c. [RT# 20597]
+
+2755. [placeholder]
2754. [bug] Secure-to-insecure transitions failed when zone
was signed with NSEC3. [RT #20587]
+2753. [bug] Removed an unnecessary warning that could appear when
+ building an NSEC chain. [RT #20589]
+
+2752. [bug] Locking violation. [RT #20587]
+
+2751. [bug] Fixed a memory leak in dnssec-keyfromlabel. [RT #20588]
+
2750. [bug] dig: assertion failure could occur when a server
didn't have an address. [RT #20579]
2749. [bug] ixfr-from-differences generated a non-minimal ixfr
for NSEC3 signed zones. [RT #20452]
+2748. [func] Identify bad answers from GTLD servers and treat them
+ as referrals. [RT #18884]
+
2747. [bug] Journal roll forwards failed to set the re-signing
time of RRSIGs correctly. [RT #20541]
+2746. [port] hpux: address signed/unsigned expansion mismatch of
+ dns_rbtnode_t.nsec. [RT #20542]
+
+2745. [bug] configure script didn't probe the return type of
+ gai_strerror(3) correctly. [RT #20573]
+
+2744. [func] Log if a query was over TCP. [RT #19961]
+
2743. [bug] RRSIG could be incorrectly set in the NSEC3 record
for a insecure delegation.
+ --- 9.7.0b2 released ---
+
+2742. [cleanup] Clarify some DNSSEC-related log messages in
+ validator.c. [RT #19589]
+
+2741. [func] Allow the dnssec-keygen progress messages to be
+ suppressed (dnssec-keygen -q). Automatically
+ suppress the progress messages when stdin is not
+ a tty. [RT #20474]
+
+2740. [placeholder]
+
+2739. [cleanup] Clean up API for initializing and clearing trust
+ anchors for a view. [RT #20211]
+
+2738. [func] Add RSASHA256 and RSASHA512 tests to the dnssec system
+ test. [RT #20453]
+
+2737. [func] UPDATE requests can leak existence information.
+ [RT #17261]
+
+2736. [func] Improve the performance of NSEC signed zones with
+ more than a normal amount of glue below a delegation.
+ [RT #20191]
+
+2735. [bug] dnssec-signzone could fail to read keys
+ that were specified on the command line with
+ full paths, but weren't in the current
+ directory. [RT #20421]
+
+2734. [port] cygwin: arpaname did not compile. [RT #20473]
+
+2733. [cleanup] Clean up coding style in pkcs11-* tools. [RT #20355]
+
+2732. [func] Add optional filter-aaaa-on-v4 option, available
+ if built with './configure --enable-filter-aaaa'.
+ Filters out AAAA answers to clients connecting
+ via IPv4. (This is NOT recommended for general
+ use.) [RT #20339]
+
+2731. [func] Additional work on change 2709. The key parser
+ will now ignore unrecognized fields when the
+ minor version number of the private key format
+ has been increased. It will reject any key with
+ the major version number increased. [RT #20310]
+
+2730. [func] Have dnssec-keygen display a progress indication
+ a la 'openssl genrsa' on standard error. Note
+ when the first '.' is followed by a long stop
+ one has the choice between slow generation vs.
+ poor random quality, i.e., '-r /dev/urandom'.
+ [RT #20284]
+
2729. [func] When constructing a CNAME from a DNAME use the DNAME
TTL. [RT #20451]
+2728. [bug] dnssec-keygen, dnssec-keyfromlabel and
+ dnssec-signzone now warn immediately if asked to
+ write into a nonexistent directory. [RT #20278]
+
+2727. [func] The 'key-directory' option can now specify a relative
+ path. [RT #20154]
+
+2726. [func] Added support for SHA-2 DNSSEC algorithms,
+ RSASHA256 and RSASHA512. [RT #20023]
+
+2725. [doc] Added information about the file "managed-keys.bind"
+ to the ARM. [RT #20235]
+
+2724. [bug] Updates to a existing node in secure zone using NSEC
+ were failing. [RT #20448]
+
2723. [bug] isc_base32_totext(), isc_base32hex_totext(), and
isc_base64_totext(), didn't always mark regions of
memory as fully consumed after conversion. [RT #20445]
@@ -486,11 +1078,24 @@
2721. [port] Have dst__entropy_status() prime the random number
generator. [RT #20369]
+2720. [bug] RFC 5011 trust anchor updates could trigger an
+ assert if the DNSKEY record was unsigned. [RT #20406]
+
+2719. [func] Skip trusted/managed keys for unsupported algorithms.
+ [RT #20392]
+
2718. [bug] The space calculations in opensslrsa_todns() were
incorrect. [RT #20394]
+2717. [bug] named failed to update the NSEC/NSEC3 record when
+ the last private type record was removed as a result
+ of completing the signing the zone with a key.
+ [RT #20399]
+
2716. [bug] nslookup debug mode didn't return the ttl. [RT #20414]
+ --- 9.7.0b1 released ---
+
2715. [bug] Require OpenSSL support to be explicitly disabled.
[RT #20288]
@@ -500,19 +1105,63 @@
2713. [bug] powerpc: atomic operations missing asm("ics") /
__isync() calls.
+2712. [func] New 'auto-dnssec' zone option allows zone signing
+ to be fully automated in zones configured for
+ dynamic DNS. 'auto-dnssec allow;' permits a zone
+ to be signed by creating keys for it in the
+ key-directory and using 'rndc sign '.
+ 'auto-dnssec maintain;' allows that too, plus it
+ also keeps the zone's DNSSEC keys up to date
+ according to their timing metadata. [RT #19943]
+
+2711. [port] win32: Add the bin/pkcs11 tools into the full
+ build. [RT #20372]
+
+2710. [func] New 'dnssec-signzone -x' flag and 'dnskey-ksk-only'
+ zone option cause a zone to be signed with only KSKs
+ signing the DNSKEY RRset, not ZSKs. This reduces
+ the size of a DNSKEY answer. [RT #20340]
+
+2709. [func] Added some data fields, currently unused, to the
+ private key file format, to allow implementation
+ of explicit key rollover in a future release
+ without impairing backward or forward compatibility.
+ [RT #20310]
+
+2708. [func] Insecure to secure and NSEC3 parameter changes via
+ update are now fully supported and no longer require
+ defines to enable. We now no longer overload the
+ NSEC3PARAM flag field, nor the NSEC OPT bit at the
+ apex. Secure to insecure changes are controlled by
+ by the named.conf option 'secure-to-insecure'.
+
+ Warning: If you had previously enabled support by
+ adding defines at compile time to BIND 9.6 you should
+ ensure that all changes that are in progress have
+ completed prior to upgrading to BIND 9.7. BIND 9.7
+ is not backwards compatible.
+
+2707. [func] dnssec-keyfromlabel no longer require engine name
+ to be specified in the label if there is a default
+ engine or the -E option has been used. Also, it
+ now uses default algorithms as dnssec-keygen does
+ (i.e., RSASHA1, or NSEC3RSASHA1 if -3 is used).
+ [RT #20371]
+
2706. [bug] Loading a zone with a very large NSEC3 salt could
trigger an assert. [RT #20368]
-2705. [bug] Reconcile the XML stats version number with a later
- BIND9 release, by adding a "name" attribute to
- "cache" elements and increasing the version number
- to 2.2. (This is a minor version change, but may
- affect XML parsers if they assume the cache element
- doesn't take an attribute.)
+2705. [placeholder]
2704. [bug] Serial of dynamic and stub zones could be inconsistent
with their SOA serial. [RT #19387]
+2703. [func] Introduce an OpenSSL "engine" argument with -E
+ for all binaries which can take benefit of
+ crypto hardware. [RT #20230]
+
+2702. [func] Update PKCS#11 tools (bin/pkcs11) [RT #20225 & all]
+
2701. [doc] Correction to ARM: hmac-md5 is no longer the only
supported TSIG key algorithm. [RT #18046]
@@ -521,6 +1170,8 @@
2699. [bug] Missing lock in rbtdb.c. [RT #20037]
+2698. [placeholder]
+
2697. [port] win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and
S_IFREG are defined after including .
[RT #20309]
@@ -528,8 +1179,25 @@
2696. [bug] named failed to successfully process some valid
acl constructs. [RT #20308]
+2695. [func] DHCP/DDNS - update fdwatch code for use by
+ DHCP. Modify the api to isc_sockfdwatch_t (the
+ callback functon for isc_socket_fdwatchcreate)
+ to include information about the direction (read
+ or write) and add isc_socket_fdwatchpoke.
+ [RT #20253]
+
+2694. [bug] Reduce default NSEC3 iterations from 100 to 10.
+ [RT #19970]
+
+2693. [port] Add some noreturn attributes. [RT #20257]
+
2692. [port] win32: 32/64 bit cleanups. [RT #20335]
+2691. [func] dnssec-signzone: retain the existing NSEC or NSEC3
+ chain when re-signing a previously-signed zone.
+ Use -u to modify NSEC3 parameters or switch
+ between NSEC and NSEC3. [RT #20304]
+
2690. [bug] win32: fix isc_thread_key_getspecific() prototype.
[RT #20315]
@@ -538,25 +1206,102 @@
2688. [bug] Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT,
to decide to fetch the destination address. [RT #20305]
+2687. [bug] Fixed dnssec-signzone -S handling of revoked keys.
+ Also, added warnings when revoking a ZSK, as this is
+ not defined by protocol (but is legal). [RT #19943]
+
2686. [bug] dnssec-signzone should clean the old NSEC chain when
signing with NSEC3 and vice versa. [RT #20301]
+2685. [contrib] Update contrib/zkt to version 0.99c. [RT #20054]
+
+2684. [cleanup] dig: formalize +ad and +cd as synonyms for
+ +adflag and +cdflag. [RT #19305]
+
2683. [bug] dnssec-signzone should clean out old NSEC3 chains when
the NSEC3 parameters used to sign the zone change.
[RT #20246]
+2682. [bug] "configure --enable-symtable=all" failed to
+ build. [RT #20282]
+
2681. [bug] IPSECKEY RR of gateway type 3 was not correctly
decoded. [RT #20269]
+2680. [func] Move contrib/pkcs11-keygen to bin/pkcs11. [RT #20067]
+
+2679. [func] dig -k can now accept TSIG keys in named.conf
+ format. [RT #20031]
+
2678. [func] Treat DS queries as if "minimal-response yes;"
was set. [RT #20258]
+2677. [func] Changes to key metadata behavior:
+ - Keys without "publish" or "active" dates set will
+ no longer be used for smart signing. However,
+ those dates will be set to "now" by default when
+ a key is created; to generate a key but not use
+ it yet, use dnssec-keygen -G.
+ - New "inactive" date (dnssec-keygen/settime -I)
+ sets the time when a key is no longer used for
+ signing but is still published.
+ - The "unpublished" date (-U) is deprecated in
+ favour of "deleted" (-D).
+ [RT #20247]
+
+2676. [bug] --with-export-installdir should have been
+ --with-export-includedir. [RT #20252]
+
+2675. [bug] dnssec-signzone could crash if the key directory
+ did not exist. [RT #20232]
+
+ --- 9.7.0a3 released ---
+
+2674. [bug] "dnssec-lookaside auto;" crashed if named was built
+ without openssl. [RT #20231]
+
+2673. [bug] The managed-keys.bind zone file could fail to
+ load due to a spurious result from sync_keyzone()
+ [RT #20045]
+
2672. [bug] Don't enable searching in 'host' when doing reverse
lookups. [RT #20218]
+2671. [bug] Add support for PKCS#11 providers not returning
+ the public exponent in RSA private keys
+ (OpenCryptoki for instance) in
+ dnssec-keyfromlabel. [RT #19294]
+
2670. [bug] Unexpected connect failures failed to log enough
information to be useful. [RT #20205]
+2669. [func] Update PKCS#11 support to support Keyper HSM.
+ Update PKCS#11 patch to be against openssl-0.9.8i.
+
+2668. [func] Several improvements to dnssec-* tools, including:
+ - dnssec-keygen and dnssec-settime can now set key
+ metadata fields 0 (to unset a value, use "none")
+ - dnssec-revoke sets the revocation date in
+ addition to the revoke bit
+ - dnssec-settime can now print individual metadata
+ fields instead of always printing all of them,
+ and can print them in unix epoch time format for
+ use by scripts
+ [RT #19942]
+
+2667. [func] Add support for logging stack backtrace on assertion
+ failure (not available for all platforms). [RT #19780]
+
+2666. [func] Added an 'options' argument to dns_name_fromstring()
+ (API change from 9.7.0a2). [RT #20196]
+
+2665. [func] Clarify syntax for managed-keys {} statement, add
+ ARM documentation about RFC 5011 support. [RT #19874]
+
+2664. [bug] create_keydata() and minimal_update() in zone.c
+ didn't properly check return values for some
+ functions. [RT #19956]
+
2663. [func] win32: allow named to run as a service using
"NT AUTHORITY\LocalService" as the account. [RT #19977]
@@ -567,19 +1312,40 @@
2661. [bug] Check whether socket fd exceeds FD_SETSIZE when
creating lwres context. [RT #20029]
+2660. [func] Add a new set of DNS libraries for non-BIND9
+ applications. See README.libdns. [RT #19369]
+
2659. [doc] Clarify dnssec-keygen doc: key name must match zone
name for DNSSEC keys. [RT #19938]
+2658. [bug] dnssec-settime and dnssec-revoke didn't process
+ key file paths correctly. [RT #20078]
+
+2657. [cleanup] Lower "journal file does not exist, creating it"
+ log level to debug 1. [RT #20058]
+
2656. [func] win32: add a "tools only" check box to the installer
which causes it to only install dig, host, nslookup,
nsupdate and relevant DLLs. [RT #19998]
2655. [doc] Document that key-directory does not affect
- rndc.key. [RT #20155]
+ bind.keys, rndc.key or session.key. [RT #20155]
+
+2654. [bug] Improve error reporting on duplicated names for
+ deny-answer-xxx. [RT #20164]
2653. [bug] Treat ENGINE_load_private_key() failures as key
not found rather than out of memory. [RT #18033]
+2652. [func] Provide more detail about what record is being
+ deleted. [RT #20061]
+
+2651. [bug] Dates could print incorrectly in K*.key files on
+ 64-bit systems. [RT #20076]
+
+2650. [bug] Assertion failure in dnssec-signzone when trying
+ to read keyset-* files. [RT #20075]
+
2649. [bug] Set the domain for forward only zones. [RT #19944]
2648. [port] win32: isc_time_seconds() was broken. [RT #19900]
@@ -592,37 +1358,99 @@
2645. [port] "gcc -m32" didn't work on amd64 and x86_64 platforms
which default to 64 bits. [RT #19927]
+ --- 9.7.0a2 released ---
+
+2644. [bug] Change #2628 caused a regression on some systems;
+ named was unable to write the PID file and would
+ fail on startup. [RT #20001]
+
2643. [bug] Stub zones interacted badly with NSEC3 support.
[RT #19777]
2642. [bug] nsupdate could dump core on solaris when reading
improperly formatted key files. [RT #20015]
+2641. [bug] Fixed an error in parsing update-policy syntax,
+ added a regression test to check it. [RT #20007]
+
2640. [security] A specially crafted update packet will cause named
to exit. [RT #20000]
2639. [bug] Silence compiler warnings in gssapi code. [RT #19954]
+2638. [bug] Install arpaname. [RT #19957]
+
2637. [func] Rationalize dnssec-signzone's signwithkey() calling.
[RT #19959]
+2636. [func] Simplify zone signing and key maintenance with the
+ dnssec-* tools. Major changes:
+ - all dnssec-* tools now take a -K option to
+ specify a directory in which key files will be
+ stored
+ - DNSSEC can now store metadata indicating when
+ they are scheduled to be published, activated,
+ revoked or removed; these values can be set by
+ dnssec-keygen or overwritten by the new
+ dnssec-settime command
+ - dnssec-signzone -S (for "smart") option reads key
+ metadata and uses it to determine automatically
+ which keys to publish to the zone, use for
+ signing, revoke, or remove from the zone
+ [RT #19816]
+
2635. [bug] isc_inet_ntop() incorrectly handled 0.0/16 addresses.
[RT #19716]
+2634. [port] win32: Add support for libxml2, enable
+ statschannel. [RT #19773]
+
2633. [bug] Handle 15 bit rand() functions. [RT #19783]
2632. [func] util/kit.sh: warn if documentation appears to be out of
date. [RT #19922]
+2631. [bug] Handle "//", "/./" and "/../" in mkdirpath().
+ [RT #19926 ]
+
+2630. [func] Improved syntax for DDNS autoconfiguration: use
+ "update-policy local;" to switch on local DDNS in a
+ zone. (The "ddns-autoconf" option has been removed.)
+ [RT #19875]
+
+2629. [port] Check for seteuid()/setegid(), use setresuid()/
+ setresgid() if not present. [RT #19932]
+
+2628. [port] linux: Allow /var/run/named/named.pid to be opened
+ at startup with reduced capabilities in operation.
+ [RT #19884]
+
+2627. [bug] Named aborted if the same key was included in
+ trusted-keys more than once. [RT #19918]
+
+2626. [bug] Multiple trusted-keys could trigger an assertion
+ failure. [RT #19914]
+
2625. [bug] Missing UNLOCK in rbtdb.c. [RT #19865]
-2623. [bug] Named started seaches for DS non-optimally. [RT #19915]
+2624. [func] 'named-checkconf -p' will print out the parsed
+ configuration. [RT #18871]
-2621. [doc] Made copyright boilterplate consistent. [RT #19833]
+2623. [bug] Named started searches for DS non-optimally. [RT #19915]
+
+2622. [bug] Printing of named.conf grammar was broken. [RT #19919]
+
+2621. [doc] Made copyright boilerplate consistent. [RT #19833]
2620. [bug] Delay thawing the zone until the reload of it has
completed successfully. [RT #19750]
+2619. [func] Add support for RFC 5011, automatic trust anchor
+ maintenance. The new "managed-keys" statement can
+ be used in place of "trusted-keys" for zones which
+ support this protocol. (Note: this syntax is
+ expected to change prior to 9.7.0 final.) [RT #19248]
+
2618. [bug] The sdb and sdlz db_interator_seek() methods could
loop infinitely. [RT #19847]
@@ -638,11 +1466,33 @@
2614. [port] win32: 'named -v' should automatically be executed
in the foreground. [RT #19844]
-2613. [bug] Option argument validation was missing for
- dnssec-dsfromkey. [RT #19828]
+2613. [placeholder]
+
+ --- 9.7.0a1 released ---
+
+2612. [func] Add default values for the arguments to
+ dnssec-keygen. Without arguments, it will now
+ generate a 1024-bit RSASHA1 zone-signing key,
+ or with the -f KSK option, a 2048-bit RSASHA1
+ key-signing key. [RT #19300]
+
+2611. [func] Add -l option to dnssec-dsfromkey to generate
+ DLV records instead of DS records. [RT #19300]
2610. [port] sunos: Change #2363 was not complete. [RT #19796]
+2609. [func] Simplify the configuration of dynamic zones:
+ - add ddns-confgen command to generate
+ configuration text for named.conf
+ - add zone option "ddns-autoconf yes;", which
+ causes named to generate a TSIG session key
+ and allow updates to the zone using that key
+ - add '-l' (localhost) option to nsupdate, which
+ causes nsupdate to connect to a locally-running
+ named process using the session key generated
+ by named
+ [RT #19284]
+
2608. [func] Perform post signing verification checks in
dnssec-signzone. These can be disabled with -P.
@@ -652,27 +1502,6 @@
self signed. That all records in the zone are signed
by the algorithm. [RT #19653]
-2601. [doc] Mention file creation mode mask in the
- named manual page.
-
-2593. [bug] Improve a corner source of SERVFAILs [RT #19632]
-
-2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
- [RT #19626]
-
-2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
- Requires MySQL 5.0.19 or later. [RT #19084]
-
-2580. [bug] UpdateRej statistics counter could be incremented twice
- for one rejection. [RT #19476]
-
-2533. [doc] ARM: document @ (at-sign). [RT #17144]
-
-2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
- function. [RT #18582]
-
- --- 9.6.1 released ---
-
2607. [bug] named could incorrectly delete NSEC3 records for
empty nodes when processing a update request.
[RT #19749]
@@ -683,6 +1512,11 @@
2605. [bug] Accept DS responses from delegation only zones.
[RT # 19296]
+2604. [func] Add support for DNS rebinding attack prevention through
+ new options, deny-answer-addresses and
+ deny-answer-aliases. Based on contributed code from
+ JD Nurmi, Google. [RT #18192]
+
2603. [port] win32: handle .exe extension of named-checkzone and
named-comilezone argv[0] names under windows.
[RT #19767]
@@ -690,11 +1524,17 @@
2602. [port] win32: fix debugging command line build of libisccfg.
[RT #19767]
- --- 9.6.1rc1 released ---
+2601. [doc] Mention file creation mode mask in the
+ named manual page.
+
+2600. [doc] ARM: miscellaneous reformatting for different
+ page widths. [RT #19574]
2599. [bug] Address rapid memory growth when validation fails.
[RT #19654]
+2598. [func] Reserve the -F flag. [RT #19657]
+
2597. [bug] Handle a validation failure with a insecure delegation
from a NSEC3 signed master/slave zone. [RT #19464]
@@ -704,16 +1544,31 @@
2595. [bug] Fix unknown extended rcodes in dig. [RT #19625]
+2594. [func] Have rndc warn if using its default configuration
+ file when the key file also exists. [RT #19424]
+
+2593. [bug] Improve a corner source of SERVFAILs [RT #19632]
+
2592. [bug] Treat "any" as a type in nsupdate. [RT #19455]
2591. [bug] named could die when processing a update in
removed_orphaned_ds(). [RT #19507]
+2590. [func] Report zone/class of "update with no effect".
+ [RT #19542]
+
+2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
+ [RT #19626]
+
2588. [bug] SO_REUSEADDR could be set unconditionally after failure
of bind(2) call. This should be rare and mostly
harmless, but may cause interference with other
processes that happen to use the same port. [RT #19642]
+2587. [func] Improve logging by reporting serial numbers for
+ when zone serial has gone backwards or unchanged.
+ [RT #19506]
+
2586. [bug] Missing cleanup of SIG rdataset in searching a DLZ DB
or SDB. [RT #19577]
@@ -730,28 +1585,57 @@
2582. [bug] Don't emit warning log message when we attempt to
remove non-existent journal. [RT #19516]
+2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
+ Requires MySQL 5.0.19 or later. [RT #19084]
+
+2580. [bug] UpdateRej statistics counter could be incremented twice
+ for one rejection. [RT #19476]
+
2579. [bug] DNSSEC lookaside validation failed to handle unknown
algorithms. [RT #19479]
2578. [bug] Changed default sig-signing-type to 65534, because
65535 turns out to be reserved. [RT #19477]
-2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash.
- [RT #18837]
-
- --- 9.6.1b1 released ---
-
2577. [doc] Clarified some statistics counters. [RT #19454]
2576. [bug] NSEC record were not being correctly signed when
a zone transitions from insecure to secure.
Handle such incorrectly signed zones. [RT #19114]
+2575. [func] New functions dns_name_fromstring() and
+ dns_name_tostring(), to simplify conversion
+ of a string to a dns_name structure and vice
+ versa. [RT #19451]
+
2574. [doc] Document nsupdate -g and -o. [RT #19351]
2573. [bug] Replacing a non-CNAME record with a CNAME record in a
single transaction in a signed zone failed. [RT #19397]
+2572. [func] Simplify DLV configuration, with a new option
+ "dnssec-lookaside auto;" This is the equivalent
+ of "dnssec-lookaside . trust-anchor dlv.isc.org;"
+ plus setting a trusted-key for dlv.isc.org.
+
+ Note: The trusted key is hard-coded into named,
+ but is also stored in (and can be overridden
+ by) $sysconfdir/bind.keys. As the ISC DLV key
+ rolls over it can be kept up to date by replacing
+ the bind.keys file with a key downloaded from
+ https://www.isc.org/solutions/dlv. [RT #18685]
+
+2571. [func] Add a new tool "arpaname" which translates IP addresses
+ to the corresponding IN-ADDR.ARPA or IP6.ARPA name.
+ [RT #18976]
+
+2570. [func] Log the destination address the query was sent to.
+ [RT #19209]
+
+2569. [func] Move journalprint, nsec3hash, and genrandom
+ commands from bin/tests into bin/tools;
+ "make install" will put them in $sbindir. [RT #19301]
+
2568. [bug] Report when the write to indicate a otherwise
successful start fails. [RT #19360]
@@ -760,6 +1644,15 @@
dnssec-dsfromkey could miss write errors.
[RT #19360]
+2566. [cleanup] Clarify logged message when an insecure DNSSEC
+ response arrives from a zone thought to be secure:
+ "insecurity proof failed" instead of "not
+ insecure". [RT #19400]
+
+2565. [func] Add support for HIP record. Includes new functions
+ dns_rdata_hip_first(), dns_rdata_hip_next()
+ and dns_rdata_hip_current(). [RT #19384]
+
2564. [bug] Only take EDNS fallback steps when processing timeouts.
[RT #19405]
@@ -776,6 +1669,10 @@
2559. [bug] dnssec-dsfromkey could compute bad DS records when
reading from a K* files. [RT #19357]
+2558. [func] Set the ownership of missing directories created
+ for pid-file if -u has been specified on the command
+ line. [RT #19328]
+
2557. [cleanup] PCI compliance:
* new libisc log module file
* isc_dir_chroot() now also changes the working
@@ -787,6 +1684,9 @@
error checks in the correct order resulting in the
wrong error code sometimes being returned. [RT #19249]
+2555. [func] dig: when emitting a hex dump also display the
+ corresponding characters. [RT #19258]
+
2554. [bug] Validation of uppercase queries from NSEC3 zones could
fail. [RT #19297]
@@ -810,6 +1710,10 @@
function isc_mem_reallocate() was introduced to address
this bug. [RT #19313]
+2546. [func] Add --enable-openssl-hash configure flag to use
+ OpenSSL (in place of internal routine) for hash
+ functions (MD5, SHA[12] and HMAC). [RT #18815]
+
2545. [doc] ARM: Legal hostname checking (check-names) is
for SRV RDATA too. [RT #19304]
@@ -822,6 +1726,8 @@
2541. [bug] Conditionally update dispatch manager statistics.
[RT #19247]
+2540. [func] Add a nibble mode to $GENERATE. [RT #18872]
+
2539. [security] Update the interaction between recursion, allow-query,
allow-query-cache and allow-recursion. [RT #19198]
@@ -829,7 +1735,7 @@
especially with threads and smaller max-cache-size
values. [RT #19240]
-2537. [experimental] Added more statistics counters including those on socket
+2537. [func] Added more statistics counters including those on socket
I/O events and query RTT histograms. [RT #18802]
2536. [cleanup] Silence some warnings when -Werror=format-security is
@@ -837,6 +1743,12 @@
2535. [bug] dig +showsearch and +trace interacted badly. [RT #19091]
+2534. [func] Check NAPTR records regular expressions and
+ replacement strings to ensure they are syntactically
+ valid and consistant. [RT #18168]
+
+2533. [doc] ARM: document @ (at-sign). [RT #17144]
+
2532. [bug] dig: check the question section of the response to
see if it matches the asked question. [RT #18495]
@@ -851,10 +1763,14 @@
2528. [cleanup] Silence spurious configure warning about
--datarootdir [RT #19096]
-2527. [bug] named could reuse cache on reload with
- enabling/disabling validation. [RT #19119]
+2527. [placeholder]
-2525. [experimental] New logging category "query-errors" to provide detailed
+2526. [func] New named option "attach-cache" that allows multiple
+ views to share a single cache to save memory and
+ improve lookup efficiency. Based on contributed code
+ from Barclay Osborn, Google. [RT #18905]
+
+2525. [func] New logging category "query-errors" to provide detailed
internal information about query failures, especially
about server failures. [RT #19027]
@@ -867,10 +1783,17 @@
2521. [bug] Improve epoll cross compilation support. [RT #19047]
+2520. [bug] Update xml statistics version number to 2.0 as change
+ #2388 made the schema incompatible to the previous
+ version. [RT #19080]
+
2519. [bug] dig/host with -4 or -6 didn't work if more than two
nameserver addresses of the excluded address family
preceded in resolv.conf. [RT #19081]
+2518. [func] Add support for the new CERT types from RFC 4398.
+ [RT #19077]
+
2517. [bug] dig +trace with -4 or -6 failed when it chose a
nameserver address of the excluded address type.
[RT #18843]
@@ -878,46 +1801,57 @@
2516. [bug] glue sort for responses was performed even when not
needed. [RT #19039]
+2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
+ [RT #19063]
+
2514. [bug] dig/host failed with -4 or -6 when resolv.conf contains
a nameserver of the excluded address family.
[RT #18848]
+2513. [bug] Fix windows cli build. [RT #19062]
+
+2512. [func] Print a summary of the cached records which make up
+ the negative response. [RT #18885]
+
2511. [cleanup] dns_rdata_tofmttext() add const to linebreak.
[RT #18885]
-2506. [port] solaris: Check at configure time if
- hack_shutup_pthreadonceinit is needed. [RT #19037]
-
-2505. [port] Treat amd64 similarly to x86_64 when determining
- atomic operation support. [RT #19031]
-
-2503. [port] linux: improve compatibility with Linux Standard
- Base. [RT #18793]
-
-2502. [cleanup] isc_radix: Improve compliance with coding style,
- document function in . [RT #18534]
-
- --- 9.6.0 released ---
-
-2520. [bug] Update xml statistics version number to 2.0 as change
- #2388 made the schema incompatible to the previous
- version. [RT #19080]
-
- --- 9.6.0rc2 released ---
-
-2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
- [RT #19063]
-
-2513. [bug] Fix windows cli build. [RT #19062]
-
2510. [bug] "dig +sigchase" could trigger REQUIRE failures.
[RT #19033]
2509. [bug] Specifying a fixed query source port was broken.
[RT #19051]
+2508. [placeholder]
+
+2507. [func] Log the recursion quota values when killing the
+ oldest query or refusing to recurse due to quota.
+ [RT #19022]
+
+2506. [port] solaris: Check at configure time if
+ hack_shutup_pthreadonceinit is needed. [RT #19037]
+
+2505. [port] Treat amd64 similarly to x86_64 when determining
+ atomic operation support. [RT #19031]
+
2504. [bug] Address race condition in the socket code. [RT #18899]
+2503. [port] linux: improve compatibility with Linux Standard
+ Base. [RT #18793]
+
+2502. [cleanup] isc_radix: Improve compliance with coding style,
+ document function in . [RT #18534]
+
+2501. [func] $GENERATE now supports all rdata types. Multi-field
+ rdata types need to be quoted. See the ARM for
+ details. [RT #18368]
+
+2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
+ function. [RT #18582]
+
+2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash.
+ [RT #18837]
+
--- 9.6.0rc1 released ---
2498. [bug] Removed a bogus function argument used with
diff --git a/COPYRIGHT b/COPYRIGHT
index ee90ece313e..8721ceca846 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -13,7 +13,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
-$Id: COPYRIGHT,v 1.14.176.3 2011-01-04 23:45:42 tbox Exp $
+$Id: COPYRIGHT,v 1.17 2011-01-04 23:47:13 tbox Exp $
Portions Copyright (C) 1996-2001 Nominum, Inc.
diff --git a/FAQ.xml b/FAQ.xml
index a9b2b41bbe6..4c83f764707 100644
--- a/FAQ.xml
+++ b/FAQ.xml
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
Frequently Asked Questions about BIND 9
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 00000000000..e98f9b41460
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,313 @@
+Summary of functional enhancements from prior major releases of BIND 9:
+
+BIND 9.6.0
+
+ Full NSEC3 support
+
+ Automatic zone re-signing
+
+ New update-policy methods tcp-self and 6to4-self
+
+ The BIND 8 resolver library, libbind, has been removed from the
+ BIND 9 distribution and is now available as a separate download.
+
+ Change the default pid file location from /var/run to
+ /var/run/{named,lwresd} for improved chroot/setuid support.
+
+BIND 9.5.0
+
+ GSS-TSIG support (RFC 3645).
+
+ DHCID support.
+
+ Experimental http server and statistics support for named via xml.
+
+ More detailed statistics counters including those supported in BIND 8.
+
+ Faster ACL processing.
+
+ Use Doxygen to generate internal documentation.
+
+ Efficient LRU cache-cleaning mechanism.
+
+ NSID support.
+
+BIND 9.4.0
+
+ Implemented "additional section caching (or acache)", an
+ internal cache framework for additional section content to
+ improve response performance. Several configuration options
+ were provided to control the behavior.
+
+ New notify type 'master-only'. Enable notify for master
+ zones only.
+
+ Accept 'notify-source' style syntax for query-source.
+
+ rndc now allows addresses to be set in the server clauses.
+
+ New option "allow-query-cache". This lets "allow-query"
+ be used to specify the default zone access level rather
+ than having to have every zone override the global value.
+ "allow-query-cache" can be set at both the options and view
+ levels. If "allow-query-cache" is not set then "allow-recursion"
+ is used if set, otherwise "allow-query" is used if set
+ unless "recursion no;" is set in which case "none;" is used,
+ otherwise the default (localhost; localnets;) is used.
+
+ rndc: the source address can now be specified.
+
+ ixfr-from-differences now takes master and slave in addition
+ to yes and no at the options and view levels.
+
+ Allow the journal's name to be changed via named.conf.
+
+ 'rndc notify zone [class [view]]' resend the NOTIFY messages
+ for the specified zone.
+
+ 'dig +trace' now randomly selects the next servers to try.
+ Report if there is a bad delegation.
+
+ Improve check-names error messages.
+
+ Make public the function to read a key file, dst_key_read_public().
+
+ dig now returns the byte count for axfr/ixfr.
+
+ allow-update is now settable at the options / view level.
+
+ named-checkconf now checks the logging configuration.
+
+ host now can turn on memory debugging flags with '-m'.
+
+ Don't send notify messages to self.
+
+ Perform sanity checks on NS records which refer to 'in zone' names.
+
+ New zone option "notify-delay". Specify a minimum delay
+ between sets of NOTIFY messages.
+
+ Extend adjusting TTL warning messages.
+
+ Named and named-checkzone can now both check for non-terminal
+ wildcard records.
+
+ "rndc freeze/thaw" now freezes/thaws all zones.
+
+ named-checkconf now check acls to verify that they only
+ refer to existing acls.
+
+ The server syntax has been extended to support a range of
+ servers.
+
+ Report differences between hints and real NS rrset and
+ associated address records.
+
+ Preserve the case of domain names in rdata during zone
+ transfers.
+
+ Restructured the data locking framework using architecture
+ dependent atomic operations (when available), improving
+ response performance on multi-processor machines significantly.
+ x86, x86_64, alpha, powerpc, and mips are currently supported.
+
+ UNIX domain controls are now supported.
+
+ Add support for additional zone file formats for improving
+ loading performance. The masterfile-format option in
+ named.conf can be used to specify a non-default format. A
+ separate command named-compilezone was provided to generate
+ zone files in the new format. Additionally, the -I and -O
+ options for dnssec-signzone specify the input and output
+ formats.
+
+ dnssec-signzone can now randomize signature end times
+ (dnssec-signzone -j jitter).
+
+ Add support for CH A record.
+
+ Add additional zone data constancy checks. named-checkzone
+ has extended checking of NS, MX and SRV record and the hosts
+ they reference. named has extended post zone load checks.
+ New zone options: check-mx and integrity-check.
+
+
+ edns-udp-size can now be overridden on a per server basis.
+
+ dig can now specify the EDNS version when making a query.
+
+ Added framework for handling multiple EDNS versions.
+
+ Additional memory debugging support to track size and mctx
+ arguments.
+
+ Detect duplicates of UDP queries we are recursing on and
+ drop them. New stats category "duplicates".
+
+ "USE INTERNAL MALLOC" is now runtime selectable.
+
+ The lame cache is now done on a basis
+ as some servers only appear to be lame for certain query
+ types.
+
+ Limit the number of recursive clients that can be waiting
+ for a single query () to resolve. New
+ options clients-per-query and max-clients-per-query.
+
+ dig: report the number of extra bytes still left in the
+ packet after processing all the records.
+
+ Support for IPSECKEY rdata type.
+
+ Raise the UDP recieve buffer size to 32k if it is less than 32k.
+
+ x86 and x86_64 now have seperate atomic locking implementations.
+
+ named-checkconf now validates update-policy entries.
+
+ Attempt to make the amount of work performed in a iteration
+ self tuning. The covers nodes clean from the cache per
+ iteration, nodes written to disk when rewriting a master
+ file and nodes destroyed per iteration when destroying a
+ zone or a cache.
+
+ ISC string copy API.
+
+ Automatic empty zone creation for D.F.IP6.ARPA and friends.
+ Note: RFC 1918 zones are not yet covered by this but are
+ likely to be in a future release.
+
+ New options: empty-server, empty-contact, empty-zones-enable
+ and disable-empty-zone.
+
+ dig now has a '-q queryname' and '+showsearch' options.
+
+ host/nslookup now continue (default)/fail on SERVFAIL.
+
+ dig now warns if 'RA' is not set in the answer when 'RD'
+ was set in the query. host/nslookup skip servers that fail
+ to set 'RA' when 'RD' is set unless a server is explicitly
+ set.
+
+ Integrate contibuted DLZ code into named.
+
+ Integrate contibuted IDN code from JPNIC.
+
+ libbind: corresponds to that from BIND 8.4.7.
+
+BIND 9.3.0
+
+ DNSSEC is now DS based (RFC 3658).
+ See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*.
+
+ DNSSEC lookaside validation.
+
+ check-names is now implemented.
+ rrset-order in more complete.
+
+ IPv4/IPv6 transition support, dual-stack-servers.
+
+ IXFR deltas can now be generated when loading master files,
+ ixfr-from-differences.
+
+ It is now possible to specify the size of a journal, max-journal-size.
+
+ It is now possible to define a named set of master servers to be
+ used in masters clause, masters.
+
+ The advertised EDNS UDP size can now be set, edns-udp-size.
+
+ allow-v6-synthesis has been obsoleted.
+
+ NOTE:
+ * Zones containing MD and MF will now be rejected.
+ * dig, nslookup name. now report "Not Implemented" as
+ NOTIMP rather than NOTIMPL. This will have impact on scripts
+ that are looking for NOTIMPL.
+
+ libbind: corresponds to that from BIND 8.4.5.
+
+BIND 9.2.0
+
+ The size of the cache can now be limited using the
+ "max-cache-size" option.
+
+ The server can now automatically convert RFC1886-style recursive
+ lookup requests into RFC2874-style lookups, when enabled using the
+ new option "allow-v6-synthesis". This allows stub resolvers that
+ support AAAA records but not A6 record chains or binary labels to
+ perform lookups in domains that make use of these IPv6 DNS
+ features.
+
+ Performance has been improved.
+
+ The man pages now use the more portable "man" macros rather than
+ the "mandoc" macros, and are installed by "make install".
+
+ The named.conf parser has been completely rewritten. It now
+ supports "include" directives in more places such as inside "view"
+ statements, and it no longer has any reserved words.
+
+ The "rndc status" command is now implemented.
+
+ rndc can now be configured automatically.
+
+ A BIND 8 compatible stub resolver library is now included in
+ lib/bind.
+
+ OpenSSL has been removed from the distribution. This means that to
+ use DNSSEC, OpenSSL must be installed and the --with-openssl option
+ must be supplied to configure. This does not apply to the use of
+ TSIG, which does not require OpenSSL.
+
+ The source distribution now builds on Windows. See
+ win32utils/readme1.txt and win32utils/win32-build.txt for details.
+
+ This distribution also includes a new lightweight stub
+ resolver library and associated resolver daemon that fully
+ support forward and reverse lookups of both IPv4 and IPv6
+ addresses. This library is considered experimental and
+ is not a complete replacement for the BIND 8 resolver library.
+ Applications that use the BIND 8 res_* functions to perform
+ DNS lookups or dynamic updates still need to be linked against
+ the BIND 8 libraries. For DNS lookups, they can also use the
+ new "getrrsetbyname()" API.
+
+ BIND 9.2 is capable of acting as an authoritative server
+ for DNSSEC secured zones. This functionality is believed to
+ be stable and complete except for lacking support for
+ verifications involving wildcard records in secure zones.
+
+ When acting as a caching server, BIND 9.2 can be configured
+ to perform DNSSEC secure resolution on behalf of its clients.
+ This part of the DNSSEC implementation is still considered
+ experimental. For detailed information about the state of the
+ DNSSEC implementation, see the file doc/misc/dnssec.
+
+ There are a few known bugs:
+
+ On some systems, IPv6 and IPv4 sockets interact in
+ unexpected ways. For details, see doc/misc/ipv6.
+ To reduce the impact of these problems, the server
+ no longer listens for requests on IPv6 addresses
+ by default. If you need to accept DNS queries over
+ IPv6, you must specify "listen-on-v6 { any; };"
+ in the named.conf options statement.
+
+ FreeBSD prior to 4.2 (and 4.2 if running as non-root)
+ and OpenBSD prior to 2.8 log messages like
+ "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device".
+ This is due to a bug in "/dev/random" and impacts the
+ server's DNSSEC support.
+
+ OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and
+ OS X 10.2 (Darwin 6.0) reports errors like
+ "fcntl(3, F_SETFL, 4): Operation not supported by device".
+ This is due to a bug in "/dev/random" and impacts the
+ server's DNSSEC support.
+
+ --with-libtool does not work on AIX.
+
+ A bug in some versions of the Microsoft DNS server can cause zone
+ transfers from a BIND 9 server to a W2K server to fail. For details,
+ see the "Zone Transfers" section in doc/misc/migration.
diff --git a/KNOWN-DEFECTS b/KNOWN-DEFECTS
deleted file mode 100644
index 83d71759740..00000000000
--- a/KNOWN-DEFECTS
+++ /dev/null
@@ -1,15 +0,0 @@
-dnssec-signzone was designed so that it could sign a zone partially, using
-only a subset of the DNSSEC keys needed to produce a fully-signed zone.
-This permits a zone administrator, for example, to sign a zone with one
-key on one machine, move the resulting partially-signed zone to a second
-machine, and sign it again with a second key.
-
-An unfortunate side-effect of this flexibility is that dnssec-signzone
-does not check to make sure it's signing a zone with any valid keys at
-all. An attempt to sign a zone without any keys will appear to succeed,
-producing a "signed" zone with no signatures. There is no warning issued
-when a zone is not signed.
-
-This will be corrected in a future release. In the meantime, ISC
-recommends examining the output of dnssec-signzone to confirm that
-the zone is properly signed by all keys before using it.
diff --git a/Makefile.in b/Makefile.in
index e4d56396da2..95944d9fa4f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.52.48.2 2009-02-20 23:47:23 tbox Exp $
+# $Id: Makefile.in,v 1.58 2009-11-26 20:52:44 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -21,13 +21,13 @@ top_srcdir = @top_srcdir@
@BIND9_VERSION@
-SUBDIRS = make lib bin doc
+SUBDIRS = make lib bin doc @LIBEXPORT@
TARGETS =
MANPAGES = isc-config.sh.1
-
+
HTMLPAGES = isc-config.sh.html
-
+
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
@@ -54,7 +54,8 @@ installdirs:
install:: isc-config.sh installdirs
${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir}
- ${INSTALL_DATA} ${srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${top_srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${top_srcdir}/bind.keys ${DESTDIR}${sysconfdir}
tags:
rm -f TAGS
diff --git a/NSEC3-NOTES b/NSEC3-NOTES
deleted file mode 100644
index 3f8d8f905c0..00000000000
--- a/NSEC3-NOTES
+++ /dev/null
@@ -1,128 +0,0 @@
-
- DNSSEC and UPDATE
-
- Converting from insecure to secure
-
-As of BIND 9.6.0 it is possible to move a zone between being insecure
-to secure and back again. A secure zone can be using NSEC or NSEC3.
-
-To move a zone from insecure to secure you need to configure named
-so that it can see the K* files which contain the public and private
-parts of the keys that will be used to sign the zone. These files
-will have been generated by dnssec-keygen. You can do this by
-placing them in the key-directory as specified in named.conf.
-
- zone example.net {
- type master;
- allow-update { .... };
- file "dynamic/example.net/example.net";
- key-directory "dynamic/example.net";
- };
-
-Assuming one KSK and one ZSK DNSKEY key have been generated. Then
-this will cause the zone to be signed with the ZSK and the DNSKEY
-RRset to be signed with the KSK DNSKEY. A NSEC chain will also be
-generated as part of the initial signing process.
-
- % nsupdate
- > ttl 3600
- > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
- > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
- > send
-
-While the update request will complete almost immediately the zone
-will not be completely signed until named has had time to walk the
-zone and generate the NSEC and RRSIG records. Initially the NSEC
-record at the zone apex will have the OPT bit set. When the NSEC
-chain is complete the OPT bit will be cleared. Additionally when
-the zone is fully signed the private type (default TYPE65534) records
-will have a non zero value for the final octet.
-
-The private type record has 5 octets.
- algorithm (octet 1)
- key id in network order (octet 2 and 3)
- removal flag (octet 4)
- complete flag (octet 5)
-
-If you wish to go straight to a secure zone using NSEC3 you should
-also add a NSEC3PARAM record to the update request with the flags
-field set to indicate whether the NSEC3 chain will have the OPTOUT
-bit set or not.
-
- % nsupdate
- > ttl 3600
- > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
- > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
- > update add example.net NSEC3PARAM 1 1 100 1234567890
- > send
-
-Again the update request will complete almost immediately however the
-NSEC3PARAM record will have additional flag bits set indicating that the
-NSEC3 chain is under construction. When the NSEC3 chain is complete the
-flags field will be set to zero.
-
-While the initial signing and NSEC/NSEC3 chain generation is happening
-other updates are possible.
-
- DNSKEY roll overs via UPDATE
-
-It is possible to perform key rollovers via update. You need to
-add the K* files for the new keys so that named can find them. You
-can then add the new DNSKEY RRs via update. Named will then cause
-the zone to be signed with the new keys. When the signing is
-complete the private type records will be updated so that the last
-octet is non zero.
-
-If this is for a KSK you need to inform the parent and any trust
-anchor repositories of the new KSK.
-
-You should then wait for the maximum TLL in the zone before removing the
-old DNSKEY. If it is a KSK that is being updated you also need to wait
-for the DS RRset in the parent to be updated and its TTL to expire.
-This ensures that all clients will be able to verify at least a signature
-when you remove the old DNSKEY.
-
-The old DNSKEY can be removed via UPDATE. Take care to specify
-the correct key. Named will clean out any signatures generated by
-the old key after the update completes.
-
- NSEC3PARAM rollovers via UPDATE.
-
-Add the new NSEC3PARAM record via update. When the new NSEC3 chain
-has been generated the NSEC3PARAM flag field will be zero. At this
-point you can remove the old NSEC3PARAM record. The old chain will
-be removed after the update request completes.
-
- Converting from NSEC to NSEC3
-
-To do this you just need to add a NSEC3PARAM record. When the
-conversion is complete the NSEC chain will have been removed and
-the NSEC3PARAM record will have a zero flag field. The NSEC3 chain
-will be generated before the NSEC chain is destroyed.
-
- Converting from NSEC3 to NSEC
-
-To do this remove all NSEC3PARAM records with a zero flag field. The
-NSEC chain will be generated before the NSEC3 chain is removed.
-
- Converting from secure to insecure
-
-To do this remove all the DNSKEY records. Any NSEC or NSEC3 chains
-will be removed as well as associated NSEC3PARAM records. This will
-take place after the update requests completes.
-
- Periodic re-signing.
-
-Named will periodically re-sign RRsets which have not been re-signed
-as a result of some update action. The signature lifetimes will
-be adjusted so as to spread the re-sign load over time rather than
-all at once.
-
- NSEC3 and OPTOUT
-
-Named only supports creating new NSEC3 chains where all the NSEC3
-records in the zone have the same OPTOUT state. Named supports
-UPDATES to zones where the NSEC3 records in the chain have mixed
-OPTOUT state. Named does not support changing the OPTOUT state of
-an individual NSEC3 record, the entire chain needs to be changed if
-the OPTOUT state of an individual NSEC3 needs to be changed.
diff --git a/README b/README
index 54d90fe1f22..00010c3983f 100644
--- a/README
+++ b/README
@@ -42,368 +42,95 @@ BIND 9
Stichting NLnet - NLnet Foundation
Nominum, Inc.
-BIND 9.6.3
-
- BIND 9.6.3 is a maintenance release, fixing bugs in 9.6.2.
-
-BIND 9.6.2
-
- BIND 9.6.2 is a maintenance release, fixing bugs in 9.6.1.
- It also introduces support for the SHA-2 DNSSEC algorithms,
- RSASHA256 and RSASHA512.
-
- Known issues in this release:
-
- - A validating resolver that has been incorrectly configured with
- an invalid trust anchor will be unable to resolve names covered
- by that trust anchor. In all current versions of BIND 9, such a
- resolver will also generate significant unnecessary DNS traffic
- while trying to validate. The latter problem will be addressed
- in future BIND 9 releases. In the meantime, to avoid these
- problems, exercise caution when configuring "trusted-keys":
- make sure all keys are correct and current when you add them,
- and update your configuration in a timely manner when keys
- roll over.
-
-BIND 9.6.1
-
- BIND 9.6.1 is a maintenance release, fixing bugs in 9.6.0.
-
-BIND 9.6.0
-
- BIND 9.6.0 includes a number of changes from BIND 9.5 and earlier
- releases, including:
-
- Full NSEC3 support
-
- Automatic zone re-signing
-
- New update-policy methods tcp-self and 6to4-self
-
- The BIND 8 resolver library, libbind, has been removed from the
- BIND 9 distribution and is now available as a separate download.
-
- Change the default pid file location from /var/run to
- /var/run/{named,lwresd} for improved chroot/setuid support.
-
-BIND 9.5.0
-
- BIND 9.5.0 has a number of new features over 9.4,
- including:
-
- GSS-TSIG support (RFC 3645).
-
- DHCID support.
-
- Experimental http server and statistics support for named via xml.
-
- More detailed statistics counters including those supported in BIND 8.
-
- Faster ACL processing.
-
- Use Doxygen to generate internal documentation.
-
- Efficient LRU cache-cleaning mechanism.
-
- NSID support.
-
-BIND 9.4.0
-
- BIND 9.4.0 has a number of new features over 9.3,
- including:
-
- Implemented "additional section caching (or acache)", an
- internal cache framework for additional section content to
- improve response performance. Several configuration options
- were provided to control the behavior.
-
- New notify type 'master-only'. Enable notify for master
- zones only.
-
- Accept 'notify-source' style syntax for query-source.
-
- rndc now allows addresses to be set in the server clauses.
-
- New option "allow-query-cache". This lets "allow-query"
- be used to specify the default zone access level rather
- than having to have every zone override the global value.
- "allow-query-cache" can be set at both the options and view
- levels. If "allow-query-cache" is not set then "allow-recursion"
- is used if set, otherwise "allow-query" is used if set
- unless "recursion no;" is set in which case "none;" is used,
- otherwise the default (localhost; localnets;) is used.
-
- rndc: the source address can now be specified.
-
- ixfr-from-differences now takes master and slave in addition
- to yes and no at the options and view levels.
-
- Allow the journal's name to be changed via named.conf.
-
- 'rndc notify zone [class [view]]' resend the NOTIFY messages
- for the specified zone.
-
- 'dig +trace' now randomly selects the next servers to try.
- Report if there is a bad delegation.
-
- Improve check-names error messages.
-
- Make public the function to read a key file, dst_key_read_public().
-
- dig now returns the byte count for axfr/ixfr.
-
- allow-update is now settable at the options / view level.
-
- named-checkconf now checks the logging configuration.
-
- host now can turn on memory debugging flags with '-m'.
-
- Don't send notify messages to self.
-
- Perform sanity checks on NS records which refer to 'in zone' names.
-
- New zone option "notify-delay". Specify a minimum delay
- between sets of NOTIFY messages.
-
- Extend adjusting TTL warning messages.
-
- Named and named-checkzone can now both check for non-terminal
- wildcard records.
-
- "rndc freeze/thaw" now freezes/thaws all zones.
-
- named-checkconf now check acls to verify that they only
- refer to existing acls.
-
- The server syntax has been extended to support a range of
- servers.
-
- Report differences between hints and real NS rrset and
- associated address records.
-
- Preserve the case of domain names in rdata during zone
- transfers.
-
- Restructured the data locking framework using architecture
- dependent atomic operations (when available), improving
- response performance on multi-processor machines significantly.
- x86, x86_64, alpha, powerpc, and mips are currently supported.
-
- UNIX domain controls are now supported.
-
- Add support for additional zone file formats for improving
- loading performance. The masterfile-format option in
- named.conf can be used to specify a non-default format. A
- separate command named-compilezone was provided to generate
- zone files in the new format. Additionally, the -I and -O
- options for dnssec-signzone specify the input and output
- formats.
-
- dnssec-signzone can now randomize signature end times
- (dnssec-signzone -j jitter).
-
- Add support for CH A record.
-
- Add additional zone data constancy checks. named-checkzone
- has extended checking of NS, MX and SRV record and the hosts
- they reference. named has extended post zone load checks.
- New zone options: check-mx and integrity-check.
-
-
- edns-udp-size can now be overridden on a per server basis.
-
- dig can now specify the EDNS version when making a query.
-
- Added framework for handling multiple EDNS versions.
-
- Additional memory debugging support to track size and mctx
- arguments.
-
- Detect duplicates of UDP queries we are recursing on and
- drop them. New stats category "duplicates".
-
- "USE INTERNAL MALLOC" is now runtime selectable.
-
- The lame cache is now done on a basis
- as some servers only appear to be lame for certain query
- types.
-
- Limit the number of recursive clients that can be waiting
- for a single query () to resolve. New
- options clients-per-query and max-clients-per-query.
-
- dig: report the number of extra bytes still left in the
- packet after processing all the records.
-
- Support for IPSECKEY rdata type.
-
- Raise the UDP recieve buffer size to 32k if it is less than 32k.
-
- x86 and x86_64 now have seperate atomic locking implementations.
-
- named-checkconf now validates update-policy entries.
-
- Attempt to make the amount of work performed in a iteration
- self tuning. The covers nodes clean from the cache per
- iteration, nodes written to disk when rewriting a master
- file and nodes destroyed per iteration when destroying a
- zone or a cache.
-
- ISC string copy API.
-
- Automatic empty zone creation for D.F.IP6.ARPA and friends.
- Note: RFC 1918 zones are not yet covered by this but are
- likely to be in a future release.
-
- New options: empty-server, empty-contact, empty-zones-enable
- and disable-empty-zone.
-
- dig now has a '-q queryname' and '+showsearch' options.
-
- host/nslookup now continue (default)/fail on SERVFAIL.
-
- dig now warns if 'RA' is not set in the answer when 'RD'
- was set in the query. host/nslookup skip servers that fail
- to set 'RA' when 'RD' is set unless a server is explicitly
- set.
-
- Integrate contibuted DLZ code into named.
-
- Integrate contibuted IDN code from JPNIC.
-
- libbind: corresponds to that from BIND 8.4.7.
-
-BIND 9.3.0
-
- BIND 9.3.0 has a number of new features over 9.2,
- including:
-
- DNSSEC is now DS based (RFC 3658).
- See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*.
-
- DNSSEC lookaside validation.
-
- check-names is now implemented.
- rrset-order in more complete.
-
- IPv4/IPv6 transition support, dual-stack-servers.
-
- IXFR deltas can now be generated when loading master files,
- ixfr-from-differences.
-
- It is now possible to specify the size of a journal, max-journal-size.
-
- It is now possible to define a named set of master servers to be
- used in masters clause, masters.
-
- The advertised EDNS UDP size can now be set, edns-udp-size.
-
- allow-v6-synthesis has been obsoleted.
-
- NOTE:
- * Zones containing MD and MF will now be rejected.
- * dig, nslookup name. now report "Not Implemented" as
- NOTIMP rather than NOTIMPL. This will have impact on scripts
- that are looking for NOTIMPL.
-
- libbind: corresponds to that from BIND 8.4.5.
-
-BIND 9.2.0
-
- BIND 9.2.0 has a number of new features over 9.1,
- including:
-
- - The size of the cache can now be limited using the
- "max-cache-size" option.
-
- - The server can now automatically convert RFC1886-style
- recursive lookup requests into RFC2874-style lookups,
- when enabled using the new option "allow-v6-synthesis".
- This allows stub resolvers that support AAAA records
- but not A6 record chains or binary labels to perform
- lookups in domains that make use of these IPv6 DNS
- features.
-
- - Performance has been improved.
-
- - The man pages now use the more portable "man" macros
- rather than the "mandoc" macros, and are installed
- by "make install".
-
- - The named.conf parser has been completely rewritten.
- It now supports "include" directives in more
- places such as inside "view" statements, and it no
- longer has any reserved words.
-
- - The "rndc status" command is now implemented.
-
- - rndc can now be configured automatically.
-
- - A BIND 8 compatible stub resolver library is now
- included in lib/bind.
-
- - OpenSSL has been removed from the distribution. This
- means that to use DNSSEC, OpenSSL must be installed and
- the --with-openssl option must be supplied to configure.
- This does not apply to the use of TSIG, which does not
- require OpenSSL.
-
- - The source distribution now builds on Windows.
- See win32utils/readme1.txt and win32utils/win32-build.txt
- for details.
-
- This distribution also includes a new lightweight stub
- resolver library and associated resolver daemon that fully
- support forward and reverse lookups of both IPv4 and IPv6
- addresses. This library is considered experimental and
- is not a complete replacement for the BIND 8 resolver library.
- Applications that use the BIND 8 res_* functions to perform
- DNS lookups or dynamic updates still need to be linked against
- the BIND 8 libraries. For DNS lookups, they can also use the
- new "getrrsetbyname()" API.
-
- BIND 9.2 is capable of acting as an authoritative server
- for DNSSEC secured zones. This functionality is believed to
- be stable and complete except for lacking support for
- verifications involving wildcard records in secure zones.
-
- When acting as a caching server, BIND 9.2 can be configured
- to perform DNSSEC secure resolution on behalf of its clients.
- This part of the DNSSEC implementation is still considered
- experimental. For detailed information about the state of the
- DNSSEC implementation, see the file doc/misc/dnssec.
-
- There are a few known bugs:
-
- On some systems, IPv6 and IPv4 sockets interact in
- unexpected ways. For details, see doc/misc/ipv6.
- To reduce the impact of these problems, the server
- no longer listens for requests on IPv6 addresses
- by default. If you need to accept DNS queries over
- IPv6, you must specify "listen-on-v6 { any; };"
- in the named.conf options statement.
-
- FreeBSD prior to 4.2 (and 4.2 if running as non-root)
- and OpenBSD prior to 2.8 log messages like
- "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device".
- This is due to a bug in "/dev/random" and impacts the
- server's DNSSEC support.
-
- OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and
- OS X 10.2 (Darwin 6.0) reports errors like
- "fcntl(3, F_SETFL, 4): Operation not supported by device".
- This is due to a bug in "/dev/random" and impacts the
- server's DNSSEC support.
-
- --with-libtool does not work on AIX.
-
- A bug in some versions of the Microsoft DNS server can cause zone
- transfers from a BIND 9 server to a W2K server to fail. For details,
- see the "Zone Transfers" section in doc/misc/migration.
+ For a summary of functional enhancements in previous
+ releases, see the HISTORY file.
For a detailed list of user-visible changes from
previous releases, see the CHANGES file.
+BIND 9.8.0
+
+ BIND 9.8.0 includes a number of changes from BIND 9.7 and earlier
+ releases. New features include:
+
+ - Built-in trust anchor for the root zone, which can be
+ switched on via "dnssec-validation auto;"
+ - Support for DNS64.
+ - Support for response policy zones (RPZ).
+ - Support for writable DLZ zones.
+ - Improved ease of configuration of GSS/TSIG for
+ interoperability with Active Directory
+ - Support for GOST signing algorithm for DNSSEC.
+ - Removed RTT Banding from server selection algorithm.
+ - New "static-stub" zone type.
+ - Allow configuration of resolver timeouts via
+ "resolver-query-timeout" option.
+
+BIND 9.7.0
+
+ BIND 9.7.0 includes a number of changes from BIND 9.6 and earlier
+ releases. Most are intended to simplify DNSSEC configuration.
+
+ New features include:
+
+ - Fully automatic signing of zones by "named".
+ - Simplified configuration of DNSSEC Lookaside Validation (DLV).
+ - Simplified configuration of Dynamic DNS, using the "ddns-confgen"
+ command line tool or the "local" update-policy option. (As a side
+ effect, this also makes it easier to configure automatic zone
+ re-signing.)
+ - New named option "attach-cache" that allows multiple views to
+ share a single cache.
+ - DNS rebinding attack prevention.
+ - New default values for dnssec-keygen parameters.
+ - Support for RFC 5011 automated trust anchor maintenance
+ - Smart signing: simplified tools for zone signing and key
+ maintenance.
+ - The "statistics-channels" option is now available on Windows.
+ - A new DNSSEC-aware libdns API for use by non-BIND9 applications
+ - On some platforms, named and other binaries can now print out
+ a stack backtrace on assertion failure, to aid in debugging.
+ - A "tools only" installation mode on Windows, which only installs
+ dig, host, nslookup and nsupdate.
+ - Improved PKCS#11 support, including Keyper support and explicit
+ OpenSSL engine selection.
+
+ Known issues in this release:
+
+ - In rare cases, DNSSEC validation can leak memory. When this
+ happens, it will cause an assertion failure when named exits,
+ but is otherwise harmless. A fix exists, but was too late for
+ this release; it will be included in BIND 9.7.1.
+
+ Compatibility notes:
+
+ - If you had built BIND 9.6 with any of ALLOW_NSEC3PARAM_UPDATE,
+ ALLOW_SECURE_TO_INSECURE or ALLOW_INSECURE_TO_SECURE defined, then
+ you should ensure that all changes that are in progress have
+ completed prior to upgrading to BIND 9.7. BIND 9.7 implements
+ those features in a way which is not backwards compatible.
+
+ - Prior releases had a bug which caused HMAC-SHA* keys with long
+ secrets to be used incorrectly. Fixing this bug means that older
+ versions of BIND 9 may fail to interoperate with this version
+ when using TSIG keys. If this occurs, the new "isc-hmac-fixup"
+ tool will convert a key with a long secret into a form that works
+ correctly with all versions of BIND 9. See the "isc-hmac-fixup"
+ man page for additional details.
+
+ - Revoking a DNSSEC key with "dnssec-revoke" changes its key ID.
+ It is possible for the new key ID to collide with that of a
+ different key. Newly generated keys will not have this problem,
+ as "dnssec-keygen" looks for potential collisions before
+ generating keys, but exercise caution if using key revokation
+ with keys that were generated by older versions of BIND 9. See
+ the Administrator's Reference Manual, section 4.10 ("Dynamic
+ Trust Anchor Management") for more details.
+
+ - A bug was fixed in which a key's scheduled inactivity date was
+ stored incorectly. Users who participated in the 9.7.0 BETA test
+ and had DNSSEC keys with scheduled inactivity dates will need to
+ reset those keys' dates using "dnssec-settime -I".
Building
@@ -417,7 +144,7 @@ Building
FreeBSD 4.10, 5.2.1, 6.2
HP-UX 11.11
Mac OS X 10.5
- NetBSD 3.x and 4.0-beta
+ NetBSD 3.x, 4.0-beta, 5.0-beta
OpenBSD 3.3 and up
Solaris 8, 9, 9 (x86), 10
Ubuntu 7.04, 7.10
@@ -594,6 +321,9 @@ Documentation
Frequently asked questions and their answers can be found in
FAQ.
+ Additional information on various subjects can be found
+ in the other README files.
+
Bug Reports and Mailing Lists
diff --git a/README.idnkit b/README.idnkit
deleted file mode 100644
index f5255f5f97a..00000000000
--- a/README.idnkit
+++ /dev/null
@@ -1,112 +0,0 @@
-
- BIND-9 IDN patch
-
- Japan Network Information Center (JPNIC)
-
-
-* What is this patch for?
-
-This patch adds internationalized domain name (IDN) support to BIND-9.
-You'll get internationalized version of dig/host/nslookup commands.
-
- + internationalized dig/host/nslookup
- dig/host/nslookup accepts non-ASCII domain names in the local
- codeset (such as Shift JIS, Big5 or ISO8859-1) determined by
- the locale information. The domain names are normalized and
- converted to the encoding on the DNS protocol, and sent to DNS
- servers. The replies are converted back to the local codeset
- and displayed.
-
-
-* Compilation & installation
-
-0. Prerequisite
-
-You have to build and install idnkit before building this patched version
-of bind-9.
-
-1. Running configure script
-
-Run `configure' in the top directory. See `README' for the
-configuration options.
-
-This patch adds the following 4 options to `configure'. You should
-at least specify `--with-idn' option to enable IDN support.
-
- --with-idn[=IDN_PREFIX]
- To enable IDN support, you have to specify `--with-idn' option.
- The argument IDN_PREFIX is the install prefix of idnkit. If
- IDN_PREFIX is omitted, PREFIX (derived from `--prefix=PREFIX')
- is assumed.
-
- --with-libiconv[=LIBICONV_PREFIX]
- Specify this option if idnkit you have installed links GNU
- libiconv. The argument LIBICONV_PREFIX is install prefix of
- GNU libiconv. If the argument is omitted, PREFIX (derived
- from `--prefix=PREFIX') is assumed.
-
- `--with-libiconv' is shorthand option for GNU libiconv.
-
- --with-libiconv=/usr/local
-
- This is equivalent to:
-
- --with-iconv='-L/usr/local/lib -R/usr/local/lib -liconv'
-
- `--with-libiconv' assumes that your C compiler has `-R'
- option, and that the option adds the specified run-time path
- to an executable binary. If `-R' option of your compiler has
- different meaning, or your compiler lacks the option, you
- should use `--with-iconv' option instead. Binary command
- without run-time path information might be unexecutable.
- In that case, you would see an error message like:
-
- error in loading shared libraries: libiconv.so.2: cannot
- open shared object file
-
- If both `--with-libiconv' and `--with-iconv' options are
- specified, `--with-iconv' is prior to `--with-libiconv'.
-
- --with-iconv=ICONV_LIBSPEC
- If your libc doesn't provide iconv(), you need to specify the
- library containing iconv() with this option. `ICONV_LIBSPEC'
- is the argument(s) to `cc' or `ld' to link the library, for
- example, `--with-iconv="-L/usr/local/lib -liconv"'.
- You don't need to specify the header file directory for "iconv.h"
- to the compiler, as it isn't included directly by bind-9 with
- this patch.
-
- --with-idnlib=IDN_LIBSPEC
- With this option, you can explicitly specify the argument(s)
- to `cc' or `ld' to link the idnkit's library, `libidnkit'. If
- this option is not specified, `-L${PREFIX}/lib -lidnkit' is
- assumed, where ${PREFIX} is the installation prefix specified
- with `--with-idn' option above. You may need to use this
- option to specify extra arguments, for example,
- `--with-idnlib="-L/usr/local/lib -R/usr/local/lib -lidnkit"'.
-
-Please consult `README' for other configuration options.
-
-Note that if you want to specify some extra header file directories,
-you should use the environment variable STD_CINCLUDES instead of
-CFLAGS, as described in README.
-
-2. Compilation and installation
-
-After running "configure", just do
-
- make
- make install
-
-for compiling and installing.
-
-
-* Contact information
-
-Please see http//www.nic.ad.jp/en/idn/ for the latest news
-about idnkit and this patch.
-
-Bug reports and comments on this kit should be sent to
-mdnkit-bugs@nic.ad.jp and idn-cmt@nic.ad.jp, respectively.
-
-; $Id: README.idnkit,v 1.2.762.1 2009-01-18 23:25:14 marka Exp $
diff --git a/README.pkcs11 b/README.pkcs11
deleted file mode 100644
index b58640de1c5..00000000000
--- a/README.pkcs11
+++ /dev/null
@@ -1,61 +0,0 @@
-
- BIND-9 PKCS#11 support
-
-Prerequisite
-
-The PKCS#11 support needs a PKCS#11 OpenSSL engine based on the Solaris one,
-released the 2007-11-21 for OpenSSL 0.9.8g, with a bug fix (call to free)
-and some improvements, including user friendly PIN management.
-
-Compilation
-
-"configure --with-pkcs11 ..."
-
-PKCS#11 Libraries
-
-Tested with Solaris one with a SCA board and with openCryptoki with the
-software token.
-
-OpenSSL Engines
-
-With PKCS#11 support the PKCS#11 engine is statically loaded but at its
-initialization it dynamically loads the PKCS#11 objects.
-Even the pre commands are therefore unused they are defined with:
- SO_PATH:
- define: PKCS11_SO_PATH
- default: /usr/local/lib/engines/engine_pkcs11.so
- MODULE_PATH:
- define: PKCS11_MODULE_PATH
- default: /usr/lib/libpkcs11.so
-Without PKCS#11 support, a specific OpenSSL engine can be still used
-by defining ENGINE_ID at compile time.
-
-PKCS#11 tools
-
-The contrib/pkcs11-keygen directory contains a set of experimental tools
-to handle keys stored in a Hardware Security Module at the benefit of BIND.
-
-The patch for OpenSSL 0.9.8g is in this directory. Read its README.pkcs11
-for the way to use it (these are the original notes so with the original
-path, etc. Define OPENCRYPTOKI to use it with openCryptoki.)
-
-PIN management
-
-With the just fixed PKCS#11 OpenSSL engine, the PIN should be entered
-each time it is required. With the improved engine, the PIN should be
-entered the first time it is required or can be configured in the
-OpenSSL configuration file (aka. openssl.cnf) by adding in it:
- - at the beginning:
- openssl_conf = openssl_def
- - at any place these sections:
- [ openssl_def ]
- engines = engine_section
- [ engine_section ]
- pkcs11 = pkcs11_section
- [ pkcs11_section ]
- PIN = put__your__pin__value__here
-
-Note
-
-Some names here are registered trademarks, at least Solaris is a trademark
-of Sun Microsystems Inc...
diff --git a/acconfig.h b/acconfig.h
index d64404ad1e3..d9da221f83f 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: acconfig.h,v 1.51.334.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: acconfig.h,v 1.53 2008-12-01 23:47:44 tbox Exp $ */
/*! \file */
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 1694268fb79..d263d795eb0 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,13 +13,14 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.25 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.29 2009-10-05 12:07:08 fdupont Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-SUBDIRS = named rndc dig dnssec tests nsupdate check
+SUBDIRS = named rndc dig dnssec tests tools nsupdate \
+ check confgen @PKCS11_TOOLS@
TARGETS =
@BIND9_MAKE_RULES@
diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in
index 46271c77de7..d5827dcce11 100644
--- a/bin/check/Makefile.in
+++ b/bin/check/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.32 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.36 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -32,6 +32,7 @@ CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
@@ -39,7 +40,8 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-LIBS = @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -69,14 +71,14 @@ named-checkzone.@O@: named-checkzone.c
named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \
${ISCCFGDEPLIBS} ${BIND9DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkconf.@O@ check-tool.@O@ ${BIND9LIBS} ${ISCCFGLIBS} \
- ${DNSLIBS} ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkconf.@O@ check-tool.@O@"; \
+ export LIBS0="${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkzone.@O@ check-tool.@O@ ${ISCCFGLIBS} ${DNSLIBS} \
- ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkzone.@O@ check-tool.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c
index ed9224bb9aa..4d2ca5c45ab 100644
--- a/bin/check/check-tool.c
+++ b/bin/check/check-tool.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.35.36.5 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: check-tool.c,v 1.41 2010-09-07 23:46:59 tbox Exp $ */
/*! \file */
@@ -601,8 +601,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
isc_buffer_add(&buffer, strlen(zonename));
dns_fixedname_init(&fixorigin);
origin = dns_fixedname_name(&fixorigin);
- CHECK(dns_name_fromtext(origin, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
CHECK(dns_zone_setorigin(zone, origin));
CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
CHECK(dns_zone_setfile2(zone, filename, fileformat));
diff --git a/bin/check/check-tool.h b/bin/check/check-tool.h
index f9273ff152e..4371ae29ec2 100644
--- a/bin/check/check-tool.h
+++ b/bin/check/check-tool.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.h,v 1.14.334.2 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: check-tool.h,v 1.16 2010-09-07 23:46:59 tbox Exp $ */
#ifndef CHECK_TOOL_H
#define CHECK_TOOL_H
diff --git a/bin/check/named-checkconf.8 b/bin/check/named-checkconf.8
index 71310073e8d..fabcfa916eb 100644
--- a/bin/check/named-checkconf.8
+++ b/bin/check/named-checkconf.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named-checkconf.8,v 1.30.334.1 2009-07-11 01:55:20 tbox Exp $
+.\" $Id: named-checkconf.8,v 1.33 2009-12-29 01:14:03 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,11 +33,29 @@
named\-checkconf \- named configuration file syntax checking tool
.SH "SYNOPSIS"
.HP 16
-\fBnamed\-checkconf\fR [\fB\-h\fR] [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-z\fR]
+\fBnamed\-checkconf\fR [\fB\-h\fR] [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-p\fR] [\fB\-z\fR]
.SH "DESCRIPTION"
.PP
\fBnamed\-checkconf\fR
-checks the syntax, but not the semantics, of a named configuration file.
+checks the syntax, but not the semantics, of a
+\fBnamed\fR
+configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified,
+\fI/etc/named.conf\fR
+is read by default.
+.PP
+Note: files that
+\fBnamed\fR
+reads in separate parser contexts, such as
+\fIrndc.key\fR
+and
+\fIbind.keys\fR, are not automatically read by
+\fBnamed\-checkconf\fR. Configuration errors in these files may cause
+\fBnamed\fR
+to fail to run, even if
+\fBnamed\-checkconf\fR
+was successful.
+\fBnamed\-checkconf\fR
+can be run on these files explicitly, however.
.SH "OPTIONS"
.PP
\-h
@@ -59,6 +77,13 @@ Print the version of the
program and exit.
.RE
.PP
+\-p
+.RS 4
+Print out the
+\fInamed.conf\fR
+and included files in canonical form if no errors were detected.
+.RE
+.PP
\-z
.RS 4
Perform a test load of all master zones found in
@@ -88,7 +113,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2002 Internet Software Consortium.
.br
diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c
index 20983b5b939..521ed31916c 100644
--- a/bin/check/named-checkconf.c
+++ b/bin/check/named-checkconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkconf.c,v 1.46.222.4 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: named-checkconf.c,v 1.54 2010-09-07 01:49:08 marka Exp $ */
/*! \file */
@@ -59,9 +59,12 @@ isc_log_t *logc = NULL;
} while (0)
/*% usage */
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
- fprintf(stderr, "usage: %s [-h] [-j] [-v] [-z] [-t directory] "
+ fprintf(stderr, "usage: %s [-h] [-j] [-p] [-v] [-z] [-t directory] "
"[named.conf]\n", program);
exit(1);
}
@@ -202,6 +205,24 @@ configure_zone(const char *vclass, const char *view,
return (ISC_R_FAILURE);
zfile = cfg_obj_asstring(fileobj);
+ obj = NULL;
+ if (get_maps(maps, "check-dup-records", &obj)) {
+ if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else
+ INSIST(0);
+ } else {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ }
+
obj = NULL;
if (get_maps(maps, "check-mx", &obj)) {
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
@@ -387,6 +408,15 @@ load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) {
return (result);
}
+static void
+output(void *closure, const char *text, int textlen) {
+ UNUSED(closure);
+ if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) {
+ perror("fwrite");
+ exit(1);
+ }
+}
+
/*% The main processing routine */
int
main(int argc, char **argv) {
@@ -399,10 +429,11 @@ main(int argc, char **argv) {
int exit_status = 0;
isc_entropy_t *ectx = NULL;
isc_boolean_t load_zones = ISC_FALSE;
+ isc_boolean_t print = ISC_FALSE;
isc_commandline_errprint = ISC_FALSE;
- while ((c = isc_commandline_parse(argc, argv, "dhjt:vz")) != EOF) {
+ while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) {
switch (c) {
case 'd':
debug++;
@@ -421,6 +452,10 @@ main(int argc, char **argv) {
}
break;
+ case 'p':
+ print = ISC_TRUE;
+ break;
+
case 'v':
printf(VERSION "\n");
exit(0);
@@ -485,6 +520,8 @@ main(int argc, char **argv) {
exit_status = 1;
}
+ if (print && exit_status == 0)
+ cfg_print(config, output, NULL);
cfg_obj_destroy(parser, &config);
cfg_parser_destroy(&parser);
diff --git a/bin/check/named-checkconf.docbook b/bin/check/named-checkconf.docbook
index e0c43d17118..fe12cb3ea27 100644
--- a/bin/check/named-checkconf.docbook
+++ b/bin/check/named-checkconf.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[]>
-
+
June 14, 2000
@@ -35,6 +35,7 @@
200420052007
+ 2009Internet Systems Consortium, Inc. ("ISC")
@@ -58,6 +59,7 @@
filename
+
@@ -65,8 +67,21 @@
DESCRIPTIONnamed-checkconf
- checks the syntax, but not the semantics, of a named
- configuration file.
+ checks the syntax, but not the semantics, of a
+ named configuration file. The file is parsed
+ and checked for syntax errors, along with all files included by it.
+ If no file is specified, /etc/named.conf is read
+ by default.
+
+
+ Note: files that named reads in separate
+ parser contexts, such as rndc.key and
+ bind.keys, are not automatically read
+ by named-checkconf. Configuration
+ errors in these files may cause named to
+ fail to run, even if named-checkconf was
+ successful. named-checkconf can be run
+ on these files explicitly, however.
@@ -87,8 +102,7 @@
-t directory
- Chroot to directory so that
- include
+ Chroot to directory so that include
directives in the configuration file are processed as if
run by a similarly chrooted named.
@@ -105,6 +119,16 @@
+
+ -p
+
+
+ Print out the named.conf and included files
+ in canonical form if no errors were detected.
+
+
+
+
-z
diff --git a/bin/check/named-checkconf.html b/bin/check/named-checkconf.html
index 458b486e90f..f5e4cd38511 100644
--- a/bin/check/named-checkconf.html
+++ b/bin/check/named-checkconf.html
@@ -1,5 +1,5 @@
-
+
@@ -29,17 +29,30 @@
named-checkconf
- checks the syntax, but not the semantics, of a named
- configuration file.
+ checks the syntax, but not the semantics, of a
+ named configuration file. The file is parsed
+ and checked for syntax errors, along with all files included by it.
+ If no file is specified, /etc/named.conf is read
+ by default.
+
+
+ Note: files that named reads in separate
+ parser contexts, such as rndc.key and
+ bind.keys, are not automatically read
+ by named-checkconf. Configuration
+ errors in these files may cause named to
+ fail to run, even if named-checkconf was
+ successful. named-checkconf can be run
+ on these files explicitly, however.
-
OPTIONS
+
OPTIONS
-h
@@ -47,8 +60,7 @@
-t directory
- Chroot to directory so that
- include
+ Chroot to directory so that include
directives in the configuration file are processed as if
run by a similarly chrooted named.
@@ -57,6 +69,11 @@
Print the version of the named-checkconf
program and exit.
+
-p
+
+ Print out the named.conf and included files
+ in canonical form if no errors were detected.
+
-z
Perform a test load of all master zones found in
@@ -74,21 +91,21 @@
-
RETURN VALUES
+
RETURN VALUES
named-checkconf
returns an exit status of 1 if
errors were detected and 0 otherwise.
named-checkzone
checks the syntax and integrity of a zone file. It performs the
same checks as named does when loading a
@@ -53,7 +53,7 @@
-
OPTIONS
+
OPTIONS
-d
@@ -177,6 +177,14 @@
write to standard out.
This is mandatory for named-compilezone.
+
-r mode
+
+ Check for records that are treated as different by DNSSEC but
+ are semantically equal in plain DNS.
+ Possible modes are "fail",
+ "warn" (default) and
+ "ignore".
+
-s style
Specify the style of the dumped zone file.
@@ -239,14 +247,14 @@
-
RETURN VALUES
+
RETURN VALUES
named-checkzone
returns an exit status of 1 if
errors were detected and 0 otherwise.
diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in
new file mode 100644
index 00000000000..da3587982cd
--- /dev/null
+++ b/bin/confgen/Makefile.in
@@ -0,0 +1,101 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.8 2009-12-05 23:31:40 each Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
+ ${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
+ISCCCLIBS = ../../lib/isccc/libisccc.@A@
+ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
+DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+BIND9LIBS = ../../lib/bind9/libbind9.@A@
+
+ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
+ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+DNSDEPLIBS = ../../lib/dns/libdns.@A@
+BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
+
+RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
+RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
+CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+SRCS= rndc-confgen.c ddns-confgen.c
+
+SUBDIRS = unix
+
+TARGETS = rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@
+
+MANPAGES = rndc-confgen.8 ddns-confgen.8
+
+HTMLPAGES = rndc-confgen.html ddns-confgen.html
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+UOBJS = unix/os.@O@
+
+@BIND9_MAKE_RULES@
+
+rndc-confgen.@O@: rndc-confgen.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
+ -c ${srcdir}/rndc-confgen.c
+
+ddns-confgen.@O@: ddns-confgen.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c ${srcdir}/ddns-confgen.c
+
+rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
+ export BASEOBJS="rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
+
+ddns-confgen@EXEEXT@: ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
+ export BASEOBJS="ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
+
+install:: rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@ installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} ddns-confgen@EXEEXT@ ${DESTDIR}${sbindir}
+ ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/ddns-confgen.8 ${DESTDIR}${mandir}/man8
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/bin/confgen/ddns-confgen.8 b/bin/confgen/ddns-confgen.8
new file mode 100644
index 00000000000..d69af398e61
--- /dev/null
+++ b/bin/confgen/ddns-confgen.8
@@ -0,0 +1,143 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: ddns-confgen.8,v 1.10 2009-09-19 01:14:52 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: ddns\-confgen
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: Jan 29, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DDNS\-CONFGEN" "8" "Jan 29, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+ddns\-confgen \- ddns key generation tool
+.SH "SYNOPSIS"
+.HP 13
+\fBddns\-confgen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkeyname\fR\fR] [\fB\-r\ \fR\fB\fIrandomfile\fR\fR] [\-s\ \fIname\fR | \-z\ \fIzone\fR] [\fB\-q\fR] [name]
+.SH "DESCRIPTION"
+.PP
+\fBddns\-confgen\fR
+generates a key for use by
+\fBnsupdate\fR
+and
+\fBnamed\fR. It simplifies configuration of dynamic zones by generating a key and providing the
+\fBnsupdate\fR
+and
+\fBnamed.conf\fR
+syntax that will be needed to use it, including an example
+\fBupdate\-policy\fR
+statement.
+.PP
+If a domain name is specified on the command line, it will be used in the name of the generated key and in the sample
+\fBnamed.conf\fR
+syntax. For example,
+\fBddns\-confgen example.com\fR
+would generate a key called "ddns\-key.example.com", and sample
+\fBnamed.conf\fR
+command that could be used in the zone definition for "example.com".
+.PP
+Note that
+\fBnamed\fR
+itself can configure a local DDNS key for use with
+\fBnsupdate \-l\fR.
+\fBddns\-confgen\fR
+is only needed when a more elaborate configuration is required: for instance, if
+\fBnsupdate\fR
+is to be used from a remote system.
+.SH "OPTIONS"
+.PP
+\-a \fIalgorithm\fR
+.RS 4
+Specifies the algorithm to use for the TSIG key. Available choices are: hmac\-md5, hmac\-sha1, hmac\-sha224, hmac\-sha256, hmac\-sha384 and hmac\-sha512. The default is hmac\-sha256.
+.RE
+.PP
+\-h
+.RS 4
+Prints a short summary of the options and arguments to
+\fBddns\-confgen\fR.
+.RE
+.PP
+\-k \fIkeyname\fR
+.RS 4
+Specifies the key name of the DDNS authentication key. The default is
+\fBddns\-key\fR
+when neither the
+\fB\-s\fR
+nor
+\fB\-z\fR
+option is specified; otherwise, the default is
+\fBddns\-key\fR
+as a separate label followed by the argument of the option, e.g.,
+\fBddns\-key.example.com.\fR
+The key name must have the format of a valid domain name, consisting of letters, digits, hyphens and periods.
+.RE
+.PP
+\-q
+.RS 4
+Quiet mode: Print only the key, with no explanatory text or usage examples.
+.RE
+.PP
+\-r \fIrandomfile\fR
+.RS 4
+Specifies a source of random data for generating the authorization. If the operating system does not provide a
+\fI/dev/random\fR
+or equivalent device, the default source of randomness is keyboard input.
+\fIrandomdev\fR
+specifies the name of a character device or file containing random data to be used instead of the default. The special value
+\fIkeyboard\fR
+indicates that keyboard input should be used.
+.RE
+.PP
+\-s \fIname\fR
+.RS 4
+Single host mode: The example
+\fBnamed.conf\fR
+text shows how to set an update policy for the specified
+\fIname\fR
+using the "name" nametype. The default key name is ddns\-key.\fIname\fR. Note that the "self" nametype cannot be used, since the name to be updated may differ from the key name. This option cannot be used with the
+\fB\-z\fR
+option.
+.RE
+.PP
+\-z \fIzone\fR
+.RS 4
+zone mode: The example
+\fBnamed.conf\fR
+text shows how to set an update policy for the specified
+\fIzone\fR
+using the "zonesub" nametype, allowing updates to all subdomain names within that
+\fIzone\fR. This option cannot be used with the
+\fB\-s\fR
+option.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBnsupdate\fR(1),
+\fBnamed.conf\fR(5),
+\fBnamed\fR(8),
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/confgen/ddns-confgen.c b/bin/confgen/ddns-confgen.c
new file mode 100644
index 00000000000..814a5657bb4
--- /dev/null
+++ b/bin/confgen/ddns-confgen.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ddns-confgen.c,v 1.9 2009-09-29 15:06:05 fdupont Exp $ */
+
+/*! \file */
+
+/**
+ * ddns-confgen generates configuration files for dynamic DNS. It can
+ * be used as a convenient alternative to writing the ddns.key file
+ * and the corresponding key and update-policy statements in named.conf.
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "util.h"
+#include "keygen.h"
+
+#define DEFAULT_KEYNAME "ddns-key"
+
+static char program[256];
+const char *progname;
+
+isc_boolean_t verbose = ISC_FALSE;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(int status) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(int status) {
+
+ fprintf(stderr, "\
+Usage:\n\
+ %s [-a alg] [-k keyname] [-r randomfile] [-q] [-s name | -z zone]\n\
+ -a alg: algorithm (default hmac-sha256)\n\
+ -k keyname: name of the key as it will be used in named.conf\n\
+ -r randomfile: source of random data (use \"keyboard\" for key timing)\n\
+ -s name: domain name to be updated using the created key\n\
+ -z zone: name of the zone as it will be used in named.conf\n\
+ -q: quiet mode: print the key, with no explanatory text\n",
+ progname);
+
+ exit (status);
+}
+
+int
+main(int argc, char **argv) {
+ isc_boolean_t show_final_mem = ISC_FALSE;
+ isc_boolean_t quiet = ISC_FALSE;
+ isc_buffer_t key_txtbuffer;
+ char key_txtsecret[256];
+ isc_mem_t *mctx = NULL;
+ isc_result_t result = ISC_R_SUCCESS;
+ const char *randomfile = NULL;
+ const char *keyname = NULL;
+ const char *zone = NULL;
+ const char *self_domain = NULL;
+ char *keybuf = NULL;
+ dns_secalg_t alg = DST_ALG_HMACSHA256;
+ const char *algname = alg_totext(alg);
+ int keysize = 256;
+ int len = 0;
+ int ch;
+
+ result = isc_file_progname(*argv, program, sizeof(program));
+ if (result != ISC_R_SUCCESS)
+ memcpy(program, "ddns-confgen", 13);
+ progname = program;
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((ch = isc_commandline_parse(argc, argv,
+ "a:hk:Mmr:qs:Vy:z:")) != -1) {
+ switch (ch) {
+ case 'a':
+ algname = isc_commandline_argument;
+ alg = alg_fromtext(algname);
+ if (alg == DST_ALG_UNKNOWN)
+ fatal("Unsupported algorithm '%s'", algname);
+ keysize = alg_bits(alg);
+ break;
+ case 'h':
+ usage(0);
+ case 'k':
+ case 'y':
+ keyname = isc_commandline_argument;
+ break;
+ case 'M':
+ isc_mem_debugging = ISC_MEM_DEBUGTRACE;
+ break;
+ case 'm':
+ show_final_mem = ISC_TRUE;
+ break;
+ case 'q':
+ quiet = ISC_TRUE;
+ break;
+ case 'r':
+ randomfile = isc_commandline_argument;
+ break;
+ case 's':
+ self_domain = isc_commandline_argument;
+ break;
+ case 'V':
+ verbose = ISC_TRUE;
+ break;
+ case 'z':
+ zone = isc_commandline_argument;
+ break;
+ case '?':
+ if (isc_commandline_option != '?') {
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ usage(1);
+ } else
+ usage(0);
+ break;
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ argc -= isc_commandline_index;
+ argv += isc_commandline_index;
+
+ if (self_domain != NULL && zone != NULL)
+ usage(1); /* -s and -z cannot coexist */
+
+ if (argc > 0)
+ usage(1);
+
+ DO("create memory context", isc_mem_create(0, 0, &mctx));
+
+ if (keyname == NULL) {
+ const char *suffix = NULL;
+
+ keyname = DEFAULT_KEYNAME;
+ if (self_domain != NULL)
+ suffix = self_domain;
+ else if (zone != NULL)
+ suffix = zone;
+ if (suffix != NULL) {
+ len = strlen(keyname) + strlen(suffix) + 2;
+ keybuf = isc_mem_get(mctx, len);
+ if (keybuf == NULL)
+ fatal("failed to allocate memory for keyname");
+ snprintf(keybuf, len, "%s.%s", keyname, suffix);
+ keyname = (const char *) keybuf;
+ }
+ }
+
+ isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
+
+ generate_key(mctx, randomfile, alg, keysize, &key_txtbuffer);
+
+
+ if (!quiet)
+ printf("\
+# To activate this key, place the following in named.conf, and\n\
+# in a separate keyfile on the system or systems from which nsupdate\n\
+# will be run:\n");
+
+ printf("\
+key \"%s\" {\n\
+ algorithm %s;\n\
+ secret \"%.*s\";\n\
+};\n",
+ keyname, algname,
+ (int)isc_buffer_usedlength(&key_txtbuffer),
+ (char *)isc_buffer_base(&key_txtbuffer));
+
+ if (!quiet) {
+ if (self_domain != NULL) {
+ printf("\n\
+# Then, in the \"zone\" statement for the zone containing the\n\
+# name \"%s\", place an \"update-policy\" statement\n\
+# like this one, adjusted as needed for your preferred permissions:\n\
+update-policy {\n\
+ grant %s name %s ANY;\n\
+};\n",
+ self_domain, keyname, self_domain);
+ } else if (zone != NULL) {
+ printf("\n\
+# Then, in the \"zone\" definition statement for \"%s\",\n\
+# place an \"update-policy\" statement like this one, adjusted as \n\
+# needed for your preferred permissions:\n\
+update-policy {\n\
+ grant %s zonesub ANY;\n\
+};\n",
+ zone, keyname);
+ } else {
+ printf("\n\
+# Then, in the \"zone\" statement for each zone you wish to dynamically\n\
+# update, place an \"update-policy\" statement granting update permission\n\
+# to this key. For example, the following statement grants this key\n\
+# permission to update any name within the zone:\n\
+update-policy {\n\
+ grant %s zonesub ANY;\n\
+};\n",
+ keyname);
+ }
+
+ printf("\n\
+# After the keyfile has been placed, the following command will\n\
+# execute nsupdate using this key:\n\
+nsupdate -k \n");
+
+ }
+
+ if (keybuf != NULL)
+ isc_mem_put(mctx, keybuf, len);
+
+ if (show_final_mem)
+ isc_mem_stats(mctx, stderr);
+
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/bin/confgen/ddns-confgen.docbook b/bin/confgen/ddns-confgen.docbook
new file mode 100644
index 00000000000..2b3e1c0556a
--- /dev/null
+++ b/bin/confgen/ddns-confgen.docbook
@@ -0,0 +1,218 @@
+]>
+
+
+
+
+
+ Jan 29, 2009
+
+
+
+ ddns-confgen
+ 8
+ BIND9
+
+
+
+ ddns-confgen
+ ddns key generation tool
+
+
+
+
+ 2009
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ ddns-confgen
+
+
+
+
+
+ -s name
+ -z zone
+
+
+ name
+
+
+
+
+ DESCRIPTION
+ ddns-confgen
+ generates a key for use by nsupdate
+ and named. It simplifies configuration
+ of dynamic zones by generating a key and providing the
+ nsupdate and named.conf
+ syntax that will be needed to use it, including an example
+ update-policy statement.
+
+
+
+ If a domain name is specified on the command line, it will
+ be used in the name of the generated key and in the sample
+ named.conf syntax. For example,
+ ddns-confgen example.com would
+ generate a key called "ddns-key.example.com", and sample
+ named.conf command that could be used
+ in the zone definition for "example.com".
+
+
+
+ Note that named itself can configure a
+ local DDNS key for use with nsupdate -l.
+ ddns-confgen is only needed when a
+ more elaborate configuration is required: for instance, if
+ nsupdate is to be used from a remote system.
+
+
+
+
+ OPTIONS
+
+
+
+ -a algorithm
+
+
+ Specifies the algorithm to use for the TSIG key. Available
+ choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384 and hmac-sha512. The default is hmac-sha256.
+
+
+
+
+
+ -h
+
+
+ Prints a short summary of the options and arguments to
+ ddns-confgen.
+
+
+
+
+
+ -k keyname
+
+
+ Specifies the key name of the DDNS authentication key.
+ The default is ddns-key when neither
+ the nor option is
+ specified; otherwise, the default
+ is ddns-key as a separate label
+ followed by the argument of the option, e.g.,
+ ddns-key.example.com.
+ The key name must have the format of a valid domain name,
+ consisting of letters, digits, hyphens and periods.
+
+
+
+
+
+ -q
+
+
+ Quiet mode: Print only the key, with no explanatory text or
+ usage examples.
+
+
+
+
+
+ -r randomfile
+
+
+ Specifies a source of random data for generating the
+ authorization. If the operating system does not provide a
+ /dev/random or equivalent device, the
+ default source of randomness is keyboard input.
+ randomdev specifies the name of a
+ character device or file containing random data to be used
+ instead of the default. The special value
+ keyboard indicates that keyboard input
+ should be used.
+
+
+
+
+
+ -s name
+
+
+ Single host mode: The example named.conf text
+ shows how to set an update policy for the specified
+ name
+ using the "name" nametype.
+ The default key name is
+ ddns-key.name.
+ Note that the "self" nametype cannot be used, since
+ the name to be updated may differ from the key name.
+ This option cannot be used with the option.
+
+
+
+
+
+ -z zone
+
+
+ zone mode: The example named.conf text
+ shows how to set an update policy for the specified
+ zone
+ using the "zonesub" nametype, allowing updates to all subdomain
+ names within
+ that zone.
+ This option cannot be used with the option.
+
+
+
+
+
+
+
+ SEE ALSO
+
+ nsupdate1
+ ,
+
+ named.conf5
+ ,
+
+ named8
+ ,
+ BIND 9 Administrator Reference Manual.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/confgen/ddns-confgen.html b/bin/confgen/ddns-confgen.html
new file mode 100644
index 00000000000..17c3f26dcca
--- /dev/null
+++ b/bin/confgen/ddns-confgen.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+ddns-confgen
+
+
+
+
+
+
Name
+
ddns-confgen — ddns key generation tool
+
+
+
Synopsis
+
ddns-confgen [-a algorithm] [-h] [-k keyname] [-r randomfile] [ -s name | -z zone ] [-q] [name]
+
+
+
DESCRIPTION
+
ddns-confgen
+ generates a key for use by nsupdate
+ and named. It simplifies configuration
+ of dynamic zones by generating a key and providing the
+ nsupdate and named.conf
+ syntax that will be needed to use it, including an example
+ update-policy statement.
+
+
+ If a domain name is specified on the command line, it will
+ be used in the name of the generated key and in the sample
+ named.conf syntax. For example,
+ ddns-confgen example.com would
+ generate a key called "ddns-key.example.com", and sample
+ named.conf command that could be used
+ in the zone definition for "example.com".
+
+
+ Note that named itself can configure a
+ local DDNS key for use with nsupdate -l.
+ ddns-confgen is only needed when a
+ more elaborate configuration is required: for instance, if
+ nsupdate is to be used from a remote system.
+
+
+
+
OPTIONS
+
+
-a algorithm
+
+ Specifies the algorithm to use for the TSIG key. Available
+ choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384 and hmac-sha512. The default is hmac-sha256.
+
+
-h
+
+ Prints a short summary of the options and arguments to
+ ddns-confgen.
+
+
-k keyname
+
+ Specifies the key name of the DDNS authentication key.
+ The default is ddns-key when neither
+ the -s nor -z option is
+ specified; otherwise, the default
+ is ddns-key as a separate label
+ followed by the argument of the option, e.g.,
+ ddns-key.example.com.
+ The key name must have the format of a valid domain name,
+ consisting of letters, digits, hyphens and periods.
+
+
-q
+
+ Quiet mode: Print only the key, with no explanatory text or
+ usage examples.
+
+
-r randomfile
+
+ Specifies a source of random data for generating the
+ authorization. If the operating system does not provide a
+ /dev/random or equivalent device, the
+ default source of randomness is keyboard input.
+ randomdev specifies the name of a
+ character device or file containing random data to be used
+ instead of the default. The special value
+ keyboard indicates that keyboard input
+ should be used.
+
+
-s name
+
+ Single host mode: The example named.conf text
+ shows how to set an update policy for the specified
+ name
+ using the "name" nametype.
+ The default key name is
+ ddns-key.name.
+ Note that the "self" nametype cannot be used, since
+ the name to be updated may differ from the key name.
+ This option cannot be used with the -z option.
+
+
-z zone
+
+ zone mode: The example named.conf text
+ shows how to set an update policy for the specified
+ zone
+ using the "zonesub" nametype, allowing updates to all subdomain
+ names within
+ that zone.
+ This option cannot be used with the -s option.
+
diff --git a/bin/rndc/unix/Makefile.in b/bin/confgen/unix/Makefile.in
similarity index 84%
rename from bin/rndc/unix/Makefile.in
rename to bin/confgen/unix/Makefile.in
index e503db3b0b2..1785e0d0f4d 100644
--- a/bin/rndc/unix/Makefile.in
+++ b/bin/confgen/unix/Makefile.in
@@ -1,5 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 2001 Internet Software Consortium.
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.5 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.3 2009-06-11 23:47:55 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/bin/rndc/unix/os.c b/bin/confgen/unix/os.c
similarity index 60%
rename from bin/rndc/unix/os.c
rename to bin/confgen/unix/os.c
index e9ece1ba776..e439a518264 100644
--- a/bin/rndc/unix/os.c
+++ b/bin/confgen/unix/os.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001 Internet Software Consortium.
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,13 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.10 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: os.c,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
/*! \file */
#include
-#include
+#include
#include
#include
@@ -42,29 +41,3 @@ set_user(FILE *fd, const char *user) {
}
return (fchown(fileno(fd), pw->pw_uid, -1));
}
-
-FILE *
-safe_create(const char *filename) {
- int fd;
- FILE *f;
- struct stat sb;
- int flags = O_WRONLY;
-
- if (stat(filename, &sb) == -1) {
- if (errno != ENOENT)
- return (NULL);
- flags = O_WRONLY | O_CREAT | O_EXCL;
- } else if ((sb.st_mode & S_IFREG) == 0) {
- errno = EOPNOTSUPP;
- return (NULL);
- } else
- flags = O_WRONLY | O_TRUNC;
-
- fd = open(filename, flags, S_IRUSR | S_IWUSR);
- if (fd == -1)
- return (NULL);
- f = fdopen(fd, "w");
- if (f == NULL)
- close(fd);
- return (f);
-}
diff --git a/bin/confgen/util.c b/bin/confgen/util.c
new file mode 100644
index 00000000000..158a8d35581
--- /dev/null
+++ b/bin/confgen/util.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: util.c,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
+
+/*! \file */
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "util.h"
+
+extern isc_boolean_t verbose;
+extern const char *progname;
+
+void
+notify(const char *fmt, ...) {
+ va_list ap;
+
+ if (verbose) {
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fputs("\n", stderr);
+ }
+}
+
+void
+fatal(const char *format, ...) {
+ va_list args;
+
+ fprintf(stderr, "%s: ", progname);
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit(1);
+}
diff --git a/bin/confgen/util.h b/bin/confgen/util.h
new file mode 100644
index 00000000000..651b6e558cf
--- /dev/null
+++ b/bin/confgen/util.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: util.h,v 1.4 2009-09-29 15:06:05 fdupont Exp $ */
+
+#ifndef RNDC_UTIL_H
+#define RNDC_UTIL_H 1
+
+/*! \file */
+
+#include
+#include
+
+#include
+
+#define NS_CONTROL_PORT 953
+
+#undef DO
+#define DO(name, function) \
+ do { \
+ result = function; \
+ if (result != ISC_R_SUCCESS) \
+ fatal("%s: %s", name, isc_result_totext(result)); \
+ else \
+ notify("%s", name); \
+ } while (0)
+
+ISC_LANG_BEGINDECLS
+
+void
+notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);
+
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
+
+ISC_LANG_ENDDECLS
+
+#endif /* RNDC_UTIL_H */
diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in
index ad20553d532..bebef6f45d3 100644
--- a/bin/dig/Makefile.in
+++ b/bin/dig/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.41 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.47 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \
- ${ISC_INCLUDES} ${LWRES_INCLUDES}
+ ${ISC_INCLUDES} ${LWRES_INCLUDES} ${ISCCFG_INCLUDES}
CDEFINES = -DVERSION=\"${VERSION}\"
CWARNINGS =
@@ -33,6 +33,7 @@ ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
@@ -44,8 +45,11 @@ LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \
${LWRESDEPLIBS}
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \
- ${ISCCFGLIBS} @IDNLIBS@ @LIBS@
+LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \
+ ${ISCLIBS} @IDNLIBS@ @LIBS@
+
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \
+ ${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@
SUBDIRS =
@@ -66,16 +70,16 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dig.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="dig.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- host.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="host.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- nslookup.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nslookup.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/dig/dig.1 b/bin/dig/dig.1
index 93f90b2ea84..87d5045701c 100644
--- a/bin/dig/dig.1
+++ b/bin/dig/dig.1
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dig.1,v 1.50.44.3 2009-07-11 01:55:20 tbox Exp $
+.\" $Id: dig.1,v 1.54 2010-03-05 01:14:15 tbox Exp $
.\"
.hy 0
.ad l
@@ -455,6 +455,11 @@ Print records like the SOA records in a verbose multi\-line format with human\-r
output.
.RE
.PP
+\fB+[no]onesoa\fR
+.RS 4
+Print only one (starting) SOA record when performing an AXFR. The default is to print both the starting and ending SOA records.
+.RE
+.PP
\fB+[no]fail\fR
.RS 4
Do not try the next server if you receive a SERVFAIL. The default is to not try the next server which is the reverse of normal stub resolver behavior.
@@ -562,7 +567,7 @@ RFC1035.
.PP
There are probably too many query options.
.SH "COPYRIGHT"
-Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2010 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2003 Internet Software Consortium.
.br
diff --git a/bin/dig/dig.c b/bin/dig/dig.c
index 7de934bb50d..a3143c93d27 100644
--- a/bin/dig/dig.c
+++ b/bin/dig/dig.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dig.c,v 1.225.26.7 2010-05-13 00:43:37 marka Exp $ */
+/* $Id: dig.c,v 1.237 2010-05-13 00:40:46 marka Exp $ */
/*! \file */
@@ -68,7 +68,8 @@ static char domainopt[DNS_NAME_MAXTEXT];
static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE,
ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE,
- multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE;
+ multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE,
+ onesoa = ISC_FALSE;
/*% opcode text */
static const char * const opcodetext[] = {
@@ -138,6 +139,9 @@ print_usage(FILE *fp) {
" [ host [@local-server] {local-d-opt} [...]]\n", fp);
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
print_usage(stderr);
@@ -222,6 +226,7 @@ help(void) {
#endif
#endif
" +[no]multiline (Print records in an expanded format)\n"
+" +[no]onesoa (AXFR prints only one soa record)\n"
" global d-opts and servers (before host name) affect all queries.\n"
" local d-opts and servers (after host name) affect only that lookup.\n"
" -h (print help and exit)\n"
@@ -468,6 +473,9 @@ printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
flags |= DNS_MESSAGETEXTFLAG_NOHEADERS;
flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
}
+ if (onesoa && query->lookup->rdtype == dns_rdatatype_axfr)
+ flags |= (query->msg_count == 0) ? DNS_MESSAGETEXTFLAG_ONESOA :
+ DNS_MESSAGETEXTFLAG_OMITSOA;
if (!query->lookup->comments)
flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
@@ -673,19 +681,6 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) {
}
}
-static isc_uint32_t
-parse_uint(char *arg, const char *desc, isc_uint32_t max) {
- isc_result_t result;
- isc_uint32_t tmp;
-
- result = isc_parse_uint32(&tmp, arg, 10);
- if (result == ISC_R_SUCCESS && tmp > max)
- result = ISC_R_RANGE;
- if (result != ISC_R_SUCCESS)
- fatal("%s '%s': %s", desc, arg, isc_result_totext(result));
- return (tmp);
-}
-
/*%
* We're not using isc_commandline_parse() here since the command line
* syntax of dig is quite a bit different from that which can be described
@@ -697,8 +692,10 @@ static void
plus_option(char *option, isc_boolean_t is_batchfile,
dig_lookup_t *lookup)
{
+ isc_result_t result;
char option_store[256];
char *cmd, *value, *ptr;
+ isc_uint32_t num;
isc_boolean_t state = ISC_TRUE;
#ifdef DIG_SIGCHASE
size_t n;
@@ -746,6 +743,7 @@ plus_option(char *option, isc_boolean_t is_batchfile,
lookup->section_additional = state;
break;
case 'f': /* adflag */
+ case '\0': /* +ad is a synonym for +adflag */
FULLCHECK("adflag");
lookup->adflag = state;
break;
@@ -787,8 +785,11 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->udpsize = (isc_uint16_t) parse_uint(value,
- "buffer size", COMMSIZE);
+ result = parse_uint(&num, value, COMMSIZE,
+ "buffer size");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse buffer size");
+ lookup->udpsize = num;
break;
default:
goto invalid_option;
@@ -797,8 +798,15 @@ plus_option(char *option, isc_boolean_t is_batchfile,
case 'c':
switch (cmd[1]) {
case 'd':/* cdflag */
- FULLCHECK("cdflag");
- lookup->cdflag = state;
+ switch (cmd[2]) {
+ case 'f': /* cdflag */
+ case '\0': /* +cd is a synonym for +cdflag */
+ FULLCHECK("cdflag");
+ lookup->cdflag = state;
+ break;
+ default:
+ goto invalid_option;
+ }
break;
case 'l': /* cl */
FULLCHECK("cl");
@@ -853,7 +861,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
}
if (value == NULL)
goto need_value;
- lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255);
+ result = parse_uint(&num, value, 255, "edns");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse edns");
+ lookup->edns = num;
break;
case 'f': /* fail */
FULLCHECK("fail");
@@ -883,7 +894,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- ndots = parse_uint(value, "ndots", MAXNDOTS);
+ result = parse_uint(&num, value, MAXNDOTS, "ndots");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse ndots");
+ ndots = num;
break;
case 's':
switch (cmd[2]) {
@@ -918,6 +932,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto invalid_option;
}
break;
+ case 'o':
+ FULLCHECK("onesoa");
+ onesoa = state;
+ break;
case 'q':
switch (cmd[1]) {
case 'r': /* qr */
@@ -948,8 +966,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->retries = parse_uint(value, "retries",
- MAXTRIES - 1);
+ result = parse_uint(&lookup->retries, value,
+ MAXTRIES - 1, "retries");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse retries");
lookup->retries++;
break;
default:
@@ -1025,7 +1045,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- timeout = parse_uint(value, "timeout", MAXTIMEOUT);
+ result = parse_uint(&timeout, value, MAXTIMEOUT,
+ "timeout");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse timeout");
if (timeout == 0)
timeout = 1;
break;
@@ -1058,8 +1081,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->retries = parse_uint(value, "tries",
- MAXTRIES);
+ result = parse_uint(&lookup->retries, value,
+ MAXTRIES, "tries");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse tries");
if (lookup->retries == 0)
lookup->retries = 1;
break;
@@ -1125,6 +1150,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
struct in6_addr in6;
in_port_t srcport;
char *hash, *cmd;
+ isc_uint32_t num;
while (strpbrk(option, single_dash_opts) == &option[0]) {
/*
@@ -1140,6 +1166,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
have_ipv6 = ISC_FALSE;
} else {
fatal("can't find IPv4 networking");
+ /* NOTREACHED */
return (ISC_FALSE);
}
break;
@@ -1149,6 +1176,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
have_ipv4 = ISC_FALSE;
} else {
fatal("can't find IPv6 networking");
+ /* NOTREACHED */
return (ISC_FALSE);
}
break;
@@ -1199,9 +1227,11 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
case 'b':
hash = strchr(value, '#');
if (hash != NULL) {
- srcport = (in_port_t)
- parse_uint(hash + 1,
- "port number", MAXPORT);
+ result = parse_uint(&num, hash + 1, MAXPORT,
+ "port number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse port number");
+ srcport = num;
*hash = '\0';
} else
srcport = 0;
@@ -1245,7 +1275,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
keyfile[sizeof(keyfile)-1]=0;
return (value_from_next);
case 'p':
- port = (in_port_t) parse_uint(value, "port number", MAXPORT);
+ result = parse_uint(&num, value, MAXPORT, "port number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse port number");
+ port = num;
return (value_from_next);
case 'q':
if (!config_only) {
@@ -1288,11 +1321,14 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
+ isc_uint32_t serial;
(*lookup)->rdtype = dns_rdatatype_ixfr;
(*lookup)->rdtypeset = ISC_TRUE;
- (*lookup)->ixfr_serial =
- parse_uint(&value[5], "serial number",
- MAXSERIAL);
+ result = parse_uint(&serial, &value[5],
+ MAXSERIAL, "serial number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse serial number");
+ (*lookup)->ixfr_serial = serial;
(*lookup)->section_question = plusquest;
(*lookup)->comments = pluscomm;
(*lookup)->tcp_mode = ISC_TRUE;
@@ -1320,65 +1356,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
usage();
ptr3 = next_token(&value,":"); /* secret or NULL */
if (ptr3 != NULL) {
- if (strcasecmp(ptr, "hmac-md5") == 0) {
- hmacname = DNS_TSIG_HMACMD5_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) {
- hmacname = DNS_TSIG_HMACMD5_NAME;
- digestbits = parse_uint(&ptr[9],
- "digest-bits [0..128]",
- 128);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha1") == 0) {
- hmacname = DNS_TSIG_HMACSHA1_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) {
- hmacname = DNS_TSIG_HMACSHA1_NAME;
- digestbits = parse_uint(&ptr[10],
- "digest-bits [0..160]",
- 160);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha224") == 0) {
- hmacname = DNS_TSIG_HMACSHA224_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA224_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..224]",
- 224);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha256") == 0) {
- hmacname = DNS_TSIG_HMACSHA256_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA256_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..256]",
- 256);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha384") == 0) {
- hmacname = DNS_TSIG_HMACSHA384_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA384_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..384]",
- 384);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha512") == 0) {
- hmacname = DNS_TSIG_HMACSHA512_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA512_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..512]",
- 512);
- digestbits = (digestbits + 7) & ~0x7U;
- } else {
- fprintf(stderr, ";; Warning, ignoring "
- "invalid TSIG algorithm %s\n", ptr);
- return (value_from_next);
- }
+ parse_hmac(ptr);
ptr = ptr2;
ptr2 = ptr3;
} else {
@@ -1422,6 +1400,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
fprintf(stderr, "Invalid option: -%s\n", option);
usage();
}
+ /* NOTREACHED */
return (ISC_FALSE);
}
@@ -1626,13 +1605,18 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
+ isc_uint32_t serial;
lookup->rdtype =
dns_rdatatype_ixfr;
lookup->rdtypeset = ISC_TRUE;
- lookup->ixfr_serial =
- parse_uint(&rv[0][5],
- "serial number",
- MAXSERIAL);
+ result = parse_uint(&serial,
+ &rv[0][5],
+ MAXSERIAL,
+ "serial number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse "
+ "serial number");
+ lookup->ixfr_serial = serial;
lookup->section_question =
plusquest;
lookup->comments = pluscomm;
diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook
index d8e358644c9..19e2ca2afbf 100644
--- a/bin/dig/dig.docbook
+++ b/bin/dig/dig.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[]>
-
+
@@ -44,6 +44,7 @@
200720082009
+ 2010Internet Systems Consortium, Inc. ("ISC")
@@ -766,6 +767,17 @@
+
+
+
+
+ Print only one (starting) SOA record when performing
+ an AXFR. The default is to print both the starting and
+ ending SOA records.
+
+
+
+
diff --git a/bin/dig/dig.html b/bin/dig/dig.html
index 17fd5bb3bc7..c9ce8f0e254 100644
--- a/bin/dig/dig.html
+++ b/bin/dig/dig.html
@@ -1,5 +1,5 @@
-
+
@@ -34,7 +34,7 @@
dig [global-queryopt...] [query...]
-
DESCRIPTION
+
DESCRIPTION
dig
(domain information groper) is a flexible tool
for interrogating DNS name servers. It performs DNS lookups and
@@ -80,7 +80,7 @@
-
SIMPLE USAGE
+
SIMPLE USAGE
A typical invocation of dig looks like:
@@ -126,7 +126,7 @@
-
OPTIONS
+
OPTIONS
The -b option sets the source IP address of the query
to address. This must be a valid
@@ -230,7 +230,7 @@
-
QUERY OPTIONS
+
QUERY OPTIONS
dig
provides a number of query options which affect
the way in which lookups are made and the results displayed. Some of
@@ -499,6 +499,12 @@
each record on a single line, to facilitate machine parsing
of the dig output.
+
+[no]onesoa
+
+ Print only one (starting) SOA record when performing
+ an AXFR. The default is to print both the starting and
+ ending SOA records.
+
+[no]fail
Do not try the next server if you receive a SERVFAIL. The
@@ -555,7 +561,7 @@
-
MULTIPLE QUERIES
+
MULTIPLE QUERIES
The BIND 9 implementation of dig
supports
@@ -601,7 +607,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
-
IDN SUPPORT
+
IDN SUPPORT
If dig has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -615,14 +621,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
dnssec-dsfromkey
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
-
OPTIONS
+
OPTIONS
-1
@@ -53,34 +53,54 @@
-a algorithm
Select the digest algorithm. The value of
- algorithm must be one of SHA-1 (SHA1) or
- SHA-256 (SHA256). These values are case insensitive.
+ algorithm must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
+
+
-K directory
+
+ Look for key files (or, in keyset mode,
+ keyset- files) in
+ directory.
+
+
-f file
+
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from file. If the zone name is the same as
+ file, then it may be omitted.
+
+
-A
+
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+
+
-l domain
+
+ Generate a DLV set instead of a DS set. The specified
+ domain is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
+
+
-s
+
+ Keyset mode: in place of the keyfile name, the argument is
+ the DNS domain name of a keyset file.
+
+
-c class
+
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
-v level
Sets the debugging level.
-
-s
-
- Keyset mode: in place of the keyfile name, the argument is
- the DNS domain name of a keyset file. Following options make sense
- only in this mode.
-
-
-c class
-
- Specifies the DNS class (default is IN), useful only
- in the keyset mode.
-
-
-d directory
-
- Look for keyset files in
- directory as the directory, ignored when
- not in the keyset mode.
-
-
EXAMPLE
+
EXAMPLE
To build the SHA-256 DS RR from the
Kexample.com.+003+26160
@@ -95,7 +115,7 @@
-
FILES
+
FILES
The keyfile can be designed by the key identification
Knnnn.+aaa+iiiii or the full file name
@@ -109,22 +129,23 @@
-
CAVEAT
+
CAVEAT
A keyfile error can give a "file not found" even if the file exists.
diff --git a/bin/dnssec/dnssec-keyfromlabel.8 b/bin/dnssec/dnssec-keyfromlabel.8
index 45fc0877b72..d8c19f2e527 100644
--- a/bin/dnssec/dnssec-keyfromlabel.8
+++ b/bin/dnssec/dnssec-keyfromlabel.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keyfromlabel.8,v 1.6.14.3 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keyfromlabel.8,v 1.18.14.1.2.1 2011-06-09 03:41:05 tbox Exp $
.\"
.hy 0
.ad l
@@ -32,18 +32,22 @@
dnssec\-keyfromlabel \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 20
-\fBdnssec\-keyfromlabel\fR {\-a\ \fIalgorithm\fR} {\-l\ \fIlabel\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-k\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keyfromlabel\fR {\-l\ \fIlabel\fR} [\fB\-3\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-y\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keyfromlabel\fR
gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. This must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or DH (Diffie Hellman). These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. These values are case insensitive.
.sp
If no algorithm is specified, then RSASHA1 will be used by default, unless the
\fB\-3\fR
@@ -56,9 +60,19 @@ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA
Note 2: DH automatically sets the \-k flag.
.RE
.PP
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Specifies the name of the crypto hardware (OpenSSL engine). When compiled with PKCS#11 support it defaults to "pkcs11".
+.RE
+.PP
\-l \fIlabel\fR
.RS 4
-Specifies the label of keys in the crypto hardware (PKCS#11 device).
+Specifies the label of the key pair in the crypto hardware. The label may be preceded by an optional OpenSSL engine name, separated by a colon, as in "pkcs11:keylabel".
.RE
.PP
\-n \fInametype\fR
@@ -68,6 +82,15 @@ Specifies the owner type of the key. The value of
must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.
.RE
.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keyfromlabel\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.RE
+.PP
\-c \fIclass\fR
.RS 4
Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
@@ -75,13 +98,23 @@ Indicates that the DNS record containing the key should have the specified class
.PP
\-f \fIflag\fR
.RS 4
-Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-h
.RS 4
Prints a short summary of the options and arguments to
-\fBdnssec\-keygen\fR.
+\fBdnssec\-keyfromlabel\fR.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
.RE
.PP
\-k
@@ -91,7 +124,7 @@ Generate KEY records rather than DNSKEY records.
.PP
\-p \fIprotocol\fR
.RS 4
-Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
+Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
.RE
.PP
\-t \fItype\fR
@@ -105,6 +138,39 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.PP
+\-y
+.RS 4
+Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.)
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
.SH "GENERATED KEY FILES"
.PP
When
@@ -138,7 +204,7 @@ file contains a DNS KEY record that can be inserted into a zone file (directly o
.PP
The
\fI.private\fR
-file contains algorithm specific fields. For obvious security reasons, this file does not have general read permission.
+file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
@@ -149,5 +215,5 @@ RFC 4034.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008\-2011 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c
index 8e9a53bb798..323f9187c64 100644
--- a/bin/dnssec/dnssec-keyfromlabel.c
+++ b/bin/dnssec/dnssec-keyfromlabel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,12 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keyfromlabel.c,v 1.4.50.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keyfromlabel.c,v 1.32 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include
+#include
#include
#include
@@ -27,9 +28,11 @@
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -47,35 +50,60 @@
const char *program = "dnssec-keyfromlabel";
int verbose;
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
+
static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |"
" NSEC3DSA | NSEC3RSASHA1 |"
- " RSASHA256 | RSASHA512";
+ " RSASHA256 | RSASHA512 | ECCGOST";
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -l label [options] name\n\n",
+ fprintf(stderr, " %s -l label [options] name\n\n",
program);
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Required options:\n");
- fprintf(stderr, " -a algorithm: %s\n", algs);
- fprintf(stderr, " -l label: label of the key\n");
+ fprintf(stderr, " -l label: label of the key pair\n");
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
+ fprintf(stderr, " -a algorithm: %s\n", algs);
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -c class (default: IN)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E enginename (default: pkcs11)\n");
+#else
+ fprintf(stderr, " -E enginename\n");
+#endif
+ fprintf(stderr, " -f keyflag: KSK | REVOKE\n");
+ fprintf(stderr, " -K directory: directory in which to place "
+ "key files\n");
+ fprintf(stderr, " -k: generate a TYPE=KEY key\n");
fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
- fprintf(stderr, " -c (default: IN)\n");
- fprintf(stderr, " -f keyflag: KSK\n");
- fprintf(stderr, " -t : "
+ fprintf(stderr, " -p protocol: default: 3 [dnssec]\n");
+ fprintf(stderr, " -t type: "
"AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
"(default: AUTHCONF)\n");
- fprintf(stderr, " -p : "
- "default: 3 [dnssec]\n");
- fprintf(stderr, " -v \n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+ fprintf(stderr, " -y: permit keys that might collide\n");
+ fprintf(stderr, " -v verbose level\n");
+ fprintf(stderr, "Date options:\n");
+ fprintf(stderr, " -P date/[+-]offset: set key publication date\n");
+ fprintf(stderr, " -A date/[+-]offset: set key activation date\n");
+ fprintf(stderr, " -R date/[+-]offset: set key revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset: set key inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting"
+ " all dates\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K++.key, "
- "K++.private\n");
+ "K++.private\n");
exit (-1);
}
@@ -83,14 +111,20 @@ usage(void) {
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
+ const char *directory = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
- isc_boolean_t null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch;
int protocol = -1, signatory = 0;
@@ -103,6 +137,20 @@ main(int argc, char **argv) {
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
char *label = NULL;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t use_nsec3 = ISC_FALSE;
+ isc_boolean_t avoid_collisions = ISC_TRUE;
+ isc_boolean_t exact;
+ unsigned char c;
if (argc == 1)
usage();
@@ -113,28 +161,49 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
+ isc_stdtime_get(&now);
+
while ((ch = isc_commandline_parse(argc, argv,
- "a:c:f:kl:n:p:t:v:h")) != -1)
+ "3a:Cc:E:f:K:kl:n:p:t:v:yFhGP:A:R:I:D:")) != -1)
{
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
options |= DST_TYPE_KEY;
break;
case 'l':
- label = isc_commandline_argument;
+ label = isc_mem_strdup(mctx, isc_commandline_argument);
break;
case 'n':
nametype = isc_commandline_argument;
@@ -153,11 +222,80 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
+ case 'y':
+ avoid_collisions = ISC_FALSE;
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -170,10 +308,11 @@ main(int argc, char **argv) {
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
@@ -184,8 +323,30 @@ main(int argc, char **argv) {
if (argc > isc_commandline_index + 1)
fatal("extraneous arguments");
- if (algname == NULL)
- fatal("no algorithm was specified");
+ if (strchr(label, ':') == NULL &&
+ engine != NULL && strlen(engine) != 0U) {
+ char *l;
+ int len;
+
+ len = strlen(label) + strlen(engine) + 2;
+ l = isc_mem_allocate(mctx, len);
+ if (l == NULL)
+ fatal("cannot allocate memory");
+ snprintf(l, len, "%s:%s", engine, label);
+ isc_mem_free(mctx, label);
+ label = l;
+ }
+
+ if (algname == NULL) {
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
+ }
+
if (strcasecmp(algname, "RSA") == 0) {
fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n"
"If you still wish to use RSA (RSAMD5) please "
@@ -201,6 +362,14 @@ main(int argc, char **argv) {
options |= DST_TYPE_KEY;
}
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
if (type != NULL && (options & DST_TYPE_KEY) != 0) {
if (strcasecmp(type, "NOAUTH") == 0)
flags |= DNS_KEYTYPE_NOAUTH;
@@ -234,10 +403,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -260,53 +434,108 @@ main(int argc, char **argv) {
isc_buffer_init(&buf, argv[isc_commandline_index],
strlen(argv[isc_commandline_index]));
isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
- ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
if (ret != ISC_R_SUCCESS)
fatal("invalid key name %s: %s", argv[isc_commandline_index],
isc_result_totext(ret));
- if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
- null_key = ISC_TRUE;
-
isc_buffer_init(&buf, filename, sizeof(filename) - 1);
/* associate the key */
ret = dst_key_fromlabel(name, alg, flags, protocol,
- rdclass, "", label, NULL, mctx, &key);
+ rdclass, engine, label, NULL, mctx, &key);
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
- fatal("failed to generate key %s/%s: %s\n",
+ dns_secalg_format(alg, algstr, sizeof(algstr));
+ fatal("failed to get key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
exit(-1);
}
/*
- * Try to read a key with the same name, alg and id from disk.
- * If there is one we must continue generating a new one
- * unless we were asked to generate a null key, in which
- * case we return failure.
+ * Set key timing metadata (unless using -C)
+ *
+ * Publish and activation dates are set to "now" by default, but
+ * can be overridden. Creation date is always set to "now".
*/
- ret = dst_key_fromfile(name, dst_key_id(key), alg,
- DST_TYPE_PRIVATE, NULL, mctx, &oldkey);
- /* do not overwrite an existing key */
- if (ret == ISC_R_SUCCESS) {
- isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
- fprintf(stderr, "%s: %s already exists\n",
- program, filename);
- dst_key_free(&key);
- exit (1);
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with -P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH, activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
}
- ret = dst_key_tofile(key, options, NULL);
+ /*
+ * Do not overwrite an existing key. Warn LOUDLY if there
+ * is a risk of ID collision due to this key or another key
+ * being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory, alg, mctx, &exact))
+ {
+ isc_buffer_clear(&buf);
+ ret = dst_key_buildfilename(key, 0, directory, &buf);
+ if (exact)
+ fatal("%s: %s already exists\n", program, filename);
+
+ if (avoid_collisions)
+ fatal("%s: %s could collide with another key upon "
+ "revokation\n", program, filename);
+
+ fprintf(stderr, "%s: WARNING: Key %s could collide with "
+ "another key upon revokation. If you plan "
+ "to revoke keys, destroy this key and "
+ "generate a different one.\n",
+ program, filename);
+ }
+
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -322,6 +551,7 @@ main(int argc, char **argv) {
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, label);
isc_mem_destroy(&mctx);
return (0);
diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook
index a2fff5a0d4b..be38a246578 100644
--- a/bin/dnssec/dnssec-keyfromlabel.docbook
+++ b/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[]>
-
+
February 8, 2008
@@ -37,7 +37,9 @@
2008
+ 20092010
+ 2011Internet Systems Consortium, Inc. ("ISC")
@@ -45,15 +47,25 @@
dnssec-keyfromlabel
- -a algorithm-l label
+
+
+
+
+
+
+
+
+
+
+ name
@@ -65,6 +77,11 @@
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
+
+ The of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+
@@ -76,9 +93,8 @@
Selects the cryptographic algorithm. The value of
- must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
@@ -98,12 +114,35 @@
+
+ -3
+
+
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+
+
+
+
+
+ -E engine
+
+
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+
+
+
+
-l label
- Specifies the label of keys in the crypto hardware
- (PKCS#11 device).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
@@ -117,8 +156,22 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+
+
+
+
+
+ -C
+
+
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, dnssec-keyfromlabel
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ option suppresses them.
@@ -138,7 +191,17 @@
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+
+
+
+
+
+ -G
+
+
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
@@ -148,7 +211,16 @@
Prints a short summary of the options and arguments to
- dnssec-keygen.
+ dnssec-keyfromlabel.
+
+
+
+
+
+ -K directory
+
+
+ Sets the directory in which the key files are to be written.
@@ -166,7 +238,7 @@
-p protocol
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -195,6 +267,93 @@
+
+ -y
+
+
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+
+
+
+
+
+
+
+
+ TIMING OPTIONS
+
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+
+
+
+
+ -P date/offset
+
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+
+
+
+
+
+ -A date/offset
+
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+
+
+
+
+
+ -R date/offset
+
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
+
+
+
+ -I date/offset
+
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
+
+
+
+ -D date/offset
+
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
+
@@ -214,8 +373,7 @@
aaa is the numeric representation
- of the
- algorithm.
+ of the algorithm.
@@ -229,8 +387,7 @@
on the printed string. Knnnn.+aaa+iiiii.key
contains the public key, and
Knnnn.+aaa+iiiii.private contains the
- private
- key.
+ private key.
The .key file contains a DNS KEY record
@@ -239,8 +396,8 @@
statement).
- The .private file contains algorithm
- specific
+ The .private file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
diff --git a/bin/dnssec/dnssec-keyfromlabel.html b/bin/dnssec/dnssec-keyfromlabel.html
index ad2a5621ba9..2b1b23690bb 100644
--- a/bin/dnssec/dnssec-keyfromlabel.html
+++ b/bin/dnssec/dnssec-keyfromlabel.html
@@ -1,5 +1,5 @@
-
+
@@ -28,26 +28,30 @@
dnssec-keyfromlabel
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
+
+ The name of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+
-
OPTIONS
+
OPTIONS
-a algorithm
Selects the cryptographic algorithm. The value of
- algorithm must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ algorithm must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+
+
-E engine
+
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+
-l label
- Specifies the label of keys in the crypto hardware
- (PKCS#11 device).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
-n nametype
@@ -77,8 +94,17 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+
+
-C
+
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, dnssec-keyfromlabel
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ -C option suppresses them.
-c class
@@ -88,12 +114,21 @@
-f flag
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+
+
-G
+
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
-h
Prints a short summary of the options and arguments to
- dnssec-keygen.
+ dnssec-keyfromlabel.
+
+
-K directory
+
+ Sets the directory in which the key files are to be written.
-k
@@ -101,7 +136,7 @@
-p protocol
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -117,10 +152,65 @@
Sets the debugging level.
+
-y
+
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+
-
GENERATED KEY FILES
+
TIMING OPTIONS
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+
+
+
-P date/offset
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+
+
-A date/offset
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+
+
-R date/offset
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
-I date/offset
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
-D date/offset
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
+
+
+
GENERATED KEY FILES
When dnssec-keyfromlabel completes
successfully,
@@ -132,8 +222,7 @@
nnnn is the key name.
aaa is the numeric representation
- of the
- algorithm.
+ of the algorithm.
iiiii is the key identifier (or
footprint).
@@ -144,8 +233,7 @@
on the printed string. Knnnn.+aaa+iiiii.key
contains the public key, and
Knnnn.+aaa+iiiii.private contains the
- private
- key.
+ private key.
The .key file contains a DNS KEY record
@@ -154,14 +242,14 @@
statement).
- The .private file contains algorithm
- specific
+ The .private file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
diff --git a/bin/dnssec/dnssec-keygen.8 b/bin/dnssec/dnssec-keygen.8
index c4be24eba0c..ea4690eb71a 100644
--- a/bin/dnssec/dnssec-keygen.8
+++ b/bin/dnssec/dnssec-keygen.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keygen.8,v 1.40.44.4 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.55 2010-12-24 01:14:19 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,11 +33,11 @@
dnssec\-keygen \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 14
-\fBdnssec\-keygen\fR {\-a\ \fIalgorithm\fR} {\-b\ \fIkeysize\fR} {\-n\ \fInametype\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-k\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keygen\fR
-generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.
+generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.
.PP
The
\fBname\fR
@@ -48,16 +48,28 @@ of the key is specified on the command line. For DNSSEC keys, this must match th
.RS 4
Selects the cryptographic algorithm. For DNSSEC keys, the value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+.sp
+If no algorithm is specified, then RSASHA1 will be used by default, unless the
+\fB\-3\fR
+option is specified, in which case NSEC3RSASHA1 will be used instead. (If
+\fB\-3\fR
+is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory.
.sp
-Note 2: HMAC\-MD5 and DH automatically set the \-k flag.
+Note 2: DH, HMAC\-MD5, and HMAC\-SHA1 through HMAC\-SHA512 automatically set the \-T KEY option.
.RE
.PP
\-b \fIkeysize\fR
.RS 4
Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits.
+.sp
+The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with
+\fB\-f KSK\fR). However, if an algorithm is explicitly specified with the
+\fB\-a\fR, then there is no default key size, and the
+\fB\-b\fR
+must be used.
.RE
.PP
\-n \fInametype\fR
@@ -67,11 +79,30 @@ Specifies the owner type of the key. The value of
must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation.
.RE
.PP
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms are NSEC3\-capable.
+.RE
+.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keygen\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.RE
+.PP
\-c \fIclass\fR
.RS 4
Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
.RE
.PP
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for random number and, when supported, key generation. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
\-e
.RS 4
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -79,7 +110,12 @@ If generating an RSAMD5/RSASHA1 key, use a large exponent.
.PP
\-f \fIflag\fR
.RS 4
-Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-g \fIgenerator\fR
@@ -93,9 +129,14 @@ Prints a short summary of the options and arguments to
\fBdnssec\-keygen\fR.
.RE
.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
+.RE
+.PP
\-k
.RS 4
-Generate KEY records rather than DNSKEY records.
+Deprecated in favor of \-T KEY.
.RE
.PP
\-p \fIprotocol\fR
@@ -103,6 +144,15 @@ Generate KEY records rather than DNSKEY records.
Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
.RE
.PP
+\-q
+.RS 4
+Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when
+\fBdnssec\-keygen\fR
+is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to
+\fIstderr\fR
+indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller\-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key.
+.RE
+.PP
\-r \fIrandomdev\fR
.RS 4
Specifies the source of randomness. If the operating system does not provide a
@@ -114,11 +164,24 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S \fIkey\fR
+.RS 4
+Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
\-s \fIstrength\fR
.RS 4
Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC.
.RE
.PP
+\-T \fIrrtype\fR
+.RS 4
+Specifies the resource record type to use for the key.
+\fBrrtype\fR
+must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0).
+Using any TSIG algorithm (HMAC\-* or DH) forces this option to KEY.
+.RE
+.PP
\-t \fItype\fR
.RS 4
Indicates the use of the key.
@@ -130,6 +193,43 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
.SH "GENERATED KEYS"
.PP
When
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c
index 21841227d43..f369326aaf8 100644
--- a/bin/dnssec/dnssec-keygen.c
+++ b/bin/dnssec/dnssec-keygen.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,13 +29,15 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.81.48.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.115 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include
+#include
#include
+#include
#include
#include
@@ -45,6 +47,7 @@
#include
#include
+#include
#include
#include
#include
@@ -62,10 +65,105 @@
const char *program = "dnssec-keygen";
int verbose;
-static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | RSASHA256 |"
- " RSASHA512 | NSEC3DSA | NSEC3RSASHA1 | HMAC-MD5 |"
- " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |"
- " HMAC-SHA384 | HMAC-SHA512";
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void progress(int p);
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] name\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, " name: owner of the key\n");
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -K : write keys into directory\n");
+ fprintf(stderr, " -a :\n");
+ fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1"
+ " | NSEC3DSA |\n");
+ fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n");
+ fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | "
+ "HMAC-SHA256 | \n");
+ fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n");
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -b :\n");
+ fprintf(stderr, " RSAMD5:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA);
+ fprintf(stderr, " DH:\t\t[128..4096]\n");
+ fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n");
+ fprintf(stderr, " NSEC3DSA:\t[512..1024] and divisible "
+ "by 64\n");
+ fprintf(stderr, " ECCGOST:\tignored\n");
+ fprintf(stderr, " HMAC-MD5:\t[1..512]\n");
+ fprintf(stderr, " HMAC-SHA1:\t[1..160]\n");
+ fprintf(stderr, " HMAC-SHA224:\t[1..224]\n");
+ fprintf(stderr, " HMAC-SHA256:\t[1..256]\n");
+ fprintf(stderr, " HMAC-SHA384:\t[1..384]\n");
+ fprintf(stderr, " HMAC-SHA512:\t[1..512]\n");
+ fprintf(stderr, " (if using the default algorithm, key size\n"
+ " defaults to 2048 for KSK, or 1024 for all "
+ "others)\n");
+ fprintf(stderr, " -n : ZONE | HOST | ENTITY | "
+ "USER | OTHER\n");
+ fprintf(stderr, " (DNSKEY generation defaults to ZONE)\n");
+ fprintf(stderr, " -c : (default: IN)\n");
+ fprintf(stderr, " -d (0 => max, default)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E (default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E \n");
+#endif
+ fprintf(stderr, " -e: use large exponent (RSAMD5/RSASHA1 only)\n");
+ fprintf(stderr, " -f : KSK | REVOKE\n");
+ fprintf(stderr, " -g : use specified generator "
+ "(DH only)\n");
+ fprintf(stderr, " -p : (default: 3 [dnssec])\n");
+ fprintf(stderr, " -s : strength value this key signs DNS "
+ "records with (default: 0)\n");
+ fprintf(stderr, " -T : DNSKEY | KEY (default: DNSKEY; "
+ "use KEY for SIG(0))\n");
+ fprintf(stderr, " ECCGOST:\tignored\n");
+ fprintf(stderr, " -t : "
+ "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
+ "(default: AUTHCONF)\n");
+ fprintf(stderr, " -r : a file containing random data\n");
+
+ fprintf(stderr, " -h: print usage and exit\n");
+ fprintf(stderr, " -m :\n");
+ fprintf(stderr, " usage | trace | record | size | mctx\n");
+ fprintf(stderr, " -v : set verbosity level (0 - 10)\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set key publication date "
+ "(default: now)\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set key activation date "
+ "(default: now)\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting "
+ "all dates\n");
+ fprintf(stderr, " -S : generate a successor to an existing "
+ "key\n");
+ fprintf(stderr, " -i : prepublication interval for "
+ "successor key "
+ "(default: 30 days)\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K++.key, "
+ "K++.private\n");
+
+ exit (-1);
+}
static isc_boolean_t
dsa_size_ok(int size) {
@@ -73,53 +171,28 @@ dsa_size_ok(int size) {
}
static void
-usage(void) {
- fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -b bits [-n type] [options] name\n\n",
- program);
- fprintf(stderr, "Version: %s\n", VERSION);
- fprintf(stderr, "Required options:\n");
- fprintf(stderr, " -a algorithm: %s\n", algs);
- fprintf(stderr, " -b key size, in bits:\n");
- fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " NSEC3RSASHA1:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA);
- fprintf(stderr, " DH:\t\t[128..4096]\n");
- fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n");
- fprintf(stderr, " NSEC3DSA:\t\t[512..1024] and divisible by 64\n");
- fprintf(stderr, " HMAC-MD5:\t[1..512]\n");
- fprintf(stderr, " HMAC-SHA1:\t[1..160]\n");
- fprintf(stderr, " HMAC-SHA224:\t[1..224]\n");
- fprintf(stderr, " HMAC-SHA256:\t[1..256]\n");
- fprintf(stderr, " HMAC-SHA384:\t[1..384]\n");
- fprintf(stderr, " HMAC-SHA512:\t[1..512]\n");
- fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
- fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
- fprintf(stderr, " name: owner of the key\n");
- fprintf(stderr, "Other options:\n");
- fprintf(stderr, " -c (default: IN)\n");
- fprintf(stderr, " -d (0 => max, default)\n");
- fprintf(stderr, " -e use large exponent (RSAMD5/RSASHA1 only)\n");
- fprintf(stderr, " -f keyflag: KSK\n");
- fprintf(stderr, " -g use specified generator "
- "(DH only)\n");
- fprintf(stderr, " -t : "
- "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
- "(default: AUTHCONF)\n");
- fprintf(stderr, " -p : "
- "default: 3 [dnssec]\n");
- fprintf(stderr, " -s strength value this key signs DNS "
- "records with (default: 0)\n");
- fprintf(stderr, " -r : a file containing random data\n");
- fprintf(stderr, " -v \n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
- fprintf(stderr, "Output:\n");
- fprintf(stderr, " K++.key, "
- "K++.private\n");
+progress(int p)
+{
+ char c = '*';
- exit (-1);
+ switch (p) {
+ case 0:
+ c = '.';
+ break;
+ case 1:
+ c = '+';
+ break;
+ case 2:
+ c = '*';
+ break;
+ case 3:
+ c = ' ';
+ break;
+ default:
+ break;
+ }
+ (void) putc(c, stderr);
+ (void) fflush(stderr);
}
int
@@ -127,38 +200,89 @@ main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch, rsa_exp = 0, generator = 0, param = 0;
int protocol = -1, size = -1, signatory = 0;
isc_result_t ret;
isc_textregion_t r;
char filename[255];
+ const char *directory = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
isc_buffer_t buf;
isc_log_t *log = NULL;
isc_entropy_t *ectx = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
int dbits = 0;
+ isc_boolean_t use_default = ISC_FALSE, use_nsec3 = ISC_FALSE;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ int prepub = -1;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t quiet = ISC_FALSE;
+ isc_boolean_t show_progress = ISC_FALSE;
+ unsigned char c;
if (argc == 1)
usage();
- RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
-
dns_result_register();
isc_commandline_errprint = ISC_FALSE;
- while ((ch = isc_commandline_parse(argc, argv,
- "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1)
- {
+ /*
+ * Process memory debugging argument first.
+ */
+#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:km:n:P:p:qR:r:S:s:T:t:v:"
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
+ switch (ch) {
+ case 'm':
+ if (strcasecmp(isc_commandline_argument, "record") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
+ if (strcasecmp(isc_commandline_argument, "trace") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
+ if (strcasecmp(isc_commandline_argument, "usage") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
+ if (strcasecmp(isc_commandline_argument, "size") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
+ if (strcasecmp(isc_commandline_argument, "mctx") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGCTX;
+ break;
+ default:
+ break;
+ }
+ }
+ isc_commandline_reset = ISC_TRUE;
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+
+ isc_stdtime_get(&now);
+
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
@@ -167,6 +291,9 @@ main(int argc, char **argv) {
if (*endp != '\0' || size < 0)
fatal("-b requires a non-negative number");
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
@@ -175,12 +302,18 @@ main(int argc, char **argv) {
if (*endp != '\0' || dbits < 0)
fatal("-d requires a non-negative number");
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'e':
rsa_exp = 1;
break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -191,14 +324,22 @@ main(int argc, char **argv) {
if (*endp != '\0' || generator <= 0)
fatal("-g requires a positive number");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
- options |= DST_TYPE_KEY;
+ fatal("The -k option has been deprecated.\n"
+ "To generate a key-signing key, use -f KSK.\n"
+ "To generate a key with TYPE=KEY, use -T KEY.\n");
break;
case 'n':
nametype = isc_commandline_argument;
break;
- case 't':
- type = isc_commandline_argument;
+ case 'm':
break;
case 'p':
protocol = strtol(isc_commandline_argument, &endp, 10);
@@ -206,6 +347,12 @@ main(int argc, char **argv) {
fatal("-p must be followed by a number "
"[0..255]");
break;
+ case 'q':
+ quiet = ISC_TRUE;
+ break;
+ case 'r':
+ setup_entropy(mctx, isc_commandline_argument, &ectx);
+ break;
case 's':
signatory = strtol(isc_commandline_argument,
&endp, 10);
@@ -213,8 +360,19 @@ main(int argc, char **argv) {
fatal("-s must be followed by a number "
"[0..15]");
break;
- case 'r':
- setup_entropy(mctx, isc_commandline_argument, &ectx);
+ case 'T':
+ if (strcasecmp(isc_commandline_argument, "KEY") == 0)
+ options |= DST_TYPE_KEY;
+ else if (strcasecmp(isc_commandline_argument,
+ "DNSKEY") == 0)
+ /* default behavior */
+ ;
+ else
+ fatal("unknown type '%s'",
+ isc_commandline_argument);
+ break;
+ case 't':
+ type = isc_commandline_argument;
break;
case 'v':
endp = NULL;
@@ -222,11 +380,86 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
+ case 'z':
+ /* already the default */
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -237,73 +470,219 @@ main(int argc, char **argv) {
}
}
+ if (!isatty(0))
+ quiet = ISC_TRUE;
+
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
- if (argc < isc_commandline_index + 1)
- fatal("the key name was not specified");
- if (argc > isc_commandline_index + 1)
- fatal("extraneous arguments");
+ if (predecessor == NULL) {
+ if (prepub == -1)
+ prepub = 0;
- if (algname == NULL)
- fatal("no algorithm was specified");
- if (strcasecmp(algname, "RSA") == 0) {
- fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n"
- "If you still wish to use RSA (RSAMD5) please "
- "specify \"-a RSAMD5\"\n");
- return (1);
- } else if (strcasecmp(algname, "HMAC-MD5") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACMD5;
- } else if (strcasecmp(algname, "HMAC-SHA1") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA1;
- } else if (strcasecmp(algname, "HMAC-SHA224") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA224;
- } else if (strcasecmp(algname, "HMAC-SHA256") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA256;
- } else if (strcasecmp(algname, "HMAC-SHA384") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA384;
- } else if (strcasecmp(algname, "HMAC-SHA512") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA512;
- } else {
- r.base = algname;
- r.length = strlen(algname);
- ret = dns_secalg_fromtext(&alg, &r);
+ if (argc < isc_commandline_index + 1)
+ fatal("the key name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("extraneous arguments");
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ isc_buffer_init(&buf, argv[isc_commandline_index],
+ strlen(argv[isc_commandline_index]));
+ isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
if (ret != ISC_R_SUCCESS)
- fatal("unknown algorithm %s", algname);
- if (alg == DST_ALG_DH)
- options |= DST_TYPE_KEY;
- }
+ fatal("invalid key name %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(ret));
- if (type != NULL && (options & DST_TYPE_KEY) != 0) {
- if (strcasecmp(type, "NOAUTH") == 0)
- flags |= DNS_KEYTYPE_NOAUTH;
- else if (strcasecmp(type, "NOCONF") == 0)
- flags |= DNS_KEYTYPE_NOCONF;
- else if (strcasecmp(type, "NOAUTHCONF") == 0) {
- flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF);
- if (size < 0)
- size = 0;
+ if (algname == NULL) {
+ use_default = ISC_TRUE;
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
}
- else if (strcasecmp(type, "AUTHCONF") == 0)
- /* nothing */;
- else
- fatal("invalid type %s", type);
- }
- if (size < 0)
- fatal("key size not specified (-b option)");
+ if (strcasecmp(algname, "RSA") == 0) {
+ fprintf(stderr, "The use of RSA (RSAMD5) is not "
+ "recommended.\nIf you still wish to "
+ "use RSA (RSAMD5) please specify "
+ "\"-a RSAMD5\"\n");
+ return (1);
+ } else if (strcasecmp(algname, "HMAC-MD5") == 0)
+ alg = DST_ALG_HMACMD5;
+ else if (strcasecmp(algname, "HMAC-SHA1") == 0)
+ alg = DST_ALG_HMACSHA1;
+ else if (strcasecmp(algname, "HMAC-SHA224") == 0)
+ alg = DST_ALG_HMACSHA224;
+ else if (strcasecmp(algname, "HMAC-SHA256") == 0)
+ alg = DST_ALG_HMACSHA256;
+ else if (strcasecmp(algname, "HMAC-SHA384") == 0)
+ alg = DST_ALG_HMACSHA384;
+ else if (strcasecmp(algname, "HMAC-SHA512") == 0)
+ alg = DST_ALG_HMACSHA512;
+ else {
+ r.base = algname;
+ r.length = strlen(algname);
+ ret = dns_secalg_fromtext(&alg, &r);
+ if (ret != ISC_R_SUCCESS)
+ fatal("unknown algorithm %s", algname);
+ if (alg == DST_ALG_DH)
+ options |= DST_TYPE_KEY;
+ }
+
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
+ if (type != NULL && (options & DST_TYPE_KEY) != 0) {
+ if (strcasecmp(type, "NOAUTH") == 0)
+ flags |= DNS_KEYTYPE_NOAUTH;
+ else if (strcasecmp(type, "NOCONF") == 0)
+ flags |= DNS_KEYTYPE_NOCONF;
+ else if (strcasecmp(type, "NOAUTHCONF") == 0) {
+ flags |= (DNS_KEYTYPE_NOAUTH |
+ DNS_KEYTYPE_NOCONF);
+ if (size < 0)
+ size = 0;
+ }
+ else if (strcasecmp(type, "AUTHCONF") == 0)
+ /* nothing */;
+ else
+ fatal("invalid type %s", type);
+ }
+
+ if (size < 0) {
+ if (use_default) {
+ if ((kskflag & DNS_KEYFLAG_KSK) != 0)
+ size = 2048;
+ else
+ size = 1024;
+ if (verbose > 0)
+ fprintf(stderr, "key size not "
+ "specified; defaulting "
+ "to %d\n", size);
+ } else if (alg != DST_ALG_ECCGOST)
+ fatal("key size not specified (-b option)");
+ }
+
+ if (!oldstyle && prepub > 0) {
+ if (setpub && setact && (activate - prepub) < publish)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (!setpub && !setact) {
+ setpub = setact = ISC_TRUE;
+ publish = now;
+ activate = now + prepub;
+ } else if (setpub && !setact) {
+ setact = ISC_TRUE;
+ activate = publish + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ publish = activate - prepub;
+ }
+
+ if ((activate - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ } else {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (algname != NULL)
+ fatal("-S and -a cannot be used together");
+ if (size >= 0)
+ fatal("-S and -b cannot be used together");
+ if (nametype != NULL)
+ fatal("-S and -n cannot be used together");
+ if (type != NULL)
+ fatal("-S and -t cannot be used together");
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+ if (use_nsec3)
+ fatal("-S and -3 cannot be used together");
+ if (oldstyle)
+ fatal("-S and -C cannot be used together");
+ if (genonly)
+ fatal("-S and -G cannot be used together");
+
+ ret = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(ret));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d\n\t"
+ "It is not possible to generate a successor key.",
+ keystr, major, minor);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no activation date.\n\t"
+ "You must use dnssec-settime -A to set one "
+ "before generating a successor.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no inactivation date.\n\t"
+ "You must use dnssec-settime -I to set one "
+ "before generating a successor.", keystr);
+
+ publish = activate - prepub;
+ if (publish < now)
+ fatal("Key %s becomes inactive\n\t"
+ "sooner than the prepublication period "
+ "for the new key ends.\n\t"
+ "Either change the inactivation date with "
+ "dnssec-settime -I,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Key %s has no removal "
+ "date;\n\t it will remain in the zone "
+ "indefinitely after rollover.\n\t "
+ "You can use dnssec-settime -D to "
+ "change this.\n", program, keystr);
+
+ setpub = setact = ISC_TRUE;
+ }
switch (alg) {
case DNS_KEYALG_RSAMD5:
@@ -326,7 +705,10 @@ main(int argc, char **argv) {
if (size != 0 && !dsa_size_ok(size))
fatal("invalid DSS key size: %d", size);
break;
+ case DST_ALG_ECCGOST:
+ break;
case DST_ALG_HMACMD5:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-MD5 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 128))
@@ -336,6 +718,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA1:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 160)
fatal("HMAC-SHA1 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 160))
@@ -345,6 +728,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA224:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 224)
fatal("HMAC-SHA224 key size %d out of range", size);
if (dbits != 0 && (dbits < 112 || dbits > 224))
@@ -354,6 +738,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA256:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 256)
fatal("HMAC-SHA256 key size %d out of range", size);
if (dbits != 0 && (dbits < 128 || dbits > 256))
@@ -363,6 +748,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA384:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 384)
fatal("HMAC-384 key size %d out of range", size);
if (dbits != 0 && (dbits < 192 || dbits > 384))
@@ -372,6 +758,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA512:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-SHA512 key size %d out of range", size);
if (dbits != 0 && (dbits < 256 || dbits > 512))
@@ -384,7 +771,8 @@ main(int argc, char **argv) {
if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 ||
alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 ||
- alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0)
+ alg == DNS_KEYALG_RSASHA512 || alg == DST_ALG_ECCGOST) &&
+ rsa_exp != 0)
fatal("specified RSA exponent for a non-RSA key");
if (alg != DNS_KEYALG_DH && generator != 0)
@@ -409,10 +797,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -435,16 +828,6 @@ main(int argc, char **argv) {
fatal("a key with algorithm '%s' cannot be a zone key",
algname);
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- isc_buffer_init(&buf, argv[isc_commandline_index],
- strlen(argv[isc_commandline_index]));
- isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
- ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
- if (ret != ISC_R_SUCCESS)
- fatal("invalid key name %s: %s", argv[isc_commandline_index],
- isc_result_totext(ret));
-
switch(alg) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
@@ -452,12 +835,19 @@ main(int argc, char **argv) {
case DNS_KEYALG_RSASHA256:
case DNS_KEYALG_RSASHA512:
param = rsa_exp;
+ show_progress = ISC_TRUE;
break;
+
case DNS_KEYALG_DH:
param = generator;
break;
+
case DNS_KEYALG_DSA:
case DNS_KEYALG_NSEC3DSA:
+ case DST_ALG_ECCGOST:
+ show_progress = ISC_TRUE;
+ /* fall through */
+
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
@@ -475,62 +865,136 @@ main(int argc, char **argv) {
do {
conflict = ISC_FALSE;
- oldkey = NULL;
- /* generate the key */
- ret = dst_key_generate(name, alg, size, param, flags, protocol,
- rdclass, mctx, &key);
+ if (!quiet && show_progress) {
+ fprintf(stderr, "Generating key pair.");
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ &progress);
+ putc('\n', stderr);
+ fflush(stderr);
+ } else {
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ NULL);
+ }
+
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
+ dns_secalg_format(alg, algstr, sizeof(algstr));
fatal("failed to generate key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
exit(-1);
}
dst_key_setbits(key, dbits);
/*
- * Try to read a key with the same name, alg and id from disk.
- * If there is one we must continue generating a new one
- * unless we were asked to generate a null key, in which
- * case we return failure.
+ * Set key timing metadata (unless using -C)
+ *
+ * Creation date is always set to "now".
+ *
+ * For a new key without an explicit predecessor, publish
+ * and activation dates are set to "now" by default, but
+ * can both be overridden.
+ *
+ * For a successor key, activation is set to match the
+ * predecessor's inactivation date. Publish is set to 30
+ * days earlier than that (XXX: this should be configurable).
+ * If either of the resulting dates are in the past, that's
+ * an error; the inactivation date of the predecessor key
+ * must be updated before a successor key can be created.
*/
- ret = dst_key_fromfile(name, dst_key_id(key), alg,
- DST_TYPE_PRIVATE, NULL, mctx, &oldkey);
- /* do not overwrite an existing key */
- if (ret == ISC_R_SUCCESS) {
- dst_key_free(&oldkey);
- conflict = ISC_TRUE;
- if (null_key)
- break;
- }
- if (conflict == ISC_TRUE) {
- if (verbose > 0) {
- isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
- fprintf(stderr,
- "%s: %s already exists, "
- "generating a new key\n",
- program, filename);
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with "
+ "-P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH,
+ activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE,
+ activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
}
- dst_key_free(&key);
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE,
+ inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
}
+ /*
+ * Do not overwrite an existing key, or create a key
+ * if there is a risk of ID collision due to this key
+ * or another key being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory,
+ alg, mctx, NULL)) {
+ conflict = ISC_TRUE;
+ if (null_key) {
+ dst_key_free(&key);
+ break;
+ }
+
+ if (verbose > 0) {
+ isc_buffer_clear(&buf);
+ dst_key_buildfilename(key, 0, directory, &buf);
+ fprintf(stderr,
+ "%s: %s already exists, or might "
+ "collide with another key upon "
+ "revokation. Generating a new key\n",
+ program, filename);
+ }
+
+ dst_key_free(&key);
+ }
} while (conflict == ISC_TRUE);
if (conflict)
- fatal("cannot generate a null key when a key with id 0 "
- "already exists");
+ fatal("cannot generate a null key due to possible key ID "
+ "collision");
- ret = dst_key_tofile(key, options, NULL);
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -539,6 +1003,8 @@ main(int argc, char **argv) {
ret = dst_key_buildfilename(key, 0, NULL, &buf);
printf("%s\n", filename);
dst_key_free(&key);
+ if (prevkey != NULL)
+ dst_key_free(&prevkey);
cleanup_logging(&log);
cleanup_entropy(&ectx);
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook
index 5c7d1649fe6..dc140ebfe38 100644
--- a/bin/dnssec/dnssec-keygen.docbook
+++ b/bin/dnssec/dnssec-keygen.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
June 30, 2000
@@ -57,20 +57,34 @@
dnssec-keygen
- -a algorithm
- -b keysize
- -n nametype
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ name
@@ -80,7 +94,8 @@
dnssec-keygen
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
The of the key is specified on the command
@@ -99,19 +114,27 @@
Selects the cryptographic algorithm. For DNSSEC keys, the value
of must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
+
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
@@ -127,6 +150,15 @@
bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
+
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with ). However, if an
+ algorithm is explicitly specified with the ,
+ then there is no default key size, and the
+ must be used.
+
@@ -145,6 +177,34 @@
+
+ -3
+
+
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+
+
+
+
+
+ -C
+
+
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, dnssec-keygen
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ option suppresses them.
+
+
+
+
-c class
@@ -155,6 +215,18 @@
+
+ -E engine
+
+
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+
+
+
+
-e
@@ -169,7 +241,17 @@
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+
+
+
+
+
+ -G
+
+
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
@@ -196,11 +278,20 @@
+
+ -K directory
+
+
+ Sets the directory in which the key files are to be written.
+
+
+
+
-k
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
@@ -217,6 +308,25 @@
+
+ -q
+
+
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ dnssec-keygen is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to stderr indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+
+
+
+
-r randomdev
@@ -234,6 +344,21 @@
+
+ -S key
+
+
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+
+
+
+
-s strength
@@ -245,6 +370,22 @@
+
+ -T rrtype
+
+
+ Specifies the resource record type to use for the key.
+ must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+
+
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+
+
+
+
-t type
@@ -269,6 +410,109 @@
+
+ TIMING OPTIONS
+
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+
+
+
+
+ -P date/offset
+
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+
+
+
+
+
+ -A date/offset
+
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+
+
+
+
+
+ -R date/offset
+
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
+
+
+
+ -I date/offset
+
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
+
+
+
+ -D date/offset
+
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
+
+
+
+ -i interval
+
+
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+
+
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+
+
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+
+
+
+
+
+
+
+
GENERATED KEYS
diff --git a/bin/dnssec/dnssec-keygen.html b/bin/dnssec/dnssec-keygen.html
index 7ca7d577e8f..2f3a69b9a2f 100644
--- a/bin/dnssec/dnssec-keygen.html
+++ b/bin/dnssec/dnssec-keygen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
@@ -29,14 +29,15 @@
dnssec-keygen
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
The name of the key is specified on the command
@@ -45,37 +46,56 @@
-
OPTIONS
+
OPTIONS
-a algorithm
Selects the cryptographic algorithm. For DNSSEC keys, the value
of algorithm must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
+
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the -3 option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ -3 is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
-b keysize
-
+
+
Specifies the number of bits in the key. The choice of key
size depends on the algorithm used. RSA keys must be
between 512 and 2048 bits. Diffie Hellman keys must be between
128 and 4096 bits. DSA keys must be between 512 and 1024
bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
-
+
+
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with -f KSK). However, if an
+ algorithm is explicitly specified with the -a,
+ then there is no default key size, and the -b
+ must be used.
+
+
-n nametype
Specifies the owner type of the key. The value of
@@ -86,11 +106,36 @@
These values are case insensitive. Defaults to ZONE for DNSKEY
generation.
+
-3
+
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+
+
-C
+
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, dnssec-keygen
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ -C option suppresses them.
+
-c class
Indicates that the DNS record containing the key should have
the specified class. If not specified, class IN is used.
+
-E engine
+
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+
-e
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -98,7 +143,12 @@
-f flag
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+
+
-G
+
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
-g generator
@@ -112,9 +162,13 @@
Prints a short summary of the options and arguments to
dnssec-keygen.
+
-K directory
+
+ Sets the directory in which the key files are to be written.
+
-k
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
-p protocol
@@ -123,6 +177,20 @@
Other possible values for this argument are listed in
RFC 2535 and its successors.
+
-q
+
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ dnssec-keygen is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to stderr indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+
-r randomdev
Specifies the source of randomness. If the operating
@@ -135,12 +203,37 @@
keyboard indicates that keyboard
input should be used.
+
-S key
+
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+
-s strength
Specifies the strength value of the key. The strength is
a number between 0 and 15, and currently has no defined
purpose in DNSSEC.
+
-T rrtype
+
+
+ Specifies the resource record type to use for the key.
+ rrtype must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+
+
+
+
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+
+
-t type
Indicates the use of the key. type must be
@@ -155,7 +248,78 @@
-
GENERATED KEYS
+
TIMING OPTIONS
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+
+
+
-P date/offset
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+
+
-A date/offset
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+
+
-R date/offset
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
-I date/offset
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
-D date/offset
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
-i interval
+
+
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+
+
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+
+
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+
+
+
+
+
+
GENERATED KEYS
When dnssec-keygen completes
successfully,
@@ -201,7 +365,7 @@
-
EXAMPLE
+
EXAMPLE
To generate a 768-bit DSA key for the domain
example.com, the following command would be
@@ -222,7 +386,7 @@
dnssec-revoke
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+
+
+
+
OPTIONS
+
+
-h
+
+ Emit usage message and exit.
+
+
-K directory
+
+ Sets the directory in which the key files are to reside.
+
+
-r
+
+ After writing the new keyset files remove the original keyset
+ files.
+
+
-v level
+
+ Sets the debugging level.
+
+
-E engine
+
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+
+
-f
+
+ Force overwrite: Causes dnssec-revoke to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+
+
diff --git a/bin/dnssec/dnssec-settime.8 b/bin/dnssec/dnssec-settime.8
new file mode 100644
index 00000000000..4390494474c
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.8
@@ -0,0 +1,166 @@
+.\" Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: dnssec-settime.8,v 1.14 2010-08-17 01:15:26 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-settime
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: July 15, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-SETTIME" "8" "July 15, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-settime \- Set the key timing metadata for a DNSSEC key
+.SH "SYNOPSIS"
+.HP 15
+\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-settime\fR
+reads a DNSSEC private key file and sets the key timing metadata as specified by the
+\fB\-P\fR,
+\fB\-A\fR,
+\fB\-R\fR,
+\fB\-I\fR, and
+\fB\-D\fR
+options. The metadata can then be used by
+\fBdnssec\-signzone\fR
+or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc.
+.PP
+If none of these options is set on the command line, then
+\fBdnssec\-settime\fR
+simply prints the key timing metadata already stored in the key.
+.PP
+When key metadata fields are changed, both files of a key pair (\fIKnnnn.+aaa+iiiii.key\fR
+and
+\fIKnnnn.+aaa+iiiii.private\fR) are regenerated. Metadata fields are stored in the private file. A human\-readable description of the metadata is also placed in comments in the key file.
+.SH "OPTIONS"
+.PP
+\-f
+.RS 4
+Force an update of an old\-format key with no metadata fields. Without this option,
+\fBdnssec\-settime\fR
+will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to reside.
+.RE
+.PP
+\-h
+.RS 4
+Emit usage message and exit.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Use the given OpenSSL engine. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none'.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it.
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-S \fIpredecessor key\fR
+.RS 4
+Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
+.SH "PRINTING OPTIONS"
+.PP
+\fBdnssec\-settime\fR
+can also be used to print the timing metadata associated with a key.
+.PP
+\-u
+.RS 4
+Print times in UNIX epoch format.
+.RE
+.PP
+\-p \fIC/P/A/R/I/D/all\fR
+.RS 4
+Print a specific metadata value or set of metadata values. The
+\fB\-p\fR
+option may be followed by one or more of the following letters to indicate which value or values to print:
+\fBC\fR
+for the creation date,
+\fBP\fR
+for the publication date,
+\fBA\fR
+for the activation date,
+\fBR\fR
+for the revocation date,
+\fBI\fR
+for the inactivation date, or
+\fBD\fR
+for the deletion date. To print all of the metadata, use
+\fB\-p all\fR.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+\fBdnssec\-signzone\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 5011.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c
new file mode 100644
index 00000000000..364e2ab5926
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dnssec-settime.c,v 1.28 2010-12-19 07:29:36 each Exp $ */
+
+/*! \file */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-settime";
+int verbose;
+
+static isc_mem_t *mctx = NULL;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] keyfile\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "General options:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E engine: specify OpenSSL engine "
+ "(default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E engine: specify OpenSSL engine\n");
+#endif
+ fprintf(stderr, " -f: force update of old-style "
+ "keys\n");
+ fprintf(stderr, " -K directory: set key file location\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, " -h: help\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
+ "publication date\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set/unset key "
+ "activation date\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set/unset key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set/unset key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set/unset key "
+ "deletion date\n");
+ fprintf(stderr, "Printing options:\n");
+ fprintf(stderr, " -p C/P/A/R/I/D/all: print a particular time "
+ "value or values "
+ "[default: all]\n");
+ fprintf(stderr, " -u: print times in unix epoch "
+ "format\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K++.key, "
+ "K++.private\n");
+
+ exit (-1);
+}
+
+static void
+printtime(dst_key_t *key, int type, const char *tag, isc_boolean_t epoch,
+ FILE *stream)
+{
+ isc_result_t result;
+ const char *output = NULL;
+ isc_stdtime_t when;
+
+ if (tag != NULL)
+ fprintf(stream, "%s: ", tag);
+
+ result = dst_key_gettime(key, type, &when);
+ if (result == ISC_R_NOTFOUND) {
+ fprintf(stream, "UNSET\n");
+ } else if (epoch) {
+ fprintf(stream, "%d\n", (int) when);
+ } else {
+ time_t time = when;
+ output = ctime(&time);
+ fprintf(stream, "%s", output);
+ }
+}
+
+int
+main(int argc, char **argv) {
+ isc_result_t result;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
+ char *filename = NULL, *directory = NULL;
+ char newname[1024];
+ char keystr[DST_KEY_FORMATSIZE];
+ char *endp, *p;
+ int ch;
+ isc_entropy_t *ectx = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
+ dst_key_t *key = NULL;
+ isc_buffer_t buf;
+ dns_name_t *name = NULL;
+ dns_secalg_t alg = 0;
+ unsigned int size = 0;
+ isc_uint16_t flags = 0;
+ int prepub = -1;
+ isc_stdtime_t now;
+ isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE;
+ isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE;
+ isc_boolean_t printinact = ISC_FALSE, printdel = ISC_FALSE;
+ isc_boolean_t force = ISC_FALSE;
+ isc_boolean_t epoch = ISC_FALSE;
+ isc_boolean_t changed = ISC_FALSE;
+
+ if (argc == 1)
+ usage();
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS)
+ fatal("Out of memory");
+
+ dns_result_register();
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ isc_stdtime_get(&now);
+
+#define CMDLINE_FLAGS "A:D:E:fhI:i:K:P:p:R:S:uv:"
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
+ switch (ch) {
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
+ case 'f':
+ force = ISC_TRUE;
+ break;
+ case 'p':
+ p = isc_commandline_argument;
+ if (!strcasecmp(p, "all")) {
+ printcreate = ISC_TRUE;
+ printpub = ISC_TRUE;
+ printact = ISC_TRUE;
+ printrev = ISC_TRUE;
+ printinact = ISC_TRUE;
+ printdel = ISC_TRUE;
+ break;
+ }
+
+ do {
+ switch (*p++) {
+ case 'C':
+ printcreate = ISC_TRUE;
+ break;
+ case 'P':
+ printpub = ISC_TRUE;
+ break;
+ case 'A':
+ printact = ISC_TRUE;
+ break;
+ case 'R':
+ printrev = ISC_TRUE;
+ break;
+ case 'I':
+ printinact = ISC_TRUE;
+ break;
+ case 'D':
+ printdel = ISC_TRUE;
+ break;
+ case ' ':
+ break;
+ default:
+ usage();
+ break;
+ }
+ } while (*p != '\0');
+ break;
+ case 'u':
+ epoch = ISC_TRUE;
+ break;
+ case 'K':
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ directory = isc_mem_strdup(mctx,
+ isc_commandline_argument);
+ if (directory == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetpub = ISC_TRUE;
+ } else {
+ setpub = ISC_TRUE;
+ pub = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetact = ISC_TRUE;
+ } else {
+ setact = ISC_TRUE;
+ act = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetrev = ISC_TRUE;
+ } else {
+ setrev = ISC_TRUE;
+ rev = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetinact = ISC_TRUE;
+ } else {
+ setinact = ISC_TRUE;
+ inact = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetdel = ISC_TRUE;
+ } else {
+ setdel = ISC_TRUE;
+ del = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ /* Falls into */
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (argc < isc_commandline_index + 1 ||
+ argv[isc_commandline_index] == NULL)
+ fatal("The key file name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("Extraneous arguments");
+
+ if (ectx == NULL)
+ setup_entropy(mctx, NULL, &ectx);
+ result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize hash");
+ result = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize dst: %s",
+ isc_result_totext(result));
+ isc_entropy_stopcallbacksources(ectx);
+
+ if (predecessor != NULL) {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+
+ result = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Predecessor has incompatible format "
+ "version %d.%d\n\t", major, minor);
+
+ result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no activation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &act);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no inactivation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ pub = act - prepub;
+ if (pub < now && prepub != 0)
+ fatal("Predecessor will become inactive before the\n\t"
+ "prepublication period ends. Either change "
+ "its inactivation date,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Predecessor has no "
+ "removal date;\n\t"
+ "it will remain in the zone "
+ "indefinitely after rollover.\n",
+ program);
+
+ changed = setpub = setact = ISC_TRUE;
+ dst_key_free(&prevkey);
+ } else {
+ if (prepub < 0)
+ prepub = 0;
+
+ if (prepub > 0) {
+ if (setpub && setact && (act - prepub) < pub)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (setpub && !setact) {
+ setact = ISC_TRUE;
+ act = pub + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ pub = act - prepub;
+ }
+
+ if ((act - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ }
+
+ if (directory != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ result = isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &directory, &filename);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot process filename %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(result));
+ }
+
+ result = dst_key_fromnamedfile(filename, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+
+ if (!dst_key_isprivate(key))
+ fatal("%s is not a private key", filename);
+
+ dst_key_format(key, keystr, sizeof(keystr));
+
+ if (predecessor != NULL) {
+ if (!dns_name_equal(name, dst_key_name(key)))
+ fatal("Key name mismatch");
+ if (alg != dst_key_alg(key))
+ fatal("Key algorithm mismatch");
+ if (size != dst_key_size(key))
+ fatal("Key size mismatch");
+ if (flags != dst_key_flags(key))
+ fatal("Key flags mismatch");
+ }
+
+ if (force)
+ set_keyversion(key);
+ else
+ check_keyversion(key, keystr);
+
+ if (verbose > 2)
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ /*
+ * Set time values.
+ */
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, pub);
+ else if (unsetpub)
+ dst_key_unsettime(key, DST_TIME_PUBLISH);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, act);
+ else if (unsetact)
+ dst_key_unsettime(key, DST_TIME_ACTIVATE);
+
+ if (setrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; changing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0)
+ fprintf(stderr, "%s: warning: Key %s is not flagged as "
+ "a KSK, but -R was used. Revoking a "
+ "ZSK is legal, but undefined.\n",
+ program, keystr);
+ dst_key_settime(key, DST_TIME_REVOKE, rev);
+ } else if (unsetrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; removing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ dst_key_unsettime(key, DST_TIME_REVOKE);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inact);
+ else if (unsetinact)
+ dst_key_unsettime(key, DST_TIME_INACTIVE);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, del);
+ else if (unsetdel)
+ dst_key_unsettime(key, DST_TIME_DELETE);
+
+ /*
+ * Print out time values, if -p was used.
+ */
+ if (printcreate)
+ printtime(key, DST_TIME_CREATED, "Created", epoch, stdout);
+
+ if (printpub)
+ printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout);
+
+ if (printact)
+ printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout);
+
+ if (printrev)
+ printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout);
+
+ if (printinact)
+ printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout);
+
+ if (printdel)
+ printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout);
+
+ if (changed) {
+ isc_buffer_init(&buf, newname, sizeof(newname));
+ result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build public key filename: %s",
+ isc_result_totext(result));
+ }
+
+ result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ directory);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Failed to write key %s: %s", keystr,
+ isc_result_totext(result));
+ }
+
+ printf("%s\n", newname);
+
+ isc_buffer_clear(&buf);
+ result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build private key filename: %s",
+ isc_result_totext(result));
+ }
+ printf("%s\n", newname);
+ }
+
+ dst_key_free(&key);
+ dst_lib_destroy();
+ isc_hash_destroy();
+ cleanup_entropy(&ectx);
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, directory);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/bin/dnssec/dnssec-settime.docbook b/bin/dnssec/dnssec-settime.docbook
new file mode 100644
index 00000000000..1096cb7ec5a
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.docbook
@@ -0,0 +1,319 @@
+]>
+
+
+
+
+
+ July 15, 2009
+
+
+
+ dnssec-settime
+ 8
+ BIND9
+
+
+
+ dnssec-settime
+ Set the key timing metadata for a DNSSEC key
+
+
+
+
+ 2009
+ 2010
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ dnssec-settime
+
+
+
+
+
+
+
+
+
+
+ keyfile
+
+
+
+
+ DESCRIPTION
+ dnssec-settime
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the , ,
+ , , and
+ options. The metadata can then be used by
+ dnssec-signzone or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+
+
+ If none of these options is set on the command line,
+ then dnssec-settime simply prints the key timing
+ metadata already stored in the key.
+
+
+ When key metadata fields are changed, both files of a key
+ pair (Knnnn.+aaa+iiiii.key and
+ Knnnn.+aaa+iiiii.private) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+
+
+
+
+ OPTIONS
+
+
+
+ -f
+
+
+ Force an update of an old-format key with no metadata fields.
+ Without this option, dnssec-settime will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+
+
+
+
+
+ -K directory
+
+
+ Sets the directory in which the key files are to reside.
+
+
+
+
+
+ -h
+
+
+ Emit usage message and exit.
+
+
+
+
+
+ -v level
+
+
+ Sets the debugging level.
+
+
+
+
+
+ -E engine
+
+
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+
+
+
+
+
+
+
+ TIMING OPTIONS
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+
+
+
+
+ -P date/offset
+
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+
+
+
+
+
+ -A date/offset
+
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+
+
+
+
+
+ -R date/offset
+
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
+
+
+
+ -I date/offset
+
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
+
+
+
+ -D date/offset
+
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
+
+
+
+ -S predecessor key
+
+
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+
+
+
+
+
+ -i interval
+
+
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+
+
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+
+
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+
+
+
+
+
+
+
+ PRINTING OPTIONS
+
+ dnssec-settime can also be used to print the
+ timing metadata associated with a key.
+
+
+
+
+ -u
+
+
+ Print times in UNIX epoch format.
+
+
+
+
+
+ -p C/P/A/R/I/D/all
+
+
+ Print a specific metadata value or set of metadata values.
+ The option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ for the creation date,
+ for the publication date,
+ for the activation date,
+ for the revocation date,
+ for the inactivation date, or
+ for the deletion date.
+ To print all of the metadata, use .
+
+
+
+
+
+
+
+
+ SEE ALSO
+
+ dnssec-keygen8
+ ,
+
+ dnssec-signzone8
+ ,
+ BIND 9 Administrator Reference Manual,
+ RFC 5011.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/dnssec/dnssec-settime.html b/bin/dnssec/dnssec-settime.html
new file mode 100644
index 00000000000..84c8dde49a1
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.html
@@ -0,0 +1,208 @@
+
+
+
+
+
+dnssec-settime
+
+
+
+
+
+
Name
+
dnssec-settime — Set the key timing metadata for a DNSSEC key
dnssec-settime
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the -P, -A,
+ -R, -I, and -D
+ options. The metadata can then be used by
+ dnssec-signzone or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+
+
+ If none of these options is set on the command line,
+ then dnssec-settime simply prints the key timing
+ metadata already stored in the key.
+
+
+ When key metadata fields are changed, both files of a key
+ pair (Knnnn.+aaa+iiiii.key and
+ Knnnn.+aaa+iiiii.private) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+
+
+
+
OPTIONS
+
+
-f
+
+ Force an update of an old-format key with no metadata fields.
+ Without this option, dnssec-settime will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+
+
-K directory
+
+ Sets the directory in which the key files are to reside.
+
+
-h
+
+ Emit usage message and exit.
+
+
-v level
+
+ Sets the debugging level.
+
+
-E engine
+
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+
+
+
+
+
TIMING OPTIONS
+
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+
+
+
-P date/offset
+
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+
+
-A date/offset
+
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+
+
-R date/offset
+
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+
+
-I date/offset
+
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+
+
-D date/offset
+
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+
+
-S predecessor key
+
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+
+
-i interval
+
+
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+
+
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+
+
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+
+
+
+
+
+
PRINTING OPTIONS
+
+ dnssec-settime can also be used to print the
+ timing metadata associated with a key.
+
+
+
-u
+
+ Print times in UNIX epoch format.
+
+
-p C/P/A/R/I/D/all
+
+ Print a specific metadata value or set of metadata values.
+ The -p option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ C for the creation date,
+ P for the publication date,
+ A for the activation date,
+ R for the revocation date,
+ I for the inactivation date, or
+ D for the deletion date.
+ To print all of the metadata, use -p all.
+
+
diff --git a/bin/dnssec/dnssec-signzone.8 b/bin/dnssec/dnssec-signzone.8
index bfe7a2013b1..9822883747b 100644
--- a/bin/dnssec/dnssec-signzone.8
+++ b/bin/dnssec/dnssec-signzone.8
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.47.44.8 2009-11-07 01:56:11 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.59 2009-12-04 01:13:44 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec\-signzone
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1
-.\" Date: June 08, 2009
+.\" Date: June 05, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-SIGNZONE" "8" "June 08, 2009" "BIND9" "BIND9"
+.TH "DNSSEC\-SIGNZONE" "8" "June 05, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,15 +33,13 @@
dnssec\-signzone \- DNSSEC zone signing tool
.SH "SYNOPSIS"
.HP 16
-\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
+\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
.SH "DESCRIPTION"
.PP
\fBdnssec\-signzone\fR
-signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. It also generates a
-\fIkeyset\-\fR
-file containing the key\-signing keys for the zone, and if signing a zone which contains delegations, it can optionally generate DS records for the child zones from their
-\fIkeyset\-\fR
-files.
+signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a
+\fIkeyset\fR
+file for each child zone.
.SH "OPTIONS"
.PP
\-a
@@ -54,6 +52,45 @@ Verify all generated signatures.
Specifies the DNS class of the zone.
.RE
.PP
+\-C
+.RS 4
+Compatibility mode: Generate a
+\fIkeyset\-\fR\fI\fIzonename\fR\fR
+file in addition to
+\fIdsset\-\fR\fI\fIzonename\fR\fR
+when signing a zone, for use by older versions of
+\fBdnssec\-signzone\fR.
+.RE
+.PP
+\-d \fIdirectory\fR
+.RS 4
+Look for
+\fIdsset\-\fR
+or
+\fIkeyset\-\fR
+files in
+\fBdirectory\fR.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for the crypto operations it supports, for instance signing with private keys from a secure key store. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
+\-g
+.RS 4
+Generate DS records for child zones from
+\fIdsset\-\fR
+or
+\fIkeyset\-\fR
+file. Existing DS records will be removed.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory.
+.RE
+.PP
\-k \fIkey\fR
.RS 4
Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.
@@ -64,22 +101,6 @@ Treat specified key as a key signing key ignoring any key flags. This option may
Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.
.RE
.PP
-\-d \fIdirectory\fR
-.RS 4
-Look for
-\fIkeyset\fR
-files in
-\fBdirectory\fR
-as the directory
-.RE
-.PP
-\-g
-.RS 4
-If the zone contains any delegations, and there are
-\fIkeyset\-\fR
-files for any of the child zones, then DS records for the child zones will be generated from the keys in those files. Existing DS records will be removed.
-.RE
-.PP
\-s \fIstart\-time\fR
.RS 4
Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no
@@ -93,6 +114,9 @@ Specify the date and time when the generated RRSIG records expire. As with
\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no
\fBend\-time\fR
is specified, 30 days from the start time is used as a default.
+\fBend\-time\fR
+must be later than
+\fBstart\-time\fR.
.RE
.PP
\-f \fIoutput\-file\fR
@@ -208,34 +232,94 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S
+.RS 4
+Smart signing: Instructs
+\fBdnssec\-signzone\fR
+to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate.
+.sp
+When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones:
+.RS 4
+.PP
+.RS 4
+If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's publication date is set and is in the past, the key is published in the zone.
+.RE
+.PP
+.RS 4
+If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone.
+.RE
+.PP
+.RS 4
+If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata.
+.RE
+.RE
+.RE
+.PP
+\-T \fIttl\fR
+.RS 4
+Specifies the TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the minimum TTL value from the zone's SOA record. This option is ignored when signing without
+\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them.
+.RE
+.PP
\-t
.RS 4
Print statistics at completion.
.RE
.PP
+\-u
+.RS 4
+Update NSEC/NSEC3 chain when re\-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option,
+\fBdnssec\-signzone\fR
+will retain the existing chain when re\-signing.
+.RE
+.PP
\-v \fIlevel\fR
.RS 4
Sets the debugging level.
.RE
.PP
+\-x
+.RS 4
+Only sign the DNSKEY RRset with key\-signing keys, and omit signatures from zone\-signing keys. (This is similar to the
+\fBdnssec\-dnskey\-kskonly yes;\fR
+zone option in
+\fBnamed\fR.)
+.RE
+.PP
\-z
.RS 4
-Ignore KSK flag on key when determining what to sign.
+Ignore KSK flag on key when determining what to sign. This causes KSK\-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the
+\fBupdate\-check\-ksk no;\fR
+zone option in
+\fBnamed\fR.)
.RE
.PP
\-3 \fIsalt\fR
.RS 4
-Generate a NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain.
+Generate an NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain.
.RE
.PP
\-H \fIiterations\fR
.RS 4
-When generating a NSEC3 chain use this many interations. The default is 100.
+When generating an NSEC3 chain, use this many interations. The default is 10.
.RE
.PP
\-A
.RS 4
-When generating a NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+.sp
+Using this option twice (i.e.,
+\fB\-AA\fR) turns the OPTOUT flag off for all records. This is useful when using the
+\fB\-u\fR
+option to modify an NSEC3 chain which previously had OPTOUT set.
.RE
.PP
zonefile
@@ -253,9 +337,11 @@ The following command signs the
\fBexample.com\fR
zone with the DSA key generated by
\fBdnssec\-keygen\fR
-(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
-\fIkeyset\fR
-files, in the current directory, so that DS records can be generated from them (\fB\-g\fR).
+(Kexample.com.+003+17247). Because the
+\fB\-S\fR
+option is not being used, the zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
+\fIdsset\fR
+files, in the current directory, so that DS records can be imported from them (\fB\-g\fR).
.sp
.RS 4
.nf
@@ -283,18 +369,6 @@ db.example.com.signed
%
.fi
.RE
-.SH "KNOWN BUGS"
-.PP
-\fBdnssec\-signzone\fR
-was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys needed to produce a fully\-signed zone. This permits a zone administrator, for example, to sign a zone with one key on one machine, move the resulting partially\-signed zone to a second machine, and sign it again with a second key.
-.PP
-An unfortunate side\-effect of this flexibility is that
-\fBdnssec\-signzone\fR
-does not check to make sure it's signing a zone with any valid keys at all. An attempt to sign a zone without any keys will appear to succeed, producing a "signed" zone with no signatures. There is no warning issued when a zone is not fully signed.
-.PP
-This will be corrected in a future release. In the meantime, ISC recommends examining the output of
-\fBdnssec\-signzone\fR
-to confirm that the zone is properly signed by all keys before using it.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index b8f4d664b6d..3997a135b46 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.209.12.20 2010-06-03 23:47:48 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.262 2010-06-03 23:51:04 tbox Exp $ */
/*! \file */
@@ -87,6 +87,10 @@
#include "dnssectool.h"
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
+#endif
+
const char *program = "dnssec-signzone";
int verbose;
@@ -97,22 +101,11 @@ static int nsec_datatype = dns_rdatatype_nsec;
#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+
#define BUFSIZE 2048
#define MAXDSKEYS 8
-typedef struct signer_key_struct signer_key_t;
-
-struct signer_key_struct {
- dst_key_t *key;
- isc_boolean_t issigningkey;
- isc_boolean_t isdsk;
- isc_boolean_t isksk;
- isc_boolean_t wasused;
- isc_boolean_t commandline;
- unsigned int position;
- ISC_LINK(signer_key_t) link;
-};
-
#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453)
#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0)
#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1)
@@ -128,7 +121,7 @@ struct signer_event {
dns_dbnode_t *node;
};
-static ISC_LIST(signer_key_t) keylist;
+static dns_dnsseckeylist_t keylist;
static unsigned int keycount = 0;
isc_rwlock_t keylist_lock;
static isc_stdtime_t starttime = 0, endtime = 0, now;
@@ -138,7 +131,8 @@ static isc_boolean_t tryverify = ISC_FALSE;
static isc_boolean_t printstats = ISC_FALSE;
static isc_mem_t *mctx = NULL;
static isc_entropy_t *ectx = NULL;
-static dns_ttl_t zonettl;
+static dns_ttl_t zone_soa_min_ttl;
+static dns_ttl_t soa_ttl;
static FILE *fp;
static char *tempfile = NULL;
static const dns_master_style_t *masterstyle;
@@ -146,7 +140,7 @@ static dns_masterformat_t inputformat = dns_masterformat_text;
static dns_masterformat_t outputformat = dns_masterformat_text;
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
static unsigned int nverified = 0, nverifyfailed = 0;
-static const char *directory;
+static const char *directory = NULL, *dsdir = NULL;
static isc_mutex_t namelock, statslock;
static isc_taskmgr_t *taskmgr = NULL;
static dns_db_t *gdb; /* The database */
@@ -155,13 +149,18 @@ static dns_dbiterator_t *gdbiter; /* The database iterator */
static dns_rdataclass_t gclass; /* The class */
static dns_name_t *gorigin; /* The database origin */
static int nsec3flags = 0;
+static dns_iterations_t nsec3iter = 10U;
+static unsigned char saltbuf[255];
+static unsigned char *salt = saltbuf;
+static size_t salt_length = 0;
static isc_task_t *master = NULL;
static unsigned int ntasks = 0;
static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
static isc_boolean_t nokeys = ISC_FALSE;
static isc_boolean_t removefile = ISC_FALSE;
static isc_boolean_t generateds = ISC_FALSE;
-static isc_boolean_t ignoreksk = ISC_FALSE;
+static isc_boolean_t ignore_kskflag = ISC_FALSE;
+static isc_boolean_t keyset_kskonly = ISC_FALSE;
static dns_name_t *dlv = NULL;
static dns_fixedname_t dlv_fixed;
static dns_master_style_t *dsstyle = NULL;
@@ -169,6 +168,9 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
static isc_boolean_t disable_zone_check = ISC_FALSE;
+static isc_boolean_t update_chain = ISC_FALSE;
+static isc_boolean_t set_keyttl = ISC_FALSE;
+static dns_ttl_t keyttl;
#define INCSTAT(counter) \
if (printstats) { \
@@ -195,48 +197,23 @@ dumpnode(dns_name_t *name, dns_dbnode_t *node) {
check_result(result, "dns_master_dumpnodetostream");
}
-static signer_key_t *
-newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) {
- signer_key_t *key;
-
- key = isc_mem_get(mctx, sizeof(signer_key_t));
- if (key == NULL)
- fatal("out of memory");
- key->key = dstkey;
- if ((dst_key_flags(dstkey) & DNS_KEYFLAG_KSK) != 0) {
- key->issigningkey = signwithkey;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- } else {
- key->issigningkey = signwithkey;
- key->isksk = ISC_FALSE;
- key->isdsk = ISC_TRUE;
- }
- key->wasused = ISC_FALSE;
- key->commandline = ISC_FALSE;
- key->position = keycount++;
- ISC_LINK_INIT(key, link);
- return (key);
-}
-
/*%
* Sign the given RRset with given key, and add the signature record to the
* given tuple.
*/
-
static void
signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
{
isc_result_t result;
isc_stdtime_t jendtime;
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
dns_rdata_t trdata = DNS_RDATA_INIT;
unsigned char array[BUFSIZE];
isc_buffer_t b;
dns_difftuple_t *tuple;
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
vbprintf(1, "\t%s %s\n", logmsg, keystr);
jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
@@ -245,8 +222,8 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
mctx, &b, &trdata);
isc_entropy_stopcallbacksources(ectx);
if (result != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("dnskey '%s' failed to sign data: %s",
keystr, isc_result_totext(result));
}
@@ -272,31 +249,43 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
}
static inline isc_boolean_t
-issigningkey(signer_key_t *key) {
- return (key->issigningkey);
+issigningkey(dns_dnsseckey_t *key) {
+ return (key->force_sign || key->hint_sign);
}
static inline isc_boolean_t
-iszonekey(signer_key_t *key) {
+iszonekey(dns_dnsseckey_t *key) {
return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
dst_key_iszonekey(key->key)));
}
+static inline isc_boolean_t
+isksk(dns_dnsseckey_t *key) {
+ return (key->ksk);
+}
+
+static inline isc_boolean_t
+iszsk(dns_dnsseckey_t *key) {
+ return (ignore_kskflag || !key->ksk);
+}
+
/*%
- * Find the key if it is in our list. If it is, return it, otherwise null.
+ * Find the key that generated an RRSIG, if it is in the key list. If
+ * so, return a pointer to it, otherwise return NULL.
+ *
* No locking is performed here, this must be done by the caller.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
- signer_key_t *key;
+ dns_dnsseckey_t *key;
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
if (rrsig->keyid == dst_key_id(key->key) &&
rrsig->algorithm == dst_key_alg(key->key) &&
dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
return (key);
- key = ISC_LIST_NEXT(key, link);
}
return (NULL);
}
@@ -305,11 +294,11 @@ keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
* Finds the key that generated a RRSIG, if possible. First look at the keys
* that we've loaded already, and then see if there's a key on disk.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned(dns_rdata_rrsig_t *rrsig) {
isc_result_t result;
dst_key_t *pubkey = NULL, *privkey = NULL;
- signer_key_t *key;
+ dns_dnsseckey_t *key = NULL;
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
key = keythatsigned_unlocked(rrsig);
@@ -325,7 +314,6 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
* after all.
*/
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
-
key = keythatsigned_unlocked(rrsig);
if (key != NULL) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -334,7 +322,7 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm, DST_TYPE_PUBLIC,
- NULL, mctx, &pubkey);
+ directory, mctx, &pubkey);
if (result != ISC_R_SUCCESS) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (NULL);
@@ -343,12 +331,15 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm,
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
- NULL, mctx, &privkey);
+ directory, mctx, &privkey);
if (result == ISC_R_SUCCESS) {
dst_key_free(&pubkey);
- key = newkeystruct(privkey, ISC_FALSE);
- } else
- key = newkeystruct(pubkey, ISC_FALSE);
+ dns_dnsseckey_create(mctx, &privkey, &key);
+ } else {
+ dns_dnsseckey_create(mctx, &pubkey, &key);
+ }
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_FALSE;
ISC_LIST_APPEND(keylist, key, link);
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -383,15 +374,16 @@ expecttofindkey(dns_name_t *name) {
dns_name_format(name, namestr, sizeof(namestr));
fatal("failure looking for '%s DNSKEY' in database: %s",
namestr, isc_result_totext(result));
+ /* NOTREACHED */
return (ISC_FALSE); /* removes a warning */
}
static inline isc_boolean_t
-setverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key,
+setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_rdata_t *rrsig)
{
isc_result_t result;
- result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, rrsig);
+ result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
if (result == ISC_R_SUCCESS) {
INCSTAT(nverified);
return (ISC_TRUE);
@@ -413,7 +405,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
dns_rdataset_t sigset;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_rrsig_t rrsig;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_boolean_t nosigs = ISC_FALSE;
isc_boolean_t *wassignedby, *nowsignedby;
@@ -483,8 +475,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
"invalid validity period\n",
sigstr);
} else if (key == NULL && !future &&
- expecttofindkey(&rrsig.signer))
- {
+ expecttofindkey(&rrsig.signer)) {
/* rrsig is dropped and not replaced */
vbprintf(2, "\trrsig by %s dropped - "
"private dnskey not found\n",
@@ -495,35 +486,33 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
if (!expired)
keep = ISC_TRUE;
} else if (issigningkey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
resign = ISC_TRUE;
}
} else if (iszonekey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
}
} else if (!expired) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
@@ -533,7 +522,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
}
if (keep) {
- nowsignedby[key->position] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
INCSTAT(nretained);
if (sigset.ttl != ttl) {
vbprintf(2, "\tfixing ttl %s\n", sigstr);
@@ -568,8 +557,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
signwithkey(name, set, key->key, ttl, add,
"resigning with dnskey");
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
}
dns_rdata_reset(&sigrdata);
@@ -587,20 +575,37 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (nowsignedby[key->position])
+ if (nowsignedby[key->index])
continue;
- if (!key->issigningkey)
- continue;
- if (!(ignoreksk || key->isdsk ||
- (key->isksk &&
- set->type == dns_rdatatype_dnskey &&
- dns_name_equal(name, gorigin))))
+ if (!issigningkey(key))
continue;
- signwithkey(name, set, key->key, ttl, add,
- "signing with dnskey");
- key->wasused = ISC_TRUE;
+ if (set->type == dns_rdatatype_dnskey &&
+ dns_name_equal(name, gorigin)) {
+ isc_boolean_t have_ksk;
+ dns_dnsseckey_t *tmpkey;
+
+ have_ksk = isksk(key);
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) !=
+ dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ }
+ if (isksk(key) || !have_ksk ||
+ (iszsk(key) && !keyset_kskonly))
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ } else if (iszsk(key)) {
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ }
}
isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
@@ -774,16 +779,21 @@ static void
opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
dns_db_t **dbp)
{
- char filename[256];
+ char filename[PATH_MAX];
isc_buffer_t b;
isc_result_t result;
isc_buffer_init(&b, filename, sizeof(filename));
- if (directory != NULL) {
- isc_buffer_putstr(&b, directory);
- if (directory[strlen(directory) - 1] != '/')
+ if (dsdir != NULL) {
+ /* allow room for a trailing slash */
+ if (strlen(dsdir) >= isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
+ isc_buffer_putstr(&b, dsdir);
+ if (dsdir[strlen(dsdir) - 1] != '/')
isc_buffer_putstr(&b, "/");
}
+ if (strlen(prefix) > isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
isc_buffer_putstr(&b, prefix);
result = dns_name_tofilenametext(name, ISC_FALSE, &b);
check_result(result, "dns_name_tofilenametext()");
@@ -798,13 +808,15 @@ opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
rdclass, 0, NULL, dbp);
check_result(result, "dns_db_create()");
- result = dns_db_load(*dbp, filename);
+ result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
dns_db_detach(dbp);
}
/*%
- * Loads the key set for a child zone, if there is one, and builds DS records.
+ * Load the DS set for a child zone, if a dsset-* file can be found.
+ * If not, try to find a keyset-* file from an earlier version of
+ * dnssec-signzone, and build DS records from that.
*/
static isc_result_t
loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
@@ -818,29 +830,49 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
dns_diff_t diff;
dns_difftuple_t *tuple = NULL;
+ opendb("dsset-", name, gclass, &db);
+ if (db != NULL) {
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_init(dsset);
+ result = dns_db_findrdataset(db, node, NULL,
+ dns_rdatatype_ds, 0, 0,
+ dsset, NULL);
+ dns_db_detachnode(db, &node);
+ if (result == ISC_R_SUCCESS) {
+ vbprintf(2, "found DS records\n");
+ dsset->ttl = ttl;
+ dns_db_detach(&db);
+ return (result);
+ }
+ }
+ dns_db_detach(&db);
+ }
+
+ /* No DS records found; try again, looking for DNSKEY records */
opendb("keyset-", name, gclass, &db);
- if (db == NULL)
+ if (db == NULL) {
return (ISC_R_NOTFOUND);
+ }
result = dns_db_findnode(db, name, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS) {
dns_db_detach(&db);
- return (DNS_R_BADDB);
+ return (result);
}
+
dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0,
- 0, &keyset, NULL);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
+ &keyset, NULL);
if (result != ISC_R_SUCCESS) {
dns_db_detachnode(db, &node);
dns_db_detach(&db);
return (result);
}
-
vbprintf(2, "found DNSKEY records\n");
result = dns_db_newversion(db, &ver);
check_result(result, "dns_db_newversion");
-
dns_diff_init(mctx, &diff);
for (result = dns_rdataset_first(&keyset);
@@ -869,6 +901,7 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
}
+
result = dns_diff_apply(&diff, db, ver);
check_result(result, "dns_diff_apply");
dns_diff_clear(&diff);
@@ -1112,17 +1145,15 @@ active_node(dns_dbnode_t *node) {
}
/*%
- * Extracts the TTL from the SOA.
+ * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
*/
-static dns_ttl_t
-soattl(void) {
+static void
+get_soa_ttls(void) {
dns_rdataset_t soaset;
dns_fixedname_t fname;
dns_name_t *name;
isc_result_t result;
- dns_ttl_t ttl;
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -1136,11 +1167,9 @@ soattl(void) {
result = dns_rdataset_first(&soaset);
check_result(result, "dns_rdataset_first");
dns_rdataset_current(&soaset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- check_result(result, "dns_rdata_tostruct");
- ttl = soa.minimum;
+ zone_soa_min_ttl = dns_soa_getminimum(&rdata);
+ soa_ttl = soaset.ttl;
dns_rdataset_disassociate(&soaset);
- return (ttl);
}
/*%
@@ -1371,7 +1400,7 @@ verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
for (i = 0; i < 256; i++)
if ((ksk_algorithms[i] != 0) &&
(set_algorithms[i] == 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, "Missing %s signature for "
"%s %s\n", algbuf, namebuf, typebuf);
bad_algorithms[i] = 1;
@@ -1414,8 +1443,8 @@ verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
/*%
* Verify that certain things are sane:
*
- * The apex has a DNSKEY record with at least one KSK and at least
- * one ZSK.
+ * The apex has a DNSKEY record with at least one KSK, and at least
+ * one ZSK if the -x flag was not used.
*
* The DNSKEY record was signed with at least one of the KSKs in this
* set.
@@ -1440,8 +1469,10 @@ verifyzone(void) {
isc_boolean_t goodksk = ISC_FALSE;
isc_boolean_t goodzsk = ISC_FALSE;
isc_result_t result;
- unsigned char revoked[256];
- unsigned char standby[256];
+ unsigned char revoked_ksk[256];
+ unsigned char revoked_zsk[256];
+ unsigned char standby_ksk[256];
+ unsigned char standby_zsk[256];
unsigned char ksk_algorithms[256];
unsigned char zsk_algorithms[256];
unsigned char bad_algorithms[256];
@@ -1470,8 +1501,10 @@ verifyzone(void) {
if (!dns_rdataset_isassociated(&sigrdataset))
fatal("cannot find DNSKEY RRSIGs\n");
- memset(revoked, 0, sizeof(revoked));
- memset(standby, 0, sizeof(revoked));
+ memset(revoked_ksk, 0, sizeof(revoked_ksk));
+ memset(revoked_zsk, 0, sizeof(revoked_zsk));
+ memset(standby_ksk, 0, sizeof(standby_ksk));
+ memset(standby_zsk, 0, sizeof(standby_zsk));
memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
memset(bad_algorithms, 0, sizeof(bad_algorithms));
@@ -1480,8 +1513,9 @@ verifyzone(void) {
#endif
/*
- * Check that the DNSKEY RR has at least one self signing KSK and
- * one ZSK per algorithm in it.
+ * Check that the DNSKEY RR has at least one self signing KSK
+ * and one ZSK per algorithm in it (or, if -x was used, one
+ * self-signing KSK).
*/
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
@@ -1511,8 +1545,11 @@ verifyzone(void) {
(int)isc_buffer_usedlength(&buf), buffer);
}
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
- revoked[dnskey.algorithm] != 255)
- revoked[dnskey.algorithm]++;
+ revoked_ksk[dnskey.algorithm] != 255)
+ revoked_ksk[dnskey.algorithm]++;
+ else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
+ revoked_zsk[dnskey.algorithm] != 255)
+ revoked_zsk[dnskey.algorithm]++;
} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE, mctx)) {
@@ -1520,8 +1557,8 @@ verifyzone(void) {
ksk_algorithms[dnskey.algorithm]++;
goodksk = ISC_TRUE;
} else {
- if (standby[dnskey.algorithm] != 255)
- standby[dnskey.algorithm]++;
+ if (standby_ksk[dnskey.algorithm] != 255)
+ standby_ksk[dnskey.algorithm]++;
}
} else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE,
@@ -1534,8 +1571,8 @@ verifyzone(void) {
zsk_algorithms[dnskey.algorithm]++;
goodzsk = ISC_TRUE;
} else {
- if (zsk_algorithms[dnskey.algorithm] != 255)
- zsk_algorithms[dnskey.algorithm]++;
+ if (standby_zsk[dnskey.algorithm] != 255)
+ standby_zsk[dnskey.algorithm]++;
#ifdef ALLOW_KSKLESS_ZONES
allzsksigned = ISC_FALSE;
#endif
@@ -1545,42 +1582,54 @@ verifyzone(void) {
}
dns_rdataset_disassociate(&sigrdataset);
- if (!goodksk) {
#ifdef ALLOW_KSKLESS_ZONES
- if (!goodzsk)
- fatal("no self signing keys found");
- fprintf(stderr, "No self signing KSK found. Using self signed "
- "ZSK's for active algorithm list.\n");
+ if (!goodksk) {
+ if (!ignore_kskflag)
+ fprintf(stderr, "No self signing KSK found. Using "
+ "self signed ZSK's for active "
+ "algorithm list.\n");
memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
if (!allzsksigned)
fprintf(stderr, "warning: not all ZSK's are self "
"signed.\n");
-#else
- fatal("no self signed KSK's found");
-#endif
}
+#else
+ if (!goodksk) {
+ fatal("no self signed KSK's found");
+ }
+#endif
fprintf(stderr, "Verifying the zone using the following algorithms:");
for (i = 0; i < 256; i++) {
- if (ksk_algorithms[i] != 0) {
- alg_format(i, algbuf, sizeof(algbuf));
+#ifdef ALLOW_KSKLESS_ZONES
+ if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
+#else
+ if (ksk_algorithms[i] != 0)
+#endif
+ {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
}
}
fprintf(stderr, ".\n");
- for (i = 0; i < 256; i++) {
- /*
- * The counts should both be zero or both be non-zero.
- * Mark the algorithm as bad if this is not met.
- */
- if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0))
- continue;
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Missing %s for algorithm %s\n",
- (ksk_algorithms[i] != 0) ? "ZSK" : "self signing KSK",
- algbuf);
- bad_algorithms[i] = 1;
+ if (!ignore_kskflag && !keyset_kskonly) {
+ for (i = 0; i < 256; i++) {
+ /*
+ * The counts should both be zero or both be non-zero.
+ * Mark the algorithm as bad if this is not met.
+ */
+ if ((ksk_algorithms[i] != 0) ==
+ (zsk_algorithms[i] != 0))
+ continue;
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s for algorithm %s\n",
+ (ksk_algorithms[i] != 0)
+ ? "ZSK"
+ : "self signing KSK",
+ algbuf);
+ bad_algorithms[i] = 1;
+ }
}
/*
@@ -1674,7 +1723,7 @@ verifyzone(void) {
if (first)
fprintf(stderr, "The zone is not fully signed "
"for the following algorithms:");
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
first = ISC_FALSE;
}
@@ -1684,21 +1733,30 @@ verifyzone(void) {
fatal("DNSSEC completeness test failed.");
}
- if (goodksk) {
+ if (goodksk || ignore_kskflag) {
/*
* Print the success summary.
*/
fprintf(stderr, "Zone signing complete:\n");
for (i = 0; i < 256; i++) {
- if ((zsk_algorithms[i] != 0) ||
- (ksk_algorithms[i] != 0) ||
- (revoked[i] != 0) || (standby[i] != 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Algorithm: %s: ZSKs: %u, "
- "KSKs: %u active, %u revoked, %u "
- "stand-by\n", algbuf,
- zsk_algorithms[i], ksk_algorithms[i],
- revoked[i], standby[i]);
+ if ((ksk_algorithms[i] != 0) ||
+ (standby_ksk[i] != 0) ||
+ (revoked_zsk[i] != 0) ||
+ (zsk_algorithms[i] != 0) ||
+ (standby_zsk[i] != 0) ||
+ (revoked_zsk[i] != 0)) {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Algorithm: %s: KSKs: "
+ "%u active, %u stand-by, %u revoked\n",
+ algbuf, ksk_algorithms[i],
+ standby_ksk[i], revoked_ksk[i]);
+ fprintf(stderr, "%*sZSKs: "
+ "%u active, %u %s, %u revoked\n",
+ (int) strlen(algbuf) + 13, "",
+ zsk_algorithms[i],
+ standby_zsk[i],
+ keyset_kskonly ? "present" : "stand-by",
+ revoked_zsk[i]);
}
}
}
@@ -1923,6 +1981,7 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
dns_rdatatype_ds, 0);
check_result(result, "dns_db_deleterdataset");
}
+
result = loadds(name, nsttl, &dsset);
if (result == ISC_R_SUCCESS) {
result = dns_db_addrdataset(gdb, node, gversion, 0,
@@ -1953,7 +2012,7 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
dns_rdataset_init(&rdataset);
/*
- * Delete any NSEC records at the apex.
+ * Delete any records of the given type at the apex.
*/
result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()");
@@ -1965,6 +2024,12 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
covers = rdataset.covers;
dns_rdataset_disassociate(&rdataset);
if (type == which || covers == which) {
+ if (which == dns_rdatatype_nsec && !update_chain)
+ fatal("Zone contains NSEC records. Use -u "
+ "to update to NSEC3.");
+ if (which == dns_rdatatype_nsec3param && !update_chain)
+ fatal("Zone contains NSEC3 chains. Use -u "
+ "to update to NSEC.");
result = dns_db_deleterdataset(gdb, node, gversion,
type, covers);
check_result(result, "dns_db_deleterdataset()");
@@ -2088,8 +2153,9 @@ nsecify(void) {
} else if (result != ISC_R_SUCCESS)
fatal("iterating through the database failed: %s",
isc_result_totext(result));
+ dns_dbiterator_pause(dbiter);
result = dns_nsec_build(gdb, gversion, node, nextname,
- zonettl);
+ zone_soa_min_ttl);
check_result(result, "dns_nsec_build()");
dns_db_detachnode(gdb, &node);
}
@@ -2320,6 +2386,97 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
}
+static void
+rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
+ dns_diff_t *diff)
+{
+ dns_difftuple_t *tuple = NULL;
+ isc_result_t result;
+ unsigned int count1 = 0;
+ dns_rdataset_t tmprdataset;
+
+ dns_rdataset_init(&tmprdataset);
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ unsigned int count2 = 0;
+
+ count1++;
+ dns_rdataset_current(rdataset, &rdata1);
+ dns_rdataset_clone(rdataset, &tmprdataset);
+ for (result = dns_rdataset_first(&tmprdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&tmprdataset)) {
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ count2++;
+ if (count1 >= count2)
+ continue;
+ dns_rdataset_current(&tmprdataset, &rdata2);
+ if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
+ result = dns_difftuple_create(mctx,
+ DNS_DIFFOP_DEL,
+ name,
+ rdataset->ttl,
+ &rdata2, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(diff, &tuple);
+ }
+ }
+ dns_rdataset_disassociate(&tmprdataset);
+ }
+}
+
+static void
+remove_duplicates(void) {
+ isc_result_t result;
+ dns_dbiterator_t *dbiter = NULL;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ dns_diff_t diff;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+
+ dns_diff_init(mctx, &diff);
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_createiterator(gdb, 0, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter)) {
+
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ rrset_remove_duplicates(name, &rdataset, &diff);
+ dns_rdataset_disassociate(&rdataset);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdatasets iteration failed.");
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("zone iteration failed.");
+
+ if (!ISC_LIST_EMPTY(diff.tuples)) {
+ result = dns_diff_applysilently(&diff, gdb, gversion);
+ check_result(result, "dns_diff_applysilently");
+ }
+ dns_diff_clear(&diff);
+ dns_dbiterator_destroy(&dbiter);
+}
+
/*
* Generate NSEC3 records for the zone.
*/
@@ -2546,7 +2703,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
*/
dns_dbiterator_pause(dbiter);
addnsec3(name, node, salt, salt_length, iterations,
- hashlist, zonettl);
+ hashlist, zone_soa_min_ttl);
dns_db_detachnode(gdb, &node);
/*
* Add NSEC3's for empty nodes. Use closest encloser logic.
@@ -2557,7 +2714,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
count--;
dns_name_split(nextname, count, NULL, nextname);
addnsec3(nextname, NULL, salt, salt_length,
- iterations, hashlist, zonettl);
+ iterations, hashlist, zone_soa_min_ttl);
}
}
dns_dbiterator_destroy(&dbiter);
@@ -2580,7 +2737,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("failed converting name '%s' to dns format: %s",
origin, isc_result_totext(result));
@@ -2600,90 +2757,169 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
* private keys from disk.
*/
static void
-loadzonekeys(dns_db_t *db) {
+loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
dns_dbnode_t *node;
- dns_dbversion_t *currentversion;
+ dns_dbversion_t *currentversion = NULL;
isc_result_t result;
- dst_key_t *keys[20];
- unsigned int nkeys, i;
-
- currentversion = NULL;
- dns_db_currentversion(db, ¤tversion);
+ dns_rdataset_t rdataset, keysigs, soasigs;
node = NULL;
- result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
+ result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s",
isc_result_totext(result));
- result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin,
- mctx, 20, keys, &nkeys);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
- if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone keys: %s",
- isc_result_totext(result));
-
- for (i = 0; i < nkeys; i++) {
- signer_key_t *key;
-
- key = newkeystruct(keys[i], dst_key_isprivate(keys[i]));
- ISC_LIST_APPEND(keylist, key, link);
- }
- dns_db_detachnode(db, &node);
- dns_db_closeversion(db, ¤tversion, ISC_FALSE);
-}
-
-/*%
- * Finds all public zone keys in the zone.
- */
-static void
-loadzonepubkeys(dns_db_t *db) {
- dns_dbversion_t *currentversion = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dst_key_t *pubkey;
- signer_key_t *key;
- isc_result_t result;
-
- dns_db_currentversion(db, ¤tversion);
-
- result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone's origin: %s",
- isc_result_totext(result));
+ dns_db_currentversion(gdb, ¤tversion);
dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, currentversion,
- dns_rdatatype_dnskey, 0, 0, &rdataset,
- NULL);
+ dns_rdataset_init(&soasigs);
+ dns_rdataset_init(&keysigs);
+
+ /* Make note of the keys which signed the SOA, if any */
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_soa, 0, 0,
+ &rdataset, &soasigs);
if (result != ISC_R_SUCCESS)
- fatal("failed to find keys at the zone apex: %s",
+ goto cleanup;
+
+ /* Preserve the TTL of the DNSKEY RRset, if any */
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_dnskey, 0, 0,
+ &rdataset, &keysigs);
+
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ if (set_keyttl && keyttl != rdataset.ttl) {
+ fprintf(stderr, "User-specified TTL (%d) conflicts "
+ "with existing DNSKEY RRset TTL.\n",
+ keyttl);
+ fprintf(stderr, "Imported keys will use the RRSet "
+ "TTL (%d) instead.\n",
+ rdataset.ttl);
+ }
+ keyttl = rdataset.ttl;
+
+ /* Load keys corresponding to the existing DNSKEY RRset */
+ result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
+ &rdataset, &keysigs, &soasigs,
+ preserve_keys, load_public,
+ &keylist);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to load the zone keys: %s",
isc_result_totext(result));
- result = dns_rdataset_first(&rdataset);
- check_result(result, "dns_rdataset_first");
- while (result == ISC_R_SUCCESS) {
- pubkey = NULL;
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
- &pubkey);
+
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (dns_rdataset_isassociated(&keysigs))
+ dns_rdataset_disassociate(&keysigs);
+ if (dns_rdataset_isassociated(&soasigs))
+ dns_rdataset_disassociate(&soasigs);
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, ¤tversion, ISC_FALSE);
+}
+
+static void
+loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
+ isc_result_t result;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ dns_dnsseckey_t *key = NULL;
+ dst_key_t *newkey = NULL;
+
+ result = dst_key_fromnamedfile(keyfiles[i], directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &newkey);
if (result != ISC_R_SUCCESS)
- goto next;
- if (!dst_key_iszonekey(pubkey)) {
- dst_key_free(&pubkey);
- goto next;
+ fatal("cannot load dnskey %s: %s", keyfiles[i],
+ isc_result_totext(result));
+
+ if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+ fatal("key %s not at origin\n", keyfiles[i]);
+
+ if (!dst_key_isprivate(newkey))
+ fatal("cannot sign zone with non-private dnskey %s",
+ keyfiles[i]);
+
+ /* Skip any duplicates */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (dst_key_id(key->key) == dst_key_id(newkey) &&
+ dst_key_alg(key->key) == dst_key_alg(newkey))
+ break;
}
- key = newkeystruct(pubkey, ISC_FALSE);
- ISC_LIST_APPEND(keylist, key, link);
- next:
- result = dns_rdataset_next(&rdataset);
+ if (key == NULL) {
+ /* We haven't seen this key before */
+ dns_dnsseckey_create(mctx, &newkey, &key);
+ ISC_LIST_APPEND(keylist, key, link);
+ key->source = dns_keysource_user;
+ } else {
+ dst_key_free(&key->key);
+ key->key = newkey;
+ }
+
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_TRUE;
+
+ if (setksk)
+ key->ksk = ISC_TRUE;
}
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- dns_db_closeversion(db, ¤tversion, ISC_FALSE);
+}
+
+static void
+report(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+}
+
+static void
+build_final_keylist() {
+ isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ dns_dnsseckeylist_t matchkeys;
+ char name[DNS_NAME_FORMATSIZE];
+
+ /*
+ * Find keys that match this zone in the key repository.
+ */
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(gorigin, directory,
+ mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_SUCCESS;
+ check_result(result, "dns_dnssec_findmatchingkeys");
+
+ result = dns_db_newversion(gdb, &ver);
+ check_result(result, "dns_db_newversion");
+
+ dns_diff_init(mctx, &diff);
+
+ /*
+ * Update keylist with information from from the key repository.
+ */
+ dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
+ &diff, ignore_kskflag, mctx, report);
+
+ dns_name_format(gorigin, name, sizeof(name));
+
+ result = dns_diff_applysilently(&diff, gdb, ver);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to update DNSKEY RRset at node '%s': %s",
+ name, isc_result_totext(result));
+
+ dns_db_closeversion(gdb, &ver, ISC_TRUE);
+
+ dns_diff_clear(&diff);
}
static void
@@ -2727,17 +2963,111 @@ warnifallksk(dns_db_t *db) {
dns_rdataset_disassociate(&rdataset);
dns_db_detachnode(db, &node);
dns_db_closeversion(db, ¤tversion, ISC_FALSE);
- if (!have_non_ksk && !ignoreksk) {
+ if (!have_non_ksk && !ignore_kskflag) {
if (disable_zone_check)
- fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.\n",
+ fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.\n",
program);
else
- fatal("No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.");
+ fatal("No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.");
}
}
+static void
+set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
+ isc_boolean_t set_optout, isc_boolean_t set_iter)
+{
+ isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_nsec3_t nsec3;
+ dns_fixedname_t fname;
+ dns_name_t *hashname;
+ unsigned char orig_salt[256];
+ size_t orig_saltlen;
+ dns_hash_t orig_hash;
+ isc_uint16_t orig_iter;
+
+ dns_db_currentversion(gdb, &ver);
+ dns_rdataset_init(&rdataset);
+
+ orig_saltlen = sizeof(orig_salt);
+ result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
+ &orig_iter, orig_salt,
+ &orig_saltlen);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ nsec_datatype = dns_rdatatype_nsec3;
+
+ if (!update_chain && set_salt) {
+ if (salt_length != orig_saltlen ||
+ memcmp(saltbuf, orig_salt, salt_length) != 0)
+ fatal("An NSEC3 chain exists with a different salt. "
+ "Use -u to update it.");
+ } else if (!set_salt) {
+ salt_length = orig_saltlen;
+ memcpy(saltbuf, orig_salt, orig_saltlen);
+ salt = saltbuf;
+ }
+
+ if (!update_chain && set_iter) {
+ if (nsec3iter != orig_iter)
+ fatal("An NSEC3 chain exists with different "
+ "iterations. Use -u to update it.");
+ } else if (!set_iter)
+ nsec3iter = orig_iter;
+
+ /*
+ * Find an NSEC3 record to get the current OPTOUT value.
+ * (This assumes all NSEC3 records agree.)
+ */
+
+ dns_fixedname_init(&fname);
+ hashname = dns_fixedname_name(&fname);
+ result = dns_nsec3_hashname(&fname, NULL, NULL,
+ gorigin, gorigin, dns_hash_sha1,
+ orig_iter, orig_salt, orig_saltlen);
+ check_result(result, "dns_nsec3_hashname");
+
+ result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_rdataset_first(&rdataset);
+ check_result(result, "dns_rdataset_first");
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ check_result(result, "dns_rdata_tostruct");
+
+ if (!update_chain && set_optout) {
+ if (nsec3flags != nsec3.flags)
+ fatal("An NSEC3 chain exists with%s OPTOUT. "
+ "Use -u -%s to %s it.",
+ OPTOUT(nsec3.flags) ? "" : "out",
+ OPTOUT(nsec3.flags) ? "AA" : "A",
+ OPTOUT(nsec3.flags) ? "clear" : "set");
+ } else if (!set_optout)
+ nsec3flags = nsec3.flags;
+
+ dns_rdata_freestruct(&nsec3);
+
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, &ver, ISC_FALSE);
+}
+
static void
writeset(const char *prefix, dns_rdatatype_t type) {
char *filename;
@@ -2755,7 +3085,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
isc_buffer_t namebuf;
isc_region_t r;
isc_result_t result;
- signer_key_t *key;
+ dns_dnsseckey_t *key, *tmpkey;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
unsigned char keybuf[DST_KEY_MAXSIZE];
unsigned int filenamelen;
@@ -2767,13 +3097,13 @@ writeset(const char *prefix, dns_rdatatype_t type) {
check_result(result, "dns_name_tofilenametext");
isc_buffer_putuint8(&namebuf, 0);
filenamelen = strlen(prefix) + strlen(namestr);
- if (directory != NULL)
- filenamelen += strlen(directory) + 1;
+ if (dsdir != NULL)
+ filenamelen += strlen(dsdir) + 1;
filename = isc_mem_get(mctx, filenamelen + 1);
if (filename == NULL)
fatal("out of memory");
- if (directory != NULL)
- sprintf(filename, "%s/", directory);
+ if (dsdir != NULL)
+ sprintf(filename, "%s/", dsdir);
else
filename[0] = 0;
strcat(filename, prefix);
@@ -2781,22 +3111,6 @@ writeset(const char *prefix, dns_rdatatype_t type) {
dns_diff_init(mctx, &diff);
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (!key->isksk) {
- have_non_ksk = ISC_TRUE;
- break;
- }
-
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (key->isksk) {
- have_ksk = ISC_TRUE;
- break;
- }
-
if (type == dns_rdatatype_dlv) {
dns_name_t tname;
unsigned int labels;
@@ -2815,7 +3129,28 @@ writeset(const char *prefix, dns_rdatatype_t type) {
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (have_ksk && have_non_ksk && !key->isksk)
+ if (REVOKE(key->key))
+ continue;
+ if (isksk(key)) {
+ have_ksk = ISC_TRUE;
+ have_non_ksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_non_ksk = ISC_TRUE;
+ }
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ else
+ have_non_ksk = ISC_TRUE;
+ }
+ if (have_ksk && have_non_ksk && !isksk(key))
continue;
dns_rdata_init(&rdata);
dns_rdata_init(&ds);
@@ -2848,7 +3183,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
} else
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
- gorigin, zonettl,
+ gorigin, zone_soa_min_ttl,
&rdata, &tuple);
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
@@ -2893,6 +3228,9 @@ print_version(FILE *fp) {
fprintf(fp, "; dnssec_signzone version " VERSION "\n");
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
fprintf(stderr, "Usage:\n");
@@ -2903,14 +3241,18 @@ usage(void) {
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options: (default value in parenthesis) \n");
- fprintf(stderr, "\t-c class (IN)\n");
- fprintf(stderr, "\t-d directory\n");
- fprintf(stderr, "\t\tdirectory to find keyset files (.)\n");
+ fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
+ "\t\tfor the zone and determines how they are to "
+ "be used\n");
+ fprintf(stderr, "\t-K directory:\n");
+ fprintf(stderr, "\t\tdirectory to find key files (.)\n");
+ fprintf(stderr, "\t-d directory:\n");
+ fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n");
fprintf(stderr, "\t-g:\t");
- fprintf(stderr, "generate DS records from keyset files\n");
+ fprintf(stderr, "update DS records based on child zones' "
+ "dsset-* files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
- fprintf(stderr, "\t\tRRSIG start time - absolute|offset "
- "(now - 1 hour)\n");
+ fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
@@ -2918,8 +3260,7 @@ usage(void) {
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-j jitter:\n");
- fprintf(stderr, "\t\trandomize signature end time up to jitter "
- "seconds\n");
+ fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
fprintf(stderr, "\t-v debuglevel (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
@@ -2936,20 +3277,33 @@ usage(void) {
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
fprintf(stderr, "verify generated signatures\n");
+ fprintf(stderr, "\t-c class (IN)\n");
+ fprintf(stderr, "\t-E engine:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use "
+ "(default is \"pkcs11\")\n");
+#else
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
+#endif
fprintf(stderr, "\t-p:\t");
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-P:\t");
fprintf(stderr, "disable post-sign verification\n");
+ fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
+ fprintf(stderr, "\t-u:\t");
+ fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
+ fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n");
+ fprintf(stderr, "\t-z:\tsign all records with KSKs\n");
+ fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
+ "\t\twith older versions of dnssec-signzone -g\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
fprintf(stderr, "\t-k key_signing_key\n");
fprintf(stderr, "\t-l lookasidezone\n");
- fprintf(stderr, "\t-3 salt (NSEC3 salt)\n");
- fprintf(stderr, "\t-H iterations (NSEC3 iterations)\n");
- fprintf(stderr, "\t-A (NSEC3 optout)\n");
- fprintf(stderr, "\t-z:\t");
- fprintf(stderr, "ignore KSK flag in DNSKEYs");
+ fprintf(stderr, "\t-3 NSEC3 salt\n");
+ fprintf(stderr, "\t-H NSEC3 iterations (10)\n");
+ fprintf(stderr, "\t-A NSEC3 optout\n");
fprintf(stderr, "\n");
@@ -3001,10 +3355,15 @@ main(int argc, char *argv[]) {
int ndskeys = 0;
char *endp;
isc_time_t timer_start, timer_finish;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_boolean_t pseudorandom = ISC_FALSE;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
unsigned int eflags;
isc_boolean_t free_output = ISC_FALSE;
int tempfilelen;
@@ -3012,13 +3371,15 @@ main(int argc, char *argv[]) {
isc_task_t **tasks = NULL;
isc_buffer_t b;
int len;
- unsigned int iterations = 100U;
- const unsigned char *salt = NULL;
- size_t salt_length = 0;
- unsigned char saltbuf[255];
hashlist_t hashlist;
+ isc_boolean_t smartsign = ISC_FALSE;
+ isc_boolean_t make_keyset = ISC_FALSE;
+ isc_boolean_t set_salt = ISC_FALSE;
+ isc_boolean_t set_optout = ISC_FALSE;
+ isc_boolean_t set_iter = ISC_FALSE;
-#define CMDLINE_FLAGS "3:aAc:d:e:f:FghH:i:I:j:k:l:m:n:N:o:O:pPr:s:StUv:z"
+#define CMDLINE_FLAGS \
+ "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
/*
* Process memory debugging argument first.
@@ -3058,7 +3419,9 @@ main(int argc, char *argv[]) {
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
case '3':
- if (strcmp(isc_commandline_argument, "-")) {
+ set_salt = ISC_TRUE;
+ nsec_datatype = dns_rdatatype_nsec3;
+ if (strcmp(isc_commandline_argument, "-") != 0) {
isc_buffer_t target;
char *sarg;
@@ -3068,29 +3431,42 @@ main(int argc, char *argv[]) {
result = isc_hex_decodestring(sarg, &target);
check_result(result,
"isc_hex_decodestring(salt)");
- salt = saltbuf;
salt_length = isc_buffer_usedlength(&target);
- } else {
- salt = saltbuf;
- salt_length = 0;
}
- nsec_datatype = dns_rdatatype_nsec3;
break;
case 'A':
- nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
+ set_optout = ISC_TRUE;
+ if (OPTOUT(nsec3flags))
+ nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
+ else
+ nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
break;
case 'a':
tryverify = ISC_TRUE;
break;
+ case 'C':
+ make_keyset = ISC_TRUE;
+ break;
+
case 'c':
classname = isc_commandline_argument;
break;
case 'd':
- directory = isc_commandline_argument;
+ dsdir = isc_commandline_argument;
+ if (strlen(dsdir) == 0U)
+ fatal("DS directory must be non-empty string");
+ result = try_dir(dsdir);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ dsdir, isc_result_totext(result));
+ break;
+
+ case 'E':
+ engine = isc_commandline_argument;
break;
case 'e':
@@ -3106,11 +3482,11 @@ main(int argc, char *argv[]) {
break;
case 'H':
- iterations = strtoul(isc_commandline_argument,
- &endp, 0);
+ set_iter = ISC_TRUE;
+ nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("iterations must be numeric");
- if (iterations > 0xffffU)
+ if (nsec3iter > 0xffffU)
fatal("iterations too big");
break;
@@ -3118,6 +3494,10 @@ main(int argc, char *argv[]) {
usage();
break;
+ case 'I':
+ inputformatstr = isc_commandline_argument;
+ break;
+
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
@@ -3126,10 +3506,6 @@ main(int argc, char *argv[]) {
"positive");
break;
- case 'I':
- inputformatstr = isc_commandline_argument;
- break;
-
case 'j':
endp = NULL;
jitter = strtol(isc_commandline_argument, &endp, 0);
@@ -3137,6 +3513,10 @@ main(int argc, char *argv[]) {
fatal("jitter must be numeric and positive");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ break;
+
case 'k':
if (ndskeys == MAXDSKEYS)
fatal("too many key-signing keys specified");
@@ -3150,14 +3530,18 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&dlv_fixed);
dlv = dns_fixedname_name(&dlv_fixed);
- result = dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
+ NULL);
check_result(result, "dns_name_fromtext(dlv)");
break;
case 'm':
break;
+ case 'N':
+ serialformatstr = isc_commandline_argument;
+ break;
+
case 'n':
endp = NULL;
ntasks = strtol(isc_commandline_argument, &endp, 0);
@@ -3165,38 +3549,38 @@ main(int argc, char *argv[]) {
fatal("number of cpus must be numeric");
break;
- case 'N':
- serialformatstr = isc_commandline_argument;
+ case 'O':
+ outputformatstr = isc_commandline_argument;
break;
case 'o':
origin = isc_commandline_argument;
break;
- case 'O':
- outputformatstr = isc_commandline_argument;
+ case 'P':
+ disable_zone_check = ISC_TRUE;
break;
case 'p':
pseudorandom = ISC_TRUE;
break;
- case 'P':
- disable_zone_check = ISC_TRUE;
- break;
-
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
+ case 'S':
+ smartsign = ISC_TRUE;
+ break;
+
case 's':
startstr = isc_commandline_argument;
break;
- case 'S':
- /* This is intentionally undocumented */
- /* -S: simple output style */
- masterstyle = &dns_master_style_simple;
+ case 'T':
+ endp = NULL;
+ set_keyttl = ISC_TRUE;
+ keyttl = strtottl(isc_commandline_argument);
break;
case 't':
@@ -3207,6 +3591,10 @@ main(int argc, char *argv[]) {
unknownalg = ISC_TRUE;
break;
+ case 'u':
+ update_chain = ISC_TRUE;
+ break;
+
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
@@ -3214,8 +3602,12 @@ main(int argc, char *argv[]) {
fatal("verbose level must be numeric");
break;
+ case 'x':
+ keyset_kskonly = ISC_TRUE;
+ break;
+
case 'z':
- ignoreksk = ISC_TRUE;
+ ignore_kskflag = ISC_TRUE;
break;
case 'F':
@@ -3245,20 +3637,21 @@ main(int argc, char *argv[]) {
if (result != ISC_R_SUCCESS)
fatal("could not create hash context");
- result = dst_lib_init(mctx, ectx, eflags);
+ result = dst_lib_init2(mctx, ectx, engine, eflags);
if (result != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(result));
isc_stdtime_get(&now);
- if (startstr != NULL)
+ if (startstr != NULL) {
starttime = strtotime(startstr, now, now);
- else
+ } else
starttime = now - 3600; /* Allow for some clock skew. */
- if (endstr != NULL)
+ if (endstr != NULL) {
endtime = strtotime(endstr, now, starttime);
- else
+ } else
endtime = starttime + (30 * 24 * 60 * 60);
if (cycle == -1)
@@ -3270,6 +3663,9 @@ main(int argc, char *argv[]) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
setup_logging(verbose, mctx, &log);
argc -= isc_commandline_index;
@@ -3335,7 +3731,19 @@ main(int argc, char *argv[]) {
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
gclass = dns_db_class(gdb);
- zonettl = soattl();
+ get_soa_ttls();
+
+ if (!set_keyttl)
+ keyttl = soa_ttl;
+
+ /*
+ * Check for any existing NSEC3 parameters in the zone,
+ * and use them as defaults if -u was not specified.
+ */
+ if (update_chain && !set_optout && !set_iter && !set_salt)
+ nsec_datatype = dns_rdatatype_nsec;
+ else
+ set_nsec3params(update_chain, set_salt, set_optout, set_iter);
if (IS_NSEC3) {
isc_boolean_t answer;
@@ -3356,95 +3764,42 @@ main(int argc, char *argv[]) {
ISC_LIST_INIT(keylist);
isc_rwlock_init(&keylist_lock, 0, 0);
- if (argc == 0) {
- loadzonekeys(gdb);
- } else {
- for (i = 0; i < argc; i++) {
- dst_key_t *newkey = NULL;
+ /*
+ * Fill keylist with:
+ * 1) Keys listed in the DNSKEY set that have
+ * private keys associated, *if* no keys were
+ * set on the command line.
+ * 2) ZSKs set on the command line
+ * 3) KSKs set on the command line
+ * 4) Any keys remaining in the DNSKEY set which
+ * do not have private keys associated and were
+ * not specified on the command line.
+ */
+ if (argc == 0 || smartsign)
+ loadzonekeys(!smartsign, ISC_FALSE);
+ loadexplicitkeys(argv, argc, ISC_FALSE);
+ loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
+ loadzonekeys(!smartsign, ISC_TRUE);
- result = dst_key_fromnamedfile(argv[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- fatal("cannot load dnskey %s: %s", argv[i],
- isc_result_totext(result));
+ /*
+ * If we're doing smart signing, look in the key repository for
+ * key files with metadata, and merge them with the keylist
+ * we have now.
+ */
+ if (smartsign)
+ build_final_keylist();
- if (!dns_name_equal(gorigin, dst_key_name(newkey)))
- fatal("key %s not at origin\n", argv[i]);
-
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
- dst_key_t *dkey = key->key;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- if (!dst_key_isprivate(dkey))
- fatal("cannot sign zone with "
- "non-private dnskey %s",
- argv[i]);
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- key = newkeystruct(newkey, ISC_TRUE);
- key->commandline = ISC_TRUE;
- ISC_LIST_APPEND(keylist, key, link);
- } else
- dst_key_free(&newkey);
- }
-
- loadzonepubkeys(gdb);
+ /* Now enumerate the key list */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ key->index = keycount++;
}
- for (i = 0; i < ndskeys; i++) {
- dst_key_t *newkey = NULL;
-
- result = dst_key_fromnamedfile(dskeyfile[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- fatal("cannot load dnskey %s: %s", dskeyfile[i],
- isc_result_totext(result));
-
- if (!dns_name_equal(gorigin, dst_key_name(newkey)))
- fatal("key %s not at origin\n", dskeyfile[i]);
-
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
- dst_key_t *dkey = key->key;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- /* Override key flags. */
- key->issigningkey = ISC_TRUE;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- dst_key_free(&dkey);
- key->key = newkey;
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- /* Override dnskey flags. */
- key = newkeystruct(newkey, ISC_TRUE);
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- ISC_LIST_APPEND(keylist, key, link);
- }
- }
-
- if (ISC_LIST_EMPTY(keylist)) {
+ if (keycount == 0) {
if (disable_zone_check)
fprintf(stderr, "%s: warning: No keys specified "
- "or found\n", program);
+ "or found\n", program);
else
fatal("No signing keys specified or found.");
nokeys = ISC_TRUE;
@@ -3454,7 +3809,7 @@ main(int argc, char *argv[]) {
unsigned int max;
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
check_result(result, "dns_nsec3_maxiterations()");
- if (iterations > max)
+ if (nsec3iter > max)
fatal("NSEC3 iterations too big for weakest DNSKEY "
"strength. Maximum iterations allowed %u.", max);
}
@@ -3478,15 +3833,18 @@ main(int argc, char *argv[]) {
break;
}
+ remove_duplicates();
+
if (IS_NSEC3)
- nsec3ify(dns_hash_sha1, iterations, salt, salt_length,
+ nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
&hashlist);
else
nsecify();
if (!nokeys) {
- writeset("keyset-", dns_rdatatype_dnskey);
writeset("dsset-", dns_rdatatype_ds);
+ if (make_keyset)
+ writeset("keyset-", dns_rdatatype_dnskey);
if (dlv != NULL) {
writeset("dlvset-", dns_rdatatype_dlv);
}
@@ -3591,8 +3949,7 @@ main(int argc, char *argv[]) {
while (!ISC_LIST_EMPTY(keylist)) {
key = ISC_LIST_HEAD(keylist);
ISC_LIST_UNLINK(keylist, key, link);
- dst_key_free(&key->key);
- isc_mem_put(mctx, key, sizeof(signer_key_t));
+ dns_dnsseckey_destroy(mctx, &key);
}
isc_mem_put(mctx, tempfile, tempfilelen);
diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook
index 87a801e7442..51a14968a9c 100644
--- a/bin/dnssec/dnssec-signzone.docbook
+++ b/bin/dnssec/dnssec-signzone.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
- June 08, 2009
+ June 05, 2009
@@ -60,10 +60,12 @@
+
+
@@ -75,9 +77,13 @@
+
+
+
+
@@ -92,10 +98,10 @@
dnssec-signzone
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a keyset- file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their keyset- files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ keyset file for each child zone.
@@ -121,6 +127,63 @@
+
+ -C
+
+
+ Compatibility mode: Generate a
+ keyset-zonename
+ file in addition to
+ dsset-zonename
+ when signing a zone, for use by older versions of
+ dnssec-signzone.
+
+
+
+
+
+ -d directory
+
+
+ Look for dsset- or
+ keyset- files in .
+
+
+
+
+
+ -E engine
+
+
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+
+
+
+
+
+ -g
+
+
+ Generate DS records for child zones from
+ dsset- or keyset-
+ file. Existing DS records will be removed.
+
+
+
+
+
+ -K directory
+
+
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+
+
+
+
-k key
@@ -141,28 +204,6 @@
-
- -d directory
-
-
- Look for keyset files in
- as the directory
-
-
-
-
-
- -g
-
-
- If the zone contains any delegations, and there are
- keyset- files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
-
-
-
-
-s start-time
@@ -190,6 +231,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no is
specified, 30 days from the start time is used as a default.
+ must be later than
+ .
@@ -395,6 +438,89 @@
+
+ -S
+
+
+ Smart signing: Instructs dnssec-signzone to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+
+
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+
+
+
+
+
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+
+
+
+
+
+
+
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+
+
+
+
+
+
+
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+
+
+
+
+
+
+
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+
+
+
+
+
+
+
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+
+
+
+
+
+
+
+
+ -T ttl
+
+
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ , since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+
+
+
+
-t
@@ -404,6 +530,20 @@
+
+ -u
+
+
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, dnssec-signzone will
+ retain the existing chain when re-signing.
+
+
+
+
-v level
@@ -413,11 +553,27 @@
+
+ -x
+
+
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ dnssec-dnskey-kskonly yes; zone option in
+ named.)
+
+
+
+
-z
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ update-check-ksk no; zone option in
+ named.)
@@ -426,7 +582,7 @@
-3 salt
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an NSEC3 chain with the given hex encoded salt.
A dash (salt) can
be used to indicate that no salt is to be used when generating the NSEC3 chain.
@@ -437,8 +593,8 @@
-H iterations
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
@@ -447,10 +603,16 @@
-A
- When generating a NSEC3 chain set the OPTOUT flag on all
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
+
+ Using this option twice (i.e., )
+ turns the OPTOUT flag off for all records. This is useful
+ when using the option to modify an NSEC3
+ chain which previously had OPTOUT set.
+
@@ -484,10 +646,11 @@
The following command signs the example.com
zone with the DSA key generated by dnssec-keygen
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (db.example.com). This invocation looks
- for keyset files, in the current directory,
- so that DS records can be generated from them (-g).
+ (Kexample.com.+003+17247). Because the -S option
+ is not being used, the zone's keys must be in the master file
+ (db.example.com). This invocation looks
+ for dsset files, in the current directory,
+ so that DS records can be imported from them (-g).
% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -509,33 +672,6 @@ db.example.com.signed
%
-
- KNOWN BUGS
-
- dnssec-signzone was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
-
-
- An unfortunate side-effect of this flexibility is that
- dnssec-signzone does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
-
-
-
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of dnssec-signzone
- to confirm that the zone is properly signed by all keys before
- using it.
-
-
-
SEE ALSO
diff --git a/bin/dnssec/dnssec-signzone.html b/bin/dnssec/dnssec-signzone.html
index 1d4ecffc85b..28e7158e6e7 100644
--- a/bin/dnssec/dnssec-signzone.html
+++ b/bin/dnssec/dnssec-signzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
@@ -29,21 +29,21 @@
dnssec-signzone
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a keyset- file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their keyset- files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ keyset file for each child zone.
-
OPTIONS
+
OPTIONS
-a
@@ -53,6 +53,38 @@
Specifies the DNS class of the zone.
+
-C
+
+ Compatibility mode: Generate a
+ keyset-zonename
+ file in addition to
+ dsset-zonename
+ when signing a zone, for use by older versions of
+ dnssec-signzone.
+
+
-d directory
+
+ Look for dsset- or
+ keyset- files in directory.
+
+
-E engine
+
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+
+
-g
+
+ Generate DS records for child zones from
+ dsset- or keyset-
+ file. Existing DS records will be removed.
+
+
-K directory
+
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+
-k key
Treat specified key as a key signing key ignoring any
@@ -63,18 +95,6 @@
Generate a DLV set in addition to the key (DNSKEY) and DS sets.
The domain is appended to the name of the records.
-
-d directory
-
- Look for keyset files in
- directory as the directory
-
-
-g
-
- If the zone contains any delegations, and there are
- keyset- files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
-
-s start-time
Specify the date and time when the generated RRSIG records
@@ -95,6 +115,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no end-time is
specified, 30 days from the start time is used as a default.
+ end-time must be later than
+ start-time.
-f output-file
@@ -229,35 +251,119 @@
keyboard indicates that keyboard
input should be used.
+
-S
+
+
+ Smart signing: Instructs dnssec-signzone to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+
+
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+
+
+
+
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+
+
+
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+
+
+
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+
+
+
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+
+
+
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+
+
+
+
-T ttl
+
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ -S, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+
-t
Print statistics at completion.
+
-u
+
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, dnssec-signzone will
+ retain the existing chain when re-signing.
+
-v level
Sets the debugging level.
+
-x
+
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ dnssec-dnskey-kskonly yes; zone option in
+ named.)
+
-z
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ update-check-ksk no; zone option in
+ named.)
-3 salt
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an NSEC3 chain with the given hex encoded salt.
A dash (salt) can
be used to indicate that no salt is to be used when generating the NSEC3 chain.
-H iterations
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
-A
-
- When generating a NSEC3 chain set the OPTOUT flag on all
+
+
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
-
+
+
+ Using this option twice (i.e., -AA)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the -u option to modify an NSEC3
+ chain which previously had OPTOUT set.
+
+
zonefile
The file containing the zone to be signed.
@@ -273,14 +379,15 @@
-
EXAMPLE
+
EXAMPLE
The following command signs the example.com
zone with the DSA key generated by dnssec-keygen
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (db.example.com). This invocation looks
- for keyset files, in the current directory,
- so that DS records can be generated from them (-g).
+ (Kexample.com.+003+17247). Because the -S option
+ is not being used, the zone's keys must be in the master file
+ (db.example.com). This invocation looks
+ for dsset files, in the current directory,
+ so that DS records can be imported from them (-g).
- dnssec-signzone was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
-
-
- An unfortunate side-effect of this flexibility is that
- dnssec-signzone does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
-
-
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of dnssec-signzone
- to confirm that the zone is properly signed by all keys before
- using it.
-
masterfile-format ( text | raw );
notify notifytype;
@@ -569,12 +619,12 @@ zone
-
FILES
+
FILES
/etc/named.conf
-
SEE ALSO
+
SEE ALSO
named(8),
named-checkconf(8),
rndc(8),
diff --git a/bin/named/named.docbook b/bin/named/named.docbook
index 808e998eb8a..214f8ac6e9d 100644
--- a/bin/named/named.docbook
+++ b/bin/named/named.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
May 21, 2009
@@ -60,6 +60,7 @@
+
@@ -116,6 +117,7 @@
+
-c config-file
@@ -144,6 +146,19 @@
+
+ -E engine-name
+
+
+ Use a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance re-signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ engine-name
+ defaults to pkcs11, the empty name resets it to no engine.
+
+
+
+
-f
diff --git a/bin/named/named.html b/bin/named/named.html
index 031b4921ff4..fa869c4c6d1 100644
--- a/bin/named/named.html
+++ b/bin/named/named.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
@@ -29,10 +29,10 @@
named
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -47,7 +47,7 @@
-
OPTIONS
+
OPTIONS
-4
@@ -79,6 +79,14 @@
Debugging traces from named become
more verbose as the debug level increases.
+
-E engine-name
+
+ Use a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance re-signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ engine-name
+ defaults to pkcs11, the empty name resets it to no engine.
+
-f
Run the server in the foreground (i.e. do not daemonize).
@@ -220,7 +228,7 @@
-
SIGNALS
+
SIGNALS
In routine operation, signals should not be used to control
the nameserver; rndc should be used
@@ -241,7 +249,7 @@
-
CONFIGURATION
+
CONFIGURATION
The named configuration file is too complex
to describe in detail here. A complete description is provided
@@ -258,7 +266,7 @@
-
FILES
+
FILES
/etc/named.conf
@@ -271,7 +279,7 @@
-
SEE ALSO
+
SEE ALSO
RFC 1033,
RFC 1034,
RFC 1035,
@@ -284,7 +292,7 @@
-
AUTHOR
+
AUTHOR
Internet Systems Consortium
diff --git a/bin/named/query.c b/bin/named/query.c
index fa34da6e28c..1950257dca2 100644
--- a/bin/named/query.c
+++ b/bin/named/query.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.313.20.24 2010-09-24 08:09:07 marka Exp $ */
+/* $Id: query.c,v 1.353.8.2.2.5 2011-06-09 03:17:10 marka Exp $ */
/*! \file */
@@ -34,6 +34,7 @@
#ifdef DLZ
#include
#endif
+#include
#include
#include
#include
@@ -62,6 +63,17 @@
#include
#include
+#if 0
+/*
+ * It has been recommended that DNS64 be changed to return excluded
+ * AAAA addresses if DNS64 synthesis does not occur. This minimises
+ * the impact on the lookup results. While most DNS AAAA lookups are
+ * done to send IP packets to a host, not all of them are and filtering
+ * excluded addresses has a negative impact on those uses.
+ */
+#define dns64_bis_return_excluded_addresses 1
+#endif
+
/*% Partial answer? */
#define PARTIALANSWER(c) (((c)->query.attributes & \
NS_QUERYATTR_PARTIALANSWER) != 0)
@@ -92,6 +104,12 @@
/*% Secure? */
#define SECURE(c) (((c)->query.attributes & \
NS_QUERYATTR_SECURE) != 0)
+/*% DNS64 A lookup? */
+#define DNS64(c) (((c)->query.attributes & \
+ NS_QUERYATTR_DNS64) != 0)
+
+#define DNS64EXCLUDE(c) (((c)->query.attributes & \
+ NS_QUERYATTR_DNS64EXCLUDE) != 0)
/*% No QNAME Proof? */
#define NOQNAME(r) (((r)->attributes & \
@@ -116,6 +134,7 @@
#define DNS_GETDB_NOEXACT 0x01U
#define DNS_GETDB_NOLOG 0x02U
#define DNS_GETDB_PARTIAL 0x04U
+#define DNS_GETDB_IGNOREACL 0x08U
#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
@@ -141,6 +160,9 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
static inline void
log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
+static void
+rpz_st_clear(ns_client_t *client);
+
/*%
* Increment query statistics counters.
*/
@@ -251,6 +273,19 @@ ns_query_cancel(ns_client_t *client) {
UNLOCK(&client->query.fetchlock);
}
+static inline void
+query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset = *rdatasetp;
+
+ CTRACE("query_putrdataset");
+ if (rdataset != NULL) {
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ dns_message_puttemprdataset(client->message, rdatasetp);
+ }
+ CTRACE("query_putrdataset: done");
+}
+
static inline void
query_reset(ns_client_t *client, isc_boolean_t everything) {
isc_buffer_t *dbuf, *dbuf_next;
@@ -285,6 +320,18 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
if (client->query.authzone != NULL)
dns_zone_detach(&client->query.authzone);
+ if (client->query.dns64_aaaa != NULL)
+ query_putrdataset(client, &client->query.dns64_aaaa);
+ if (client->query.dns64_sigaaaa != NULL)
+ query_putrdataset(client, &client->query.dns64_sigaaaa);
+ if (client->query.dns64_aaaaok != NULL) {
+ isc_mem_put(client->mctx, client->query.dns64_aaaaok,
+ client->query.dns64_aaaaoklen *
+ sizeof(isc_boolean_t));
+ client->query.dns64_aaaaok = NULL;
+ client->query.dns64_aaaaoklen = 0;
+ }
+
query_freefreeversions(client, everything);
for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
@@ -310,13 +357,22 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
NS_QUERYATTR_SECURE);
client->query.restarts = 0;
client->query.timerset = ISC_FALSE;
+ if (client->query.rpz_st != NULL) {
+ rpz_st_clear(client);
+ if (everything) {
+ isc_mem_put(client->mctx, client->query.rpz_st,
+ sizeof(*client->query.rpz_st));
+ client->query.rpz_st = NULL;
+ }
+ }
client->query.origqname = NULL;
- client->query.qname = NULL;
client->query.dboptions = 0;
client->query.fetchoptions = 0;
client->query.gluedb = NULL;
client->query.authdbset = ISC_FALSE;
client->query.isreferral = ISC_FALSE;
+ client->query.dns64_options = 0;
+ client->query.dns64_ttl = ISC_UINT32_MAX;
}
static void
@@ -473,20 +529,6 @@ query_newrdataset(ns_client_t *client) {
return (rdataset);
}
-static inline void
-query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
- dns_rdataset_t *rdataset = *rdatasetp;
-
- CTRACE("query_putrdataset");
- if (rdataset != NULL) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- dns_message_puttemprdataset(client->message, rdatasetp);
- }
- CTRACE("query_putrdataset: done");
-}
-
-
static inline isc_result_t
query_newdbversion(ns_client_t *client, unsigned int n) {
unsigned int i;
@@ -540,6 +582,7 @@ ns_query_init(ns_client_t *client) {
ISC_LIST_INIT(client->query.freeversions);
client->query.restarts = 0;
client->query.timerset = ISC_FALSE;
+ client->query.rpz_st = NULL;
client->query.qname = NULL;
result = isc_mutex_init(&client->query.fetchlock);
if (result != ISC_R_SUCCESS)
@@ -549,6 +592,10 @@ ns_query_init(ns_client_t *client) {
client->query.authzone = NULL;
client->query.authdbset = ISC_FALSE;
client->query.isreferral = ISC_FALSE;
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ client->query.dns64_aaaaok = NULL;
+ client->query.dns64_aaaaoklen = 0;
query_reset(client, ISC_FALSE);
result = query_newdbversion(client, 3);
if (result != ISC_R_SUCCESS) {
@@ -563,8 +610,7 @@ ns_query_init(ns_client_t *client) {
}
static inline ns_dbversion_t *
-query_findversion(ns_client_t *client, dns_db_t *db,
- isc_boolean_t *newzonep)
+query_findversion(ns_client_t *client, dns_db_t *db)
{
ns_dbversion_t *dbversion;
@@ -590,12 +636,11 @@ query_findversion(ns_client_t *client, dns_db_t *db,
return (NULL);
dns_db_attach(db, &dbversion->db);
dns_db_currentversion(db, &dbversion->version);
+ dbversion->acl_checked = ISC_FALSE;
dbversion->queryok = ISC_FALSE;
ISC_LIST_APPEND(client->query.activeversions,
dbversion, link);
- *newzonep = ISC_TRUE;
- } else
- *newzonep = ISC_FALSE;
+ }
return (dbversion);
}
@@ -607,7 +652,6 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
dns_dbversion_t **versionp)
{
isc_result_t result;
- isc_boolean_t check_acl, new_zone;
dns_acl_t *queryacl;
ns_dbversion_t *dbversion;
@@ -623,7 +667,17 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
if (!client->view->additionalfromauth &&
client->query.authdbset &&
db != client->query.authdb)
- goto refuse;
+ return (DNS_R_REFUSED);
+
+ /*
+ * Non recursive query to a static-stub zone is prohibited; its
+ * zone content is not public data, but a part of local configuration
+ * and should not be disclosed.
+ */
+ if (dns_zone_gettype(zone) == dns_zone_staticstub &&
+ !RECURSIONOK(client)) {
+ return (DNS_R_REFUSED);
+ }
/*
* If the zone has an ACL, we'll check it, otherwise
@@ -633,23 +687,19 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
* Also, get the database version to use.
*/
- check_acl = ISC_TRUE; /* Keep compiler happy. */
- queryacl = NULL;
-
/*
* Get the current version of this database.
*/
- dbversion = query_findversion(client, db, &new_zone);
- if (dbversion == NULL) {
- result = DNS_R_SERVFAIL;
- goto fail;
- }
- if (new_zone) {
- check_acl = ISC_TRUE;
- } else if (!dbversion->queryok) {
- goto refuse;
- } else {
- check_acl = ISC_FALSE;
+ dbversion = query_findversion(client, db);
+ if (dbversion == NULL)
+ return (DNS_R_SERVFAIL);
+
+ if ((options & DNS_GETDB_IGNOREACL) != 0)
+ goto approved;
+ if (dbversion->acl_checked) {
+ if (!dbversion->queryok)
+ return (DNS_R_REFUSED);
+ goto approved;
}
queryacl = dns_zone_getqueryacl(zone);
@@ -663,88 +713,69 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
* allowed to make queries, otherwise the query should
* be refused.
*/
- check_acl = ISC_FALSE;
+ dbversion->acl_checked = ISC_TRUE;
if ((client->query.attributes &
- NS_QUERYATTR_QUERYOK) == 0)
- goto refuse;
- } else {
- /*
- * We haven't evaluated the view's queryacl yet.
- */
- check_acl = ISC_TRUE;
+ NS_QUERYATTR_QUERYOK) == 0) {
+ dbversion->queryok = ISC_FALSE;
+ return (DNS_R_REFUSED);
+ }
+ dbversion->queryok = ISC_TRUE;
+ goto approved;
}
}
- if (check_acl) {
- isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0);
-
- result = ns_client_checkaclsilent(client, NULL, queryacl,
- ISC_TRUE);
- if (log) {
- char msg[NS_CLIENT_ACLMSGSIZE("query")];
- if (result == ISC_R_SUCCESS) {
- if (isc_log_wouldlog(ns_g_lctx,
- ISC_LOG_DEBUG(3)))
- {
- ns_client_aclmsg("query", name, qtype,
- client->view->rdclass,
- msg, sizeof(msg));
- ns_client_log(client,
- DNS_LOGCATEGORY_SECURITY,
- NS_LOGMODULE_QUERY,
- ISC_LOG_DEBUG(3),
- "%s approved", msg);
- }
- } else {
+ result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
+ if ((options & DNS_GETDB_NOLOG) == 0) {
+ char msg[NS_CLIENT_ACLMSGSIZE("query")];
+ if (result == ISC_R_SUCCESS) {
+ if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) {
ns_client_aclmsg("query", name, qtype,
client->view->rdclass,
msg, sizeof(msg));
- ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
- NS_LOGMODULE_QUERY, ISC_LOG_INFO,
- "%s denied", msg);
+ ns_client_log(client,
+ DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_QUERY,
+ ISC_LOG_DEBUG(3),
+ "%s approved", msg);
}
+ } else {
+ ns_client_aclmsg("query", name, qtype,
+ client->view->rdclass,
+ msg, sizeof(msg));
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_QUERY, ISC_LOG_INFO,
+ "%s denied", msg);
}
-
- if (queryacl == client->view->queryacl) {
- if (result == ISC_R_SUCCESS) {
- /*
- * We were allowed by the default
- * "allow-query" ACL. Remember this so we
- * don't have to check again.
- */
- client->query.attributes |=
- NS_QUERYATTR_QUERYOK;
- }
- /*
- * We've now evaluated the view's query ACL, and
- * the NS_QUERYATTR_QUERYOK attribute is now valid.
- */
- client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
- }
-
- if (result != ISC_R_SUCCESS)
- goto refuse;
}
- /* Approved. */
+ if (queryacl == client->view->queryacl) {
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We were allowed by the default
+ * "allow-query" ACL. Remember this so we
+ * don't have to check again.
+ */
+ client->query.attributes |= NS_QUERYATTR_QUERYOK;
+ }
+ /*
+ * We've now evaluated the view's query ACL, and
+ * the NS_QUERYATTR_QUERYOK attribute is now valid.
+ */
+ client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
+ }
- /*
- * Remember the result of the ACL check so we
- * don't have to check again.
- */
+ dbversion->acl_checked = ISC_TRUE;
+ if (result != ISC_R_SUCCESS) {
+ dbversion->queryok = ISC_FALSE;
+ return (DNS_R_REFUSED);
+ }
dbversion->queryok = ISC_TRUE;
+ approved:
/* Transfer ownership, if necessary. */
if (versionp != NULL)
*versionp = dbversion->version;
-
return (ISC_R_SUCCESS);
-
- refuse:
- return (DNS_R_REFUSED);
-
- fail:
- return (result);
}
static inline isc_result_t
@@ -800,6 +831,97 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
return (result);
}
+static void
+rpz_log(ns_client_t *client) {
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+ dns_rpz_st_t *st;
+ const char *pat;
+
+ if (!ns_g_server->log_queries ||
+ !isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL))
+ return;
+
+ st = client->query.rpz_st;
+ dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1));
+ dns_name_format(st->qname, namebuf2, sizeof(namebuf2));
+
+ switch (st->m.policy) {
+ case DNS_RPZ_POLICY_NO_OP:
+ pat ="response policy %s rewrite %s NO-OP using %s";
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ pat = "response policy %s rewrite %s to NXDOMAIN using %s";
+ break;
+ case DNS_RPZ_POLICY_NODATA:
+ pat = "response policy %s rewrite %s to NODATA using %s";
+ break;
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ pat = "response policy %s rewrite %s using %s";
+ break;
+ default:
+ INSIST(0);
+ }
+ ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
+ DNS_RPZ_INFO_LEVEL, pat, dns_rpz_type2str(st->m.type),
+ namebuf1, namebuf2);
+}
+
+static void
+rpz_fail_log(ns_client_t *client, int level, dns_rpz_type_t rpz_type,
+ dns_name_t *name, const char *str, isc_result_t result)
+{
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+
+ if (!ns_g_server->log_queries || !isc_log_wouldlog(ns_g_lctx, level))
+ return;
+
+ dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1));
+ dns_name_format(name, namebuf2, sizeof(namebuf2));
+ ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS,
+ NS_LOGMODULE_QUERY, level,
+ "response policy %s rewrite %s via %s %sfailed: %s",
+ dns_rpz_type2str(rpz_type),
+ namebuf1, namebuf2, str, isc_result_totext(result));
+}
+
+/*
+ * Get a policy rewrite zone database.
+ */
+static isc_result_t
+rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type,
+ dns_name_t *rpz_qname, dns_zone_t **zonep,
+ dns_db_t **dbp, dns_dbversion_t **versionp)
+{
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+ dns_dbversion_t *rpz_version = NULL;
+ isc_result_t result;
+
+ result = query_getzonedb(client, rpz_qname, dns_rdatatype_any,
+ DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
+ if (result == ISC_R_SUCCESS) {
+ if (ns_g_server->log_queries &&
+ isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) {
+ dns_name_format(client->query.qname, namebuf1,
+ sizeof(namebuf1));
+ dns_name_format(rpz_qname, namebuf2, sizeof(namebuf2));
+ ns_client_log(client, NS_LOGCATEGORY_QUERIES,
+ NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
+ "try rpz %s rewrite %s via %s",
+ dns_rpz_type2str(rpz_type),
+ namebuf1, namebuf2);
+ }
+ *versionp = rpz_version;
+ return (ISC_R_SUCCESS);
+ }
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, rpz_qname,
+ "query_getzonedb() ", result);
+ return (result);
+}
+
static inline isc_result_t
query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
dns_db_t **dbp, unsigned int options)
@@ -1958,6 +2080,323 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
CTRACE("query_addrdataset: done");
}
+static isc_result_t
+query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf,
+ dns_section_t section)
+{
+ dns_name_t *name, *mname;
+ dns_rdata_t *dns64_rdata;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdatalist_t *dns64_rdatalist;
+ dns_rdataset_t *dns64_rdataset;
+ dns_rdataset_t *mrdataset;
+ isc_buffer_t *buffer;
+ isc_region_t r;
+ isc_result_t result;
+ dns_view_t *view = client->view;
+ isc_netaddr_t netaddr;
+ dns_dns64_t *dns64;
+ unsigned int flags = 0;
+
+ /*%
+ * To the current response for 'client', add the answer RRset
+ * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
+ * owner name '*namep', to section 'section', unless they are
+ * already there. Also add any pertinent additional data.
+ *
+ * If 'dbuf' is not NULL, then '*namep' is the name whose data is
+ * stored in 'dbuf'. In this case, query_addrrset() guarantees that
+ * when it returns the name will either have been kept or released.
+ */
+ CTRACE("query_dns64");
+ name = *namep;
+ mname = NULL;
+ mrdataset = NULL;
+ buffer = NULL;
+ dns64_rdata = NULL;
+ dns64_rdataset = NULL;
+ dns64_rdatalist = NULL;
+ result = dns_message_findname(client->message, section,
+ name, dns_rdatatype_aaaa,
+ rdataset->covers,
+ &mname, &mrdataset);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We've already got an RRset of the given name and type.
+ * There's nothing else to do;
+ */
+ CTRACE("query_dns64: dns_message_findname succeeded: done");
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ return (ISC_R_SUCCESS);
+ } else if (result == DNS_R_NXDOMAIN) {
+ /*
+ * The name doesn't exist.
+ */
+ if (dbuf != NULL)
+ query_keepname(client, name, dbuf);
+ dns_message_addname(client->message, name, section);
+ *namep = NULL;
+ mname = name;
+ } else {
+ RUNTIME_CHECK(result == DNS_R_NXRRSET);
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ }
+
+ if (rdataset->trust != dns_trust_secure &&
+ (section == DNS_SECTION_ANSWER ||
+ section == DNS_SECTION_AUTHORITY))
+ client->query.attributes &= ~NS_QUERYATTR_SECURE;
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+
+ result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt *
+ 16 * dns_rdataset_count(rdataset));
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdatalist(client->message,
+ &dns64_rdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_init(dns64_rdataset);
+ dns_rdatalist_init(dns64_rdatalist);
+ dns64_rdatalist->rdclass = dns_rdataclass_in;
+ dns64_rdatalist->type = dns_rdatatype_aaaa;
+ if (client->query.dns64_ttl != ISC_UINT32_MAX)
+ dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl,
+ client->query.dns64_ttl);
+ else
+ dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600);
+
+ if (RECURSIONOK(client))
+ flags |= DNS_DNS64_RECURSIVE;
+
+ /*
+ * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
+ * as this provides a easy way to see if the answer was signed.
+ */
+ if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
+ flags |= DNS_DNS64_DNSSEC;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ for (dns64 = ISC_LIST_HEAD(client->view->dns64);
+ dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
+
+ dns_rdataset_current(rdataset, &rdata);
+ isc__buffer_availableregion(buffer, &r);
+ INSIST(r.length >= 16);
+ result = dns_dns64_aaaafroma(dns64, &netaddr,
+ client->signer,
+ &ns_g_server->aclenv,
+ flags, rdata.data, r.base);
+ if (result != ISC_R_SUCCESS) {
+ dns_rdata_reset(&rdata);
+ continue;
+ }
+ isc_buffer_add(buffer, 16);
+ isc_buffer_remainingregion(buffer, &r);
+ isc_buffer_forward(buffer, 16);
+ result = dns_message_gettemprdata(client->message,
+ &dns64_rdata);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdata_init(dns64_rdata);
+ dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
+ dns_rdatatype_aaaa, &r);
+ ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
+ link);
+ dns64_rdata = NULL;
+ dns_rdata_reset(&rdata);
+ }
+ }
+ if (result != ISC_R_NOMORE)
+ goto cleanup;
+
+ if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
+ goto cleanup;
+
+ result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
+ dns64_rdataset->trust = rdataset->trust;
+ query_addrdataset(client, mname, dns64_rdataset);
+ dns64_rdataset = NULL;
+ dns64_rdatalist = NULL;
+ dns_message_takebuffer(client->message, &buffer);
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (buffer != NULL)
+ isc_buffer_free(&buffer);
+
+ if (dns64_rdata != NULL)
+ dns_message_puttemprdata(client->message, &dns64_rdata);
+
+ if (dns64_rdataset != NULL)
+ dns_message_puttemprdataset(client->message, &dns64_rdataset);
+
+ if (dns64_rdatalist != NULL) {
+ for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
+ dns64_rdata != NULL;
+ dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
+ {
+ ISC_LIST_UNLINK(dns64_rdatalist->rdata,
+ dns64_rdata, link);
+ dns_message_puttemprdata(client->message, &dns64_rdata);
+ }
+ dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
+ }
+
+ CTRACE("query_dns64: done");
+ return (result);
+}
+
+static void
+query_filter64(ns_client_t *client, dns_name_t **namep,
+ dns_rdataset_t *rdataset, isc_buffer_t *dbuf,
+ dns_section_t section)
+{
+ dns_name_t *name, *mname;
+ dns_rdata_t *myrdata;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdatalist_t *myrdatalist;
+ dns_rdataset_t *myrdataset;
+ isc_buffer_t *buffer;
+ isc_region_t r;
+ isc_result_t result;
+ unsigned int i;
+
+ CTRACE("query_filter64");
+
+ INSIST(client->query.dns64_aaaaok != NULL);
+ INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
+
+ name = *namep;
+ mname = NULL;
+ buffer = NULL;
+ myrdata = NULL;
+ myrdataset = NULL;
+ myrdatalist = NULL;
+ result = dns_message_findname(client->message, section,
+ name, dns_rdatatype_aaaa,
+ rdataset->covers,
+ &mname, &myrdataset);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We've already got an RRset of the given name and type.
+ * There's nothing else to do;
+ */
+ CTRACE("query_filter64: dns_message_findname succeeded: done");
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ return;
+ } else if (result == DNS_R_NXDOMAIN) {
+ mname = name;
+ *namep = NULL;
+ } else {
+ RUNTIME_CHECK(result == DNS_R_NXRRSET);
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ dbuf = NULL;
+ }
+
+ if (rdataset->trust != dns_trust_secure &&
+ (section == DNS_SECTION_ANSWER ||
+ section == DNS_SECTION_AUTHORITY))
+ client->query.attributes &= ~NS_QUERYATTR_SECURE;
+
+ result = isc_buffer_allocate(client->mctx, &buffer,
+ 16 * dns_rdataset_count(rdataset));
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdataset(client->message, &myrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdatalist(client->message, &myrdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_init(myrdataset);
+ dns_rdatalist_init(myrdatalist);
+ myrdatalist->rdclass = dns_rdataclass_in;
+ myrdatalist->type = dns_rdatatype_aaaa;
+ myrdatalist->ttl = rdataset->ttl;
+
+ i = 0;
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ if (!client->query.dns64_aaaaok[i++])
+ continue;
+ dns_rdataset_current(rdataset, &rdata);
+ INSIST(rdata.length == 16);
+ isc_buffer_putmem(buffer, rdata.data, rdata.length);
+ isc_buffer_remainingregion(buffer, &r);
+ isc_buffer_forward(buffer, rdata.length);
+ result = dns_message_gettemprdata(client->message, &myrdata);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdata_init(myrdata);
+ dns_rdata_fromregion(myrdata, dns_rdataclass_in,
+ dns_rdatatype_aaaa, &r);
+ ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
+ myrdata = NULL;
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto cleanup;
+
+ result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
+ if (mname == name) {
+ if (dbuf != NULL)
+ query_keepname(client, name, dbuf);
+ dns_message_addname(client->message, name, section);
+ dbuf = NULL;
+ }
+ myrdataset->trust = rdataset->trust;
+ query_addrdataset(client, mname, myrdataset);
+ myrdataset = NULL;
+ myrdatalist = NULL;
+ dns_message_takebuffer(client->message, &buffer);
+
+ cleanup:
+ if (buffer != NULL)
+ isc_buffer_free(&buffer);
+
+ if (myrdata != NULL)
+ dns_message_puttemprdata(client->message, &myrdata);
+
+ if (myrdataset != NULL)
+ dns_message_puttemprdataset(client->message, &myrdataset);
+
+ if (myrdatalist != NULL) {
+ for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
+ myrdata != NULL;
+ myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
+ {
+ ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
+ dns_message_puttemprdata(client->message, &myrdata);
+ }
+ dns_message_puttemprdatalist(client->message, &myrdatalist);
+ }
+ if (dbuf != NULL)
+ query_releasename(client, &name);
+
+ CTRACE("query_filter64: done");
+}
+
static void
query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
@@ -2036,7 +2475,7 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
static inline isc_result_t
query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
- isc_boolean_t zero_ttl, isc_boolean_t isassociated)
+ unsigned int override_ttl, isc_boolean_t isassociated)
{
dns_name_t *name;
dns_dbnode_t *node;
@@ -2119,10 +2558,11 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
goto cleanup;
- if (zero_ttl) {
- rdataset->ttl = 0;
+ if (override_ttl != ISC_UINT32_MAX &&
+ override_ttl < rdataset->ttl) {
+ rdataset->ttl = override_ttl;
if (sigrdataset != NULL)
- sigrdataset->ttl = 0;
+ sigrdataset->ttl = override_ttl;
}
/*
@@ -2246,67 +2686,79 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
return (eresult);
}
-static inline isc_result_t
-query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
- dns_rdataset_t *dname, dns_name_t **anamep,
- dns_rdatatype_t type)
+static isc_result_t
+query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
+ dns_trust_t trust, dns_ttl_t ttl)
{
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
dns_rdata_t *rdata;
- isc_result_t result;
isc_region_t r;
+ dns_name_t *aname;
+ isc_result_t result;
/*
* We assume the name data referred to by tname won't go away.
*/
- REQUIRE(anamep != NULL);
-
- rdatalist = NULL;
- result = dns_message_gettemprdatalist(client->message, &rdatalist);
+ aname = NULL;
+ result = dns_message_gettempname(client->message, &aname);
if (result != ISC_R_SUCCESS)
return (result);
- rdata = NULL;
- result = dns_message_gettemprdata(client->message, &rdata);
- if (result != ISC_R_SUCCESS)
- return (result);
- rdataset = NULL;
- result = dns_message_gettemprdataset(client->message, &rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_init(rdataset);
- result = dns_name_dup(qname, client->mctx, *anamep);
+ result = dns_name_dup(qname, client->mctx, aname);
if (result != ISC_R_SUCCESS) {
- dns_message_puttemprdataset(client->message, &rdataset);
+ dns_message_puttempname(client->message, &aname);
return (result);
}
- rdatalist->type = type;
+ rdatalist = NULL;
+ result = dns_message_gettemprdatalist(client->message, &rdatalist);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
+ return (result);
+ }
+ rdata = NULL;
+ result = dns_message_gettemprdata(client->message, &rdata);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
+ dns_message_puttemprdatalist(client->message, &rdatalist);
+ return (result);
+ }
+ rdataset = NULL;
+ result = dns_message_gettemprdataset(client->message, &rdataset);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
+ dns_message_puttemprdatalist(client->message, &rdatalist);
+ dns_message_puttemprdata(client->message, &rdata);
+ return (result);
+ }
+ dns_rdataset_init(rdataset);
+ rdatalist->type = dns_rdatatype_cname;
rdatalist->covers = 0;
rdatalist->rdclass = client->message->rdclass;
- rdatalist->ttl = dname->ttl;
+ rdatalist->ttl = ttl;
dns_name_toregion(tname, &r);
rdata->data = r.base;
rdata->length = r.length;
rdata->rdclass = client->message->rdclass;
- rdata->type = type;
+ rdata->type = dns_rdatatype_cname;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
== ISC_R_SUCCESS);
- rdataset->trust = dname->trust;
+ rdataset->trust = trust;
- query_addrrset(client, anamep, &rdataset, NULL, NULL,
+ query_addrrset(client, &aname, &rdataset, NULL, NULL,
DNS_SECTION_ANSWER);
-
if (rdataset != NULL) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(client->message, &rdataset);
}
+ if (aname != NULL)
+ dns_message_puttempname(client->message, &aname);
return (ISC_R_SUCCESS);
}
@@ -2860,7 +3312,7 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
* j.example -> z.i.example NSEC example
* owner common example
* next common example
- * wild *.f.example
+ * wild *.example
*/
options = client->query.dboptions | DNS_DBFIND_NOWILD;
dns_fixedname_init(&wfixed);
@@ -3196,8 +3648,9 @@ query_resume(isc_task_t *task, isc_event_t *event) {
}
static isc_result_t
-query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
- dns_rdataset_t *nameservers, isc_boolean_t resuming)
+query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
+ dns_name_t *qdomain, dns_rdataset_t *nameservers,
+ isc_boolean_t resuming)
{
isc_result_t result;
dns_rdataset_t *rdataset, *sigrdataset;
@@ -3229,7 +3682,11 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
NS_LOGMODULE_QUERY,
ISC_LOG_WARNING,
"recursive-clients soft limit "
- "exceeded, aborting oldest query");
+ "exceeded (%d/%d/%d), "
+ "aborting oldest query",
+ client->recursionquota->used,
+ client->recursionquota->soft,
+ client->recursionquota->max);
}
ns_client_killoldestquery(client);
result = ISC_R_SUCCESS;
@@ -3242,7 +3699,11 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_QUERY,
ISC_LOG_WARNING,
- "no more recursive clients: %s",
+ "no more recursive clients "
+ "(%d/%d/%d): %s",
+ ns_g_server->recursionquota.used,
+ ns_g_server->recursionquota.soft,
+ ns_g_server->recursionquota.max,
isc_result_totext(result));
}
ns_client_killoldestquery(client);
@@ -3289,8 +3750,7 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
else
peeraddr = NULL;
result = dns_resolver_createfetch2(client->view->resolver,
- client->query.qname,
- qtype, qdomain, nameservers,
+ qname, qtype, qdomain, nameservers,
NULL, peeraddr, client->message->id,
client->query.fetchoptions,
client->task,
@@ -3313,6 +3773,696 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
return (result);
}
+static inline void
+rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
+ dns_rdataset_t **rdatasetp)
+{
+ if (nodep != NULL && *nodep != NULL) {
+ REQUIRE(dbp != NULL && *dbp != NULL);
+ dns_db_detachnode(*dbp, nodep);
+ }
+ if (dbp != NULL && *dbp != NULL)
+ dns_db_detach(dbp);
+ if (zonep != NULL && *zonep != NULL)
+ dns_zone_detach(zonep);
+ if (rdatasetp != NULL && *rdatasetp != NULL &&
+ dns_rdataset_isassociated(*rdatasetp))
+ dns_rdataset_disassociate(*rdatasetp);
+}
+
+static inline isc_result_t
+rpz_ready(ns_client_t *client, dns_zone_t **zonep, dns_db_t **dbp,
+ dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp)
+{
+ REQUIRE(rdatasetp != NULL);
+
+ rpz_clean(zonep, dbp, nodep, rdatasetp);
+ if (*rdatasetp == NULL) {
+ *rdatasetp = query_newrdataset(client);
+ if (*rdatasetp == NULL)
+ return (DNS_R_SERVFAIL);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rpz_st_clear(ns_client_t *client) {
+ dns_rpz_st_t *st = client->query.rpz_st;
+
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node, NULL);
+ if (st->m.rdataset != NULL)
+ query_putrdataset(client, &st->m.rdataset);
+
+ rpz_clean(NULL, &st->ns.db, NULL, NULL);
+ if (st->ns.ns_rdataset != NULL)
+ query_putrdataset(client, &st->ns.ns_rdataset);
+ if (st->ns.r_rdataset != NULL)
+ query_putrdataset(client, &st->ns.r_rdataset);
+
+ rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
+ if (st->q.rdataset != NULL)
+ query_putrdataset(client, &st->q.rdataset);
+ if (st->q.sigrdataset != NULL)
+ query_putrdataset(client, &st->q.sigrdataset);
+ st->state = 0;
+}
+
+/*
+ * Get NS, A, or AAAA rrset for rpz nsdname or nsip checking.
+ */
+static isc_result_t
+rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
+ dns_db_t **dbp, dns_dbversion_t *version,
+ dns_rdataset_t **rdatasetp, isc_boolean_t resuming)
+{
+ dns_rpz_st_t *st;
+ isc_boolean_t is_zone;
+ dns_dbnode_t *node;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ if ((st->state & DNS_RPZ_RECURSING) != 0) {
+ INSIST(st->ns.r_type == type);
+ INSIST(dns_name_equal(name, st->r_name));
+ INSIST(*rdatasetp == NULL ||
+ !dns_rdataset_isassociated(*rdatasetp));
+ st->state &= ~DNS_RPZ_RECURSING;
+ *dbp = st->ns.db;
+ st->ns.db = NULL;
+ if (*rdatasetp != NULL)
+ query_putrdataset(client, rdatasetp);
+ *rdatasetp = st->ns.r_rdataset;
+ st->ns.r_rdataset = NULL;
+ result = st->ns.r_result;
+ if (result == DNS_R_DELEGATION) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, name,
+ "rpz_ns_find() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ result = DNS_R_SERVFAIL;
+ }
+ return (result);
+ }
+
+ result = rpz_ready(client, NULL, NULL, NULL, rdatasetp);
+ if (result != ISC_R_SUCCESS) {
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ return (result);
+ }
+ if (*dbp != NULL) {
+ is_zone = ISC_FALSE;
+ } else {
+ dns_zone_t *zone;
+
+ version = NULL;
+ zone = NULL;
+ result = query_getdb(client, name, type, 0, &zone, dbp,
+ &version, &is_zone);
+ if (result != ISC_R_SUCCESS) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, name, "NS getdb() ",
+ result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ return (result);
+ }
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ }
+
+ node = NULL;
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ result = dns_db_find(*dbp, name, version, type, 0, client->now, &node,
+ found, *rdatasetp, NULL);
+ if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
+ /*
+ * Try the cache if we're authoritative for an
+ * ancestor but not the domain itself.
+ */
+ rpz_clean(NULL, dbp, &node, rdatasetp);
+ version = NULL;
+ dns_db_attach(client->view->cachedb, dbp);
+ result = dns_db_find(*dbp, name, version, dns_rdatatype_ns,
+ 0, client->now, &node, found,
+ *rdatasetp, NULL);
+ }
+ rpz_clean(NULL, dbp, &node, NULL);
+ if (result == DNS_R_DELEGATION) {
+ /*
+ * Recurse to get NS rrset or A or AAAA rrset for an NS name.
+ */
+ rpz_clean(NULL, NULL, NULL, rdatasetp);
+ dns_name_copy(name, st->r_name, NULL);
+ result = query_recurse(client, type, st->r_name, NULL, NULL,
+ resuming);
+ if (result == ISC_R_SUCCESS) {
+ st->state |= DNS_RPZ_RECURSING;
+ result = DNS_R_DELEGATION;
+ }
+ }
+ return (result);
+}
+
+/*
+ * Check the IP address in an A or AAAA rdataset against
+ * the IP or NSIP response policy rules of a view.
+ */
+static isc_result_t
+rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
+ dns_rpz_type_t rpz_type)
+{
+ dns_rpz_st_t *st;
+ dns_dbversion_t *version;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_rpz_zone_t *new_rpz;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ if (st->m.rdataset == NULL) {
+ st->m.rdataset = query_newrdataset(client);
+ if (st->m.rdataset == NULL)
+ return (DNS_R_SERVFAIL);
+ }
+ zone = NULL;
+ db = NULL;
+ for (new_rpz = ISC_LIST_HEAD(client->view->rpz_zones);
+ new_rpz != NULL;
+ new_rpz = ISC_LIST_NEXT(new_rpz, link)) {
+ version = NULL;
+
+ /*
+ * Find the database for this policy zone to get its
+ * radix tree.
+ */
+ result = rpz_getdb(client, rpz_type, &new_rpz->origin,
+ &zone, &db, &version);
+ if (result != ISC_R_SUCCESS) {
+ rpz_clean(&zone, &db, NULL, NULL);
+ continue;
+ }
+ /*
+ * Look for a better (e.g. longer prefix) hit for an IP address
+ * in this rdataset in this radix tree than than the previous
+ * hit, if any. Note the domain name and quality of the
+ * best hit.
+ */
+ result = dns_db_rpz_findips(new_rpz, rpz_type, zone, db,
+ version, rdataset, st);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ rpz_clean(&zone, &db, NULL, NULL);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rpz_rewrite_nsip(ns_client_t *client, dns_rdatatype_t type, dns_name_t *name,
+ dns_db_t **dbp, dns_dbversion_t *version,
+ dns_rdataset_t **rdatasetp, isc_boolean_t resuming)
+{
+ isc_result_t result;
+
+ result = rpz_ns_find(client, name, type, dbp, version, rdatasetp,
+ resuming);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ result = rpz_rewrite_ip(client, *rdatasetp, DNS_RPZ_TYPE_NSIP);
+ break;
+ case DNS_R_EMPTYNAME:
+ case DNS_R_EMPTYWILD:
+ case DNS_R_NXDOMAIN:
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NXRRSET:
+ case DNS_R_NCACHENXRRSET:
+ result = ISC_R_SUCCESS;
+ break;
+ case DNS_R_DELEGATION:
+ case DNS_R_DUPLICATE:
+ case DNS_R_DROP:
+ break;
+ default:
+ if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
+ client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
+ rpz_fail_log(client, ISC_LOG_WARNING, DNS_RPZ_TYPE_NSIP,
+ name, "NS address rewrite nsip ", result);
+ }
+ break;
+ }
+ return (result);
+}
+
+/*
+ * Get the rrset from a response policy zone.
+ */
+static isc_result_t
+rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
+ dns_name_t *sname, dns_rpz_type_t rpz_type, dns_zone_t **zonep,
+ dns_db_t **dbp, dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
+ dns_rpz_policy_t *policyp)
+{
+ dns_dbversion_t *version;
+ dns_rpz_policy_t policy;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ isc_result_t result;
+
+ result = rpz_ready(client, zonep, dbp, nodep, rdatasetp);
+ if (result != ISC_R_SUCCESS) {
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (result);
+ }
+
+ /*
+ * Try to get either a CNAME or the type of record demanded by the
+ * request from the policy zone.
+ */
+ version = NULL;
+ result = rpz_getdb(client, rpz_type, qnamef, zonep, dbp, &version);
+ if (result != ISC_R_SUCCESS) {
+ *policyp = DNS_RPZ_POLICY_MISS;
+ return (DNS_R_NXDOMAIN);
+ }
+
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ result = dns_db_find(*dbp, qnamef, version, dns_rdatatype_any, 0,
+ client->now, nodep, found, *rdatasetp, NULL);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdatasetiter_t *rdsiter;
+
+ rdsiter = NULL;
+ result = dns_db_allrdatasets(*dbp, *nodep, version, 0,
+ &rdsiter);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detachnode(*dbp, nodep);
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type,
+ qnamef, "allrdatasets()", result);
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ }
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, *rdatasetp);
+ if ((*rdatasetp)->type == dns_rdatatype_cname ||
+ (*rdatasetp)->type == qtype)
+ break;
+ dns_rdataset_disassociate(*rdatasetp);
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (result != ISC_R_SUCCESS) {
+ if (result != ISC_R_NOMORE) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ rpz_type, qnamef, "rdatasetiter",
+ result);
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ }
+ /*
+ * Ask again to get the right DNS_R_DNAME/NXRRSET/...
+ * result if there is neither a CNAME nor target type.
+ */
+ if (dns_rdataset_isassociated(*rdatasetp))
+ dns_rdataset_disassociate(*rdatasetp);
+ dns_db_detachnode(*dbp, nodep);
+
+ if (qtype == dns_rdatatype_rrsig ||
+ qtype == dns_rdatatype_sig)
+ result = DNS_R_NXRRSET;
+ else
+ result = dns_db_find(*dbp, qnamef, version,
+ qtype, 0, client->now,
+ nodep, found, *rdatasetp,
+ NULL);
+ }
+ }
+ switch (result) {
+ case ISC_R_SUCCESS:
+ if ((*rdatasetp)->type != dns_rdatatype_cname) {
+ policy = DNS_RPZ_POLICY_RECORD;
+ } else {
+ policy = dns_rpz_decode_cname(*rdatasetp, sname);
+ if (policy == DNS_RPZ_POLICY_RECORD &&
+ qtype != dns_rdatatype_cname &&
+ qtype != dns_rdatatype_any)
+ result = DNS_R_CNAME;
+ }
+ break;
+ case DNS_R_DNAME:
+ /*
+ * DNAME policy RRs have very few if any uses that are not
+ * better served with simple wildcards. Making the work would
+ * require complications to get the number of labels matched
+ * in the name or the found name itself to the main DNS_R_DNAME
+ * case in query_find(). So fall through to treat them as NODATA.
+ */
+ case DNS_R_NXRRSET:
+ policy = DNS_RPZ_POLICY_NODATA;
+ break;
+ case DNS_R_NXDOMAIN:
+ case DNS_R_EMPTYNAME:
+ /*
+ * If we don't get a qname hit,
+ * see if it is worth looking for other types.
+ */
+ dns_db_rpz_enabled(*dbp, client->query.rpz_st);
+ dns_db_detach(dbp);
+ dns_zone_detach(zonep);
+ policy = DNS_RPZ_POLICY_MISS;
+ break;
+ default:
+ dns_db_detach(dbp);
+ dns_zone_detach(zonep);
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef,
+ "", result);
+ policy = DNS_RPZ_POLICY_ERROR;
+ result = DNS_R_SERVFAIL;
+ break;
+ }
+
+ *policyp = policy;
+ return (result);
+}
+
+/*
+ * Build and look for a QNAME or NSDNAME owner name in a response policy zone.
+ */
+static isc_result_t
+rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
+ dns_rpz_type_t rpz_type, dns_rdataset_t **rdatasetp)
+{
+ dns_rpz_st_t *st;
+ dns_rpz_zone_t *rpz;
+ dns_fixedname_t prefixf, rpz_qnamef;
+ dns_name_t *prefix, *suffix, *rpz_qname;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_dbnode_t *node;
+ dns_rpz_policy_t policy;
+ unsigned int labels;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ zone = NULL;
+ db = NULL;
+ node = NULL;
+
+ for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
+ rpz != NULL;
+ rpz = ISC_LIST_NEXT(rpz, link)) {
+ /*
+ * Construct the rule's owner name.
+ */
+ dns_fixedname_init(&prefixf);
+ prefix = dns_fixedname_name(&prefixf);
+ dns_name_split(qname, 1, prefix, NULL);
+ if (rpz_type == DNS_RPZ_TYPE_NSDNAME)
+ suffix = &rpz->nsdname;
+ else
+ suffix = &rpz->origin;
+ dns_fixedname_init(&rpz_qnamef);
+ rpz_qname = dns_fixedname_name(&rpz_qnamef);
+ for (;;) {
+ result = dns_name_concatenate(prefix, suffix,
+ rpz_qname, NULL);
+ if (result == ISC_R_SUCCESS)
+ break;
+ INSIST(result == DNS_R_NAMETOOLONG);
+ labels = dns_name_countlabels(prefix);
+ if (labels < 2) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ rpz_type, suffix,
+ "concatentate() ", result);
+ return (ISC_R_SUCCESS);
+ }
+ if (labels+1 == dns_name_countlabels(qname)) {
+ rpz_fail_log(client, DNS_RPZ_DEBUG_LEVEL1,
+ rpz_type, suffix,
+ "concatentate() ", result);
+ }
+ dns_name_split(prefix, labels - 1, NULL, prefix);
+ }
+
+ /*
+ * See if the qname rule (or RR) exists.
+ */
+ result = rpz_find(client, qtype, rpz_qname, qname, rpz_type,
+ &zone, &db, &node, rdatasetp, &policy);
+ switch (result) {
+ case DNS_R_NXDOMAIN:
+ case DNS_R_EMPTYNAME:
+ break;
+ case DNS_R_SERVFAIL:
+ rpz_clean(&zone, &db, &node, rdatasetp);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ default:
+ /*
+ * when more than one name or address hits a rule,
+ * prefer the first set of names (qname or NS),
+ * the first policy zone, and the smallest name
+ */
+ if (st->m.type == rpz_type &&
+ rpz->num > st->m.rpz->num &&
+ 0 <= dns_name_compare(rpz_qname, st->qname))
+ continue;
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node,
+ &st->m.rdataset);
+ st->m.rpz = rpz;
+ st->m.type = rpz_type;
+ st->m.prefix = 0;
+ st->m.policy = policy;
+ st->m.result = result;
+ dns_name_copy(rpz_qname, st->qname, NULL);
+ if (dns_rdataset_isassociated(*rdatasetp)) {
+ dns_rdataset_t *trdataset;
+
+ trdataset = st->m.rdataset;
+ st->m.rdataset = *rdatasetp;
+ *rdatasetp = trdataset;
+ st->m.ttl = st->m.rdataset->ttl;
+ } else {
+ st->m.ttl = DNS_RPZ_TTL_DEFAULT;
+ }
+ st->m.node = node;
+ node = NULL;
+ st->m.db = db;
+ db = NULL;
+ st->m.zone = zone;
+ zone = NULL;
+ }
+ }
+
+ rpz_clean(&zone, &db, &node, rdatasetp);
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Look for response policy zone NSIP and NSDNAME rewriting.
+ */
+static isc_result_t
+rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype,
+ isc_boolean_t resuming)
+{
+ dns_rpz_st_t *st;
+ dns_db_t *ipdb;
+ dns_rdataset_t *rdataset;
+ dns_fixedname_t nsnamef;
+ dns_name_t *nsname;
+ dns_dbversion_t *version;
+ isc_result_t result;
+
+ ipdb = NULL;
+ rdataset = NULL;
+
+ st = client->query.rpz_st;
+ if (st == NULL) {
+ st = isc_mem_get(client->mctx, sizeof(*st));
+ if (st == NULL)
+ return (ISC_R_NOMEMORY);
+ st->state = 0;
+ memset(&st->m, 0, sizeof(st->m));
+ memset(&st->ns, 0, sizeof(st->ns));
+ memset(&st->q, 0, sizeof(st->q));
+ dns_fixedname_init(&st->_qnamef);
+ dns_fixedname_init(&st->_r_namef);
+ dns_fixedname_init(&st->_fnamef);
+ st->qname = dns_fixedname_name(&st->_qnamef);
+ st->r_name = dns_fixedname_name(&st->_r_namef);
+ st->fname = dns_fixedname_name(&st->_fnamef);
+ client->query.rpz_st = st;
+ }
+ if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
+ st->state = DNS_RPZ_DONE_QNAME;
+ st->m.type = DNS_RPZ_TYPE_BAD;
+ st->m.policy = DNS_RPZ_POLICY_MISS;
+
+ /*
+ * Check rules for the name if this it the first time,
+ * i.e. we've not been recursing.
+ */
+ result = DNS_R_SERVFAIL;
+ st->state &= ~(DNS_RPZ_HAVE_IP | DNS_RPZ_HAVE_NSIPv4 |
+ DNS_RPZ_HAVE_NSIPv6 | DNS_RPZ_HAD_NSDNAME);
+ result = rpz_rewrite_name(client, qtype, client->query.qname,
+ DNS_RPZ_TYPE_QNAME, &rdataset);
+ if (st->m.policy != DNS_RPZ_POLICY_MISS)
+ goto cleanup;
+ if ((st->state & (DNS_RPZ_HAVE_NSIPv4 | DNS_RPZ_HAVE_NSIPv6 |
+ DNS_RPZ_HAD_NSDNAME)) == 0)
+ goto cleanup;
+ st->ns.label = dns_name_countlabels(client->query.qname);
+ }
+
+ dns_fixedname_init(&nsnamef);
+ dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
+ while (st->ns.label > 1 && st->m.policy == DNS_RPZ_POLICY_MISS) {
+ if (st->ns.label == dns_name_countlabels(client->query.qname)) {
+ nsname = client->query.qname;
+ } else {
+ nsname = dns_fixedname_name(&nsnamef);
+ dns_name_split(client->query.qname, st->ns.label,
+ NULL, nsname);
+ }
+ if (st->ns.ns_rdataset == NULL ||
+ !dns_rdataset_isassociated(st->ns.ns_rdataset)) {
+ dns_db_t *db = NULL;
+ result = rpz_ns_find(client, nsname, dns_rdatatype_ns,
+ &db, NULL, &st->ns.ns_rdataset,
+ resuming);
+ if (db != NULL)
+ dns_db_detach(&db);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_DELEGATION)
+ goto cleanup;
+ if (result == DNS_R_EMPTYNAME ||
+ result == DNS_R_NXRRSET ||
+ result == DNS_R_EMPTYWILD ||
+ result == DNS_R_NXDOMAIN ||
+ result == DNS_R_NCACHENXDOMAIN ||
+ result == DNS_R_NCACHENXRRSET ||
+ result == DNS_R_CNAME ||
+ result == DNS_R_DNAME) {
+ rpz_fail_log(client,
+ DNS_RPZ_DEBUG_LEVEL2,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "NS db_find() ", result);
+ dns_rdataset_disassociate(st->ns.
+ ns_rdataset);
+ st->ns.label--;
+ continue;
+ }
+ if (st->m.policy != DNS_RPZ_POLICY_ERROR) {
+ rpz_fail_log(client, DNS_RPZ_INFO_LEVEL,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "NS db_find() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ }
+ goto cleanup;
+ }
+ result = dns_rdataset_first(st->ns.ns_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ /*
+ * Check all NS names.
+ */
+ do {
+ dns_rdata_ns_t ns;
+ dns_rdata_t nsrdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(st->ns.ns_rdataset, &nsrdata);
+ result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
+ dns_rdata_reset(&nsrdata);
+ if (result != ISC_R_SUCCESS) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "rdata_tostruct() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ goto cleanup;
+ }
+ if ((st->state & DNS_RPZ_HAD_NSDNAME) != 0) {
+ result = rpz_rewrite_name(client, qtype,
+ &ns.name,
+ DNS_RPZ_TYPE_NSDNAME,
+ &rdataset);
+ if (result != ISC_R_SUCCESS) {
+ dns_rdata_freestruct(&ns);
+ goto cleanup;
+ }
+ }
+ /*
+ * Check all IP addresses for this NS name, but don't
+ * bother without NSIP rules or with a NSDNAME hit.
+ */
+ version = NULL;
+ if ((st->state & DNS_RPZ_HAVE_NSIPv4) != 0 &&
+ st->m.type != DNS_RPZ_TYPE_NSDNAME &&
+ (st->state & DNS_RPZ_DONE_A) == 0) {
+ result = rpz_rewrite_nsip(client,
+ dns_rdatatype_a,
+ &ns.name, &ipdb,
+ version, &rdataset,
+ resuming);
+ if (result == ISC_R_SUCCESS)
+ st->state |= DNS_RPZ_DONE_A;
+ }
+ if (result == ISC_R_SUCCESS &&
+ (st->state & DNS_RPZ_HAVE_NSIPv6) != 0 &&
+ st->m.type != DNS_RPZ_TYPE_NSDNAME) {
+ result = rpz_rewrite_nsip(client,
+ dns_rdatatype_aaaa,
+ &ns.name, &ipdb, version,
+ &rdataset, resuming);
+ }
+ dns_rdata_freestruct(&ns);
+ if (ipdb != NULL)
+ dns_db_detach(&ipdb);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ st->state &= ~DNS_RPZ_DONE_A;
+ result = dns_rdataset_next(st->ns.ns_rdataset);
+ } while (result == ISC_R_SUCCESS);
+ dns_rdataset_disassociate(st->ns.ns_rdataset);
+ st->ns.label--;
+ }
+
+ /*
+ * Use the best, if any, hit.
+ */
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ if (st->m.policy != DNS_RPZ_POLICY_MISS &&
+ st->m.policy != DNS_RPZ_POLICY_NO_OP &&
+ st->m.policy != DNS_RPZ_POLICY_ERROR &&
+ st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
+ st->m.policy = st->m.rpz->policy;
+ if (st->m.policy == DNS_RPZ_POLICY_NO_OP)
+ rpz_log(client);
+ if (st->m.policy == DNS_RPZ_POLICY_MISS ||
+ st->m.policy == DNS_RPZ_POLICY_NO_OP ||
+ st->m.policy == DNS_RPZ_POLICY_ERROR)
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
+ if (st->m.policy != DNS_RPZ_POLICY_MISS)
+ st->state |= DNS_RPZ_REWRITTEN;
+ if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
+ st->m.type = DNS_RPZ_TYPE_BAD;
+ result = DNS_R_SERVFAIL;
+ }
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if ((st->state & DNS_RPZ_RECURSING) == 0) {
+ rpz_clean(NULL, &st->ns.db, NULL, &st->ns.ns_rdataset);
+ }
+
+ return (result);
+}
+
#define MAX_RESTARTS 16
#define QUERY_ERROR(r) \
@@ -3698,6 +4848,99 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
return;
}
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+static isc_boolean_t
+is_v4_client(ns_client_t *client) {
+ if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
+ return (ISC_TRUE);
+ if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+#endif
+
+static isc_uint32_t
+dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
+ dns_dbnode_t *node = NULL;
+ dns_rdata_soa_t soa;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ isc_result_t result;
+ isc_uint32_t ttl = ISC_UINT32_MAX;
+
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdataset_init(&rdataset);
+ result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_rdataset_first(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &soa, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ ttl = ISC_MIN(rdataset.ttl, soa.minimum);
+
+cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (ttl);
+}
+
+static isc_boolean_t
+dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset)
+{
+ isc_netaddr_t netaddr;
+ dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
+ unsigned int flags = 0;
+ unsigned int i, count;
+ isc_boolean_t *aaaaok;
+
+ INSIST(client->query.dns64_aaaaok == NULL);
+ INSIST(client->query.dns64_aaaaoklen == 0);
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+
+ if (dns64 == NULL)
+ return (ISC_TRUE);
+
+ if (RECURSIONOK(client))
+ flags |= DNS_DNS64_RECURSIVE;
+
+ if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
+ flags |= DNS_DNS64_DNSSEC;
+
+ count = dns_rdataset_count(rdataset);
+ aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
+ &ns_g_server->aclenv, flags, rdataset,
+ aaaaok, count)) {
+ for (i = 0; i < count; i++) {
+ if (aaaaok != NULL && !aaaaok[i]) {
+ client->query.dns64_aaaaok = aaaaok;
+ client->query.dns64_aaaaoklen = count;
+ break;
+ }
+ }
+ if (i == count)
+ isc_mem_put(client->mctx, aaaaok,
+ sizeof(isc_boolean_t) * count);
+ return (ISC_TRUE);
+ }
+ isc_mem_put(client->mctx, aaaaok, sizeof(isc_boolean_t) * count);
+ return (ISC_FALSE);
+}
+
/*
* Do the bulk of query processing for the current query of 'client'.
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
@@ -3716,6 +4959,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t want_restart, authoritative, is_zone, need_wildcardproof;
+ isc_boolean_t is_staticstub_zone;
unsigned int n, nlabels;
dns_namereln_t namereln;
int order;
@@ -3731,8 +4975,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
unsigned int options;
isc_boolean_t empty_wild;
dns_rdataset_t *noqname;
+ dns_rpz_st_t *rpz_st;
isc_boolean_t resuming;
int line = -1;
+ isc_boolean_t dns64_exclude, dns64;
CTRACE("query_find");
@@ -3758,28 +5004,67 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
zone = NULL;
need_wildcardproof = ISC_FALSE;
empty_wild = ISC_FALSE;
+ dns64_exclude = dns64 = ISC_FALSE;
options = 0;
resuming = ISC_FALSE;
is_zone = ISC_FALSE;
+ is_staticstub_zone = ISC_FALSE;
if (event != NULL) {
/*
* We're returning from recursion. Restore the query context
* and resume.
*/
-
want_restart = ISC_FALSE;
- authoritative = ISC_FALSE;
- qtype = event->qtype;
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ is_zone = rpz_st->q.is_zone;
+ authoritative = rpz_st->q.authoritative;
+ zone = rpz_st->q.zone;
+ rpz_st->q.zone = NULL;
+ node = rpz_st->q.node;
+ rpz_st->q.node = NULL;
+ db = rpz_st->q.db;
+ rpz_st->q.db = NULL;
+ rdataset = rpz_st->q.rdataset;
+ rpz_st->q.rdataset = NULL;
+ sigrdataset = rpz_st->q.sigrdataset;
+ rpz_st->q.sigrdataset = NULL;
+ qtype = rpz_st->q.qtype;
+
+ if (event->node != NULL)
+ dns_db_detachnode(db, &event->node);
+ rpz_st->ns.db = event->db;
+ rpz_st->ns.r_type = event->qtype;
+ rpz_st->ns.r_rdataset = event->rdataset;
+ if (event->sigrdataset != NULL &&
+ dns_rdataset_isassociated(event->sigrdataset))
+ dns_rdataset_disassociate(event->sigrdataset);
+ } else {
+ authoritative = ISC_FALSE;
+
+ qtype = event->qtype;
+ db = event->db;
+ node = event->node;
+ rdataset = event->rdataset;
+ sigrdataset = event->sigrdataset;
+ }
+
if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
type = dns_rdatatype_any;
else
type = qtype;
- db = event->db;
- node = event->node;
- rdataset = event->rdataset;
- sigrdataset = event->sigrdataset;
+
+ if (DNS64(client)) {
+ client->query.attributes &= ~NS_QUERYATTR_DNS64;
+ dns64 = ISC_TRUE;
+ }
+ if (DNS64EXCLUDE(client)) {
+ client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
+ dns64_exclude = ISC_TRUE;
+ }
/*
* We'll need some resources...
@@ -3794,16 +5079,26 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
- tname = dns_fixedname_name(&event->foundname);
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ tname = rpz_st->fname;
+ } else {
+ tname = dns_fixedname_name(&event->foundname);
+ }
result = dns_name_copy(tname, fname, NULL);
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
-
- result = event->result;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ rpz_st->ns.r_result = event->result;
+ result = rpz_st->q.result;
+ isc_event_free(ISC_EVENT_PTR(&event));
+ } else {
+ result = event->result;
+ }
resuming = ISC_TRUE;
-
goto resume;
}
@@ -3902,8 +5197,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
}
- if (is_zone)
+ is_staticstub_zone = ISC_FALSE;
+ if (is_zone && zone != NULL) {
authoritative = ISC_TRUE;
+ if (dns_zone_gettype(zone) == dns_zone_staticstub)
+ is_staticstub_zone = ISC_TRUE;
+ }
if (event == NULL && client->query.restarts == 0) {
if (is_zone) {
@@ -3956,6 +5255,119 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
resume:
CTRACE("query_find: resume");
+
+ if (!ISC_LIST_EMPTY(client->view->rpz_zones) &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ result != DNS_R_DELEGATION && result != ISC_R_NOTFOUND &&
+ (client->query.rpz_st == NULL ||
+ (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
+ !dns_name_equal(client->query.qname, dns_rootname)) {
+ isc_result_t rresult;
+
+ rresult = rpz_rewrite(client, qtype, resuming);
+ rpz_st = client->query.rpz_st;
+ switch (rresult) {
+ case ISC_R_SUCCESS:
+ break;
+ case DNS_R_DELEGATION:
+ /*
+ * recursing for NS names or addresses,
+ * so save the main query state
+ */
+ rpz_st->q.qtype = qtype;
+ rpz_st->q.is_zone = is_zone;
+ rpz_st->q.authoritative = authoritative;
+ rpz_st->q.zone = zone;
+ zone = NULL;
+ rpz_st->q.db = db;
+ db = NULL;
+ rpz_st->q.node = node;
+ node = NULL;
+ rpz_st->q.rdataset = rdataset;
+ rdataset = NULL;
+ rpz_st->q.sigrdataset = sigrdataset;
+ sigrdataset = NULL;
+ dns_name_copy(fname, rpz_st->fname, NULL);
+ rpz_st->q.result = result;
+ client->query.attributes |= NS_QUERYATTR_RECURSING;
+ result = ISC_R_SUCCESS;
+ goto cleanup;
+ default:
+ RECURSE_ERROR(rresult);
+ goto cleanup;
+ }
+ if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
+ rpz_st->m.policy != DNS_RPZ_POLICY_NO_OP) {
+ result = dns_name_copy(client->query.qname, fname,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ finish_rewrite:
+ rpz_clean(&zone, &db, &node, NULL);
+ if (rpz_st->m.rdataset != NULL) {
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ rdataset = rpz_st->m.rdataset;
+ rpz_st->m.rdataset = NULL;
+ } else if (rdataset != NULL &&
+ dns_rdataset_isassociated(rdataset)) {
+ dns_rdataset_disassociate(rdataset);
+ }
+ node = rpz_st->m.node;
+ rpz_st->m.node = NULL;
+ db = rpz_st->m.db;
+ rpz_st->m.db = NULL;
+ zone = rpz_st->m.zone;
+ rpz_st->m.zone = NULL;
+
+ result = rpz_st->m.result;
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ result = DNS_R_NXDOMAIN;
+ break;
+ case DNS_RPZ_POLICY_NODATA:
+ result = DNS_R_NXRRSET;
+ break;
+ case DNS_RPZ_POLICY_RECORD:
+ if (type == dns_rdatatype_any &&
+ result != DNS_R_CNAME &&
+ dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ break;
+ case DNS_RPZ_POLICY_CNAME:
+ result = dns_name_copy(&rpz_st->m.rpz->cname,
+ fname, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ query_keepname(client, fname, dbuf);
+ result = query_add_cname(client,
+ client->query.qname,
+ fname,
+ dns_trust_authanswer,
+ rpz_st->m.ttl);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ ns_client_qnamereplace(client, fname);
+ fname = NULL;
+ client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+ rpz_log(client);
+ want_restart = ISC_TRUE;
+ goto cleanup;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Turn off DNSSEC because the results of a
+ * response policy zone cannot verify.
+ */
+ client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+ if (sigrdataset != NULL &&
+ dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ is_zone = ISC_TRUE;
+ rpz_log(client);
+ }
+ }
+
switch (result) {
case ISC_R_SUCCESS:
/*
@@ -4008,11 +5420,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
if (RECURSIONOK(client)) {
result = query_recurse(client, qtype,
+ client->query.qname,
NULL, NULL, resuming);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
client->query.attributes |=
NS_QUERYATTR_RECURSING;
- else
+ if (dns64)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64;
+ if (dns64_exclude)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64EXCLUDE;
+ } else
RECURSE_ERROR(result);
goto cleanup;
} else {
@@ -4143,12 +5562,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
} else {
if (zfname != NULL &&
- !dns_name_issubdomain(fname, zfname)) {
+ (!dns_name_issubdomain(fname, zfname) ||
+ (is_staticstub_zone &&
+ dns_name_equal(fname, zfname)))) {
/*
- * We've already got a delegation from
- * authoritative data, and it is better
- * than what we found in the cache. Use
- * it instead of the cache delegation.
+ * In the following cases use "authoritative"
+ * data instead of the cache delegation:
+ * 1. We've already got a delegation from
+ * authoritative data, and it is better
+ * than what we found in the cache.
+ * 2. The query name matches the origin name
+ * of a static-stub zone. This needs to be
+ * considered for the case where the NS of
+ * the static-stub zone and the cached NS
+ * are different. We still need to contact
+ * the nameservers configured in the
+ * static-stub zone.
*/
query_releasename(client, &fname);
fname = zfname;
@@ -4183,15 +5612,31 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
if (dns_rdatatype_atparent(type))
result = query_recurse(client, qtype,
- NULL, NULL,
- resuming);
+ client->query.qname,
+ NULL, NULL, resuming);
+ else if (dns64)
+ result = query_recurse(client,
+ dns_rdatatype_a,
+ client->query.qname,
+ NULL, NULL, resuming);
else
result = query_recurse(client, qtype,
- fname, rdataset,
- resuming);
- if (result == ISC_R_SUCCESS)
+ client->query.qname,
+ fname, rdataset,
+ resuming);
+
+ if (result == ISC_R_SUCCESS) {
client->query.attributes |=
NS_QUERYATTR_RECURSING;
+ if (dns64)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64;
+ if (dns64_exclude)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64EXCLUDE;
+ } else if (result == DNS_R_DUPLICATE ||
+ result == DNS_R_DROP)
+ QUERY_ERROR(result);
else
RECURSE_ERROR(result);
} else {
@@ -4231,11 +5676,75 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
}
goto cleanup;
+
case DNS_R_EMPTYNAME:
- result = DNS_R_NXRRSET;
- /* FALLTHROUGH */
case DNS_R_NXRRSET:
+ nxrrset:
INSIST(is_zone);
+
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64)
+#else
+ if (dns64 && !dns64_exclude)
+#endif
+ {
+ /*
+ * Restore the answers from the previous AAAA lookup.
+ */
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if (sigrdataset != NULL)
+ query_putrdataset(client, &sigrdataset);
+ rdataset = client->query.dns64_aaaa;
+ sigrdataset = client->query.dns64_sigaaaa;
+ if (fname == NULL) {
+ dbuf = query_getnamebuf(client);
+ if (dbuf == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ fname = query_newname(client, dbuf, &b);
+ if (fname == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ }
+ dns_name_copy(client->query.qname, fname, NULL);
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ dns64 = ISC_FALSE;
+#ifdef dns64_bis_return_excluded_addresses
+ /*
+ * Resume the diverted processing of the AAAA response?
+ */
+ if (dns64_excluded)
+ break;
+#endif
+ } else if (result == DNS_R_NXRRSET &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ qtype == dns_rdatatype_aaaa)
+ {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ client->query.dns64_ttl = dns64_ttl(db, version);
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
+ result = DNS_R_NXRRSET;
+
/*
* Look for a NSEC3 record if we don't have a NSEC record.
*/
@@ -4258,10 +5767,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* instead? If so add the nearest to the
* closest provable encloser.
*/
- if (found &&
- dns_rdataset_isassociated(rdataset) &&
- !dns_name_equal(qname, found))
- {
+ if (dns_rdataset_isassociated(rdataset) &&
+ !dns_name_equal(qname, found)) {
unsigned int count;
unsigned int skip;
@@ -4328,7 +5835,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* Add SOA.
*/
- result = query_addsoa(client, db, version, ISC_FALSE,
+ result = query_addsoa(client, db, version, ISC_UINT32_MAX,
dns_rdataset_isassociated(rdataset));
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(result);
@@ -4377,10 +5884,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
zone != NULL &&
#endif
dns_zone_getzeronosoattl(zone))
- result = query_addsoa(client, db, version, ISC_TRUE,
+ result = query_addsoa(client, db, version, 0,
dns_rdataset_isassociated(rdataset));
else
- result = query_addsoa(client, db, version, ISC_FALSE,
+ result = query_addsoa(client, db, version,
+ ISC_UINT32_MAX,
dns_rdataset_isassociated(rdataset));
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(result);
@@ -4411,6 +5919,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
+ ncache_nxrrset:
INSIST(!is_zone);
authoritative = ISC_FALSE;
/*
@@ -4426,6 +5935,74 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
client->message->rdclass == dns_rdataclass_in &&
dns_name_countlabels(fname) == 7)
warn_rfc1918(client, fname, rdataset);
+
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64)
+#else
+ if (dns64 && !dns64_exclude)
+#endif
+ {
+ /*
+ * Restore the answers from the previous AAAA lookup.
+ */
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if (sigrdataset != NULL)
+ query_putrdataset(client, &sigrdataset);
+ rdataset = client->query.dns64_aaaa;
+ sigrdataset = client->query.dns64_sigaaaa;
+ if (fname == NULL) {
+ dbuf = query_getnamebuf(client);
+ if (dbuf == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ fname = query_newname(client, dbuf, &b);
+ if (fname == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ }
+ dns_name_copy(client->query.qname, fname, NULL);
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ dns64 = ISC_FALSE;
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64_excluded)
+ break;
+#endif
+ } else if (result == DNS_R_NCACHENXRRSET &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ qtype == dns_rdatatype_aaaa)
+ {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ /*
+ * If the ttl is zero we need to workout if we have just
+ * decremented to zero or if there was no negative cache
+ * ttl in the answer.
+ */
+ if (rdataset->ttl != 0)
+ client->query.dns64_ttl = rdataset->ttl;
+ else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS)
+ client->query.dns64_ttl = 0;
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ fname = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
/*
* We don't call query_addrrset() because we don't need any
* of its extra features (and things would probably break!).
@@ -4562,11 +6139,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_message_puttempname(client->message, &tname);
goto cleanup;
}
- dns_name_init(tname, NULL);
dns_name_clone(&dname.dname, tname);
dns_rdata_freestruct(&dname);
/*
- * Construct the new qname.
+ * Construct the new qname consisting of
+ * .
*/
dns_fixedname_init(&fixed);
prefix = dns_fixedname_name(&fixed);
@@ -4583,8 +6160,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
}
result = dns_name_concatenate(prefix, tname, fname, NULL);
+ dns_message_puttempname(client->message, &tname);
if (result != ISC_R_SUCCESS) {
- dns_message_puttempname(client->message, &tname);
if (result == ISC_R_NOSPACE) {
/*
* RFC2672, section 4.1, subsection 3c says
@@ -4597,11 +6174,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
query_keepname(client, fname, dbuf);
/*
- * Synthesize a CNAME for this DNAME.
+ * Synthesize a CNAME consisting of
+ * CNAME
+ * with
*
- * We want to synthesize a CNAME since if we don't
- * then older software that doesn't understand DNAME
- * will not chain like it should.
+ * Synthesize a CNAME so old old clients that don't understand
+ * DNAME can chain.
*
* We do not try to synthesize a signature because we hope
* that security aware servers will understand DNAME. Also,
@@ -4609,12 +6187,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* on-the-fly is costly, and not really legitimate anyway
* since the synthesized CNAME is NOT in the zone.
*/
- dns_name_init(tname, NULL);
- (void)query_addcnamelike(client, client->query.qname, fname,
- trdataset, &tname,
- dns_rdatatype_cname);
- if (tname != NULL)
- dns_message_puttempname(client->message, &tname);
+ result = query_add_cname(client, client->query.qname, fname,
+ trdataset->trust, trdataset->ttl);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
/*
* Switch to the new qname and restart.
*/
@@ -4641,6 +6217,28 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
if (type == dns_rdatatype_any) {
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ isc_boolean_t have_aaaa, have_a, have_sig, filter_aaaa;
+
+ /*
+ * The filter-aaaa-on-v4 option should
+ * suppress AAAAs for IPv4 clients if there is an A.
+ * If we are not authoritative, assume there is a A
+ * even in if it is not in our cache. This assumption could
+ * be wrong but it is a good bet.
+ */
+ have_aaaa = ISC_FALSE;
+ have_a = !authoritative;
+ have_sig = ISC_FALSE;
+ if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
+ is_v4_client(client) &&
+ ns_client_checkaclsilent(client, NULL,
+ client->view->v4_aaaa_acl,
+ ISC_TRUE) == ISC_R_SUCCESS)
+ filter_aaaa = ISC_TRUE;
+ else
+ filter_aaaa = ISC_FALSE;
+#endif
/*
* XXXRTH Need to handle zonecuts with special case
* code.
@@ -4652,6 +6250,54 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
+
+ /*
+ * Check all A and AAAA records in all response policy
+ * IP address zones
+ */
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 &&
+ (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ (rpz_st->state & DNS_RPZ_HAVE_IP) != 0) {
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, rdataset);
+ if (rdataset->type == dns_rdatatype_a ||
+ rdataset->type == dns_rdatatype_aaaa)
+ result = rpz_rewrite_ip(client,
+ rdataset,
+ DNS_RPZ_TYPE_IP);
+ dns_rdataset_disassociate(rdataset);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+ if (result != ISC_R_NOMORE) {
+ dns_rdatasetiter_destroy(&rdsiter);
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_MISS:
+ break;
+ case DNS_RPZ_POLICY_NO_OP:
+ rpz_log(client);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ case DNS_RPZ_POLICY_NODATA:
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ dns_rdatasetiter_destroy(&rdsiter);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ goto finish_rewrite;
+ default:
+ INSIST(0);
+ }
+ }
+
/*
* Calling query_addrrset() with a non-NULL dbuf is going
* to either keep or release the name. We don't want it to
@@ -4668,6 +6314,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset);
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Notice the presence of A and AAAAs so
+ * that AAAAs can be hidden from IPv4 clients.
+ */
+ if (filter_aaaa) {
+ if (rdataset->type == dns_rdatatype_aaaa)
+ have_aaaa = ISC_TRUE;
+ else if (rdataset->type == dns_rdatatype_a)
+ have_a = ISC_TRUE;
+ }
+#endif
if (is_zone && qtype == dns_rdatatype_any &&
!dns_db_issecure(db) &&
dns_rdatatype_isdnssec(rdataset->type)) {
@@ -4679,6 +6337,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdataset_disassociate(rdataset);
} else if ((qtype == dns_rdatatype_any ||
rdataset->type == qtype) && rdataset->type != 0) {
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ if (dns_rdatatype_isdnssec(rdataset->type))
+ have_sig = ISC_TRUE;
+#endif
if (NOQNAME(rdataset) && WANTDNSSEC(client))
noqname = rdataset;
else
@@ -4709,6 +6371,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
result = dns_rdatasetiter_next(rdsiter);
}
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Filter AAAAs if there is an A and there is no signature
+ * or we are supposed to break DNSSEC.
+ */
+ if (filter_aaaa && have_aaaa && have_a &&
+ (!have_sig || !WANTDNSSEC(client) ||
+ client->view->v4_aaaa == dns_v4_aaaa_break_dnssec))
+ client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
+#endif
if (fname != NULL)
dns_message_puttempname(client->message, &fname);
@@ -4742,10 +6414,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdatasetiter_destroy(&rdsiter);
if (RECURSIONOK(client)) {
result = query_recurse(client,
- qtype,
- NULL,
- NULL,
- resuming);
+ qtype,
+ client->query.qname,
+ NULL, NULL,
+ resuming);
if (result == ISC_R_SUCCESS)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
@@ -4763,7 +6435,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* Add SOA.
*/
result = query_addsoa(client, db, version,
- ISC_FALSE, ISC_FALSE);
+ ISC_UINT32_MAX,
+ ISC_FALSE);
if (result == ISC_R_SUCCESS)
result = ISC_R_NOMORE;
} else {
@@ -4783,6 +6456,162 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* This is the "normal" case -- an ordinary question to which
* we know the answer.
*/
+
+ /*
+ * Check all A and AAAA records in all response policy
+ * IP address zones
+ */
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 &&
+ (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ (rpz_st->state & DNS_RPZ_HAVE_IP) != 0 &&
+ (qtype == dns_rdatatype_aaaa || qtype == dns_rdatatype_a)) {
+ result = rpz_rewrite_ip(client, rdataset,
+ DNS_RPZ_TYPE_IP);
+ if (result != ISC_R_SUCCESS) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ /*
+ * After a hit in the radix tree for the policy domain,
+ * either stop trying to rewrite (DNS_RPZ_POLICY_NO_OP)
+ * or restart to ask the ordinary database of the
+ * policy zone for the DNS record corresponding to the
+ * record in the radix tree.
+ */
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_MISS:
+ break;
+ case DNS_RPZ_POLICY_NO_OP:
+ rpz_log(client);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ case DNS_RPZ_POLICY_NODATA:
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ goto finish_rewrite;
+ default:
+ INSIST(0);
+ }
+ }
+
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Optionally hide AAAAs from IPv4 clients if there is an A.
+ * We add the AAAAs now, but might refuse to render them later
+ * after DNSSEC is figured out.
+ * This could be more efficient, but the whole idea is
+ * so fundamentally wrong, unavoidably inaccurate, and
+ * unneeded that it is best to keep it as short as possible.
+ */
+ if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
+ is_v4_client(client) &&
+ ns_client_checkaclsilent(client, NULL,
+ client->view->v4_aaaa_acl,
+ ISC_TRUE) == ISC_R_SUCCESS &&
+ (!WANTDNSSEC(client) ||
+ sigrdataset == NULL ||
+ !dns_rdataset_isassociated(sigrdataset) ||
+ client->view->v4_aaaa == dns_v4_aaaa_break_dnssec)) {
+ if (qtype == dns_rdatatype_aaaa) {
+ trdataset = query_newrdataset(client);
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_a, 0,
+ client->now,
+ trdataset, NULL);
+ if (dns_rdataset_isassociated(trdataset))
+ dns_rdataset_disassociate(trdataset);
+ query_putrdataset(client, &trdataset);
+
+ /*
+ * We have an AAAA but the A is not in our cache.
+ * Assume any result other than DNS_R_DELEGATION
+ * or ISC_R_NOTFOUND means there is no A and
+ * so AAAAs are ok.
+ * Assume there is no A if we can't recurse
+ * for this client, although that could be
+ * the wrong answer. What else can we do?
+ * Besides, that we have the AAAA and are using
+ * this mechanism suggests that we care more
+ * about As than AAAAs and would have cached
+ * the A if it existed.
+ */
+ if (result == ISC_R_SUCCESS) {
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA;
+
+ } else if (authoritative ||
+ !RECURSIONOK(client) ||
+ (result != DNS_R_DELEGATION &&
+ result != ISC_R_NOTFOUND)) {
+ client->attributes &=
+ ~NS_CLIENTATTR_FILTER_AAAA;
+ } else {
+ /*
+ * This is an ugly kludge to recurse
+ * for the A and discard the result.
+ *
+ * Continue to add the AAAA now.
+ * We'll make a note to not render it
+ * if the recursion for the A succeeds.
+ */
+ result = query_recurse(client,
+ dns_rdatatype_a,
+ client->query.qname,
+ NULL, NULL, resuming);
+ if (result == ISC_R_SUCCESS) {
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA_RC;
+ client->query.attributes |=
+ NS_QUERYATTR_RECURSING;
+ }
+ }
+
+ } else if (qtype == dns_rdatatype_a &&
+ (client->attributes &
+ NS_CLIENTATTR_FILTER_AAAA_RC) != 0) {
+ client->attributes &=
+ ~NS_CLIENTATTR_FILTER_AAAA_RC;
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA;
+ dns_rdataset_disassociate(rdataset);
+ if (sigrdataset != NULL &&
+ dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ goto cleanup;
+ }
+ }
+#endif
+ /*
+ * Check to see if the AAAA RRset has non-excluded addresses
+ * in it. If not look for a A RRset.
+ */
+ INSIST(client->query.dns64_aaaaok == NULL);
+
+ if (qtype == dns_rdatatype_aaaa && !dns64_exclude &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ !dns64_aaaaok(client, rdataset, sigrdataset)) {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ client->query.dns64_ttl = rdataset->ttl;
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64_exclude = dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
if (sigrdataset != NULL)
sigrdatasetp = &sigrdataset;
else
@@ -4798,8 +6627,43 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_name_equal(client->query.qname, dns_rootname))
client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
- query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
- DNS_SECTION_ANSWER);
+ if (dns64) {
+ qtype = type = dns_rdatatype_aaaa;
+ result = query_dns64(client, &fname, rdataset,
+ sigrdataset, dbuf,
+ DNS_SECTION_ANSWER);
+ dns_rdataset_disassociate(rdataset);
+ dns_message_puttemprdataset(client->message, &rdataset);
+ if (result == ISC_R_NOMORE) {
+#ifndef dns64_bis_return_excluded_addresses
+ if (dns64_exclude) {
+ if (!is_zone)
+ goto cleanup;
+ /*
+ * Add a fake SOA record.
+ */
+ result = query_addsoa(client, db,
+ version, 600,
+ ISC_FALSE);
+ goto cleanup;
+ }
+#endif
+ if (is_zone)
+ goto nxrrset;
+ else
+ goto ncache_nxrrset;
+ } else if (result != ISC_R_SUCCESS) {
+ eresult = result;
+ goto cleanup;
+ }
+ } else if (client->query.dns64_aaaaok != NULL) {
+ query_filter64(client, &fname, rdataset, dbuf,
+ DNS_SECTION_ANSWER);
+ query_putrdataset(client, &rdataset);
+ } else
+ query_addrrset(client, &fname, &rdataset,
+ sigrdatasetp, dbuf, DNS_SECTION_ANSWER);
+
if (noqname != NULL)
query_addnoqnameproof(client, noqname);
/*
@@ -4842,6 +6706,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* General cleanup.
*/
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0)
+ rpz_clean(&rpz_st->m.zone, &rpz_st->m.db, &rpz_st->m.node,
+ &rpz_st->m.rdataset);
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
@@ -4949,6 +6817,7 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
char namebuf[DNS_NAME_FORMATSIZE];
char typename[DNS_RDATATYPE_FORMATSIZE];
char classname[DNS_RDATACLASS_FORMATSIZE];
+ char onbuf[ISC_NETADDR_FORMATSIZE];
dns_rdataset_t *rdataset;
int level = ISC_LOG_INFO;
@@ -4960,14 +6829,18 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname));
dns_rdatatype_format(rdataset->type, typename, sizeof(typename));
+ isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
- level, "query: %s %s %s %s%s%s%s%s", namebuf, classname,
- typename, WANTRECURSION(client) ? "+" : "-",
+ level, "query: %s %s %s %s%s%s%s%s%s (%s)", namebuf,
+ classname, typename, WANTRECURSION(client) ? "+" : "-",
(client->signer != NULL) ? "S": "",
(client->opt != NULL) ? "E" : "",
+ ((client->attributes & NS_CLIENTATTR_TCP) != 0) ?
+ "T" : "",
((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
- ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "");
+ ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
+ onbuf);
}
static inline void
diff --git a/bin/named/server.c b/bin/named/server.c
index bc7fc17c329..5bbf94b9b60 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.520.12.21 2011-01-14 23:45:49 tbox Exp $ */
+/* $Id: server.c,v 1.599.8.4 2011-02-16 19:46:12 each Exp $ */
/*! \file */
@@ -23,6 +23,10 @@
#include
#include
+#include
+#include
+#include
+#include
#include
#include
@@ -36,7 +40,9 @@
#include
#include
#include
+#include
#include
+#include
#include
#include
#include
@@ -57,9 +63,11 @@
#ifdef DLZ
#include
#endif
+#include
#include
#include
#include
+#include
#include
#include
#include
@@ -102,6 +110,10 @@
#include
#endif
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
/*%
* Check an operation for failure. Assumes that the function
* using it has a 'result' variable and a 'cleanup' label.
@@ -143,6 +155,14 @@
fatal(msg, result); \
} while (0) \
+/*%
+ * Maximum ADB size for views that share a cache. Use this limit to suppress
+ * the total of memory footprint, which should be the main reason for sharing
+ * a cache. Only effective when a finite max-cache-size is specified.
+ * This is currently defined to be 8MB.
+ */
+#define MAX_ADB_SIZE_FOR_CACHESHARE 8388608
+
struct ns_dispatch {
isc_sockaddr_t addr;
unsigned int dispatchgen;
@@ -150,6 +170,14 @@ struct ns_dispatch {
ISC_LINK(struct ns_dispatch) link;
};
+struct ns_cache {
+ dns_cache_t *cache;
+ dns_view_t *primaryview;
+ isc_boolean_t needflush;
+ isc_boolean_t adbsizeadjusted;
+ ISC_LINK(ns_cache_t) link;
+};
+
struct dumpcontext {
isc_mem_t *mctx;
isc_boolean_t dumpcache;
@@ -176,6 +204,17 @@ struct zonelistentry {
ISC_LINK(struct zonelistentry) link;
};
+/*%
+ * Configuration context to retain for each view that allows
+ * new zones to be added at runtime
+ */
+struct cfg_context {
+ isc_mem_t * mctx;
+ cfg_obj_t * config;
+ cfg_parser_t * parser;
+ cfg_aclconfctx_t actx;
+};
+
/*
* These zones should not leak onto the Internet.
*/
@@ -230,8 +269,8 @@ static const struct {
{ NULL, ISC_FALSE }
};
-static void
-fatal(const char *msg, isc_result_t result);
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *msg, isc_result_t result) ISC_PLATFORM_NORETURN_POST;
static void
ns_server_reload(isc_task_t *task, isc_event_t *event);
@@ -256,19 +295,25 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
- cfg_aclconfctx_t *aclconf);
+ cfg_aclconfctx_t *aclconf, isc_boolean_t added);
+
+static isc_result_t
+add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
static void
end_reserved_dispatches(ns_server_t *server, isc_boolean_t all);
+static void
+cfgctx_destroy(void **cfgp);
+
/*%
* Configure a single view ACL at '*aclp'. Get its configuration from
* 'vconfig' (for per-view configuration) and maybe from 'config'
*/
static isc_result_t
configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config,
- const char *aclname, cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, dns_acl_t **aclp)
+ const char *aclname, const char *acltuplename,
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx, dns_acl_t **aclp)
{
isc_result_t result;
const cfg_obj_t *maps[3];
@@ -294,13 +339,21 @@ configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config,
*/
return (ISC_R_SUCCESS);
+ if (acltuplename != NULL) {
+ /*
+ * If the ACL is given in an optional tuple, retrieve it.
+ * The parser should have ensured that a valid object be
+ * returned.
+ */
+ aclobj = cfg_tuple_get(aclobj, acltuplename);
+ }
+
result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx,
actx, mctx, 0, aclp);
return (result);
}
-
/*%
* Configure a sortlist at '*aclp'. Essentially the same as
* configure_view_acl() except it calls cfg_acl_fromconfig with a
@@ -345,8 +398,88 @@ configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config,
}
static isc_result_t
-configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
- dns_keytable_t *keytable, isc_mem_t *mctx)
+configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
+ const char *confname, const char *conftuplename,
+ isc_mem_t *mctx, dns_rbt_t **rbtp)
+{
+ isc_result_t result;
+ const cfg_obj_t *maps[3];
+ const cfg_obj_t *obj = NULL;
+ const cfg_listelt_t *element;
+ int i = 0;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ isc_buffer_t b;
+ const char *str;
+ const cfg_obj_t *nameobj;
+
+ if (*rbtp != NULL)
+ dns_rbt_destroy(rbtp);
+ if (vconfig != NULL)
+ maps[i++] = cfg_tuple_get(vconfig, "options");
+ if (config != NULL) {
+ const cfg_obj_t *options = NULL;
+ (void)cfg_map_get(config, "options", &options);
+ if (options != NULL)
+ maps[i++] = options;
+ }
+ maps[i] = NULL;
+
+ (void)ns_config_get(maps, confname, &obj);
+ if (obj == NULL)
+ /*
+ * No value available. *rbtp == NULL.
+ */
+ return (ISC_R_SUCCESS);
+
+ if (conftuplename != NULL) {
+ obj = cfg_tuple_get(obj, conftuplename);
+ if (cfg_obj_isvoid(obj))
+ return (ISC_R_SUCCESS);
+ }
+
+ result = dns_rbt_create(mctx, NULL, NULL, rbtp);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ nameobj = cfg_listelt_value(element);
+ str = cfg_obj_asstring(nameobj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ /*
+ * We don't need the node data, but need to set dummy data to
+ * avoid a partial match with an empty node. For example, if
+ * we have foo.example.com and bar.example.com, we'd get a match
+ * for baz.example.com, which is not the expected result.
+ * We simply use (void *)1 as the dummy data.
+ */
+ result = dns_rbt_addname(*rbtp, name, (void *)1);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR,
+ "failed to add %s for %s: %s",
+ str, confname, isc_result_totext(result));
+ goto cleanup;
+ }
+
+ }
+
+ return (result);
+
+ cleanup:
+ dns_rbt_destroy(rbtp);
+ return (result);
+
+}
+
+static isc_result_t
+dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
+ isc_boolean_t managed, dst_key_t **target, isc_mem_t *mctx)
{
dns_rdataclass_t viewclass;
dns_rdata_dnskey_t keystruct;
@@ -363,12 +496,28 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
isc_result_t result;
dst_key_t *dstkey = NULL;
+ INSIST(target != NULL && *target == NULL);
+
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
keyname = dns_fixedname_name(&fkeyname);
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
+ if (managed) {
+ const char *initmethod;
+ initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
+
+ if (strcasecmp(initmethod, "initial-key") != 0) {
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
+ "managed key '%s': "
+ "invalid initialization method '%s'",
+ keynamestr, initmethod);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+ }
+
if (vconfig == NULL)
viewclass = dns_rdataclass_in;
else {
@@ -408,7 +557,8 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
keystruct.algorithm == DST_ALG_RSAMD5) &&
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
- "trusted key '%s' has a weak exponent",
+ "%s key '%s' has a weak exponent",
+ managed ? "managed" : "trusted",
keynamestr);
CHECK(dns_rdata_fromstruct(NULL,
@@ -418,25 +568,28 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
dns_fixedname_init(&fkeyname);
isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
- CHECK(dns_name_fromtext(keyname, &namebuf,
- dns_rootname, ISC_FALSE,
- NULL));
+ CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL));
CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf,
mctx, &dstkey));
- CHECK(dns_keytable_add(keytable, &dstkey));
- INSIST(dstkey == NULL);
+ *target = dstkey;
return (ISC_R_SUCCESS);
cleanup:
if (result == DST_R_NOCRYPTO) {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
- "ignoring trusted key for '%s': no crypto support",
+ "ignoring %s key for '%s': no crypto support",
+ managed ? "managed" : "trusted",
keynamestr);
- result = ISC_R_SUCCESS;
+ } else if (result == DST_R_UNSUPPORTEDALG) {
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
+ "skipping %s key for '%s': %s",
+ managed ? "managed" : "trusted",
+ keynamestr, isc_result_totext(result));
} else {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
- "configuring trusted key for '%s': %s",
+ "configuring %s key for '%s': %s",
+ managed ? "managed" : "trusted",
keynamestr, isc_result_totext(result));
result = ISC_R_FAILURE;
}
@@ -447,63 +600,215 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
return (result);
}
-/*%
- * Configure DNSSEC keys for a view. Currently used only for
- * the security roots.
- *
- * The per-view configuration values and the server-global defaults are read
- * from 'vconfig' and 'config'. The variable to be configured is '*target'.
- */
static isc_result_t
-configure_view_dnsseckeys(const cfg_obj_t *vconfig, const cfg_obj_t *config,
- isc_mem_t *mctx, dns_keytable_t **target)
+load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig,
+ dns_view_t *view, isc_boolean_t managed,
+ dns_name_t *keyname, isc_mem_t *mctx)
{
+ const cfg_listelt_t *elt, *elt2;
+ const cfg_obj_t *key, *keylist;
+ dst_key_t *dstkey = NULL;
isc_result_t result;
- const cfg_obj_t *keys = NULL;
- const cfg_obj_t *voptions = NULL;
- const cfg_listelt_t *element, *element2;
- const cfg_obj_t *keylist;
- const cfg_obj_t *key;
- dns_keytable_t *keytable = NULL;
+ dns_keytable_t *secroots = NULL;
- CHECK(dns_keytable_create(mctx, &keytable));
+ CHECK(dns_view_getsecroots(view, &secroots));
- if (vconfig != NULL)
- voptions = cfg_tuple_get(vconfig, "options");
+ for (elt = cfg_list_first(keys);
+ elt != NULL;
+ elt = cfg_list_next(elt)) {
+ keylist = cfg_listelt_value(elt);
- keys = NULL;
- if (voptions != NULL)
- (void)cfg_map_get(voptions, "trusted-keys", &keys);
- if (keys == NULL)
- (void)cfg_map_get(config, "trusted-keys", &keys);
+ for (elt2 = cfg_list_first(keylist);
+ elt2 != NULL;
+ elt2 = cfg_list_next(elt2)) {
+ key = cfg_listelt_value(elt2);
+ result = dstkey_fromconfig(vconfig, key, managed,
+ &dstkey, mctx);
+ if (result == DST_R_UNSUPPORTEDALG) {
+ result = ISC_R_SUCCESS;
+ continue;
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
- for (element = cfg_list_first(keys);
- element != NULL;
- element = cfg_list_next(element))
- {
- keylist = cfg_listelt_value(element);
- for (element2 = cfg_list_first(keylist);
- element2 != NULL;
- element2 = cfg_list_next(element2))
- {
- key = cfg_listelt_value(element2);
- CHECK(configure_view_dnsseckey(vconfig, key,
- keytable, mctx));
+ /*
+ * If keyname was specified, we only add that key.
+ */
+ if (keyname != NULL &&
+ !dns_name_equal(keyname, dst_key_name(dstkey)))
+ {
+ dst_key_free(&dstkey);
+ continue;
+ }
+
+ CHECK(dns_keytable_add(secroots, managed, &dstkey));
}
}
- dns_keytable_detach(target);
- *target = keytable; /* Transfer ownership. */
- keytable = NULL;
- result = ISC_R_SUCCESS;
-
cleanup:
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ if (result == DST_R_NOCRYPTO)
+ result = ISC_R_SUCCESS;
+ return (result);
+}
+
+/*%
+ * Configure DNSSEC keys for a view.
+ *
+ * The per-view configuration values and the server-global defaults are read
+ * from 'vconfig' and 'config'.
+ */
+static isc_result_t
+configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
+ const cfg_obj_t *config, const cfg_obj_t *bindkeys,
+ isc_boolean_t auto_dlv, isc_boolean_t auto_root,
+ isc_mem_t *mctx)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ const cfg_obj_t *view_keys = NULL;
+ const cfg_obj_t *global_keys = NULL;
+ const cfg_obj_t *view_managed_keys = NULL;
+ const cfg_obj_t *global_managed_keys = NULL;
+ const cfg_obj_t *maps[4];
+ const cfg_obj_t *voptions = NULL;
+ const cfg_obj_t *options = NULL;
+ const cfg_obj_t *obj = NULL;
+ const char *directory;
+ int i = 0;
+
+ /* We don't need trust anchors for the _bind view */
+ if (strcmp(view->name, "_bind") == 0 &&
+ view->rdclass == dns_rdataclass_chaos) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (vconfig != NULL) {
+ voptions = cfg_tuple_get(vconfig, "options");
+ if (voptions != NULL) {
+ (void) cfg_map_get(voptions, "trusted-keys",
+ &view_keys);
+ (void) cfg_map_get(voptions, "managed-keys",
+ &view_managed_keys);
+ maps[i++] = voptions;
+ }
+ }
+
+ if (config != NULL) {
+ (void)cfg_map_get(config, "trusted-keys", &global_keys);
+ (void)cfg_map_get(config, "managed-keys", &global_managed_keys);
+ (void)cfg_map_get(config, "options", &options);
+ if (options != NULL) {
+ maps[i++] = options;
+ }
+ }
+
+ maps[i++] = ns_g_defaults;
+ maps[i] = NULL;
+
+ result = dns_view_initsecroots(view, mctx);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "couldn't create keytable");
+ return (ISC_R_UNEXPECTED);
+ }
+
+ if (auto_dlv && view->rdclass == dns_rdataclass_in) {
+ const cfg_obj_t *builtin_keys = NULL;
+ const cfg_obj_t *builtin_managed_keys = NULL;
+
+ isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "using built-in DLV key for view %s",
+ view->name);
+
+ /*
+ * If bind.keys exists, it overrides the managed-keys
+ * clause hard-coded in ns_g_config.
+ */
+ if (bindkeys != NULL) {
+ (void)cfg_map_get(bindkeys, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(bindkeys, "managed-keys",
+ &builtin_managed_keys);
+ } else {
+ (void)cfg_map_get(ns_g_config, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(ns_g_config, "managed-keys",
+ &builtin_managed_keys);
+ }
+
+ if (builtin_keys != NULL)
+ CHECK(load_view_keys(builtin_keys, vconfig, view,
+ ISC_FALSE, view->dlv, mctx));
+ if (builtin_managed_keys != NULL)
+ CHECK(load_view_keys(builtin_managed_keys, vconfig,
+ view, ISC_TRUE, view->dlv, mctx));
+ }
+
+ if (auto_root && view->rdclass == dns_rdataclass_in) {
+ const cfg_obj_t *builtin_keys = NULL;
+ const cfg_obj_t *builtin_managed_keys = NULL;
+
+ isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "using built-in root key for view %s",
+ view->name);
+
+ /*
+ * If bind.keys exists, it overrides the managed-keys
+ * clause hard-coded in ns_g_config.
+ */
+ if (bindkeys != NULL) {
+ (void)cfg_map_get(bindkeys, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(bindkeys, "managed-keys",
+ &builtin_managed_keys);
+ } else {
+ (void)cfg_map_get(ns_g_config, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(ns_g_config, "managed-keys",
+ &builtin_managed_keys);
+ }
+
+ if (builtin_keys != NULL)
+ CHECK(load_view_keys(builtin_keys, vconfig, view,
+ ISC_FALSE, dns_rootname, mctx));
+ if (builtin_managed_keys != NULL)
+ CHECK(load_view_keys(builtin_managed_keys, vconfig,
+ view, ISC_TRUE, dns_rootname,
+ mctx));
+ }
+
+ CHECK(load_view_keys(view_keys, vconfig, view, ISC_FALSE,
+ NULL, mctx));
+ CHECK(load_view_keys(view_managed_keys, vconfig, view, ISC_TRUE,
+ NULL, mctx));
+
+ if (view->rdclass == dns_rdataclass_in) {
+ CHECK(load_view_keys(global_keys, vconfig, view, ISC_FALSE,
+ NULL, mctx));
+ CHECK(load_view_keys(global_managed_keys, vconfig, view,
+ ISC_TRUE, NULL, mctx));
+ }
+
+ /*
+ * Add key zone for managed-keys.
+ */
+ obj = NULL;
+ (void)ns_config_get(maps, "managed-keys-directory", &obj);
+ directory = obj != NULL ? cfg_obj_asstring(obj) : NULL;
+ CHECK(add_keydata_zone(view, directory, ns_g_mctx));
+
+ cleanup:
return (result);
}
static isc_result_t
-mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
-{
+mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) {
const cfg_listelt_t *element;
const cfg_obj_t *obj;
const char *str;
@@ -523,8 +828,7 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
value = cfg_obj_asboolean(cfg_tuple_get(obj, "value"));
CHECK(dns_resolver_setmustbesecure(resolver, name, value));
}
@@ -684,7 +988,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
isc_buffer_add(&b, strlen(str));
dns_fixedname_init(&fixed);
result = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -868,7 +1172,7 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
algorithms = cfg_tuple_get(disabled, "algorithms");
for (element = cfg_list_first(algorithms);
@@ -921,7 +1225,7 @@ on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
+ 0, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_equal(name, zonename))
return (ISC_TRUE);
@@ -979,6 +1283,20 @@ setquerystats(dns_zone_t *zone, isc_mem_t *mctx, isc_boolean_t on) {
return (ISC_R_SUCCESS);
}
+static ns_cache_t *
+cachelist_find(ns_cachelist_t *cachelist, const char *cachename) {
+ ns_cache_t *nsc;
+
+ for (nsc = ISC_LIST_HEAD(*cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (strcmp(dns_cache_getname(nsc->cache), cachename) == 0)
+ return (nsc);
+ }
+
+ return (NULL);
+}
+
static isc_boolean_t
cache_reusable(dns_view_t *originview, dns_view_t *view,
isc_boolean_t new_zero_no_soattl)
@@ -996,6 +1314,238 @@ cache_reusable(dns_view_t *originview, dns_view_t *view,
return (ISC_TRUE);
}
+static isc_boolean_t
+cache_sharable(dns_view_t *originview, dns_view_t *view,
+ isc_boolean_t new_zero_no_soattl,
+ unsigned int new_cleaning_interval,
+ isc_uint32_t new_max_cache_size)
+{
+ /*
+ * If the cache cannot even reused for the same view, it cannot be
+ * shared with other views.
+ */
+ if (!cache_reusable(originview, view, new_zero_no_soattl))
+ return (ISC_FALSE);
+
+ /*
+ * Check other cache related parameters that must be consistent among
+ * the sharing views.
+ */
+ if (dns_cache_getcleaninginterval(originview->cache) !=
+ new_cleaning_interval ||
+ dns_cache_getcachesize(originview->cache) != new_max_cache_size) {
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
+#ifdef DLZ
+/*
+ * Callback from DLZ configure when the driver sets up a writeable zone
+ */
+static isc_result_t
+dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) {
+ dns_name_t *origin = dns_zone_getorigin(zone);
+ dns_rdataclass_t zclass = view->rdclass;
+ isc_result_t result;
+
+ result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone);
+ if (result != ISC_R_SUCCESS)
+ return result;
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+
+ return ns_zone_configure_writeable_dlz(view->dlzdatabase,
+ zone, zclass, origin);
+}
+#endif
+
+static isc_result_t
+dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
+ unsigned int prefixlen, const char *server,
+ const char *contact)
+{
+ char *cp;
+ char reverse[48+sizeof("ip6.arpa.")];
+ const char *dns64_dbtype[4] = { "_builtin", "dns64", ".", "." };
+ const char *sep = ": view ";
+ const char *viewname = view->name;
+ const unsigned char *s6;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ dns_zone_t *zone = NULL;
+ int dns64_dbtypec = 4;
+ isc_buffer_t b;
+ isc_result_t result;
+
+ REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
+ prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
+
+ if (!strcmp(viewname, "_default")) {
+ sep = "";
+ viewname = "";
+ }
+
+ /*
+ * Construct the reverse name of the zone.
+ */
+ cp = reverse;
+ s6 = na->type.in6.s6_addr;
+ while (prefixlen > 0) {
+ prefixlen -= 8;
+ sprintf(cp, "%x.%x.", s6[prefixlen/8] & 0xf,
+ (s6[prefixlen/8] >> 4) & 0xf);
+ cp += 4;
+ }
+ strcat(cp, "ip6.arpa.");
+
+ /*
+ * Create the actual zone.
+ */
+ if (server != NULL)
+ dns64_dbtype[2] = server;
+ if (contact != NULL)
+ dns64_dbtype[3] = contact;
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ isc_buffer_init(&b, reverse, strlen(reverse));
+ isc_buffer_add(&b, strlen(reverse));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, name));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+ dns_zone_setclass(zone, view->rdclass);
+ dns_zone_settype(zone, dns_zone_master);
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype));
+ if (view->queryacl != NULL)
+ dns_zone_setqueryacl(zone, view->queryacl);
+ if (view->queryonacl != NULL)
+ dns_zone_setqueryonacl(zone, view->queryonacl);
+ dns_zone_setdialup(zone, dns_dialuptype_no);
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+ dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
+ CHECK(setquerystats(zone, mctx, ISC_FALSE)); /* XXXMPA */
+ CHECK(dns_view_addzone(view, zone));
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep,
+ viewname, reverse);
+
+cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ return (result);
+}
+
+static isc_result_t
+configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
+ const cfg_obj_t *rpz_obj, *policy_obj;
+ const char *str;
+ dns_fixedname_t fixed;
+ dns_name_t *origin;
+ dns_rpz_zone_t *old, *new;
+ dns_zone_t *zone = NULL;
+ isc_result_t result;
+ unsigned int l1, l2;
+
+ new = isc_mem_get(view->mctx, sizeof(*new));
+ if (new == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+
+ memset(new, 0, sizeof(*new));
+ dns_name_init(&new->nsdname, NULL);
+ dns_name_init(&new->origin, NULL);
+ dns_name_init(&new->cname, NULL);
+ ISC_LIST_INITANDAPPEND(view->rpz_zones, new, link);
+
+ rpz_obj = cfg_listelt_value(element);
+ policy_obj = cfg_tuple_get(rpz_obj, "policy");
+ if (cfg_obj_isvoid(policy_obj)) {
+ new->policy = DNS_RPZ_POLICY_GIVEN;
+ } else {
+ str = cfg_obj_asstring(policy_obj);
+ new->policy = dns_rpz_str2policy(str);
+ INSIST(new->policy != DNS_RPZ_POLICY_ERROR);
+ }
+
+ dns_fixedname_init(&fixed);
+ origin = dns_fixedname_name(&fixed);
+ str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "name"));
+ result = dns_name_fromstring(origin, str, DNS_NAME_DOWNCASE, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid zone '%s'", str);
+ goto cleanup;
+ }
+
+ result = dns_name_fromstring2(&new->nsdname, DNS_RPZ_NSDNAME_ZONE,
+ origin, DNS_NAME_DOWNCASE, view->mctx);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid zone '%s'", str);
+ goto cleanup;
+ }
+
+ /*
+ * The origin is part of 'nsdname' so we don't need to keep it
+ * seperately.
+ */
+ l1 = dns_name_countlabels(&new->nsdname);
+ l2 = dns_name_countlabels(origin);
+ dns_name_getlabelsequence(&new->nsdname, l1 - l2, l2, &new->origin);
+
+ /*
+ * Are we configured to with the reponse policy zone?
+ */
+ result = dns_view_findzone(view, &new->origin, &zone);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "unknown zone '%s'", str);
+ goto cleanup;
+ }
+
+ if (dns_zone_gettype(zone) != dns_zone_master &&
+ dns_zone_gettype(zone) != dns_zone_slave) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "zone '%s' is neither master nor slave", str);
+ dns_zone_detach(&zone);
+ result = DNS_R_NOTMASTER;
+ goto cleanup;
+ }
+ dns_zone_detach(&zone);
+
+ for (old = ISC_LIST_HEAD(view->rpz_zones);
+ old != new;
+ old = ISC_LIST_NEXT(old, link)) {
+ ++new->num;
+ if (dns_name_equal(&old->origin, &new->origin)) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "duplicate '%s'", str);
+ result = DNS_R_DUPLICATE;
+ goto cleanup;
+ }
+ }
+
+ if (new->policy == DNS_RPZ_POLICY_CNAME) {
+ str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "cname"));
+ result = dns_name_fromstring(&new->cname, str, 0, view->mctx);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid cname '%s'", str);
+ goto cleanup;
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ dns_rpz_view_destroy(view);
+ return (result);
+}
+
/*
* Configure 'view' according to 'vconfig', taking defaults from 'config'
* where values are missing in 'vconfig'.
@@ -1004,12 +1554,15 @@ cache_reusable(dns_view_t *originview, dns_view_t *view,
* global defaults in 'config' used exclusively.
*/
static isc_result_t
-configure_view(dns_view_t *view, const cfg_obj_t *config,
- const cfg_obj_t *vconfig, isc_mem_t *mctx,
- cfg_aclconfctx_t *actx, isc_boolean_t need_hints)
+configure_view(dns_view_t *view, cfg_parser_t* parser,
+ cfg_obj_t *config, cfg_obj_t *vconfig,
+ ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys,
+ isc_mem_t *mctx, cfg_aclconfctx_t *actx,
+ isc_boolean_t need_hints)
{
const cfg_obj_t *maps[4];
const cfg_obj_t *cfgmaps[3];
+ const cfg_obj_t *optionmaps[3];
const cfg_obj_t *options = NULL;
const cfg_obj_t *voptions = NULL;
const cfg_obj_t *forwardtype;
@@ -1028,17 +1581,20 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_cache_t *cache = NULL;
isc_result_t result;
isc_uint32_t max_adb_size;
+ unsigned int cleaning_interval;
isc_uint32_t max_cache_size;
isc_uint32_t max_acache_size;
isc_uint32_t lame_ttl;
- dns_tsig_keyring_t *ring;
+ dns_tsig_keyring_t *ring = NULL;
dns_view_t *pview = NULL; /* Production view */
isc_mem_t *cmctx;
dns_dispatch_t *dispatch4 = NULL;
dns_dispatch_t *dispatch6 = NULL;
isc_boolean_t reused_cache = ISC_FALSE;
- int i;
+ isc_boolean_t shared_cache = ISC_FALSE;
+ int i = 0, j = 0, k = 0;
const char *str;
+ const char *cachename = NULL;
dns_order_t *order = NULL;
isc_uint32_t udpsize;
unsigned int resopts = 0;
@@ -1052,7 +1608,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
const cfg_obj_t *disablelist = NULL;
isc_stats_t *resstats = NULL;
dns_stats_t *resquerystats = NULL;
+ isc_boolean_t auto_dlv = ISC_FALSE;
+ isc_boolean_t auto_root = ISC_FALSE;
+ ns_cache_t *nsc;
isc_boolean_t zero_no_soattl;
+ cfg_parser_t *newzones_parser = NULL;
+ cfg_obj_t *nzfconf = NULL;
+ dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
+ unsigned int query_timeout;
REQUIRE(DNS_VIEW_VALID(view));
@@ -1061,22 +1624,28 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (config != NULL)
(void)cfg_map_get(config, "options", &options);
- i = 0;
+ /*
+ * maps: view options, options, defaults
+ * cfgmaps: view options, config
+ * optionmaps: view options, options
+ */
if (vconfig != NULL) {
voptions = cfg_tuple_get(vconfig, "options");
maps[i++] = voptions;
+ optionmaps[j++] = voptions;
+ cfgmaps[k++] = voptions;
}
- if (options != NULL)
+ if (options != NULL) {
maps[i++] = options;
+ optionmaps[j++] = options;
+ }
+
maps[i++] = ns_g_defaults;
maps[i] = NULL;
-
- i = 0;
- if (voptions != NULL)
- cfgmaps[i++] = voptions;
+ optionmaps[j] = NULL;
if (config != NULL)
- cfgmaps[i++] = config;
- cfgmaps[i] = NULL;
+ cfgmaps[k++] = config;
+ cfgmaps[k] = NULL;
if (!strcmp(viewname, "_default")) {
sep = "";
@@ -1137,12 +1706,12 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_acache_setcachesize(view->acache, max_acache_size);
}
- CHECK(configure_view_acl(vconfig, config, "allow-query", actx,
+ CHECK(configure_view_acl(vconfig, config, "allow-query", NULL, actx,
ns_g_mctx, &view->queryacl));
-
if (view->queryacl == NULL) {
- CHECK(configure_view_acl(NULL, ns_g_config, "allow-query", actx,
- ns_g_mctx, &view->queryacl));
+ CHECK(configure_view_acl(NULL, ns_g_config, "allow-query",
+ NULL, actx, ns_g_mctx,
+ &view->queryacl));
}
/*
@@ -1159,7 +1728,62 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
{
const cfg_obj_t *zconfig = cfg_listelt_value(element);
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
- actx));
+ actx, ISC_FALSE));
+ }
+
+ /*
+ * Are we allowing zones to be added and deleted dynamically?
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "allow-new-zones", &obj);
+ if (result == ISC_R_SUCCESS) {
+ isc_boolean_t allow = cfg_obj_asboolean(obj);
+ struct cfg_context *cfg = NULL;
+ if (allow) {
+ cfg = isc_mem_get(view->mctx, sizeof(*cfg));
+ if (cfg == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ memset(cfg, 0, sizeof(*cfg));
+ isc_mem_attach(view->mctx, &cfg->mctx);
+ if (config != NULL)
+ cfg_obj_attach(config, &cfg->config);
+ cfg_parser_attach(parser, &cfg->parser);
+ cfg_aclconfctx_clone(actx, &cfg->actx);
+ }
+ dns_view_setnewzones(view, allow, cfg, cfgctx_destroy);
+ }
+
+ /*
+ * If we're allowing added zones, then load zone configuration
+ * from the newzone file for zones that were added during previous
+ * runs.
+ */
+ if (view->new_zone_file != NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "loading additional zones for view '%s'",
+ view->name);
+
+ CHECK(cfg_parser_create(view->mctx, ns_g_lctx,
+ &newzones_parser));
+ result = cfg_parse_file(newzones_parser, view->new_zone_file,
+ &cfg_type_newzones, &nzfconf);
+ if (result == ISC_R_SUCCESS) {
+ zonelist = NULL;
+ cfg_map_get(nzfconf, "zone", &zonelist);
+ for (element = cfg_list_first(zonelist);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *zconfig =
+ cfg_listelt_value(element);
+ CHECK(configure_zone(config, zconfig, vconfig,
+ mctx, view, actx,
+ ISC_TRUE));
+ }
+ }
}
#ifdef DLZ
@@ -1197,6 +1821,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv));
if (result != ISC_R_SUCCESS)
goto cleanup;
+
+ /*
+ * If the dlz backend supports configuration,
+ * then call its configure method now.
+ */
+ result = dns_dlzconfigure(view, dlzconfigure_callback);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
}
}
#endif
@@ -1205,6 +1837,32 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* Obtain configuration parameters that affect the decision of whether
* we can reuse/share an existing cache.
*/
+ obj = NULL;
+ result = ns_config_get(maps, "cleaning-interval", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ cleaning_interval = cfg_obj_asuint32(obj) * 60;
+
+ obj = NULL;
+ result = ns_config_get(maps, "max-cache-size", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ if (cfg_obj_isstring(obj)) {
+ str = cfg_obj_asstring(obj);
+ INSIST(strcasecmp(str, "unlimited") == 0);
+ max_cache_size = ISC_UINT32_MAX;
+ } else {
+ isc_resourcevalue_t value;
+ value = cfg_obj_asuint64(obj);
+ if (value > ISC_UINT32_MAX) {
+ cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
+ "'max-cache-size "
+ "%" ISC_PRINT_QUADFORMAT "d' is too large",
+ value);
+ result = ISC_R_RANGE;
+ goto cleanup;
+ }
+ max_cache_size = (isc_uint32_t)value;
+ }
+
/* Check-names. */
obj = NULL;
result = ns_checknames_get(maps, "response", &obj);
@@ -1228,6 +1886,109 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
INSIST(result == ISC_R_SUCCESS);
zero_no_soattl = cfg_obj_asboolean(obj);
+ obj = NULL;
+ result = ns_config_get(maps, "dns64", &obj);
+ if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") &&
+ strcmp(view->name, "_meta")) {
+ const cfg_listelt_t *element;
+ isc_netaddr_t na, suffix, *sp;
+ unsigned int prefixlen;
+ const char *server, *contact;
+ const cfg_obj_t *myobj;
+
+ myobj = NULL;
+ result = ns_config_get(maps, "dns64-server", &myobj);
+ if (result == ISC_R_SUCCESS)
+ server = cfg_obj_asstring(myobj);
+ else
+ server = NULL;
+
+ myobj = NULL;
+ result = ns_config_get(maps, "dns64-contact", &myobj);
+ if (result == ISC_R_SUCCESS)
+ contact = cfg_obj_asstring(myobj);
+ else
+ contact = NULL;
+
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *map = cfg_listelt_value(element);
+ dns_dns64_t *dns64 = NULL;
+ unsigned int dns64options = 0;
+
+ cfg_obj_asnetprefix(cfg_map_getname(map), &na,
+ &prefixlen);
+
+ obj = NULL;
+ (void)cfg_map_get(map, "suffix", &obj);
+ if (obj != NULL) {
+ sp = &suffix;
+ isc_netaddr_fromsockaddr(sp,
+ cfg_obj_assockaddr(obj));
+ } else
+ sp = NULL;
+
+ clients = mapped = excluded = NULL;
+ obj = NULL;
+ (void)cfg_map_get(map, "clients", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &clients);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ obj = NULL;
+ (void)cfg_map_get(map, "mapped", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &mapped);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ obj = NULL;
+ (void)cfg_map_get(map, "exclude", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &excluded);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(map, "recursive-only", &obj);
+ if (obj != NULL && cfg_obj_asboolean(obj))
+ dns64options |= DNS_DNS64_RECURSIVE_ONLY;
+
+ obj = NULL;
+ (void)cfg_map_get(map, "break-dnssec", &obj);
+ if (obj != NULL && cfg_obj_asboolean(obj))
+ dns64options |= DNS_DNS64_BREAK_DNSSEC;
+
+ result = dns_dns64_create(mctx, &na, prefixlen, sp,
+ clients, mapped, excluded,
+ dns64options, &dns64);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_dns64_append(&view->dns64, dns64);
+ view->dns64cnt++;
+ result = dns64_reverse(view, mctx, &na, prefixlen,
+ server, contact);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (clients != NULL)
+ dns_acl_detach(&clients);
+ if (mapped != NULL)
+ dns_acl_detach(&mapped);
+ if (excluded != NULL)
+ dns_acl_detach(&excluded);
+ }
+ }
+
obj = NULL;
result = ns_config_get(maps, "dnssec-accept-expired", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -1236,7 +1997,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
obj = NULL;
result = ns_config_get(maps, "dnssec-validation", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->enablevalidation = cfg_obj_asboolean(obj);
+ if (cfg_obj_isboolean(obj)) {
+ view->enablevalidation = cfg_obj_asboolean(obj);
+ } else {
+ /* If dnssec-validation is not boolean, it must be "auto" */
+ view->enablevalidation = ISC_TRUE;
+ auto_root = ISC_TRUE;
+ }
obj = NULL;
result = ns_config_get(maps, "max-cache-ttl", &obj);
@@ -1251,53 +2018,113 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
view->maxncachettl = 7 * 24 * 3600;
/*
- * Configure the view's cache. Try to reuse an existing
- * cache if possible, otherwise create a new cache.
- * Note that the ADB is not preserved in either case.
- * When a matching view is found, the associated statistics are
- * also retrieved and reused.
+ * Configure the view's cache.
*
- * XXX Determining when it is safe to reuse a cache is tricky.
+ * First, check to see if there are any attach-cache options. If yes,
+ * attempt to lookup an existing cache at attach it to the view. If
+ * there is not one, then try to reuse an existing cache if possible;
+ * otherwise create a new cache.
+ *
+ * Note that the ADB is not preserved or shared in either case.
+ *
+ * When a matching view is found, the associated statistics are also
+ * retrieved and reused.
+ *
+ * XXX Determining when it is safe to reuse or share a cache is tricky.
* When the view's configuration changes, the cached data may become
* invalid because it reflects our old view of the world. We check
- * some of the configuration parameters that could invalidate the cache,
- * but there are other configuration options that should be checked.
- * For example, if a view uses a forwarder, changes in the forwarder
- * configuration may invalidate the cache. At the moment, it's the
- * administrator's responsibility to ensure these configuration options
- * don't invalidate reusing.
+ * some of the configuration parameters that could invalidate the cache
+ * or otherwise make it unsharable, but there are other configuration
+ * options that should be checked. For example, if a view uses a
+ * forwarder, changes in the forwarder configuration may invalidate
+ * the cache. At the moment, it's the administrator's responsibility to
+ * ensure these configuration options don't invalidate reusing/sharing.
*/
- result = dns_viewlist_find(&ns_g_server->viewlist,
- view->name, view->rdclass,
- &pview);
- if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
- goto cleanup;
- if (pview != NULL) {
- if (cache_reusable(pview, view, zero_no_soattl)) {
- INSIST(pview->cache != NULL);
+ obj = NULL;
+ result = ns_config_get(maps, "attach-cache", &obj);
+ if (result == ISC_R_SUCCESS)
+ cachename = cfg_obj_asstring(obj);
+ else
+ cachename = view->name;
+ cache = NULL;
+ nsc = cachelist_find(cachelist, cachename);
+ if (nsc != NULL) {
+ if (!cache_sharable(nsc->primaryview, view, zero_no_soattl,
+ cleaning_interval, max_cache_size)) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3),
- "reusing existing cache");
- reused_cache = ISC_TRUE;
- dns_cache_attach(pview->cache, &cache);
- } else {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
- "cache cannot be reused for view %s "
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "views %s and %s can't share the cache "
"due to configuration parameter mismatch",
- view->name);
+ nsc->primaryview->name, view->name);
+ result = ISC_R_FAILURE;
+ goto cleanup;
}
- dns_view_getresstats(pview, &resstats);
- dns_view_getresquerystats(pview, &resquerystats);
- dns_view_detach(&pview);
+ dns_cache_attach(nsc->cache, &cache);
+ shared_cache = ISC_TRUE;
+ } else {
+ if (strcmp(cachename, view->name) == 0) {
+ result = dns_viewlist_find(&ns_g_server->viewlist,
+ cachename, view->rdclass,
+ &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL) {
+ if (!cache_reusable(pview, view,
+ zero_no_soattl)) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_DEBUG(1),
+ "cache cannot be reused "
+ "for view %s due to "
+ "configuration parameter "
+ "mismatch", view->name);
+ } else {
+ INSIST(pview->cache != NULL);
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_DEBUG(3),
+ "reusing existing cache");
+ reused_cache = ISC_TRUE;
+ dns_cache_attach(pview->cache, &cache);
+ }
+ dns_view_getresstats(pview, &resstats);
+ dns_view_getresquerystats(pview,
+ &resquerystats);
+ dns_view_detach(&pview);
+ }
+ }
+ if (cache == NULL) {
+ /*
+ * Create a cache with the desired name. This normally
+ * equals the view name, but may also be a forward
+ * reference to a view that share the cache with this
+ * view but is not yet configured. If it is not the
+ * view name but not a forward reference either, then it
+ * is simply a named cache that is not shared.
+ */
+ CHECK(isc_mem_create(0, 0, &cmctx));
+ isc_mem_setname(cmctx, "cache", NULL);
+ CHECK(dns_cache_create2(cmctx, ns_g_taskmgr,
+ ns_g_timermgr, view->rdclass,
+ cachename, "rbt", 0, NULL,
+ &cache));
+ }
+ nsc = isc_mem_get(mctx, sizeof(*nsc));
+ if (nsc == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ nsc->cache = NULL;
+ dns_cache_attach(cache, &nsc->cache);
+ nsc->primaryview = view;
+ nsc->needflush = ISC_FALSE;
+ nsc->adbsizeadjusted = ISC_FALSE;
+ ISC_LINK_INIT(nsc, link);
+ ISC_LIST_APPEND(*cachelist, nsc, link);
}
- if (cache == NULL) {
- CHECK(isc_mem_create(0, 0, &cmctx));
- CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr,
- view->rdclass, "rbt", 0, NULL, &cache));
- isc_mem_setname(cmctx, "cache", NULL);
- }
- dns_view_setcache(view, cache);
+ dns_view_setcache2(view, cache, shared_cache);
/*
* cache-file cannot be inherited if views are present, but this
@@ -1307,35 +2134,11 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
result = ns_config_get(maps, "cache-file", &obj);
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) {
CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj)));
- if (!reused_cache)
+ if (!reused_cache && !shared_cache)
CHECK(dns_cache_load(cache));
}
- obj = NULL;
- result = ns_config_get(maps, "cleaning-interval", &obj);
- INSIST(result == ISC_R_SUCCESS);
- dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60);
-
- obj = NULL;
- result = ns_config_get(maps, "max-cache-size", &obj);
- INSIST(result == ISC_R_SUCCESS);
- if (cfg_obj_isstring(obj)) {
- str = cfg_obj_asstring(obj);
- INSIST(strcasecmp(str, "unlimited") == 0);
- max_cache_size = ISC_UINT32_MAX;
- } else {
- isc_resourcevalue_t value;
- value = cfg_obj_asuint64(obj);
- if (value > ISC_UINT32_MAX) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
- "'max-cache-size "
- "%" ISC_PRINT_QUADFORMAT "d' is too large",
- value);
- result = ISC_R_RANGE;
- goto cleanup;
- }
- max_cache_size = (isc_uint32_t)value;
- }
+ dns_cache_setcleaninginterval(cache, cleaning_interval);
dns_cache_setcachesize(cache, max_cache_size);
dns_cache_detach(&cache);
@@ -1373,13 +2176,23 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_view_setresquerystats(view, resquerystats);
/*
- * Set the ADB cache size to 1/8th of the max-cache-size.
+ * Set the ADB cache size to 1/8th of the max-cache-size or
+ * MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared.
*/
max_adb_size = 0;
if (max_cache_size != 0) {
max_adb_size = max_cache_size / 8;
if (max_adb_size == 0)
max_adb_size = 1; /* Force minimum. */
+ if (view != nsc->primaryview &&
+ max_adb_size > MAX_ADB_SIZE_FOR_CACHESHARE) {
+ max_adb_size = MAX_ADB_SIZE_FOR_CACHESHARE;
+ if (!nsc->adbsizeadjusted) {
+ dns_adb_setadbsize(nsc->primaryview->adb,
+ MAX_ADB_SIZE_FOR_CACHESHARE);
+ nsc->adbsizeadjusted = ISC_TRUE;
+ }
+ }
}
dns_adb_setadbsize(view->adb, max_adb_size);
@@ -1394,6 +2207,18 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
lame_ttl = 1800;
dns_resolver_setlamettl(view->resolver, lame_ttl);
+ /*
+ * Set the resolver's query timeout.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "resolver-query-timeout", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ query_timeout = cfg_obj_asuint32(obj);
+ dns_resolver_settimeout(view->resolver, query_timeout);
+
+ /* Specify whether to use 0-TTL for negative response for SOA query */
+ dns_resolver_setzeronosoattl(view->resolver, zero_no_soattl);
+
/*
* Set the resolver's EDNS UDP size.
*/
@@ -1484,9 +2309,29 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Configure the view's TSIG keys.
*/
- ring = NULL;
CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring));
+ if (ns_g_server->sessionkey != NULL) {
+ CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname,
+ ns_g_server->sessionkey));
+ }
dns_view_setkeyring(view, ring);
+ dns_tsigkeyring_detach(&ring);
+
+ /*
+ * See if we can re-use a dynamic key ring.
+ */
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL) {
+ dns_view_getdynamickeyring(pview, &ring);
+ if (ring != NULL)
+ dns_view_setdynamickeyring(view, ring);
+ dns_tsigkeyring_detach(&ring);
+ dns_view_detach(&pview);
+ } else
+ dns_view_restorekeyring(view);
/*
* Configure the view's peer list.
@@ -1543,10 +2388,10 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Configure the "match-clients" and "match-destinations" ACL.
*/
- CHECK(configure_view_acl(vconfig, config, "match-clients", actx,
+ CHECK(configure_view_acl(vconfig, config, "match-clients", NULL, actx,
ns_g_mctx, &view->matchclients));
- CHECK(configure_view_acl(vconfig, config, "match-destinations", actx,
- ns_g_mctx, &view->matchdestinations));
+ CHECK(configure_view_acl(vconfig, config, "match-destinations", NULL,
+ actx, ns_g_mctx, &view->matchdestinations));
/*
* Configure the "match-recursive-only" option.
@@ -1618,20 +2463,20 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* "allow-recursion", and "allow-recursion-on" acls if
* configured in named.conf.
*/
- CHECK(configure_view_acl(vconfig, config, "allow-query-cache",
+ CHECK(configure_view_acl(vconfig, config, "allow-query-cache", NULL,
actx, ns_g_mctx, &view->cacheacl));
- CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on",
+ CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on", NULL,
actx, ns_g_mctx, &view->cacheonacl));
if (view->cacheonacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-query-cache-on", actx,
+ "allow-query-cache-on", NULL, actx,
ns_g_mctx, &view->cacheonacl));
if (strcmp(view->name, "_bind") != 0) {
CHECK(configure_view_acl(vconfig, config, "allow-recursion",
- actx, ns_g_mctx,
+ NULL, actx, ns_g_mctx,
&view->recursionacl));
CHECK(configure_view_acl(vconfig, config, "allow-recursion-on",
- actx, ns_g_mctx,
+ NULL, actx, ns_g_mctx,
&view->recursiononacl));
}
@@ -1643,8 +2488,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->cacheacl == NULL && view->recursionacl != NULL)
dns_acl_attach(view->recursionacl, &view->cacheacl);
+ /*
+ * XXXEACH: This call to configure_view_acl() is redundant. We
+ * are leaving it as it is because we are making a minimal change
+ * for a patch release. In the future this should be changed to
+ * dns_acl_attach(view->queryacl, &view->cacheacl).
+ */
if (view->cacheacl == NULL && view->recursion)
- CHECK(configure_view_acl(vconfig, config, "allow-query",
+ CHECK(configure_view_acl(vconfig, config, "allow-query", NULL,
actx, ns_g_mctx, &view->cacheacl));
if (view->recursion &&
view->recursionacl == NULL && view->cacheacl != NULL)
@@ -1656,23 +2507,43 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->recursionacl == NULL && view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-recursion",
+ "allow-recursion", NULL,
actx, ns_g_mctx,
&view->recursionacl));
if (view->recursiononacl == NULL && view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-recursion-on",
+ "allow-recursion-on", NULL,
actx, ns_g_mctx,
&view->recursiononacl));
if (view->cacheacl == NULL) {
if (view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-query-cache", actx,
- ns_g_mctx, &view->cacheacl));
+ "allow-query-cache", NULL,
+ actx, ns_g_mctx,
+ &view->cacheacl));
else
- CHECK(dns_acl_none(ns_g_mctx, &view->cacheacl));
+ CHECK(dns_acl_none(mctx, &view->cacheacl));
}
+ /*
+ * Filter setting on addresses in the answer section.
+ */
+ CHECK(configure_view_acl(vconfig, config, "deny-answer-addresses",
+ "acl", actx, ns_g_mctx, &view->denyansweracl));
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-addresses",
+ "except-from", ns_g_mctx,
+ &view->answeracl_exclude));
+
+ /*
+ * Filter setting on names (CNAME/DNAME targets) in the answer section.
+ */
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
+ "name", ns_g_mctx,
+ &view->denyanswernames));
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
+ "except-from", ns_g_mctx,
+ &view->answernames_exclude));
+
/*
* Configure sortlist, if set
*/
@@ -1686,19 +2557,19 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->notifyacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-notify", actx,
+ "allow-notify", NULL, actx,
ns_g_mctx, &view->notifyacl));
if (view->transferacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-transfer", actx,
+ "allow-transfer", NULL, actx,
ns_g_mctx, &view->transferacl));
if (view->updateacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-update", actx,
+ "allow-update", NULL, actx,
ns_g_mctx, &view->updateacl));
if (view->upfwdacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-update-forwarding", actx,
+ "allow-update-forwarding", NULL, actx,
ns_g_mctx, &view->upfwdacl));
obj = NULL;
@@ -1728,13 +2599,47 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
cfg_obj_asuint32(obj),
max_clients_per_query);
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ obj = NULL;
+ result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ view->v4_aaaa = dns_v4_aaaa_filter;
+ else
+ view->v4_aaaa = dns_v4_aaaa_ok;
+ } else {
+ const char *v4_aaaastr = cfg_obj_asstring(obj);
+ if (strcasecmp(v4_aaaastr, "break-dnssec") == 0)
+ view->v4_aaaa = dns_v4_aaaa_break_dnssec;
+ else
+ INSIST(0);
+ }
+ CHECK(configure_view_acl(vconfig, config, "filter-aaaa", NULL,
+ actx, ns_g_mctx, &view->v4_aaaa_acl));
+#endif
+
obj = NULL;
result = ns_config_get(maps, "dnssec-enable", &obj);
INSIST(result == ISC_R_SUCCESS);
view->enablednssec = cfg_obj_asboolean(obj);
obj = NULL;
- result = ns_config_get(maps, "dnssec-lookaside", &obj);
+ result = ns_config_get(optionmaps, "dnssec-lookaside", &obj);
+ if (result == ISC_R_SUCCESS) {
+ /* If set to "auto", use the version from the defaults */
+ const cfg_obj_t *dlvobj;
+ dlvobj = cfg_listelt_value(cfg_list_first(obj));
+ if (!strcmp(cfg_obj_asstring(cfg_tuple_get(dlvobj, "domain")),
+ "auto") &&
+ cfg_obj_isvoid(cfg_tuple_get(dlvobj, "trust-anchor"))) {
+ auto_dlv = ISC_TRUE;
+ obj = NULL;
+ result = cfg_map_get(ns_g_defaults,
+ "dnssec-lookaside", &obj);
+ }
+ }
+
if (result == ISC_R_SUCCESS) {
for (element = cfg_list_first(obj);
element != NULL;
@@ -1745,31 +2650,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_name_t *dlv;
obj = cfg_listelt_value(element);
-#if 0
- dns_fixedname_t fixed;
- dns_name_t *name;
-
- /*
- * When we support multiple dnssec-lookaside
- * entries this is how to find the domain to be
- * checked. XXXMPA
- */
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- str = cfg_obj_asstring(cfg_tuple_get(obj,
- "domain"));
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL));
-#endif
str = cfg_obj_asstring(cfg_tuple_get(obj,
"trust-anchor"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
dlv = dns_fixedname_name(&view->dlv_fixed);
CHECK(dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_TRUE, NULL));
+ DNS_NAME_DOWNCASE, NULL));
view->dlv = dns_fixedname_name(&view->dlv_fixed);
}
} else
@@ -1779,8 +2666,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* For now, there is only one kind of trusted keys, the
* "security roots".
*/
- CHECK(configure_view_dnsseckeys(vconfig, config, mctx,
- &view->secroots));
+ CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys,
+ auto_dlv, auto_root, mctx));
dns_resolver_resetmustbesecure(view->resolver);
obj = NULL;
result = ns_config_get(maps, "dnssec-must-be-secure", &obj);
@@ -1821,7 +2708,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ 0, NULL));
CHECK(dns_view_excludedelegationonly(view,
name));
}
@@ -1874,8 +2761,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, server, sizeof(server) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
server[isc_buffer_usedlength(&buffer)] = 0;
@@ -1889,8 +2776,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, contact, sizeof(contact) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
contact[isc_buffer_usedlength(&buffer)] = 0;
@@ -1916,8 +2803,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Look for zone on drop list.
*/
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
if (disablelist != NULL &&
on_disable_list(disablelist, name))
continue;
@@ -2012,9 +2899,40 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
}
}
+ /*
+ * Make the list of response policy zone names for views that
+ * are used for real lookups and so care about hints.
+ */
+ zonelist = NULL;
+ if (view->rdclass == dns_rdataclass_in && need_hints) {
+ obj = NULL;
+ result = ns_config_get(maps, "response-policy", &obj);
+ if (result == ISC_R_SUCCESS)
+ cfg_map_get(obj, "zone", &zonelist);
+ }
+ if (zonelist != NULL) {
+
+ for (element = cfg_list_first(zonelist);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ result = configure_rpz(view, element);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rpz_set_need(ISC_TRUE);
+ }
+ }
+
result = ISC_R_SUCCESS;
cleanup:
+ if (clients != NULL)
+ dns_acl_detach(&clients);
+ if (mapped != NULL)
+ dns_acl_detach(&mapped);
+ if (excluded != NULL)
+ dns_acl_detach(&excluded);
+ if (ring != NULL)
+ dns_tsigkeyring_detach(&ring);
if (zone != NULL)
dns_zone_detach(&zone);
if (dispatch4 != NULL)
@@ -2033,6 +2951,12 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (cache != NULL)
dns_cache_detach(&cache);
+ if (newzones_parser != NULL) {
+ if (nzfconf != NULL)
+ cfg_obj_destroy(newzones_parser, &nzfconf);
+ cfg_parser_destroy(&newzones_parser);
+ }
+
return (result);
}
@@ -2105,8 +3029,8 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
isc_buffer_add(&buffer, strlen(str));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
portobj = cfg_tuple_get(alternate, "port");
if (cfg_obj_isuint32(portobj)) {
@@ -2286,7 +3210,7 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
- cfg_aclconfctx_t *aclconf)
+ cfg_aclconfctx_t *aclconf, isc_boolean_t added)
{
dns_view_t *pview = NULL; /* Production view */
dns_zone_t *zone = NULL; /* New or reused zone */
@@ -2319,7 +3243,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
isc_buffer_add(&buffer, strlen(zname));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
- &buffer, dns_rootname, ISC_FALSE, NULL));
+ &buffer, dns_rootname, 0, NULL));
origin = dns_fixedname_name(&fixorigin);
CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
@@ -2349,7 +3273,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
ztypestr = cfg_obj_asstring(typeobj);
/*
- * "hints zones" aren't zones. If we've got one,
+ * "hints zones" aren't zones. If we've got one,
* configure it and return.
*/
if (strcasecmp(ztypestr, "hint") == 0) {
@@ -2499,6 +3423,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
CHECK(dns_view_adddelegationonly(view, origin));
}
+ /*
+ * Mark whether the zone was originally added at runtime or not
+ */
+ dns_zone_setadded(zone, added);
+
/*
* Configure the zone.
*/
@@ -2518,6 +3447,95 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
return (result);
}
+/*
+ * Configure built-in zone for storing managed-key data.
+ */
+
+#define KEYZONE "managed-keys.bind"
+#define MKEYS ".mkeys"
+
+static isc_result_t
+add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
+ isc_result_t result;
+ dns_view_t *pview = NULL;
+ dns_zone_t *zone = NULL;
+ dns_acl_t *none = NULL;
+ char filename[PATH_MAX];
+ char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(MKEYS)];
+ int n;
+
+ REQUIRE(view != NULL);
+
+ /* See if we can re-use an existing keydata zone. */
+ result = dns_viewlist_find(&ns_g_server->viewlist,
+ view->name, view->rdclass,
+ &pview);
+ if (result != ISC_R_NOTFOUND &&
+ result != ISC_R_SUCCESS)
+ return (result);
+
+ if (pview != NULL && pview->managed_keys != NULL) {
+ dns_zone_attach(pview->managed_keys, &view->managed_keys);
+ dns_zone_setview(pview->managed_keys, view);
+ dns_view_detach(&pview);
+ return (ISC_R_SUCCESS);
+ }
+
+ /* No existing keydata zone was found; create one */
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, dns_rootname));
+
+ isc_sha256_data((void *)view->name, strlen(view->name), buffer);
+ strcat(buffer, MKEYS);
+ n = snprintf(filename, sizeof(filename), "%s%s%s",
+ directory ? directory : "", directory ? "/" : "",
+ strcmp(view->name, "_default") == 0 ? KEYZONE : buffer);
+ if (n < 0 || (size_t)n >= sizeof(filename)) {
+ result = (n < 0) ? ISC_R_FAILURE : ISC_R_NOSPACE;
+ goto cleanup;
+ }
+ CHECK(dns_zone_setfile(zone, filename));
+
+ dns_zone_setview(zone, view);
+ dns_zone_settype(zone, dns_zone_key);
+ dns_zone_setclass(zone, view->rdclass);
+
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+
+ if (view->acache != NULL)
+ dns_zone_setacache(zone, view->acache);
+
+ CHECK(dns_acl_none(mctx, &none));
+ dns_zone_setqueryacl(zone, none);
+ dns_zone_setqueryonacl(zone, none);
+ dns_acl_detach(&none);
+
+ dns_zone_setdialup(zone, dns_dialuptype_no);
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+ dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
+ dns_zone_setjournalsize(zone, 0);
+
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ CHECK(setquerystats(zone, mctx, ISC_FALSE));
+
+ if (view->managed_keys != NULL)
+ dns_zone_detach(&view->managed_keys);
+ dns_zone_attach(zone, &view->managed_keys);
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "set up managed keys zone for view %s, file '%s'",
+ view->name, filename);
+
+cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ if (none != NULL)
+ dns_acl_detach(&none);
+
+ return (result);
+}
+
/*
* Configure a single server quota.
*/
@@ -2914,13 +3932,226 @@ removed(dns_zone_t *zone, void *uap) {
return (ISC_R_SUCCESS);
}
+static void
+cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) {
+ if (server->session_keyfile != NULL) {
+ isc_file_remove(server->session_keyfile);
+ isc_mem_free(mctx, server->session_keyfile);
+ server->session_keyfile = NULL;
+ }
+
+ if (server->session_keyname != NULL) {
+ if (dns_name_dynamic(server->session_keyname))
+ dns_name_free(server->session_keyname, mctx);
+ isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t));
+ server->session_keyname = NULL;
+ }
+
+ if (server->sessionkey != NULL)
+ dns_tsigkey_detach(&server->sessionkey);
+
+ server->session_keyalg = DST_ALG_UNKNOWN;
+ server->session_keybits = 0;
+}
+
+static isc_result_t
+generate_session_key(const char *filename, const char *keynamestr,
+ dns_name_t *keyname, const char *algstr,
+ dns_name_t *algname, unsigned int algtype,
+ isc_uint16_t bits, isc_mem_t *mctx,
+ dns_tsigkey_t **tsigkeyp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ dst_key_t *key = NULL;
+ isc_buffer_t key_txtbuffer;
+ isc_buffer_t key_rawbuffer;
+ char key_txtsecret[256];
+ char key_rawsecret[64];
+ isc_region_t key_rawregion;
+ isc_stdtime_t now;
+ dns_tsigkey_t *tsigkey = NULL;
+ FILE *fp = NULL;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "generating session key for dynamic DNS");
+
+ /* generate key */
+ result = dst_key_generate(keyname, algtype, bits, 1, 0,
+ DNS_KEYPROTO_ANY, dns_rdataclass_in,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Dump the key to the buffer for later use. Should be done before
+ * we transfer the ownership of key to tsigkey.
+ */
+ isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
+ CHECK(dst_key_tobuffer(key, &key_rawbuffer));
+
+ isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
+ isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
+ CHECK(isc_base64_totext(&key_rawregion, -1, "", &key_txtbuffer));
+
+ /* Store the key in tsigkey. */
+ isc_stdtime_get(&now);
+ CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key,
+ ISC_FALSE, NULL, now, now, mctx, NULL,
+ &tsigkey));
+
+ /* Dump the key to the key file. */
+ fp = ns_os_openfile(filename, S_IRUSR|S_IWUSR, ISC_TRUE);
+ if (fp == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "could not create %s", filename);
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ fprintf(fp, "key \"%s\" {\n"
+ "\talgorithm %s;\n"
+ "\tsecret \"%.*s\";\n};\n", keynamestr, algstr,
+ (int) isc_buffer_usedlength(&key_txtbuffer),
+ (char*) isc_buffer_base(&key_txtbuffer));
+
+ RUNTIME_CHECK(isc_stdio_flush(fp) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_stdio_close(fp) == ISC_R_SUCCESS);
+
+ dst_key_free(&key);
+
+ *tsigkeyp = tsigkey;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "failed to generate session key "
+ "for dynamic DNS: %s", isc_result_totext(result));
+ if (tsigkey != NULL)
+ dns_tsigkey_detach(&tsigkey);
+ if (key != NULL)
+ dst_key_free(&key);
+
+ return (result);
+}
+
+static isc_result_t
+configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
+ isc_mem_t *mctx)
+{
+ const char *keyfile, *keynamestr, *algstr;
+ unsigned int algtype;
+ dns_fixedname_t fname;
+ dns_name_t *keyname, *algname;
+ isc_buffer_t buffer;
+ isc_uint16_t bits;
+ const cfg_obj_t *obj;
+ isc_boolean_t need_deleteold = ISC_FALSE;
+ isc_boolean_t need_createnew = ISC_FALSE;
+ isc_result_t result;
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyfile", &obj);
+ if (result == ISC_R_SUCCESS) {
+ if (cfg_obj_isvoid(obj))
+ keyfile = NULL; /* disable it */
+ else
+ keyfile = cfg_obj_asstring(obj);
+ } else
+ keyfile = ns_g_defaultsessionkeyfile;
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyname", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ keynamestr = cfg_obj_asstring(obj);
+ dns_fixedname_init(&fname);
+ isc_buffer_init(&buffer, keynamestr, strlen(keynamestr));
+ isc_buffer_add(&buffer, strlen(keynamestr));
+ keyname = dns_fixedname_name(&fname);
+ result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyalg", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ algstr = cfg_obj_asstring(obj);
+ algname = NULL;
+ result = ns_config_getkeyalgorithm2(algstr, &algname, &algtype, &bits);
+ if (result != ISC_R_SUCCESS) {
+ const char *s = " (keeping current key)";
+
+ cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: "
+ "unsupported or unknown algorithm '%s'%s",
+ algstr,
+ server->session_keyfile != NULL ? s : "");
+ return (result);
+ }
+
+ /* See if we need to (re)generate a new key. */
+ if (keyfile == NULL) {
+ if (server->session_keyfile != NULL)
+ need_deleteold = ISC_TRUE;
+ } else if (server->session_keyfile == NULL)
+ need_createnew = ISC_TRUE;
+ else if (strcmp(keyfile, server->session_keyfile) != 0 ||
+ !dns_name_equal(server->session_keyname, keyname) ||
+ server->session_keyalg != algtype ||
+ server->session_keybits != bits) {
+ need_deleteold = ISC_TRUE;
+ need_createnew = ISC_TRUE;
+ }
+
+ if (need_deleteold) {
+ INSIST(server->session_keyfile != NULL);
+ INSIST(server->session_keyname != NULL);
+ INSIST(server->sessionkey != NULL);
+
+ cleanup_session_key(server, mctx);
+ }
+
+ if (need_createnew) {
+ INSIST(server->sessionkey == NULL);
+ INSIST(server->session_keyfile == NULL);
+ INSIST(server->session_keyname == NULL);
+ INSIST(server->session_keyalg == DST_ALG_UNKNOWN);
+ INSIST(server->session_keybits == 0);
+
+ server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
+ if (server->session_keyname == NULL)
+ goto cleanup;
+ dns_name_init(server->session_keyname, NULL);
+ CHECK(dns_name_dup(keyname, mctx, server->session_keyname));
+
+ server->session_keyfile = isc_mem_strdup(mctx, keyfile);
+ if (server->session_keyfile == NULL)
+ goto cleanup;
+
+ server->session_keyalg = algtype;
+ server->session_keybits = bits;
+
+ CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr,
+ algname, algtype, bits, mctx,
+ &server->sessionkey));
+ }
+
+ return (result);
+
+ cleanup:
+ cleanup_session_key(server, mctx);
+ return (result);
+}
+
static isc_result_t
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
{
cfg_aclconfctx_t aclconfctx;
- cfg_obj_t *config;
- cfg_parser_t *parser = NULL;
+ cfg_obj_t *config = NULL, *bindkeys = NULL;
+ cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL;
const cfg_listelt_t *element;
const cfg_obj_t *builtin_views;
const cfg_obj_t *maps[3];
@@ -2931,7 +4162,7 @@ load_configuration(const char *filename, ns_server_t *server,
dns_view_t *view = NULL;
dns_view_t *view_next;
dns_viewlist_t tmpviewlist;
- dns_viewlist_t viewlist;
+ dns_viewlist_t viewlist, builtin_viewlist;
in_port_t listen_port, udpport_low, udpport_high;
int i;
isc_interval_t interval;
@@ -2943,10 +4174,14 @@ load_configuration(const char *filename, ns_server_t *server,
isc_uint32_t interface_interval;
isc_uint32_t reserved;
isc_uint32_t udpsize;
+ ns_cachelist_t cachelist, tmpcachelist;
unsigned int maxsocks;
+ ns_cache_t *nsc;
cfg_aclconfctx_init(&aclconfctx);
ISC_LIST_INIT(viewlist);
+ ISC_LIST_INIT(builtin_viewlist);
+ ISC_LIST_INIT(cachelist);
/* Ensure exclusive access to configuration data. */
result = isc_task_beginexclusive(server->task);
@@ -2958,8 +4193,7 @@ load_configuration(const char *filename, ns_server_t *server,
if (first_time) {
CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config));
RUNTIME_CHECK(cfg_map_get(ns_g_config, "options",
- &ns_g_defaults) ==
- ISC_R_SUCCESS);
+ &ns_g_defaults) == ISC_R_SUCCESS);
}
/*
@@ -2976,10 +4210,10 @@ load_configuration(const char *filename, ns_server_t *server,
NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "loading configuration from '%s'",
filename);
- CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser));
- cfg_parser_setcallback(parser, directory_callback, NULL);
- result = cfg_parse_file(parser, filename, &cfg_type_namedconf,
- &config);
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
+ cfg_parser_setcallback(conf_parser, directory_callback, NULL);
+ result = cfg_parse_file(conf_parser, filename,
+ &cfg_type_namedconf, &config);
}
/*
@@ -2994,10 +4228,10 @@ load_configuration(const char *filename, ns_server_t *server,
NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "loading configuration from '%s'",
lwresd_g_resolvconffile);
- if (parser != NULL)
- cfg_parser_destroy(&parser);
- CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser));
- result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser,
+ if (conf_parser != NULL)
+ cfg_parser_destroy(&conf_parser);
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
+ result = ns_lwresd_parseeresolvconf(ns_g_mctx, conf_parser,
&config);
}
CHECK(result);
@@ -3018,6 +4252,31 @@ load_configuration(const char *filename, ns_server_t *server,
maps[i++] = ns_g_defaults;
maps[i++] = NULL;
+ /*
+ * If bind.keys exists, load it. If "dnssec-lookaside auto"
+ * is turned on, the keys found there will be used as default
+ * trust anchors.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "bindkeys-file", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ CHECKM(setstring(server, &server->bindkeysfile,
+ cfg_obj_asstring(obj)), "strdup");
+
+ if (access(server->bindkeysfile, R_OK) == 0) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "reading built-in trusted "
+ "keys from file '%s'", server->bindkeysfile);
+
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx,
+ &bindkeys_parser));
+
+ result = cfg_parse_file(bindkeys_parser, server->bindkeysfile,
+ &cfg_type_bindkeys, &bindkeys);
+ CHECK(result);
+ }
+
/*
* Set process limits, which (usually) needs to be done as root.
*/
@@ -3025,7 +4284,7 @@ load_configuration(const char *filename, ns_server_t *server,
/*
* Check if max number of open sockets that the system allows is
- * sufficiently large. Failing this condition is not necessarily fatal,
+ * sufficiently large. Failing this condition is not necessarily fatal,
* but may cause subsequent runtime failures for a busy recursive
* server.
*/
@@ -3078,7 +4337,7 @@ load_configuration(const char *filename, ns_server_t *server,
else
isc_quota_soft(&server->recursionquota, 0);
- CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx,
+ CHECK(configure_view_acl(NULL, config, "blackhole", NULL, &aclconfctx,
ns_g_mctx, &server->blackholeacl));
if (server->blackholeacl != NULL)
dns_dispatchmgr_setblackhole(ns_g_dispatchmgr,
@@ -3317,6 +4576,31 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL,
&interval, ISC_FALSE));
+ /*
+ * Write the PID file.
+ */
+ obj = NULL;
+ if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
+ if (cfg_obj_isvoid(obj))
+ ns_os_writepidfile(NULL, first_time);
+ else
+ ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
+ else if (ns_g_lwresdonly)
+ ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
+ else
+ ns_os_writepidfile(ns_g_defaultpidfile, first_time);
+
+ /*
+ * Configure the server-wide session key. This must be done before
+ * configure views because zone configuration may need to know
+ * session-keyname.
+ *
+ * Failure of session key generation isn't fatal at this time; if it
+ * turns out that a session key is really needed but doesn't exist,
+ * we'll treat it as a fatal error then.
+ */
+ (void)configure_session_key(maps, server, ns_g_mctx);
+
/*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
@@ -3328,12 +4612,13 @@ load_configuration(const char *filename, ns_server_t *server,
element != NULL;
element = cfg_list_next(element))
{
- const cfg_obj_t *vconfig = cfg_listelt_value(element);
+ cfg_obj_t *vconfig = cfg_listelt_value(element);
view = NULL;
CHECK(create_view(vconfig, &viewlist, &view));
INSIST(view != NULL);
- CHECK(configure_view(view, config, vconfig,
+ CHECK(configure_view(view, conf_parser, config, vconfig,
+ &cachelist, bindkeys,
ns_g_mctx, &aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
@@ -3351,15 +4636,15 @@ load_configuration(const char *filename, ns_server_t *server,
* In either case, we need to configure and freeze it.
*/
CHECK(create_view(NULL, &viewlist, &view));
- CHECK(configure_view(view, config, NULL, ns_g_mctx,
- &aclconfctx, ISC_TRUE));
+ CHECK(configure_view(view, conf_parser, config, NULL,
+ &cachelist, bindkeys,
+ ns_g_mctx, &aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
}
/*
- * Create (or recreate) the built-in views. Currently
- * there is only one, the _bind view.
+ * Create (or recreate) the built-in views.
*/
builtin_views = NULL;
RUNTIME_CHECK(cfg_map_get(ns_g_config, "view",
@@ -3368,25 +4653,38 @@ load_configuration(const char *filename, ns_server_t *server,
element != NULL;
element = cfg_list_next(element))
{
- const cfg_obj_t *vconfig = cfg_listelt_value(element);
- CHECK(create_view(vconfig, &viewlist, &view));
- CHECK(configure_view(view, config, vconfig, ns_g_mctx,
- &aclconfctx, ISC_FALSE));
+ cfg_obj_t *vconfig = cfg_listelt_value(element);
+
+ CHECK(create_view(vconfig, &builtin_viewlist, &view));
+ CHECK(configure_view(view, conf_parser, config, vconfig,
+ &cachelist, bindkeys,
+ ns_g_mctx, &aclconfctx, ISC_FALSE));
dns_view_freeze(view);
dns_view_detach(&view);
view = NULL;
}
- /*
- * Swap our new view list with the production one.
- */
+ /* Now combine the two viewlists into one */
+ ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
+
+ /* Swap our new view list with the production one. */
tmpviewlist = server->viewlist;
server->viewlist = viewlist;
viewlist = tmpviewlist;
- /*
- * Load the TKEY information from the configuration.
- */
+ /* Make the view list available to each of the views */
+ view = ISC_LIST_HEAD(server->viewlist);
+ while (view != NULL) {
+ view->viewlist = &server->viewlist;
+ view = ISC_LIST_NEXT(view, link);
+ }
+
+ /* Swap our new cache list with the production one. */
+ tmpcachelist = server->cachelist;
+ server->cachelist = cachelist;
+ cachelist = tmpcachelist;
+
+ /* Load the TKEY information from the configuration. */
if (options != NULL) {
dns_tkeyctx_t *t = NULL;
CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy,
@@ -3551,16 +4849,6 @@ load_configuration(const char *filename, ns_server_t *server,
}
}
- obj = NULL;
- if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
- if (cfg_obj_isvoid(obj))
- ns_os_writepidfile(NULL, first_time);
- else
- ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
- else if (ns_g_lwresdonly)
- ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
- else
- ns_os_writepidfile(ns_g_defaultpidfile, first_time);
obj = NULL;
if (options != NULL &&
@@ -3590,6 +4878,12 @@ load_configuration(const char *filename, ns_server_t *server,
CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)),
"strdup");
+ obj = NULL;
+ result = ns_config_get(maps, "secroots-file", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ CHECKM(setstring(server, &server->secrootsfile, cfg_obj_asstring(obj)),
+ "strdup");
+
obj = NULL;
result = ns_config_get(maps, "recursing-file", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -3647,12 +4941,18 @@ load_configuration(const char *filename, ns_server_t *server,
if (v6portset != NULL)
isc_portset_destroy(ns_g_mctx, &v6portset);
- cfg_aclconfctx_destroy(&aclconfctx);
+ cfg_aclconfctx_clear(&aclconfctx);
- if (parser != NULL) {
+ if (conf_parser != NULL) {
if (config != NULL)
- cfg_obj_destroy(parser, &config);
- cfg_parser_destroy(&parser);
+ cfg_obj_destroy(conf_parser, &config);
+ cfg_parser_destroy(&conf_parser);
+ }
+
+ if (bindkeys_parser != NULL) {
+ if (bindkeys != NULL)
+ cfg_obj_destroy(bindkeys_parser, &bindkeys);
+ cfg_parser_destroy(&bindkeys_parser);
}
if (view != NULL)
@@ -3675,6 +4975,13 @@ load_configuration(const char *filename, ns_server_t *server,
dns_view_detach(&view);
}
+ /* Same cleanup for cache list. */
+ while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) {
+ ISC_LIST_UNLINK(cachelist, nsc, link);
+ dns_cache_detach(&nsc->cache);
+ isc_mem_put(server->mctx, nsc, sizeof(*nsc));
+ }
+
/*
* Adjust the listening interfaces in accordance with the source
* addresses specified in views and zones.
@@ -3708,6 +5015,8 @@ load_zones(ns_server_t *server, isc_boolean_t stop) {
view = ISC_LIST_NEXT(view, link))
{
CHECK(dns_view_load(view, stop));
+ if (view->managed_keys != NULL)
+ CHECK(dns_zone_load(view->managed_keys));
}
/*
@@ -3737,11 +5046,14 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) {
view = ISC_LIST_NEXT(view, link))
{
CHECK(dns_view_loadnew(view, stop));
+
+ /* Load managed-keys data */
+ if (view->managed_keys != NULL)
+ CHECK(dns_zone_loadnew(view->managed_keys));
}
+
/*
- * Force zone maintenance. Do this after loading
- * so that we know when we need to force AXFR of
- * slave zones whose master files are missing.
+ * Resume zone XFRs.
*/
dns_zonemgr_resumexfrs(server->zonemgr);
cleanup:
@@ -3820,6 +5132,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_t *view, *view_next;
ns_server_t *server = (ns_server_t *)event->ev_arg;
isc_boolean_t flush = server->flushonshutdown;
+ ns_cache_t *nsc;
UNUSED(task);
INSIST(task == server->task);
@@ -3834,6 +5147,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
ns_statschannels_shutdown(server);
ns_controls_shutdown(server->controls);
end_reserved_dispatches(server, ISC_TRUE);
+ cleanup_session_key(server, server->mctx);
cfg_obj_destroy(ns_g_parser, &ns_g_config);
cfg_parser_destroy(&ns_g_parser);
@@ -3849,6 +5163,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_detach(&view);
}
+ while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) {
+ ISC_LIST_UNLINK(server->cachelist, nsc, link);
+ dns_cache_detach(&nsc->cache);
+ isc_mem_put(server->mctx, nsc, sizeof(*nsc));
+ }
+
isc_timer_detach(&server->interface_timer);
isc_timer_detach(&server->heartbeat_timer);
isc_timer_detach(&server->pps_timer);
@@ -3860,6 +5180,11 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_zonemgr_shutdown(server->zonemgr);
+ if (ns_g_sessionkey != NULL) {
+ dns_tsigkey_detach(&ns_g_sessionkey);
+ dns_name_free(&ns_g_sessionkeyname, server->mctx);
+ }
+
if (server->blackholeacl != NULL)
dns_acl_detach(&server->blackholeacl);
@@ -3918,7 +5243,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
ISC_R_NOMEMORY : ISC_R_SUCCESS,
"allocating reload event");
- CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, ISC_ENTROPY_GOODONLY),
+ CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy,
+ ns_g_engine, ISC_ENTROPY_GOODONLY),
"initializing DST");
server->tkeyctx = NULL;
@@ -3963,10 +5289,20 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
"isc_stats_create");
isc_socketmgr_setstats(ns_g_socketmgr, server->sockstats);
+ server->bindkeysfile = isc_mem_strdup(server->mctx, "bind.keys");
+ CHECKFATAL(server->bindkeysfile == NULL ? ISC_R_NOMEMORY :
+ ISC_R_SUCCESS,
+ "isc_mem_strdup");
+
server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db");
CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
+ server->secrootsfile = isc_mem_strdup(server->mctx, "named.secroots");
+ CHECKFATAL(server->secrootsfile == NULL ? ISC_R_NOMEMORY :
+ ISC_R_SUCCESS,
+ "isc_mem_strdup");
+
server->recfile = isc_mem_strdup(server->mctx, "named.recursing");
CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
@@ -4008,6 +5344,14 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
ISC_LIST_INIT(server->statschannels);
+ ISC_LIST_INIT(server->cachelist);
+
+ server->sessionkey = NULL;
+ server->session_keyfile = NULL;
+ server->session_keyname = NULL;
+ server->session_keyalg = DST_ALG_UNKNOWN;
+ server->session_keybits = 0;
+
server->magic = NS_SERVER_MAGIC;
*serverp = server;
}
@@ -4027,7 +5371,9 @@ ns_server_destroy(ns_server_t **serverp) {
isc_stats_detach(&server->sockstats);
isc_mem_free(server->mctx, server->statsfile);
+ isc_mem_free(server->mctx, server->bindkeysfile);
isc_mem_free(server->mctx, server->dumpfile);
+ isc_mem_free(server->mctx, server->secrootsfile);
isc_mem_free(server->mctx, server->recfile);
if (server->version != NULL)
@@ -4047,6 +5393,7 @@ ns_server_destroy(ns_server_t **serverp) {
isc_event_free(&server->reload_event);
INSIST(ISC_LIST_EMPTY(server->viewlist));
+ INSIST(ISC_LIST_EMPTY(server->cachelist));
dns_aclenv_destroy(&server->aclenv);
@@ -4278,7 +5625,9 @@ next_token(char **stringp, const char *delim) {
* set '*zonep' to NULL.
*/
static isc_result_t
-zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
+zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep,
+ const char **zonename)
+{
char *input, *ptr;
const char *zonetxt;
char *classtxt;
@@ -4302,6 +5651,8 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
zonetxt = next_token(&input, " \t");
if (zonetxt == NULL)
return (ISC_R_SUCCESS);
+ if (zonename)
+ *zonename = zonetxt;
/* Look for the optional class name. */
classtxt = next_token(&input, " \t");
@@ -4314,7 +5665,7 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
isc_buffer_add(&buf, strlen(zonetxt));
dns_fixedname_init(&name);
result = dns_name_fromtext(dns_fixedname_name(&name),
- &buf, dns_rootname, ISC_FALSE, NULL);
+ &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
goto fail1;
@@ -4362,7 +5713,7 @@ ns_server_retransfercommand(ns_server_t *server, char *args) {
dns_zone_t *zone = NULL;
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4386,7 +5737,7 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zonetype_t type;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -4446,7 +5797,7 @@ ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zone_t *zone = NULL;
const unsigned char msg[] = "zone notify queued";
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4471,7 +5822,7 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
const unsigned char msg2[] = "not a slave or stub zone";
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4710,15 +6061,23 @@ dumpdone(void *arg, isc_result_t result) {
nextview:
fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name);
resume:
- if (dctx->zone == NULL && dctx->cache == NULL && dctx->dumpcache) {
+ if (dctx->dumpcache && dns_view_iscacheshared(dctx->view->view)) {
+ fprintf(dctx->fp,
+ ";\n; Cache of view '%s' is shared as '%s'\n",
+ dctx->view->view->name,
+ dns_cache_getname(dctx->view->view->cache));
+ } else if (dctx->zone == NULL && dctx->cache == NULL &&
+ dctx->dumpcache)
+ {
style = &dns_master_style_cache;
/* start cache dump */
if (dctx->view->view->cachedb != NULL)
dns_db_attach(dctx->view->view->cachedb, &dctx->cache);
if (dctx->cache != NULL) {
-
- fprintf(dctx->fp, ";\n; Cache dump of view '%s'\n;\n",
- dctx->view->view->name);
+ fprintf(dctx->fp,
+ ";\n; Cache dump of view '%s' (cache %s)\n;\n",
+ dctx->view->view->name,
+ dns_cache_getname(dctx->view->view->cache));
result = dns_master_dumptostreaminc(dctx->mctx,
dctx->cache, NULL,
style, dctx->fp,
@@ -4879,6 +6238,68 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
return (result);
}
+isc_result_t
+ns_server_dumpsecroots(ns_server_t *server, char *args) {
+ dns_view_t *view;
+ dns_keytable_t *secroots = NULL;
+ isc_result_t result;
+ char *ptr;
+ FILE *fp = NULL;
+ isc_time_t now;
+ char tbuf[64];
+
+ /* Skip the command name. */
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+ ptr = next_token(&args, " \t");
+
+ CHECKMF(isc_stdio_open(server->secrootsfile, "w", &fp),
+ "could not open secroots dump file", server->secrootsfile);
+ TIME_NOW(&now);
+ isc_time_formattimestamp(&now, tbuf, sizeof(tbuf));
+ fprintf(fp, "%s\n", tbuf);
+
+ nextview:
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (ptr != NULL && strcmp(view->name, ptr) != 0)
+ continue;
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ result = dns_view_getsecroots(view, &secroots);
+ if (result == ISC_R_NOTFOUND) {
+ result = ISC_R_SUCCESS;
+ continue;
+ }
+ fprintf(fp, "\n Start view %s\n\n", view->name);
+ CHECK(dns_keytable_dump(secroots, fp));
+ }
+ if (ptr != NULL) {
+ ptr = next_token(&args, " \t");
+ if (ptr != NULL)
+ goto nextview;
+ }
+
+ cleanup:
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ if (fp != NULL)
+ (void)isc_stdio_close(fp);
+ if (result == ISC_R_SUCCESS)
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "dumpsecroots complete");
+ else
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "dumpsecroots failed: %s",
+ dns_result_totext(result));
+ return (result);
+}
+
isc_result_t
ns_server_dumprecursing(ns_server_t *server) {
FILE *fp = NULL;
@@ -4997,6 +6418,7 @@ ns_server_flushcache(ns_server_t *server, char *args) {
isc_boolean_t flushed;
isc_boolean_t found;
isc_result_t result;
+ ns_cache_t *nsc;
/* Skip the command name. */
ptr = next_token(&args, " \t");
@@ -5010,22 +6432,96 @@ ns_server_flushcache(ns_server_t *server, char *args) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
flushed = ISC_TRUE;
found = ISC_FALSE;
- for (view = ISC_LIST_HEAD(server->viewlist);
- view != NULL;
- view = ISC_LIST_NEXT(view, link))
- {
- if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
- continue;
+
+ /*
+ * Flushing a cache is tricky when caches are shared by multiple views.
+ * We first identify which caches should be flushed in the local cache
+ * list, flush these caches, and then update other views that refer to
+ * the flushed cache DB.
+ */
+ if (viewname != NULL) {
+ /*
+ * Mark caches that need to be flushed. This is an O(#view^2)
+ * operation in the very worst case, but should be normally
+ * much more lightweight because only a few (most typically just
+ * one) views will match.
+ */
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (strcasecmp(viewname, view->name) != 0)
+ continue;
+ found = ISC_TRUE;
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (nsc->cache == view->cache)
+ break;
+ }
+ INSIST(nsc != NULL);
+ nsc->needflush = ISC_TRUE;
+ }
+ } else
found = ISC_TRUE;
- result = dns_view_flushcache(view);
+
+ /* Perform flush */
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (viewname != NULL && !nsc->needflush)
+ continue;
+ nsc->needflush = ISC_TRUE;
+ result = dns_view_flushcache2(nsc->primaryview, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"flushing cache in view '%s' failed: %s",
- view->name, isc_result_totext(result));
+ nsc->primaryview->name,
+ isc_result_totext(result));
}
}
+
+ /*
+ * Fix up views that share a flushed cache: let the views update the
+ * cache DB they're referring to. This could also be an expensive
+ * operation, but should typically be marginal: the inner loop is only
+ * necessary for views that share a cache, and if there are many such
+ * views the number of shared cache should normally be small.
+ * A worst case is that we have n views and n/2 caches, each shared by
+ * two views. Then this will be a O(n^2/4) operation.
+ */
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (!dns_view_iscacheshared(view))
+ continue;
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (!nsc->needflush || nsc->cache != view->cache)
+ continue;
+ result = dns_view_flushcache2(view, ISC_TRUE);
+ if (result != ISC_R_SUCCESS) {
+ flushed = ISC_FALSE;
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "fixing cache in view '%s' "
+ "failed: %s", view->name,
+ isc_result_totext(result));
+ }
+ }
+ }
+
+ /* Cleanup the cache list. */
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ nsc->needflush = ISC_FALSE;
+ }
+
if (flushed && found) {
if (viewname != NULL)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
@@ -5076,7 +6572,7 @@ ns_server_flushname(ns_server_t *server, char *args) {
isc_buffer_add(&b, strlen(target));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -5094,6 +6590,11 @@ ns_server_flushname(ns_server_t *server, char *args) {
if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
continue;
found = ISC_TRUE;
+ /*
+ * It's a little inefficient to try flushing name for all views
+ * if some of the views share a single cache. But since the
+ * operation is lightweight we prefer simplicity here.
+ */
result = dns_view_flushname(view, name);
if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE;
@@ -5407,6 +6908,46 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
return (ISC_R_SUCCESS);
}
+/*
+ * Act on a "sign" or "loadkeys" command from the command channel.
+ */
+isc_result_t
+ns_server_rekey(ns_server_t *server, char *args) {
+ isc_result_t result;
+ dns_zone_t *zone = NULL;
+ dns_zonetype_t type;
+ isc_uint16_t keyopts;
+ isc_boolean_t fullsign = ISC_FALSE;
+
+ if (strncasecmp(args, NS_COMMAND_SIGN, strlen(NS_COMMAND_SIGN)) == 0)
+ fullsign = ISC_TRUE;
+
+ result = zone_from_args(server, args, &zone, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (zone == NULL)
+ return (ISC_R_UNEXPECTEDEND); /* XXX: or do all zones? */
+
+ type = dns_zone_gettype(zone);
+ if (type != dns_zone_master) {
+ dns_zone_detach(&zone);
+ return (DNS_R_NOTMASTER);
+ }
+
+ keyopts = dns_zone_getkeyopts(zone);
+
+ /* "rndc loadkeys" requires "auto-dnssec maintain". */
+ if ((keyopts & DNS_ZONEKEY_ALLOW) == 0)
+ result = ISC_R_NOPERM;
+ else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign)
+ result = ISC_R_NOPERM;
+ else
+ dns_zone_rekey(zone, fullsign);
+
+ dns_zone_detach(&zone);
+ return (result);
+}
+
/*
* Act on a "freeze" or "thaw" command from the command channel.
*/
@@ -5425,7 +6966,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_boolean_t frozen;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -5451,7 +6992,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
type = dns_zone_gettype(zone);
if (type != dns_zone_master) {
dns_zone_detach(&zone);
- return (ISC_R_NOTFOUND);
+ return (DNS_R_NOTMASTER);
}
result = isc_task_beginexclusive(server->task);
@@ -5502,8 +7043,8 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
strlen(msg) + 1);
view = dns_zone_getview(zone);
- if (strcmp(view->name, "_bind") == 0 ||
- strcmp(view->name, "_default") == 0)
+ if (strcmp(view->name, "_default") == 0 ||
+ strcmp(view->name, "_bind") == 0)
{
vname = "";
sep = "";
@@ -5543,3 +7084,376 @@ ns_smf_add_message(isc_buffer_t *text) {
return (ISC_R_SUCCESS);
}
#endif /* HAVE_LIBSCF */
+
+/*
+ * Act on an "addzone" command from the command channel.
+ */
+isc_result_t
+ns_server_add_zone(ns_server_t *server, char *args) {
+ isc_result_t result;
+ isc_buffer_t argbuf;
+ size_t arglen;
+ cfg_parser_t *parser = NULL;
+ cfg_obj_t *config = NULL;
+ const cfg_obj_t *vconfig = NULL;
+ const cfg_obj_t *views = NULL;
+ const cfg_obj_t *parms = NULL;
+ const cfg_obj_t *obj = NULL;
+ const cfg_listelt_t *element;
+ const char *zonename;
+ const char *classname = NULL;
+ const char *argp;
+ const char *viewname = NULL;
+ dns_rdataclass_t rdclass;
+ dns_view_t *view = 0;
+ isc_buffer_t buf, *nbuf = NULL;
+ dns_name_t dnsname;
+ dns_zone_t *zone = NULL;
+ FILE *fp = NULL;
+ struct cfg_context *cfg = NULL;
+
+ /* Try to parse the argument string */
+ arglen = strlen(args);
+ isc_buffer_init(&argbuf, args, arglen);
+ isc_buffer_add(&argbuf, strlen(args));
+ CHECK(cfg_parser_create(server->mctx, ns_g_lctx, &parser));
+ CHECK(cfg_parse_buffer(parser, &argbuf, &cfg_type_addzoneconf,
+ &config));
+ CHECK(cfg_map_get(config, "addzone", &parms));
+
+ zonename = cfg_obj_asstring(cfg_tuple_get(parms, "name"));
+ isc_buffer_init(&buf, zonename, strlen(zonename));
+ isc_buffer_add(&buf, strlen(zonename));
+ dns_name_init(&dnsname, NULL);
+ isc_buffer_allocate(server->mctx, &nbuf, 256);
+ dns_name_setbuffer(&dnsname, nbuf);
+ CHECK(dns_name_fromtext(&dnsname, &buf, dns_rootname, ISC_FALSE, NULL));
+
+ /* Make sense of optional class argument */
+ obj = cfg_tuple_get(parms, "class");
+ CHECK(ns_config_getclass(obj, dns_rdataclass_in, &rdclass));
+ if (rdclass != dns_rdataclass_in && obj)
+ classname = cfg_obj_asstring(obj);
+
+ /* Make sense of optional view argument */
+ obj = cfg_tuple_get(parms, "view");
+ if (obj && cfg_obj_isstring(obj))
+ viewname = cfg_obj_asstring(obj);
+ if (viewname == NULL || *viewname == '\0')
+ viewname = "_default";
+ CHECK(dns_viewlist_find(&server->viewlist, viewname, rdclass, &view));
+
+ /* Are we accepting new zones? */
+ if (view->new_zone_file == NULL) {
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ cfg = (struct cfg_context *) view->new_zone_config;
+ if (cfg == NULL) {
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /* Zone shouldn't already exist */
+ result = dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone);
+ if (result == ISC_R_SUCCESS) {
+ result = ISC_R_EXISTS;
+ goto cleanup;
+ } else if (result == DNS_R_PARTIALMATCH) {
+ /* Create our sub-zone anyway */
+ dns_zone_detach(&zone);
+ zone = NULL;
+ }
+ else if (result != ISC_R_NOTFOUND)
+ goto cleanup;
+
+ /* Find the view statement */
+ cfg_map_get(cfg->config, "view", &views);
+ for (element = cfg_list_first(views);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const char *vname;
+ vconfig = cfg_listelt_value(element);
+ vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
+ if (vname && !strcasecmp(vname, viewname))
+ break;
+ vconfig = NULL;
+ }
+
+ /* Open save file for write configuration */
+ CHECK(isc_stdio_open(view->new_zone_file, "a", &fp));
+
+ /* Mark view unfrozen so that zone can be added */
+ dns_view_thaw(view);
+ result = configure_zone(cfg->config, parms, vconfig,
+ server->mctx, view, &cfg->actx, ISC_FALSE);
+ dns_view_freeze(view);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+
+ /* Is it there yet? */
+ CHECK(dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone));
+
+ /*
+ * Load the zone from the master file. If this fails, we'll
+ * need to undo the configuration we've done already.
+ */
+ result = dns_zone_loadnew(zone);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_t *dbp = NULL;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "addzone failed; reverting.");
+
+ /* If the zone loaded partially, unload it */
+ if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
+ dns_db_detach(&dbp);
+ dns_zone_unload(zone);
+ }
+
+ /* Remove the zone from the zone table */
+ dns_zt_unmount(view->zonetable, zone);
+ goto cleanup;
+ }
+
+ /* Flag the zone as having been added at runtime */
+ dns_zone_setadded(zone, ISC_TRUE);
+
+ /* Emit just the zone name from args */
+ CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL));
+ CHECK(isc_stdio_write(zonename, strlen(zonename), 1, fp, NULL));
+ CHECK(isc_stdio_write(" ", 1, 1, fp, NULL));
+
+ /* Classname, if not default */
+ if (classname != NULL && *classname != '\0') {
+ CHECK(isc_stdio_write(classname, strlen(classname), 1, fp,
+ NULL));
+ CHECK(isc_stdio_write(" ", 1, 1, fp, NULL));
+ }
+
+ /* Find beginning of option block from args */
+ for (argp = args; *argp; argp++, arglen--) {
+ if (*argp == '{') { /* Assume matching '}' */
+ /* Add that to our file */
+ CHECK(isc_stdio_write(argp, arglen, 1, fp, NULL));
+
+ /* Make sure we end with a LF */
+ if (argp[arglen-1] != '\n') {
+ CHECK(isc_stdio_write("\n", 1, 1, fp, NULL));
+ }
+ break;
+ }
+ }
+
+ CHECK(isc_stdio_close(fp));
+ fp = NULL;
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "zone %s added to view %s via addzone",
+ zonename, viewname);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (fp != NULL)
+ isc_stdio_close(fp);
+ if (parser != NULL) {
+ if (config != NULL)
+ cfg_obj_destroy(parser, &config);
+ cfg_parser_destroy(&parser);
+ }
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ if (view != NULL)
+ dns_view_detach(&view);
+ if (nbuf != NULL)
+ isc_buffer_free(&nbuf);
+
+ return (result);
+}
+
+/*
+ * Act on a "delzone" command from the command channel.
+ */
+isc_result_t
+ns_server_del_zone(ns_server_t *server, char *args) {
+ isc_result_t result;
+ dns_zone_t *zone = NULL;
+ dns_view_t *view = NULL;
+ dns_db_t *dbp = NULL;
+ const char *filename = NULL;
+ char *tmpname = NULL;
+ char buf[1024];
+ const char *zonename = NULL;
+ size_t znamelen = 0;
+ FILE *ifp = NULL, *ofp = NULL;
+
+ /* Parse parameters */
+ CHECK(zone_from_args(server, args, &zone, &zonename));
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (zone == NULL) {
+ result = ISC_R_UNEXPECTEDEND;
+ goto cleanup;
+ }
+
+ /*
+ * Was this zone originally added at runtime?
+ * If not, we can't delete it now.
+ */
+ if (!dns_zone_getadded(zone)) {
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ if (zonename != NULL)
+ znamelen = strlen(zonename);
+
+ /* Dig out configuration for this zone */
+ view = dns_zone_getview(zone);
+ filename = view->new_zone_file;
+ if (filename == NULL) {
+ /* No adding zones in this view */
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /* Rewrite zone list */
+ result = isc_stdio_open(filename, "r", &ifp);
+ if (ifp != NULL && result == ISC_R_SUCCESS) {
+ char *found = NULL, *p = NULL;
+ size_t n;
+
+ /* Create a temporary file */
+ CHECK(isc_string_printf(buf, 1023, "%s.%ld", filename,
+ (long)getpid()));
+ if (!(tmpname = isc_mem_strdup(server->mctx, buf))) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ CHECK(isc_stdio_open(tmpname, "w", &ofp));
+
+ /* Look for the entry for that zone */
+ while (fgets(buf, 1024, ifp)) {
+ /* A 'zone' line */
+ if (strncasecmp(buf, "zone", 4)) {
+ fputs(buf, ofp);
+ continue;
+ }
+ p = buf+4;
+
+ /* Locate a name */
+ while (*p &&
+ ((*p == '"') || isspace((unsigned char)*p)))
+ p++;
+
+ /* Is that the zone we're looking for */
+ if (strncasecmp(p, zonename, znamelen)) {
+ fputs(buf, ofp);
+ continue;
+ }
+
+ /* And nothing else? */
+ p += znamelen;
+ if (isspace((unsigned char)*p) ||
+ *p == '"' || *p == '{') {
+ /* This must be the entry */
+ found = p;
+ break;
+ }
+
+ /* Spit it out, keep looking */
+ fputs(buf, ofp);
+ }
+
+ /* Skip over an option block (matching # of braces) */
+ if (found) {
+ int obrace = 0, cbrace = 0;
+ for (;;) {
+ while (*p) {
+ if (*p == '{') obrace++;
+ if (*p == '}') cbrace++;
+ p++;
+ }
+ if (obrace && (obrace == cbrace))
+ break;
+ if (!fgets(buf, 1024, ifp))
+ break;
+ p = buf;
+ }
+
+ /* Just spool the remainder of the file out */
+ result = isc_stdio_read(buf, 1, 1024, ifp, &n);
+ while (n > 0U) {
+ if (result == ISC_R_EOF)
+ result = ISC_R_SUCCESS;
+ CHECK(result);
+ isc_stdio_write(buf, 1, n, ofp, NULL);
+ result = isc_stdio_read(buf, 1, 1024, ifp, &n);
+ }
+
+ /* Move temporary into place */
+ CHECK(isc_file_rename(tmpname, view->new_zone_file));
+ } else {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "deleted zone %s was missing from "
+ "new zone file", zonename);
+ goto cleanup;
+ }
+ }
+
+ /* Stop answering for this zone */
+ if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
+ dns_db_detach(&dbp);
+ dns_zone_unload(zone);
+ }
+
+ CHECK(dns_zt_unmount(view->zonetable, zone));
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "zone %s removed via delzone", zonename);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (ifp != NULL)
+ isc_stdio_close(ifp);
+ if (ofp != NULL) {
+ isc_stdio_close(ofp);
+ isc_file_remove(tmpname);
+ }
+ if (tmpname != NULL)
+ isc_mem_free(server->mctx, tmpname);
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ return (result);
+}
+
+static void
+cfgctx_destroy(void **cfgp) {
+ struct cfg_context *cfg;
+ isc_mem_t *mctx;
+
+ REQUIRE(cfgp != NULL && *cfgp != NULL);
+ cfg = *cfgp;
+ mctx = cfg->mctx;
+ cfg->mctx = NULL;
+
+ if (cfg->parser != NULL) {
+ if (cfg->config != NULL)
+ cfg_obj_destroy(cfg->parser, &cfg->config);
+ cfg_parser_destroy(&cfg->parser);
+ }
+ cfg_aclconfctx_clear(&cfg->actx);
+
+ isc_mem_put(mctx, cfg, sizeof(*cfg));
+ isc_mem_detach(&mctx);
+ *cfgp = NULL;
+}
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index c77d3ca1bfe..6dce8e0a77c 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.14.64.11 2010-02-04 23:47:46 tbox Exp $ */
+/* $Id: statschannel.c,v 1.26 2010-02-04 23:49:13 tbox Exp $ */
/*! \file */
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
#include
@@ -823,9 +824,9 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "cache"));
TRY0(xmlTextWriterWriteAttribute(writer,
- ISC_XMLCHAR "name",
- ISC_XMLCHAR
- view->name));
+ ISC_XMLCHAR "name",
+ ISC_XMLCHAR
+ dns_cache_getname(view->cache)));
dumparg.result = ISC_R_SUCCESS;
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
&dumparg, 0);
@@ -1405,7 +1406,15 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
if (strcmp(view->name, "_default") == 0)
fprintf(fp, "[View: default]\n");
else
- fprintf(fp, "[View: %s]\n", view->name);
+ fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
+ dns_cache_getname(view->cache));
+ if (dns_view_iscacheshared(view)) {
+ /*
+ * Avoid dumping redundant statistics when the cache is
+ * shared.
+ */
+ continue;
+ }
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg,
0);
}
diff --git a/bin/named/tkeyconf.c b/bin/named/tkeyconf.c
index 73449780319..66c2d7f47cc 100644
--- a/bin/named/tkeyconf.c
+++ b/bin/named/tkeyconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tkeyconf.c,v 1.29 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: tkeyconf.c,v 1.33 2010-12-20 23:47:20 tbox Exp $ */
/*! \file */
@@ -77,8 +77,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY;
RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH,
type, NULL, mctx, &tctx->dhkey));
@@ -92,8 +91,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t));
if (tctx->domain == NULL) {
result = ISC_R_NOMEMORY;
@@ -112,12 +110,22 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
- RETERR(dst_gssapi_acquirecred(name, ISC_FALSE,
- &tctx->gsscred));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred));
}
+ obj = NULL;
+ result = cfg_map_get(options, "tkey-gssapi-keytab", &obj);
+ if (result == ISC_R_SUCCESS) {
+ s = cfg_obj_asstring(obj);
+ tctx->gssapi_keytab = isc_mem_strdup(mctx, s);
+ if (tctx->gssapi_keytab == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto failure;
+ }
+ }
+
+
*tctxp = tctx;
return (ISC_R_SUCCESS);
diff --git a/bin/named/tsigconf.c b/bin/named/tsigconf.c
index e90a86b5a78..19e8d385e05 100644
--- a/bin/named/tsigconf.c
+++ b/bin/named/tsigconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsigconf.c,v 1.30 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: tsigconf.c,v 1.35 2011-01-11 23:47:12 tbox Exp $ */
/*! \file */
@@ -82,7 +82,7 @@ add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
isc_buffer_add(&keynamesrc, strlen(keyid));
isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
- ISC_TRUE, &keynamebuf);
+ DNS_NAME_DOWNCASE, &keynamebuf);
if (ret != ISC_R_SUCCESS)
goto failure;
@@ -149,6 +149,8 @@ ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_result_t result;
int i;
+ REQUIRE(ringp != NULL && *ringp == NULL);
+
i = 0;
if (config != NULL)
maps[i++] = config;
@@ -176,6 +178,6 @@ ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_SUCCESS);
failure:
- dns_tsigkeyring_destroy(&ring);
+ dns_tsigkeyring_detach(&ring);
return (result);
}
diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in
index 502db2508c9..ca92c49b5c7 100644
--- a/bin/named/unix/Makefile.in
+++ b/bin/named/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.10 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.13 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h
index 0a846080a66..c2768f42664 100644
--- a/bin/named/unix/include/named/os.h
+++ b/bin/named/unix/include/named/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.29 2008-10-24 01:44:48 tbox Exp $ */
+/* $Id: os.h,v 1.31 2009-08-05 23:47:43 tbox Exp $ */
#ifndef NS_OS_H
#define NS_OS_H 1
@@ -51,8 +51,12 @@ ns_os_adjustnofile(void);
void
ns_os_minprivs(void);
+FILE *
+ns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user);
+
void
ns_os_writepidfile(const char *filename, isc_boolean_t first_time);
+
void
ns_os_shutdown(void);
diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c
index 3f07784fcb8..53e9e450124 100644
--- a/bin/named/unix/os.c
+++ b/bin/named/unix/os.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.89.12.5 2009-03-02 03:03:54 marka Exp $ */
+/* $Id: os.c,v 1.104 2010-11-17 23:47:08 tbox Exp $ */
/*! \file */
@@ -291,6 +291,12 @@ linux_initialprivs(void) {
*/
SET_CAP(CAP_SYS_RESOURCE);
+ /*
+ * We need to be able to set the ownership of the containing
+ * directory of the pid file when we create it.
+ */
+ SET_CAP(CAP_CHOWN);
+
linux_setcaps(caps);
#ifdef HAVE_LIBCAP
@@ -631,7 +637,7 @@ ns_os_minprivs(void) {
}
static int
-safe_open(const char *filename, isc_boolean_t append) {
+safe_open(const char *filename, mode_t mode, isc_boolean_t append) {
int fd;
struct stat sb;
@@ -644,13 +650,11 @@ safe_open(const char *filename, isc_boolean_t append) {
}
if (append)
- fd = open(filename, O_WRONLY|O_CREAT|O_APPEND,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode);
else {
if (unlink(filename) < 0 && errno != ENOENT)
return (-1);
- fd = open(filename, O_WRONLY|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
}
return (fd);
}
@@ -686,6 +690,15 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
}
if (mkdirpath(filename, report) == -1)
goto error;
+ /*
+ * Handle "//", "/./" and "/../" in path.
+ */
+ if (!strcmp(slash + 1, "") ||
+ !strcmp(slash + 1, ".") ||
+ !strcmp(slash + 1, "..")) {
+ *slash = '/';
+ return (0);
+ }
mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */
mode |= S_IRGRP | S_IXGRP; /* g=rx */
mode |= S_IROTH | S_IXOTH; /* o=rx */
@@ -695,6 +708,13 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
strbuf);
goto error;
}
+ if (runas_pw != NULL &&
+ chown(filename, runas_pw->pw_uid,
+ runas_pw->pw_gid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ (*report)("couldn't chown '%s': %s", filename,
+ strbuf);
+ }
}
*slash = '/';
}
@@ -705,11 +725,127 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
return (-1);
}
+static void
+setperms(uid_t uid, gid_t gid) {
+ char strbuf[ISC_STRERRORSIZE];
+#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
+ gid_t oldgid, tmpg;
+#endif
+#if !defined(HAVE_SETEUID) && defined(HAVE_SETRESUID)
+ uid_t olduid, tmpu;
+#endif
+#if defined(HAVE_SETEGID)
+ if (getegid() != gid && setegid(gid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective gid to %ld: %s",
+ (long)gid, strbuf);
+ }
+#elif defined(HAVE_SETRESGID)
+ if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) {
+ if (setresgid(-1, gid, -1) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective "
+ "gid to %d: %s", gid, strbuf);
+ }
+ }
+#endif
+
+#if defined(HAVE_SETEUID)
+ if (geteuid() != uid && seteuid(uid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective uid to %ld: %s",
+ (long)uid, strbuf);
+ }
+#elif defined(HAVE_SETRESUID)
+ if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) {
+ if (setresuid(-1, uid, -1) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective "
+ "uid to %d: %s", uid, strbuf);
+ }
+ }
+#endif
+}
+
+FILE *
+ns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user) {
+ char strbuf[ISC_STRERRORSIZE], *f;
+ FILE *fp;
+ int fd;
+
+ /*
+ * Make the containing directory if it doesn't exist.
+ */
+ f = strdup(filename);
+ if (f == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("couldn't strdup() '%s': %s",
+ filename, strbuf);
+ return (NULL);
+ }
+ if (mkdirpath(f, ns_main_earlywarning) == -1) {
+ free(f);
+ return (NULL);
+ }
+ free(f);
+
+ if (switch_user && runas_pw != NULL) {
+ /* Set UID/GID to the one we'll be running with eventually */
+ setperms(runas_pw->pw_uid, runas_pw->pw_gid);
+
+ fd = safe_open(filename, mode, ISC_FALSE);
+
+#ifndef HAVE_LINUXTHREADS
+ /* Restore UID/GID to root */
+ setperms(0, 0);
+#endif /* HAVE_LINUXTHREADS */
+
+ if (fd == -1) {
+#ifndef HAVE_LINUXTHREADS
+ fd = safe_open(filename, mode, ISC_FALSE);
+ if (fd != -1) {
+ ns_main_earlywarning("Required root "
+ "permissions to open "
+ "'%s'.", filename);
+ } else {
+ ns_main_earlywarning("Could not open "
+ "'%s'.", filename);
+ }
+ ns_main_earlywarning("Please check file and "
+ "directory permissions "
+ "or reconfigure the filename.");
+#else /* HAVE_LINUXTHREADS */
+ ns_main_earlywarning("Could not open "
+ "'%s'.", filename);
+ ns_main_earlywarning("Please check file and "
+ "directory permissions "
+ "or reconfigure the filename.");
+#endif /* HAVE_LINUXTHREADS */
+ }
+ } else {
+ fd = safe_open(filename, mode, ISC_FALSE);
+ }
+
+ if (fd < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("could not open file '%s': %s",
+ filename, strbuf);
+ return (NULL);
+ }
+
+ fp = fdopen(fd, "w");
+ if (fp == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("could not fdopen() file '%s': %s",
+ filename, strbuf);
+ }
+
+ return (fp);
+}
+
void
ns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
- int fd;
FILE *lockfile;
- size_t len;
pid_t pid;
char strbuf[ISC_STRERRORSIZE];
void (*report)(const char *, ...);
@@ -725,40 +861,16 @@ ns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
if (filename == NULL)
return;
- len = strlen(filename);
- pidfile = malloc(len + 1);
+ pidfile = strdup(filename);
if (pidfile == NULL) {
isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("couldn't malloc '%s': %s", filename, strbuf);
+ (*report)("couldn't strdup() '%s': %s", filename, strbuf);
return;
}
- /* This is safe. */
- strcpy(pidfile, filename);
-
- /*
- * Make the containing directory if it doesn't exist.
- */
- if (mkdirpath(pidfile, report) == -1) {
- free(pidfile);
- pidfile = NULL;
- return;
- }
-
- fd = safe_open(filename, ISC_FALSE);
- if (fd < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("couldn't open pid file '%s': %s", filename, strbuf);
- free(pidfile);
- pidfile = NULL;
- return;
- }
- lockfile = fdopen(fd, "w");
+ lockfile = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
+ first_time);
if (lockfile == NULL) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("could not fdopen() pid file '%s': %s",
- filename, strbuf);
- (void)close(fd);
cleanup_pidfile();
return;
}
diff --git a/bin/named/update.c b/bin/named/update.c
index 1504a44b5ad..eb1ed1d64ef 100644
--- a/bin/named/update.c
+++ b/bin/named/update.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.151.12.11 2010-02-26 23:48:43 tbox Exp $ */
+/* $Id: update.c,v 1.186.16.1.2.1 2011-06-02 23:47:28 tbox Exp $ */
#include
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -45,6 +46,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -280,6 +282,47 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
}
}
+/*%
+ * Check if we could have queried for the contents of this zone or
+ * if the zone is potentially updateable.
+ * If the zone can potentially be updated and the check failed then
+ * log a error otherwise we log a informational message.
+ */
+static isc_result_t
+checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename,
+ dns_acl_t *updateacl, dns_ssutable_t *ssutable)
+{
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char classbuf[DNS_RDATACLASS_FORMATSIZE];
+ int level;
+ isc_result_t result;
+
+ result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
+ if (result != ISC_R_SUCCESS) {
+ dns_name_format(zonename, namebuf, sizeof(namebuf));
+ dns_rdataclass_format(client->view->rdclass, classbuf,
+ sizeof(classbuf));
+
+ level = (updateacl == NULL && ssutable == NULL) ?
+ ISC_LOG_INFO : ISC_LOG_ERROR;
+
+ ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+ NS_LOGMODULE_UPDATE, level,
+ "update '%s/%s' denied due to allow-query",
+ namebuf, classbuf);
+ } else if (updateacl == NULL && ssutable == NULL) {
+ dns_name_format(zonename, namebuf, sizeof(namebuf));
+ dns_rdataclass_format(client->view->rdclass, classbuf,
+ sizeof(classbuf));
+
+ result = DNS_R_REFUSED;
+ ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+ NS_LOGMODULE_UPDATE, ISC_LOG_INFO,
+ "update '%s/%s' denied", namebuf, classbuf);
+ }
+ return (result);
+}
+
/*%
* Override the default acl logging when checking whether a client
* can update the zone or whether we can forward the request to the
@@ -809,6 +852,9 @@ typedef struct {
/* The ssu table to check against. */
dns_ssutable_t *table;
+
+ /* the key used for TKEY requests */
+ dst_key_t *key;
} ssu_check_t;
static isc_result_t
@@ -825,14 +871,14 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) {
return (ISC_R_SUCCESS);
result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer,
ssuinfo->name, ssuinfo->tcpaddr,
- rrset->type);
+ rrset->type, ssuinfo->key);
return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE);
}
static isc_boolean_t
ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_ssutable_t *ssutable, dns_name_t *signer,
- isc_netaddr_t *tcpaddr)
+ isc_netaddr_t *tcpaddr, dst_key_t *key)
{
isc_result_t result;
ssu_check_t ssuinfo;
@@ -841,6 +887,7 @@ ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
ssuinfo.table = ssutable;
ssuinfo.signer = signer;
ssuinfo.tcpaddr = tcpaddr;
+ ssuinfo.key = key;
result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo);
return (ISC_TF(result == ISC_R_SUCCESS));
}
@@ -889,7 +936,7 @@ temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) {
b->op == DNS_DIFFOP_EXISTS);
INSIST(a->rdata.type == b->rdata.type);
INSIST(dns_name_equal(&a->name, &b->name));
- if (dns_rdata_compare(&a->rdata, &b->rdata) != 0)
+ if (dns_rdata_casecompare(&a->rdata, &b->rdata) != 0)
return (DNS_R_NXRRSET);
a = ISC_LIST_NEXT(a, link);
b = ISC_LIST_NEXT(b, link);
@@ -917,7 +964,7 @@ temp_order(const void *av, const void *bv) {
r = (b->rdata.type - a->rdata.type);
if (r != 0)
return (r);
- r = dns_rdata_compare(&a->rdata, &b->rdata);
+ r = dns_rdata_casecompare(&a->rdata, &b->rdata);
return (r);
}
@@ -1146,7 +1193,7 @@ rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
* dns_rdata_equal() (that used dns_name_equal()), since it
* would be faster. Not a priority.
*/
- return (dns_rdata_compare(update_rr, db_rr) == 0 ?
+ return (dns_rdata_casecompare(update_rr, db_rr) == 0 ?
ISC_TRUE : ISC_FALSE);
}
@@ -1208,11 +1255,10 @@ replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
return (ISC_FALSE);
INSIST(db_rr->length >= 4 && update_rr->length >= 4);
/*
- * Replace records added in this UPDATE request.
+ * Replace NSEC3PARAM records that only differ by the
+ * flags field.
*/
if (db_rr->data[0] == update_rr->data[0] &&
- db_rr->data[1] & DNS_NSEC3FLAG_UPDATE &&
- update_rr->data[1] & DNS_NSEC3FLAG_UPDATE &&
memcmp(db_rr->data+2, update_rr->data+2,
update_rr->length - 2) == 0)
return (ISC_TRUE);
@@ -1293,7 +1339,7 @@ add_rr_prepare_action(void *data, rr_t *rr) {
* If the update RR is a "duplicate" of the update RR,
* the update should be silently ignored.
*/
- equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0);
+ equal = ISC_TF(dns_rdata_casecompare(&rr->rdata, ctx->update_rr) == 0);
if (equal && rr->ttl == ctx->update_rr_ttl) {
ctx->ignore_add = ISC_TRUE;
return (ISC_R_SUCCESS);
@@ -1717,35 +1763,6 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
return (result);
}
-static isc_boolean_t
-has_opt_bit(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- isc_boolean_t has_bit = ISC_FALSE;
-
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
- dns_rdatatype_none, 0, &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
- has_bit = dns_nsec_typepresent(&rdata, dns_rdatatype_opt);
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (has_bit);
-}
-
-static void
-set_bit(unsigned char *array, unsigned int index) {
- unsigned int shift, bit;
-
- shift = 7 - (index % 8);
- bit = 1 << shift;
-
- array[index / 8] |= bit;
-}
-
/*%
* Add a NSEC record for "name", recording the change in "diff".
* The existing NSEC is removed.
@@ -1777,24 +1794,6 @@ add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
dns_rdata_init(&rdata);
CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));
- /*
- * Preserve the status of the OPT bit in the origin's NSEC record.
- */
- if (dns_name_equal(dns_db_origin(db), name) &&
- has_opt_bit(db, ver, node))
- {
- isc_region_t region;
- dns_name_t next;
-
- dns_name_init(&next, NULL);
- dns_rdata_toregion(&rdata, ®ion);
- dns_name_fromregion(&next, ®ion);
- isc_region_consume(®ion, next.length);
- INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
- region.base[0] == 0 &&
- region.base[1] > dns_rdatatype_opt / 8);
- set_bit(region.base + 2, dns_rdatatype_opt);
- }
dns_db_detachnode(db, &node);
/*
@@ -1856,44 +1855,6 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
return (result);
}
-static isc_boolean_t
-ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
- isc_boolean_t ret = ISC_FALSE;
- isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_dnskey_t dnskey;
-
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
- &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
- if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
- == DNS_KEYOWNER_ZONE) {
- if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
- have_ksk = ISC_TRUE;
- else
- have_nonksk = ISC_TRUE;
- }
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- if (have_ksk && have_nonksk)
- ret = ISC_TRUE;
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (ret);
-}
-
/*%
* Add RRSIG records for an RRset, recording the change in "diff".
*/
@@ -1902,7 +1863,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type,
dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk)
+ isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
{
isc_result_t result;
dns_dbnode_t *node = NULL;
@@ -1910,7 +1871,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
isc_buffer_t buffer;
unsigned char data[1024]; /* XXX */
- unsigned int i;
+ unsigned int i, j;
isc_boolean_t added_sig = ISC_FALSE;
isc_mem_t *mctx = client->mctx;
@@ -1926,15 +1887,54 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
(isc_stdtime_t) 0, &rdataset, NULL));
dns_db_detachnode(db, &node);
- for (i = 0; i < nkeys; i++) {
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
+#define ALG(x) dst_key_alg(x)
- if (check_ksk && type != dns_rdatatype_dnskey &&
- (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
- continue;
+ /*
+ * If we are honoring KSK flags then we need to check that we
+ * have both KSK and non-KSK keys that are not revoked per
+ * algorithm.
+ */
+ for (i = 0; i < nkeys; i++) {
+ isc_boolean_t both = ISC_FALSE;
if (!dst_key_isprivate(keys[i]))
continue;
+ if (check_ksk && !REVOKE(keys[i])) {
+ isc_boolean_t have_ksk, have_nonksk;
+ if (KSK(keys[i])) {
+ have_ksk = ISC_TRUE;
+ have_nonksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_nonksk = ISC_TRUE;
+ }
+ for (j = 0; j < nkeys; j++) {
+ if (j == i || ALG(keys[i]) != ALG(keys[j]))
+ continue;
+ if (REVOKE(keys[j]))
+ continue;
+ if (KSK(keys[j]))
+ have_ksk = ISC_TRUE;
+ else
+ have_nonksk = ISC_TRUE;
+ both = have_ksk && have_nonksk;
+ if (both)
+ break;
+ }
+ }
+
+ if (both) {
+ if (type == dns_rdatatype_dnskey) {
+ if (!KSK(keys[i]) && keyset_kskonly)
+ continue;
+ } else if (KSK(keys[i]))
+ continue;
+ } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
+ continue;
+
/* Calculate the signature, creating a RRSIG RDATA. */
CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
&inception, &expire,
@@ -1950,7 +1950,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
}
if (!added_sig) {
update_log(client, zone, ISC_LOG_ERROR,
- "found no private keys, "
+ "found no active private keys, "
"unable to generate any signatures");
result = ISC_R_NOTFOUND;
}
@@ -2044,7 +2044,7 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t cut,
dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk)
+ isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
{
isc_result_t result;
dns_dbnode_t *node;
@@ -2090,7 +2090,8 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
if (flag)
continue;;
result = add_sigs(client, zone, db, ver, name, type, diff,
- keys, nkeys, inception, expire, check_ksk);
+ keys, nkeys, inception, expire,
+ check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS)
goto cleanup_iterator;
}
@@ -2120,8 +2121,7 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
static isc_result_t
update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *oldver, dns_dbversion_t *newver,
- dns_diff_t *diff, isc_uint32_t sigvalidityinterval,
- isc_boolean_t *deleted_zsk)
+ dns_diff_t *diff, isc_uint32_t sigvalidityinterval)
{
isc_result_t result;
dns_difftuple_t *t;
@@ -2130,7 +2130,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_diff_t sig_diff;
dns_diff_t nsec_diff;
dns_diff_t nsec_mindiff;
- isc_boolean_t flag;
+ isc_boolean_t flag, build_nsec, build_nsec3;
dst_key_t *zone_keys[MAXZONEKEYS];
unsigned int nkeys = 0;
unsigned int i;
@@ -2140,9 +2140,10 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_t rdataset;
dns_dbnode_t *node = NULL;
- isc_boolean_t check_ksk;
+ isc_boolean_t check_ksk, keyset_kskonly;
isc_boolean_t unsecure;
isc_boolean_t cut;
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
dns_diff_init(client->mctx, &diffnames);
dns_diff_init(client->mctx, &affected);
@@ -2172,27 +2173,8 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
*/
check_ksk = ISC_TF((dns_zone_getoptions(zone) &
DNS_ZONEOPT_UPDATECHECKKSK) != 0);
- /*
- * If we are not checking the ZSK flag then all DNSKEY's are
- * already signing all RRsets so we don't need to trigger special
- * changes.
- */
- if (*deleted_zsk && (!check_ksk || !ksk_sanity(db, oldver)))
- *deleted_zsk = ISC_FALSE;
-
- if (check_ksk) {
- check_ksk = ksk_sanity(db, newver);
- if (!check_ksk && ksk_sanity(db, oldver))
- update_log(client, zone, ISC_LOG_WARNING,
- "disabling update-check-ksk");
- }
-
- /*
- * If we have deleted a ZSK and we we still have some ZSK's
- * we don't need to convert the KSK's to a ZSK's.
- */
- if (*deleted_zsk && check_ksk)
- *deleted_zsk = ISC_FALSE;
+ keyset_kskonly = ISC_TF((dns_zone_getoptions(zone) &
+ DNS_ZONEOPT_DNSKEYKSKONLY) != 0);
/*
* Get the NSEC/NSEC3 TTL from the SOA MINIMUM field.
@@ -2259,7 +2241,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, name,
type, &sig_diff, zone_keys,
nkeys, inception, expire,
- check_ksk));
+ check_ksk, keyset_kskonly));
}
skip:
/* Skip any other updates to the same RRset. */
@@ -2289,12 +2271,11 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
"removed any orphaned NSEC records");
/*
- * If we don't have a NSEC record at the origin then we need to
- * update the NSEC3 records.
+ * See if we need to build NSEC or NSEC3 chains.
*/
- CHECK(rrset_exists(db, newver, dns_db_origin(db), dns_rdatatype_nsec,
- 0, &flag));
- if (!flag)
+ CHECK(dns_private_chains(db, newver, privatetype, &build_nsec,
+ &build_nsec3));
+ if (!build_nsec)
goto update_nsec3;
update_log(client, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC chain");
@@ -2398,16 +2379,25 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdatatype_any, 0, NULL, diff));
} else {
/*
- * This name is not obscured. It should have a NSEC.
+ * This name is not obscured. It needs to have a
+ * NSEC unless it is the at the origin, in which
+ * case it should already exist if there is a complete
+ * NSEC chain and if there isn't a complete NSEC chain
+ * we don't want to add one as that would signal that
+ * there is a complete NSEC chain.
*/
- CHECK(rrset_exists(db, newver, name,
- dns_rdatatype_nsec, 0, &flag));
- if (! flag)
- CHECK(add_placeholder_nsec(db, newver, name,
- diff));
+ if (!dns_name_equal(name, dns_db_origin(db))) {
+ CHECK(rrset_exists(db, newver, name,
+ dns_rdatatype_nsec, 0,
+ &flag));
+ if (!flag)
+ CHECK(add_placeholder_nsec(db, newver,
+ name, diff));
+ }
CHECK(add_exposed_sigs(client, zone, db, newver, name,
cut, diff, zone_keys, nkeys,
- inception, expire, check_ksk));
+ inception, expire, check_ksk,
+ keyset_kskonly));
}
}
@@ -2469,7 +2459,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, &t->name,
dns_rdatatype_nsec, &sig_diff,
zone_keys, nkeys, inception, expire,
- check_ksk));
+ check_ksk, keyset_kskonly));
} else {
INSIST(0);
}
@@ -2491,13 +2481,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
- /*
- * Check if we have any active NSEC3 chains by looking for a
- * NSEC3PARAM RRset.
- */
- CHECK(rrset_exists(db, newver, dns_db_origin(db),
- dns_rdatatype_nsec3param, 0, &flag));
- if (!flag) {
+ if (!build_nsec3) {
update_log(client, zone, ISC_LOG_DEBUG(3),
"no NSEC3 chains to rebuild");
goto failure;
@@ -2521,6 +2505,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
isc_boolean_t ns_existed, dname_existed;
isc_boolean_t ns_exists, dname_exists;
+ isc_boolean_t exists, existed;
if (t->rdata.type == dns_rdatatype_nsec ||
t->rdata.type == dns_rdatatype_rrsig) {
@@ -2539,7 +2524,9 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(rrset_exists(db, newver, name, dns_rdatatype_dname, 0,
&dname_exists));
- if ((ns_exists || dname_exists) == (ns_existed || dname_existed))
+ exists = ns_exists || dname_exists;
+ existed = ns_existed || dname_existed;
+ if (exists == existed)
goto nextname;
/*
* There was a delegation change. Mark all subdomains
@@ -2563,14 +2550,16 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
if (!flag) {
CHECK(delete_if(rrsig_p, db, newver, name,
dns_rdatatype_any, 0, NULL, diff));
- CHECK(dns_nsec3_delnsec3s(db, newver, name,
- &nsec_diff));
+ CHECK(dns_nsec3_delnsec3sx(db, newver, name,
+ privatetype, &nsec_diff));
} else {
CHECK(add_exposed_sigs(client, zone, db, newver, name,
cut, diff, zone_keys, nkeys,
- inception, expire, check_ksk));
- CHECK(dns_nsec3_addnsec3s(db, newver, name, nsecttl,
- unsecure, &nsec_diff));
+ inception, expire, check_ksk,
+ keyset_kskonly));
+ CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl,
+ unsecure, privatetype,
+ &nsec_diff));
}
}
@@ -2601,7 +2590,8 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, &t->name,
dns_rdatatype_nsec3,
&sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk));
+ inception, expire, check_ksk,
+ keyset_kskonly));
} else {
INSIST(0);
}
@@ -2734,6 +2724,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
+ case dns_zone_dlz:
/*
* We can now fail due to a bad signature as we now know
* that we are the master.
@@ -2943,7 +2934,7 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = dns_rdataset_next(&rdataset)) {
dns_rdata_t myrdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &myrdata);
- if (!dns_rdata_compare(&myrdata, rdata))
+ if (!dns_rdata_casecompare(&myrdata, rdata))
break;
}
dns_rdataset_disassociate(&rdataset);
@@ -2961,7 +2952,9 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
}
static isc_result_t
-get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
+get_iterations(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype,
+ unsigned int *iterationsp)
+{
dns_dbnode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
dns_rdataset_t rdataset;
@@ -2975,9 +2968,8 @@ get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
return (result);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
0, (isc_stdtime_t) 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND)
- goto success;
+ goto try_private;
if (result != ISC_R_SUCCESS)
goto failure;
@@ -2995,11 +2987,46 @@ get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
if (result != ISC_R_NOMORE)
goto failure;
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+
+ result = dns_db_findrdataset(db, node, ver, privatetype,
+ 0, (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t private = DNS_RDATA_INIT;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
+ if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
+ continue;
+ if (nsec3param.iterations > iterations)
+ iterations = nsec3param.iterations;
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
success:
*iterationsp = iterations;
result = ISC_R_SUCCESS;
failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
return (result);
@@ -3013,77 +3040,83 @@ static isc_result_t
check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_diff_t *diff)
{
- dns_diff_t temp_diff;
- dns_diffop_t op;
- dns_difftuple_t *tuple, *newtuple = NULL, *next;
- isc_boolean_t flag;
+ dns_difftuple_t *tuple;
+ isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
isc_result_t result;
unsigned int iterations = 0, max;
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
- dns_diff_init(diff->mctx, &temp_diff);
+ /* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ if (tuple->op != DNS_DIFFOP_ADD)
+ continue;
- CHECK(dns_nsec_nseconly(db, ver, &flag));
+ if (tuple->rdata.type == dns_rdatatype_dnskey) {
+ isc_uint8_t alg;
+ alg = tuple->rdata.data[3];
+ if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
+ alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
+ nseconly = ISC_TRUE;
+ break;
+ }
+ } else if (tuple->rdata.type == dns_rdatatype_nsec3param) {
+ nsec3 = ISC_TRUE;
+ break;
+ }
+ }
- if (flag)
- CHECK(dns_nsec3_active(db, ver, ISC_FALSE, &flag));
- if (flag) {
- update_log(client, zone, ISC_LOG_WARNING,
+ /* Check existing DB for NSEC-only DNSKEY */
+ if (!nseconly)
+ CHECK(dns_nsec_nseconly(db, ver, &nseconly));
+
+ /* Check existing DB for NSEC3 */
+ if (!nsec3)
+ CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
+ privatetype, &nsec3));
+
+ /* Refuse to allow NSEC3 with NSEC-only keys */
+ if (nseconly && nsec3) {
+ update_log(client, zone, ISC_LOG_ERROR,
"NSEC only DNSKEYs and NSEC3 chains not allowed");
- } else {
- CHECK(get_iterations(db, ver, &iterations));
- CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max));
- if (max != 0 && iterations > max) {
- flag = ISC_TRUE;
- update_log(client, zone, ISC_LOG_WARNING,
- "too many NSEC3 iterations (%u) for "
- "weakest DNSKEY (%u)", iterations, max);
- }
- }
- if (flag) {
- for (tuple = ISC_LIST_HEAD(diff->tuples);
- tuple != NULL;
- tuple = next) {
- next = ISC_LIST_NEXT(tuple, link);
- if (tuple->rdata.type != dns_rdatatype_dnskey &&
- tuple->rdata.type != dns_rdatatype_nsec3param)
- continue;
- op = (tuple->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(temp_diff.mctx, op,
- &tuple->name, tuple->ttl,
- &tuple->rdata, &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff));
- INSIST(newtuple == NULL);
- }
- for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
- tuple != NULL;
- tuple = ISC_LIST_HEAD(temp_diff.tuples)) {
- ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
- dns_diff_appendminimal(diff, &tuple);
- }
+ result = DNS_R_REFUSED;
+ goto failure;
}
+ /* Verify NSEC3 params */
+ CHECK(get_iterations(db, ver, privatetype, &iterations));
+ CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max));
+ if (max != 0 && iterations > max) {
+ update_log(client, zone, ISC_LOG_ERROR,
+ "too many NSEC3 iterations (%u) for "
+ "weakest DNSKEY (%u)", iterations, max);
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
failure:
- dns_diff_clear(&temp_diff);
return (result);
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
/*
* Delay NSEC3PARAM changes as they need to be applied to the whole zone.
*/
static isc_result_t
add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_name_t *name, dns_dbversion_t *ver, dns_diff_t *diff)
+ dns_dbversion_t *ver, dns_diff_t *diff)
{
isc_result_t result = ISC_R_SUCCESS;
dns_difftuple_t *tuple, *newtuple = NULL, *next;
dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
dns_diff_t temp_diff;
dns_diffop_t op;
isc_boolean_t flag;
+ dns_name_t *name = dns_zone_getorigin(zone);
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
+ isc_uint32_t ttl = 0;
+ isc_boolean_t ttl_good = ISC_FALSE;
update_log(client, zone, ISC_LOG_DEBUG(3),
"checking for NSEC3PARAM changes");
@@ -3106,55 +3139,143 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
ISC_LIST_APPEND(temp_diff.tuples, tuple, link);
}
+ /*
+ * Extract TTL changes pairs, we don't need to convert these to
+ * delayed changes.
+ */
for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
tuple != NULL; tuple = next) {
-
if (tuple->op == DNS_DIFFOP_ADD) {
- next = ISC_LIST_NEXT(tuple, link);
+ if (!ttl_good) {
+ /*
+ * Any adds here will contain the final
+ * NSEC3PARAM RRset TTL.
+ */
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ /*
+ * Walk the temp_diff list looking for the
+ * corresponding delete.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
while (next != NULL) {
unsigned char *next_data = next->rdata.data;
unsigned char *tuple_data = tuple->rdata.data;
- if (next_data[0] != tuple_data[0] ||
- /* Ignore flags. */
+ if (next->op == DNS_DIFFOP_DEL &&
+ next->rdata.length == tuple->rdata.length &&
+ !memcmp(next_data, tuple_data,
+ next->rdata.length)) {
+ ISC_LIST_UNLINK(temp_diff.tuples, next,
+ link);
+ ISC_LIST_APPEND(diff->tuples, next,
+ link);
+ break;
+ }
+ next = ISC_LIST_NEXT(next, link);
+ }
+ /*
+ * If we have not found a pair move onto the next
+ * tuple.
+ */
+ if (next == NULL) {
+ next = ISC_LIST_NEXT(tuple, link);
+ continue;
+ }
+ /*
+ * Find the next tuple to be processed before
+ * unlinking then complete moving the pair to 'diff'.
+ */
+ next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+ } else
+ next = ISC_LIST_NEXT(tuple, link);
+ }
+
+ /*
+ * Preserve any ongoing changes from a BIND 9.6.x upgrade.
+ *
+ * Any NSEC3PARAM records with flags other than OPTOUT named
+ * in managing and should not be touched so revert such changes
+ * taking into account any TTL change of the NSEC3PARAM RRset.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ next = ISC_LIST_NEXT(tuple, link);
+ if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) {
+ /*
+ * If we havn't had any adds then the tuple->ttl must
+ * be the original ttl and should be used for any
+ * future changes.
+ */
+ if (!ttl_good) {
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ op = (tuple->op == DNS_DIFFOP_DEL) ?
+ DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
+ CHECK(dns_difftuple_create(diff->mctx, op, name,
+ ttl, &tuple->rdata,
+ &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ dns_diff_appendminimal(diff, &tuple);
+ }
+ }
+
+ /*
+ * We now have just the actual changes to the NSEC3PARAM RRset.
+ * Convert the adds to delayed adds and the deletions into delayed
+ * deletions.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ /*
+ * If we havn't had any adds then the tuple->ttl must be the
+ * original ttl and should be used for any future changes.
+ */
+ if (!ttl_good) {
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ if (tuple->op == DNS_DIFFOP_ADD) {
+ /*
+ * Look for any deletes which match this ADD ignoring
+ * OPTOUT. We don't need to explictly remove them as
+ * they will be removed a side effect of processing
+ * the add.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
+ while (next != NULL) {
+ unsigned char *next_data = next->rdata.data;
+ unsigned char *tuple_data = tuple->rdata.data;
+ if (next->op != DNS_DIFFOP_DEL ||
+ next->rdata.length != tuple->rdata.length ||
+ next_data[0] != tuple_data[0] ||
next_data[2] != tuple_data[2] ||
next_data[3] != tuple_data[3] ||
- next_data[4] != tuple_data[4] ||
- !memcmp(&next_data[5], &tuple_data[5],
- tuple_data[4])) {
+ memcmp(next_data + 4, tuple_data + 4,
+ tuple->rdata.length - 4)) {
next = ISC_LIST_NEXT(next, link);
continue;
}
- op = (next->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(diff->mctx, op,
- name, next->ttl,
- &next->rdata,
- &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, diff));
ISC_LIST_UNLINK(temp_diff.tuples, next, link);
- dns_diff_appendminimal(diff, &next);
- next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_APPEND(diff->tuples, next, link);
+ next = ISC_LIST_HEAD(temp_diff.tuples);
}
-
- INSIST(tuple->rdata.data[1] & DNS_NSEC3FLAG_UPDATE);
-
/*
* See if we already have a CREATE request in progress.
*/
- dns_rdata_clone(&tuple->rdata, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_CREATE;
- buf[1] &= ~DNS_NSEC3FLAG_UPDATE;
- rdata.data = buf;
-
+ dns_nsec3param_toprivate(&tuple->rdata, &rdata,
+ privatetype, buf, sizeof(buf));
+ buf[2] |= DNS_NSEC3FLAG_CREATE;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
if (!flag) {
CHECK(dns_difftuple_create(diff->mctx,
DNS_DIFFOP_ADD,
- name, tuple->ttl,
- &rdata,
+ name, 0, &rdata,
&newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
@@ -3164,26 +3285,26 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
* otherwise indentical chain with a reversed
* OPTOUT state.
*/
- buf[1] ^= DNS_NSEC3FLAG_OPTOUT;
+ buf[2] ^= DNS_NSEC3FLAG_OPTOUT;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
if (flag) {
CHECK(dns_difftuple_create(diff->mctx,
DNS_DIFFOP_DEL,
- name, tuple->ttl,
- &rdata,
+ name, 0, &rdata,
&newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
/*
- * Remove the temporary add record.
+ * Find the next tuple to be processed and remove the
+ * temporary add record.
*/
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
- name, tuple->ttl,
- &tuple->rdata, &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, diff));
next = ISC_LIST_NEXT(tuple, link);
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
+ name, ttl, &tuple->rdata,
+ &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
dns_diff_appendminimal(diff, &tuple);
dns_rdata_reset(&rdata);
@@ -3191,50 +3312,33 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
next = ISC_LIST_NEXT(tuple, link);
}
- /*
- * Reverse any pending changes.
- */
for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
tuple != NULL; tuple = next) {
- next = ISC_LIST_NEXT(tuple, link);
- if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) {
- op = (tuple->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(diff->mctx, op, name,
- tuple->ttl, &tuple->rdata,
- &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, diff));
- ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
- dns_diff_appendminimal(diff, &tuple);
- }
- }
- /*
- * Convert deletions into delayed deletions.
- */
- for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
- tuple != NULL; tuple = next) {
+ INSIST(ttl_good);
+
next = ISC_LIST_NEXT(tuple, link);
/*
* See if we already have a REMOVE request in progress.
*/
- dns_rdata_clone(&tuple->rdata, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_REMOVE;
- rdata.data = buf;
+ dns_nsec3param_toprivate(&tuple->rdata, &rdata, privatetype,
+ buf, sizeof(buf));
+
+ buf[2] |= DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ if (!flag) {
+ buf[2] &= ~DNS_NSEC3FLAG_NONSEC;
+ CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ }
if (!flag) {
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- name, tuple->ttl, &rdata,
- &newtuple));
+ name, 0, &rdata, &newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
- tuple->ttl, &tuple->rdata,
- &newtuple));
+ ttl, &tuple->rdata, &newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
dns_diff_appendminimal(diff, &tuple);
@@ -3246,17 +3350,75 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_diff_clear(&temp_diff);
return (result);
}
-#endif
+
+static isc_result_t
+rollback_private(dns_db_t *db, dns_rdatatype_t privatetype,
+ dns_dbversion_t *ver, dns_diff_t *diff)
+{
+ dns_diff_t temp_diff;
+ dns_diffop_t op;
+ dns_difftuple_t *tuple, *newtuple = NULL, *next;
+ dns_name_t *name = dns_db_origin(db);
+ isc_mem_t *mctx = diff->mctx;
+ isc_result_t result;
+
+ if (privatetype == 0)
+ return (ISC_R_SUCCESS);
+
+ dns_diff_init(mctx, &temp_diff);
+
+ /*
+ * Extract the changes to be rolled back.
+ */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL; tuple = next) {
+
+ next = ISC_LIST_NEXT(tuple, link);
+
+ if (tuple->rdata.type != privatetype ||
+ !dns_name_equal(name, &tuple->name))
+ continue;
+
+ /*
+ * Allow records which indicate that a zone has been
+ * signed with a DNSKEY to be be removed.
+ */
+ if (tuple->op == DNS_DIFFOP_DEL &&
+ tuple->rdata.length == 5 &&
+ tuple->rdata.data[0] != 0 &&
+ tuple->rdata.data[4] != 0)
+ continue;
+
+ ISC_LIST_UNLINK(diff->tuples, tuple, link);
+ ISC_LIST_PREPEND(temp_diff.tuples, tuple, link);
+ }
+
+ /*
+ * Rollback the changes.
+ */
+ while ((tuple = ISC_LIST_HEAD(temp_diff.tuples)) != NULL) {
+ op = (tuple->op == DNS_DIFFOP_DEL) ?
+ DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
+ CHECK(dns_difftuple_create(mctx, op, name, tuple->ttl,
+ &tuple->rdata, &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff));
+ }
+ result = ISC_R_SUCCESS;
+
+ failure:
+ dns_diff_clear(&temp_diff);
+ return (result);
+}
/*
* Add records to cause the delayed signing of the zone by added DNSKEY
* to remove the RRSIG records generated by a deleted DNSKEY.
*/
static isc_result_t
-add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
- dns_rdatatype_t privatetype, dns_diff_t *diff)
+add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
+ dns_dbversion_t *ver, dns_diff_t *diff)
{
- dns_difftuple_t *tuple, *newtuple = NULL;
+ dns_difftuple_t *tuple, *newtuple = NULL, *next;
dns_rdata_dnskey_t dnskey;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_boolean_t flag;
@@ -3264,13 +3426,82 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
isc_result_t result = ISC_R_SUCCESS;
isc_uint16_t keyid;
unsigned char buf[5];
+ dns_name_t *name = dns_db_origin(db);
+ dns_diff_t temp_diff;
+ dns_diff_init(diff->mctx, &temp_diff);
+
+ /*
+ * Extract the DNSKEY tuples from the list.
+ */
for (tuple = ISC_LIST_HEAD(diff->tuples);
- tuple != NULL;
- tuple = ISC_LIST_NEXT(tuple, link)) {
+ tuple != NULL; tuple = next) {
+
+ next = ISC_LIST_NEXT(tuple, link);
+
if (tuple->rdata.type != dns_rdatatype_dnskey)
continue;
+ ISC_LIST_UNLINK(diff->tuples, tuple, link);
+ ISC_LIST_APPEND(temp_diff.tuples, tuple, link);
+ }
+
+ /*
+ * Extract TTL changes pairs, we don't need signing records for these.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ if (tuple->op == DNS_DIFFOP_ADD) {
+ /*
+ * Walk the temp_diff list looking for the
+ * corresponding delete.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
+ while (next != NULL) {
+ unsigned char *next_data = next->rdata.data;
+ unsigned char *tuple_data = tuple->rdata.data;
+ if (next->op == DNS_DIFFOP_DEL &&
+ dns_name_equal(&tuple->name, &next->name) &&
+ next->rdata.length == tuple->rdata.length &&
+ !memcmp(next_data, tuple_data,
+ next->rdata.length)) {
+ ISC_LIST_UNLINK(temp_diff.tuples, next,
+ link);
+ ISC_LIST_APPEND(diff->tuples, next,
+ link);
+ break;
+ }
+ next = ISC_LIST_NEXT(next, link);
+ }
+ /*
+ * If we have not found a pair move onto the next
+ * tuple.
+ */
+ if (next == NULL) {
+ next = ISC_LIST_NEXT(tuple, link);
+ continue;
+ }
+ /*
+ * Find the next tuple to be processed before
+ * unlinking then complete moving the pair to 'diff'.
+ */
+ next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+ } else
+ next = ISC_LIST_NEXT(tuple, link);
+ }
+
+ /*
+ * Process the remaining DNSKEY entries.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_HEAD(temp_diff.tuples)) {
+
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+
dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
if ((dnskey.flags &
(DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
@@ -3278,6 +3509,7 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
continue;
dns_rdata_toregion(&tuple->rdata, &r);
+
keyid = dst_region_computeid(&r, dnskey.algorithm);
buf[0] = dnskey.algorithm;
@@ -3310,87 +3542,25 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
INSIST(newtuple == NULL);
}
}
+
failure:
+ dns_diff_clear(&temp_diff);
return (result);
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
-/*
- * Mark all NSEC3 chains for deletion without creating a NSEC chain as
- * a side effect of deleting the last chain.
- */
-static isc_result_t
-delete_chains(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
- dns_diff_t *diff)
-{
- dns_dbnode_t *node = NULL;
- dns_difftuple_t *tuple = NULL;
- dns_name_t next;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- isc_boolean_t flag;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+static isc_boolean_t
+isdnssec(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype) {
+ isc_result_t result;
+ isc_boolean_t build_nsec, build_nsec3;
- dns_name_init(&next, NULL);
- dns_rdataset_init(&rdataset);
+ if (dns_db_issecure(db))
+ return (ISC_TRUE);
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Cause all NSEC3 chains to be deleted.
- */
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
- 0, (isc_stdtime_t) 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
- dns_rdataset_current(&rdataset, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
-
- if (buf[1] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
- dns_rdata_reset(&rdata);
- continue;
- }
-
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
- origin, 0, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
-
- buf[1] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
- rdata.data = buf;
-
- CHECK(rr_exists(db, ver, origin, &rdata, &flag));
-
- if (!flag) {
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- origin, 0, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
- }
- dns_rdata_reset(&rdata);
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- success:
- result = ISC_R_SUCCESS;
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- return (result);
+ result = dns_private_chains(db, ver, privatetype,
+ &build_nsec, &build_nsec3);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ return (build_nsec || build_nsec3);
}
-#endif
static void
update_action(isc_task_t *task, isc_event_t *event) {
@@ -3414,15 +3584,10 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_fixedname_t tmpnamefixed;
dns_name_t *tmpname = NULL;
unsigned int options;
- isc_boolean_t deleted_zsk;
dns_difftuple_t *tuple;
dns_rdata_dnskey_t dnskey;
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
-#endif
-#if !defined(ALLOW_SECURE_TO_INSECURE) || !defined(ALLOW_INSECURE_TO_SECURE)
isc_boolean_t had_dnskey;
-#endif
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
INSIST(event->ev_type == DNS_EVENT_UPDATE);
@@ -3433,6 +3598,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
zonename = dns_db_origin(db);
zoneclass = dns_db_class(db);
dns_zone_getssutable(zone, &ssutable);
+
+ /*
+ * Update message processing can leak record existance information
+ * so check that we are allowed to query this zone. Additionally
+ * if we would refuse all updates for this zone we bail out here.
+ */
+ CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename,
+ dns_zone_getupdateacl(zone), ssutable));
+
+ /*
+ * Get old and new versions now that queryacl has been checked.
+ */
dns_db_currentversion(db, &oldver);
CHECK(dns_db_newversion(db, &ver));
@@ -3525,7 +3702,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_NOMORE)
FAIL(result);
-
/*
* Perform the final check of the "rrset exists (value dependent)"
* prerequisites.
@@ -3619,31 +3795,31 @@ update_action(isc_task_t *task, isc_event_t *event) {
update_class);
FAIL(DNS_R_FORMERR);
}
+
/*
* draft-ietf-dnsind-simple-secure-update-01 says
* "Unlike traditional dynamic update, the client
* is forbidden from updating NSEC records."
*/
- if (dns_db_issecure(db)) {
- if (rdata.type == dns_rdatatype_nsec3) {
- FAILC(DNS_R_REFUSED,
- "explicit NSEC3 updates are not allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_nsec) {
- FAILC(DNS_R_REFUSED,
- "explicit NSEC updates are not allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_rrsig &&
- !dns_name_equal(name, zonename)) {
- FAILC(DNS_R_REFUSED,
- "explicit RRSIG updates are currently "
- "not supported in secure zones except "
- "at the apex");
- }
+ if (rdata.type == dns_rdatatype_nsec3) {
+ FAILC(DNS_R_REFUSED,
+ "explicit NSEC3 updates are not allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_nsec) {
+ FAILC(DNS_R_REFUSED,
+ "explicit NSEC updates are not allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_rrsig &&
+ !dns_name_equal(name, zonename)) {
+ FAILC(DNS_R_REFUSED,
+ "explicit RRSIG updates are currently "
+ "not supported in secure zones except "
+ "at the apex");
}
if (ssutable != NULL) {
isc_netaddr_t *tcpaddr, netaddr;
+ dst_key_t *tsigkey = NULL;
/*
* If this is a TCP connection then pass the
* address of the client through for tcp-self
@@ -3656,16 +3832,22 @@ update_action(isc_task_t *task, isc_event_t *event) {
tcpaddr = &netaddr;
} else
tcpaddr = NULL;
+
+ if (client->message->tsigkey != NULL)
+ tsigkey = client->message->tsigkey->key;
+
if (rdata.type != dns_rdatatype_any) {
if (!dns_ssutable_checkrules(ssutable,
client->signer,
name, tcpaddr,
- rdata.type))
+ rdata.type,
+ tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
} else {
if (!ssu_checkall(db, ver, name, ssutable,
- client->signer, tcpaddr))
+ client->signer, tcpaddr,
+ tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
}
@@ -3774,7 +3956,14 @@ update_action(isc_task_t *task, isc_event_t *event) {
soa_serial_changed = ISC_TRUE;
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
+ if (rdata.type == privatetype) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "attempt to add a private type "
+ "(%u) record rejected internal "
+ "use only", privatetype);
+ continue;
+ }
+
if (rdata.type == dns_rdatatype_nsec3param) {
/*
* Ignore attempts to add NSEC3PARAM records
@@ -3788,27 +3977,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
"flag");
continue;
}
-
- /*
- * Set the NSEC3CHAIN creation flag.
- */
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_UPDATE;
- rdata.data = buf;
- /*
- * Force the TTL to zero for NSEC3PARAM records.
- */
- ttl = 0;
}
-#else
- if (rdata.type == dns_rdatatype_nsec3param) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "attempt to add NSEC3PARAM "
- "record ignored");
- continue;
- };
-#endif
if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 &&
dns_name_internalwildcard(name)) {
@@ -3885,13 +4054,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_rdatatype_any, 0,
&rdata, &diff));
}
-#ifndef ALLOW_NSEC3PARAM_UPDATE
- } else if (rdata.type == dns_rdatatype_nsec3param) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "attempt to delete a NSEC3PARAM "
- "records ignored");
- continue;
-#endif
} else if (dns_name_equal(name, zonename) &&
(rdata.type == dns_rdatatype_soa ||
rdata.type == dns_rdatatype_ns)) {
@@ -3920,6 +4082,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
&diff));
}
} else if (update_class == dns_rdataclass_none) {
+ char namestr[DNS_NAME_FORMATSIZE];
+ char typestr[DNS_RDATATYPE_FORMATSIZE];
+
/*
* The (name == zonename) condition appears in
* RFC2136 3.4.2.4 but is missing from the pseudocode.
@@ -3947,11 +4112,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
}
- update_log(client, zone,
- LOGLEVEL_PROTOCOL,
- "deleting an RR");
- CHECK(delete_if(rr_equal_p, db, ver, name,
- rdata.type, covers, &rdata, &diff));
+ dns_name_format(name, namestr, sizeof(namestr));
+ dns_rdatatype_format(rdata.type, typestr,
+ sizeof(typestr));
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "deleting an RR at %s %s", namestr, typestr);
+ CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type,
+ covers, &rdata, &diff));
}
}
if (result != ISC_R_NOMORE)
@@ -3965,6 +4132,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (! ISC_LIST_EMPTY(diff.tuples))
CHECK(check_dnssec(client, zone, db, ver, &diff));
+ if (! ISC_LIST_EMPTY(diff.tuples)) {
+ unsigned int errors = 0;
+ CHECK(dns_zone_nscheck(zone, db, ver, &errors));
+ if (errors != 0) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update rejected: post update name server "
+ "sanity check failed");
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
+ }
+
/*
* If any changes were made, increment the SOA serial number,
* update RRSIGs and NSECs (if zone is secure), and write the update
@@ -3990,37 +4169,29 @@ update_action(isc_task_t *task, isc_event_t *event) {
CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey,
0, &has_dnskey));
-#if !defined(ALLOW_SECURE_TO_INSECURE) || !defined(ALLOW_INSECURE_TO_SECURE)
- CHECK(rrset_exists(db, oldver, zonename, dns_rdatatype_dnskey,
- 0, &had_dnskey));
+#define ALLOW_SECURE_TO_INSECURE(zone) \
+ ((dns_zone_getoptions(zone) & DNS_ZONEOPT_SECURETOINSECURE) != 0)
-#ifndef ALLOW_SECURE_TO_INSECURE
- if (had_dnskey && !has_dnskey) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "update rejected: all DNSKEY records "
- "removed");
- result = DNS_R_REFUSED;
- goto failure;
+ if (!ALLOW_SECURE_TO_INSECURE(zone)) {
+ CHECK(rrset_exists(db, oldver, zonename,
+ dns_rdatatype_dnskey, 0,
+ &had_dnskey));
+ if (had_dnskey && !has_dnskey) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update rejected: all DNSKEY "
+ "records removed and "
+ "'dnssec-secure-to-insecure' "
+ "not set");
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
}
-#endif
-#ifndef ALLOW_INSECURE_TO_SECURE
- if (!had_dnskey && has_dnskey) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "update rejected: DNSKEY record added");
- result = DNS_R_REFUSED;
- goto failure;
- }
-#endif
-#endif
- CHECK(add_signing_records(db, zonename, ver,
- dns_zone_getprivatetype(zone),
- &diff));
+ CHECK(rollback_private(db, privatetype, ver, &diff));
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- CHECK(add_nsec3param_records(client, zone, db, zonename,
- ver, &diff));
-#endif
+ CHECK(add_signing_records(db, privatetype, ver, &diff));
+
+ CHECK(add_nsec3param_records(client, zone, db, ver, &diff));
if (!has_dnskey) {
/*
@@ -4029,15 +4200,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
* the last signature for the DNSKEY records are
* remove any NSEC chain present will also be removed.
*/
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- CHECK(delete_chains(db, ver, zonename, &diff));
-#endif
- } else if (has_dnskey && dns_db_isdnssec(db)) {
+ CHECK(dns_nsec3param_deletechains(db, ver, zone,
+ &diff));
+ } else if (has_dnskey && isdnssec(db, ver, privatetype)) {
isc_uint32_t interval;
interval = dns_zone_getsigvalidityinterval(zone);
result = update_signatures(client, zone, db, oldver,
- ver, &diff, interval,
- &deleted_zsk);
+ ver, &diff, interval);
if (result != ISC_R_SUCCESS) {
update_log(client, zone,
ISC_LOG_ERROR,
@@ -4123,7 +4292,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
/*
* Cause the zone to add/delete NSEC3 chains for the
* deferred NSEC3PARAM changes.
@@ -4133,13 +4301,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
for (tuple = ISC_LIST_HEAD(diff.tuples);
tuple != NULL;
tuple = ISC_LIST_NEXT(tuple, link)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3param_t nsec3param;
- if (tuple->rdata.type != dns_rdatatype_nsec3param ||
+ if (tuple->rdata.type != privatetype ||
tuple->op != DNS_DIFFOP_ADD)
continue;
- dns_rdata_tostruct(&tuple->rdata, &nsec3param, NULL);
+ if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ dns_rdata_tostruct(&rdata, &nsec3param, NULL);
if (nsec3param.flags == 0)
continue;
@@ -4150,7 +4323,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_result_totext(result));
}
}
-#endif
} else {
update_log(client, zone, LOGLEVEL_DEBUG, "redundant request");
dns_db_closeversion(db, &ver, ISC_TRUE);
diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c
index e61dc72efda..b036ed14d57 100644
--- a/bin/named/xfrout.c
+++ b/bin/named/xfrout.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.131.26.6 2010-05-27 23:48:18 tbox Exp $ */
+/* $Id: xfrout.c,v 1.139 2010-12-18 01:56:19 each Exp $ */
#include
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -112,43 +113,6 @@
} while (0)
/**************************************************************************/
-/*%
- * A db_rr_iterator_t is an iterator that iterates over an entire database,
- * returning one RR at a time, in some arbitrary order.
- */
-
-typedef struct db_rr_iterator db_rr_iterator_t;
-
-/*% db_rr_iterator structure */
-struct db_rr_iterator {
- isc_result_t result;
- dns_db_t *db;
- dns_dbiterator_t *dbit;
- dns_dbversion_t *ver;
- isc_stdtime_t now;
- dns_dbnode_t *node;
- dns_fixedname_t fixedname;
- dns_rdatasetiter_t *rdatasetit;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata;
-};
-
-static isc_result_t
-db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
- isc_stdtime_t now);
-
-static isc_result_t
-db_rr_iterator_first(db_rr_iterator_t *it);
-
-static isc_result_t
-db_rr_iterator_next(db_rr_iterator_t *it);
-
-static void
-db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdata_t **rdata);
-
-static void
-db_rr_iterator_destroy(db_rr_iterator_t *it);
static inline void
inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
@@ -160,145 +124,6 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
}
}
-static isc_result_t
-db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
- isc_stdtime_t now)
-{
- isc_result_t result;
- it->db = db;
- it->dbit = NULL;
- it->ver = ver;
- it->now = now;
- it->node = NULL;
- result = dns_db_createiterator(it->db, 0, &it->dbit);
- if (result != ISC_R_SUCCESS)
- return (result);
- it->rdatasetit = NULL;
- dns_rdata_init(&it->rdata);
- dns_rdataset_init(&it->rdataset);
- dns_fixedname_init(&it->fixedname);
- INSIST(! dns_rdataset_isassociated(&it->rdataset));
- it->result = ISC_R_SUCCESS;
- return (it->result);
-}
-
-static isc_result_t
-db_rr_iterator_first(db_rr_iterator_t *it) {
- it->result = dns_dbiterator_first(it->dbit);
- /*
- * The top node may be empty when out of zone glue exists.
- * Walk the tree to find the first node with data.
- */
- while (it->result == ISC_R_SUCCESS) {
- it->result = dns_dbiterator_current(it->dbit, &it->node,
- dns_fixedname_name(&it->fixedname));
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- it->result = dns_db_allrdatasets(it->db, it->node,
- it->ver, it->now,
- &it->rdatasetit);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- it->result = dns_rdatasetiter_first(it->rdatasetit);
- if (it->result != ISC_R_SUCCESS) {
- /*
- * This node is empty. Try next node.
- */
- dns_rdatasetiter_destroy(&it->rdatasetit);
- dns_db_detachnode(it->db, &it->node);
- it->result = dns_dbiterator_next(it->dbit);
- continue;
- }
- dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
- it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
- it->result = dns_rdataset_first(&it->rdataset);
- return (it->result);
- }
- return (it->result);
-}
-
-
-static isc_result_t
-db_rr_iterator_next(db_rr_iterator_t *it) {
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- INSIST(it->dbit != NULL);
- INSIST(it->node != NULL);
- INSIST(it->rdatasetit != NULL);
-
- it->result = dns_rdataset_next(&it->rdataset);
- if (it->result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&it->rdataset);
- it->result = dns_rdatasetiter_next(it->rdatasetit);
- /*
- * The while loop body is executed more than once
- * only when an empty dbnode needs to be skipped.
- */
- while (it->result == ISC_R_NOMORE) {
- dns_rdatasetiter_destroy(&it->rdatasetit);
- dns_db_detachnode(it->db, &it->node);
- it->result = dns_dbiterator_next(it->dbit);
- if (it->result == ISC_R_NOMORE) {
- /* We are at the end of the entire database. */
- return (it->result);
- }
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_dbiterator_current(it->dbit,
- &it->node,
- dns_fixedname_name(&it->fixedname));
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_db_allrdatasets(it->db, it->node,
- it->ver, it->now,
- &it->rdatasetit);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_rdatasetiter_first(it->rdatasetit);
- }
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
- it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
- it->result = dns_rdataset_first(&it->rdataset);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- }
- return (it->result);
-}
-
-static void
-db_rr_iterator_pause(db_rr_iterator_t *it) {
- RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
-}
-
-static void
-db_rr_iterator_destroy(db_rr_iterator_t *it) {
- if (dns_rdataset_isassociated(&it->rdataset))
- dns_rdataset_disassociate(&it->rdataset);
- if (it->rdatasetit != NULL)
- dns_rdatasetiter_destroy(&it->rdatasetit);
- if (it->node != NULL)
- dns_db_detachnode(it->db, &it->node);
- dns_dbiterator_destroy(&it->dbit);
-}
-
-static void
-db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdata_t **rdata)
-{
- REQUIRE(name != NULL && *name == NULL);
- REQUIRE(it->result == ISC_R_SUCCESS);
- *name = dns_fixedname_name(&it->fixedname);
- *ttl = it->rdataset.ttl;
- dns_rdata_reset(&it->rdata);
- dns_rdataset_current(&it->rdataset, &it->rdata);
- *rdata = &it->rdata;
-}
-
/**************************************************************************/
/*% Log an RR (for debugging) */
@@ -488,7 +313,7 @@ static rrstream_methods_t ixfr_rrstream_methods = {
typedef struct axfr_rrstream {
rrstream_t common;
- db_rr_iterator_t it;
+ dns_rriterator_t it;
isc_boolean_t it_valid;
} axfr_rrstream_t;
@@ -516,7 +341,7 @@ axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
s->common.methods = &axfr_rrstream_methods;
s->it_valid = ISC_FALSE;
- CHECK(db_rr_iterator_init(&s->it, db, ver, 0));
+ CHECK(dns_rriterator_init(&s->it, db, ver, 0));
s->it_valid = ISC_TRUE;
*sp = (rrstream_t *) s;
@@ -531,7 +356,7 @@ static isc_result_t
axfr_rrstream_first(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
isc_result_t result;
- result = db_rr_iterator_first(&s->it);
+ result = dns_rriterator_first(&s->it);
if (result != ISC_R_SUCCESS)
return (result);
/* Skip SOA records. */
@@ -539,11 +364,11 @@ axfr_rrstream_first(rrstream_t *rs) {
dns_name_t *name_dummy = NULL;
isc_uint32_t ttl_dummy;
dns_rdata_t *rdata = NULL;
- db_rr_iterator_current(&s->it, &name_dummy,
- &ttl_dummy, &rdata);
+ dns_rriterator_current(&s->it, &name_dummy,
+ &ttl_dummy, NULL, &rdata);
if (rdata->type != dns_rdatatype_soa)
break;
- result = db_rr_iterator_next(&s->it);
+ result = dns_rriterator_next(&s->it);
if (result != ISC_R_SUCCESS)
break;
}
@@ -560,11 +385,11 @@ axfr_rrstream_next(rrstream_t *rs) {
dns_name_t *name_dummy = NULL;
isc_uint32_t ttl_dummy;
dns_rdata_t *rdata = NULL;
- result = db_rr_iterator_next(&s->it);
+ result = dns_rriterator_next(&s->it);
if (result != ISC_R_SUCCESS)
break;
- db_rr_iterator_current(&s->it, &name_dummy,
- &ttl_dummy, &rdata);
+ dns_rriterator_current(&s->it, &name_dummy,
+ &ttl_dummy, NULL, &rdata);
if (rdata->type != dns_rdatatype_soa)
break;
}
@@ -576,20 +401,20 @@ axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
dns_rdata_t **rdata)
{
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
- db_rr_iterator_current(&s->it, name, ttl, rdata);
+ dns_rriterator_current(&s->it, name, ttl, NULL, rdata);
}
static void
axfr_rrstream_pause(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
- db_rr_iterator_pause(&s->it);
+ dns_rriterator_pause(&s->it);
}
static void
axfr_rrstream_destroy(rrstream_t **rsp) {
axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
if (s->it_valid)
- db_rr_iterator_destroy(&s->it);
+ dns_rriterator_destroy(&s->it);
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
@@ -1038,6 +863,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_slave:
+ case dns_zone_dlz:
break; /* Master and slave zones are OK for transfer. */
default:
FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class);
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 367ddd320d2..eb93f1bbe45 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.147.50.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: zoneconf.c,v 1.170 2011-01-06 23:47:00 tbox Exp $ */
/*% */
@@ -30,10 +30,16 @@
#include
#include
+#include
#include
#include
#include
+#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
@@ -55,16 +61,18 @@ typedef enum {
allow_update_forwarding
} acl_type_t;
-/*%
- * These are BIND9 server defaults, not necessarily identical to the
- * library defaults defined in zone.c.
- */
#define RETERR(x) do { \
isc_result_t _r = (x); \
if (_r != ISC_R_SUCCESS) \
return (_r); \
} while (0)
+#define CHECK(x) do { \
+ result = (x); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
/*%
* Convenience function for configuring a single zone ACL.
*/
@@ -133,8 +141,11 @@ configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
}
/* Check for default ACLs that haven't been parsed yet */
- if (vconfig != NULL)
- maps[i++] = cfg_tuple_get(vconfig, "options");
+ if (vconfig != NULL) {
+ const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
+ if (options != NULL)
+ maps[i++] = options;
+ }
if (config != NULL) {
const cfg_obj_t *options = NULL;
(void)cfg_map_get(config, "options", &options);
@@ -169,19 +180,29 @@ configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
* Parse the zone update-policy statement.
*/
static isc_result_t
-configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
+configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ const char *zname)
+{
const cfg_obj_t *updatepolicy = NULL;
const cfg_listelt_t *element, *element2;
dns_ssutable_t *table = NULL;
isc_mem_t *mctx = dns_zone_getmctx(zone);
+ isc_boolean_t autoddns = ISC_FALSE;
isc_result_t result;
(void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
+
if (updatepolicy == NULL) {
dns_zone_setssutable(zone, NULL);
return (ISC_R_SUCCESS);
}
+ if (cfg_obj_isstring(updatepolicy) &&
+ strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
+ autoddns = ISC_TRUE;
+ updatepolicy = NULL;
+ }
+
result = dns_ssutable_create(mctx, &table);
if (result != ISC_R_SUCCESS)
return (result);
@@ -198,6 +219,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
const char *str;
isc_boolean_t grant = ISC_FALSE;
+ isc_boolean_t usezone = ISC_FALSE;
unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
dns_fixedname_t fname, fident;
isc_buffer_t b;
@@ -237,6 +259,11 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
mtype = DNS_SSUMATCHTYPE_TCPSELF;
else if (strcasecmp(str, "6to4-self") == 0)
mtype = DNS_SSUMATCHTYPE_6TO4SELF;
+ else if (strcasecmp(str, "zonesub") == 0) {
+ mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
+ usezone = ISC_TRUE;
+ } else if (strcasecmp(str, "external") == 0)
+ mtype = DNS_SSUMATCHTYPE_EXTERNAL;
else
INSIST(0);
@@ -245,7 +272,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -253,15 +280,27 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
}
dns_fixedname_init(&fname);
- str = cfg_obj_asstring(dname);
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
- if (result != ISC_R_SUCCESS) {
- cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
- "'%s' is not a valid name", str);
- goto cleanup;
+ if (usezone) {
+ result = dns_name_copy(dns_zone_getorigin(zone),
+ dns_fixedname_name(&fname),
+ NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
+ "error copying origin: %s",
+ isc_result_totext(result));
+ goto cleanup;
+ }
+ } else {
+ str = cfg_obj_asstring(dname);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ result = dns_name_fromtext(dns_fixedname_name(&fname),
+ &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
+ "'%s' is not a valid name", str);
+ goto cleanup;
+ }
}
n = ns_config_listcount(typelist);
@@ -311,7 +350,34 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
+ }
+ /*
+ * If "update-policy local;" and a session key exists,
+ * then use the default policy, which is equivalent to:
+ * update-policy { grant zonesub any; };
+ */
+ if (autoddns) {
+ dns_rdatatype_t any = dns_rdatatype_any;
+
+ if (ns_g_server->session_keyname == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "failed to enable auto DDNS policy "
+ "for zone %s: session key not found",
+ zname);
+ result = ISC_R_NOTFOUND;
+ goto cleanup;
+ }
+
+ result = dns_ssutable_addrule(table, ISC_TRUE,
+ ns_g_server->session_keyname,
+ DNS_SSUMATCHTYPE_SUBDOMAIN,
+ dns_zone_getorigin(zone),
+ 1, &any);
+
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
}
result = ISC_R_SUCCESS;
@@ -322,6 +388,323 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
return (result);
}
+/*
+ * This is the TTL used for internally generated RRsets for static-stub zones.
+ * The value doesn't matter because the mapping is static, but needs to be
+ * defined for the sake of implementation.
+ */
+#define STATICSTUB_SERVER_TTL 86400
+
+/*%
+ * Configure an apex NS with glues for a static-stub zone.
+ * For example, for the zone named "example.com", the following RRs will be
+ * added to the zone DB:
+ * example.com. NS example.com.
+ * example.com. A 192.0.2.1
+ * example.com. AAAA 2001:db8::1
+ */
+static isc_result_t
+configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ dns_rdatalist_t *rdatalist_ns,
+ dns_rdatalist_t *rdatalist_a,
+ dns_rdatalist_t *rdatalist_aaaa)
+{
+ const cfg_listelt_t *element;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ isc_region_t region, sregion;
+ dns_rdata_t *rdata;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ for (element = cfg_list_first(zconfig);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const isc_sockaddr_t* sa;
+ isc_netaddr_t na;
+ const cfg_obj_t *address = cfg_listelt_value(element);
+ dns_rdatalist_t *rdatalist;
+
+ sa = cfg_obj_assockaddr(address);
+ if (isc_sockaddr_getport(sa) != 0) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "port is not configurable for "
+ "static stub server-addresses");
+ return (ISC_R_FAILURE);
+ }
+ isc_netaddr_fromsockaddr(&na, sa);
+ if (isc_netaddr_getzone(&na) != 0) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "scoped address is not allowed "
+ "for static stub "
+ "server-addresses");
+ return (ISC_R_FAILURE);
+ }
+
+ switch (na.family) {
+ case AF_INET:
+ region.length = sizeof(na.type.in);
+ rdatalist = rdatalist_a;
+ break;
+ default:
+ INSIST(na.family == AF_INET6);
+ region.length = sizeof(na.type.in6);
+ rdatalist = rdatalist_aaaa;
+ break;
+ }
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
+ if (rdata == NULL)
+ return (ISC_R_NOMEMORY);
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, &na.type, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ rdatalist->type, ®ion);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ }
+
+ /*
+ * If no address is specified (unlikely in this context, but possible),
+ * there's nothing to do anymore.
+ */
+ if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
+ ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) {
+ return (ISC_R_SUCCESS);
+ }
+
+ /* Add to the list an apex NS with the ns name being the origin name */
+ dns_name_toregion(dns_zone_getorigin(zone), &sregion);
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
+ if (rdata == NULL) {
+ /*
+ * Already allocated data will be freed in the caller, so
+ * we can simply return here.
+ */
+ return (ISC_R_NOMEMORY);
+ }
+ region.length = sregion.length;
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, sregion.base, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ dns_rdatatype_ns, ®ion);
+ ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
+
+ return (result);
+}
+
+/*%
+ * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
+ * For example, for the zone named "example.com", something like the following
+ * RRs will be added to the zone DB:
+ * example.com. NS ns.example.net.
+ */
+static isc_result_t
+configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ dns_rdatalist_t *rdatalist, const char *zname)
+{
+ const cfg_listelt_t *element;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ dns_rdata_t *rdata;
+ isc_region_t sregion, region;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ for (element = cfg_list_first(zconfig);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *obj;
+ const char *str;
+ dns_fixedname_t fixed_name;
+ dns_name_t *nsname;
+ isc_buffer_t b;
+
+ obj = cfg_listelt_value(element);
+ str = cfg_obj_asstring(obj);
+
+ dns_fixedname_init(&fixed_name);
+ nsname = dns_fixedname_name(&fixed_name);
+
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "server-name '%s' is not a valid "
+ "name", str);
+ return (result);
+ }
+ if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "server-name '%s' must not be a "
+ "subdomain of zone name '%s'",
+ str, zname);
+ return (ISC_R_FAILURE);
+ }
+
+ dns_name_toregion(nsname, &sregion);
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
+ if (rdata == NULL)
+ return (ISC_R_NOMEMORY);
+ region.length = sregion.length;
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, sregion.base, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ dns_rdatatype_ns, ®ion);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ }
+
+ return (result);
+}
+
+/*%
+ * Configure static-stub zone.
+ */
+static isc_result_t
+configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ const char *zname, const char *dbtype)
+{
+ int i = 0;
+ const cfg_obj_t *obj;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ dns_db_t *db = NULL;
+ dns_dbversion_t *dbversion = NULL;
+ dns_dbnode_t *apexnode = NULL;
+ dns_name_t apexname;
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
+ dns_rdatalist_t* rdatalists[] = {
+ &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL
+ };
+ dns_rdata_t *rdata;
+ isc_region_t region;
+
+ /* Create the DB beforehand */
+ RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
+ dns_dbtype_stub, dns_zone_getclass(zone),
+ 0, NULL, &db));
+ dns_zone_setdb(zone, db);
+
+ dns_rdatalist_init(&rdatalist_ns);
+ rdatalist_ns.rdclass = dns_zone_getclass(zone);
+ rdatalist_ns.type = dns_rdatatype_ns;
+ rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
+
+ dns_rdatalist_init(&rdatalist_a);
+ rdatalist_a.rdclass = dns_zone_getclass(zone);
+ rdatalist_a.type = dns_rdatatype_a;
+ rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
+
+ dns_rdatalist_init(&rdatalist_aaaa);
+ rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
+ rdatalist_aaaa.type = dns_rdatatype_aaaa;
+ rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
+
+ /* Prepare zone RRs from the configuration */
+ obj = NULL;
+ result = cfg_map_get(zconfig, "server-addresses", &obj);
+ if (obj != NULL) {
+ result = configure_staticstub_serveraddrs(obj, zone,
+ &rdatalist_ns,
+ &rdatalist_a,
+ &rdatalist_aaaa);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ obj = NULL;
+ result = cfg_map_get(zconfig, "server-names", &obj);
+ if (obj != NULL) {
+ result = configure_staticstub_servernames(obj, zone,
+ &rdatalist_ns,
+ zname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /*
+ * Sanity check: there should be at least one NS RR at the zone apex
+ * to trigger delegation.
+ */
+ if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "No NS record is configured for a "
+ "static-stub zone '%s'", zname);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /*
+ * Now add NS and glue A/AAAA RRsets to the zone DB.
+ * First open a new version for the add operation and get a pointer
+ * to the apex node (all RRs are of the apex name).
+ */
+ result = dns_db_newversion(db, &dbversion);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_name_init(&apexname, NULL);
+ dns_name_clone(dns_zone_getorigin(zone), &apexname);
+ result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add NS RRset */
+ dns_rdataset_init(&rdataset);
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
+ 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add glue A RRset, if any */
+ if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0,
+ &rdataset, 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Add glue AAAA RRset, if any */
+ if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa,
+ &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0,
+ &rdataset, 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (apexnode != NULL)
+ dns_db_detachnode(db, &apexnode);
+ if (dbversion != NULL)
+ dns_db_closeversion(db, &dbversion, ISC_TRUE);
+ if (db != NULL)
+ dns_db_detach(&db);
+ for (i = 0; rdatalists[i] != NULL; i++) {
+ while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) {
+ ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
+ dns_rdata_toregion(rdata, ®ion);
+ isc_mem_put(mctx, rdata,
+ sizeof(*rdata) + region.length);
+ }
+ }
+
+ return (result);
+}
+
/*%
* Convert a config file zone type into a server zone type.
*/
@@ -503,6 +886,19 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
if (result == ISC_R_SUCCESS)
filename = cfg_obj_asstring(obj);
+ /*
+ * Unless we're using some alternative database, a master zone
+ * will be needing a master file.
+ */
+ if (ztype == dns_zone_master && cpval == default_dbtype &&
+ filename == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "zone '%s': 'file' not specified",
+ zname);
+ return (ISC_R_FAILURE);
+ }
+
masterformat = dns_masterformat_text;
obj = NULL;
result= ns_config_get(maps, "masterfile-format", &obj);
@@ -577,7 +973,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
* to primary masters (type "master") and slaves
* acting as masters (type "slave"), but not to stubs.
*/
- if (ztype != dns_zone_stub) {
+ if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) {
obj = NULL;
result = ns_config_get(maps, "notify", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -731,6 +1127,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
*/
if (ztype == dns_zone_master) {
dns_acl_t *updateacl;
+
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_update, ac, zone,
dns_zone_setupdateacl,
@@ -744,7 +1141,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
"address, which is insecure",
zname);
- RETERR(configure_zone_ssutable(zoptions, zone));
+ RETERR(configure_zone_ssutable(zoptions, zone, zname));
obj = NULL;
result = ns_config_get(maps, "sig-validity-interval", &obj);
@@ -774,12 +1171,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
result = ns_config_get(maps, "key-directory", &obj);
if (result == ISC_R_SUCCESS) {
filename = cfg_obj_asstring(obj);
- if (!isc_file_isabsolute(filename)) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
- "key-directory '%s' "
- "is not absolute", filename);
- return (ISC_R_FAILURE);
- }
RETERR(dns_zone_setkeydirectory(zone, filename));
}
@@ -804,6 +1195,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
cfg_obj_asboolean(obj));
+ obj = NULL;
+ result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
+ cfg_obj_asboolean(obj));
} else if (ztype == dns_zone_slave) {
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_update_forwarding, ac, zone,
@@ -811,11 +1207,13 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_clearforwardacl));
}
-
/*%
* Primary master functionality.
*/
if (ztype == dns_zone_master) {
+ isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
+ isc_boolean_t create = ISC_FALSE;
+
obj = NULL;
result = ns_config_get(maps, "check-wildcard", &obj);
if (result == ISC_R_SUCCESS)
@@ -824,6 +1222,21 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
check = ISC_FALSE;
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check);
+ obj = NULL;
+ result = ns_config_get(maps, "check-dup-records", &obj);
+ INSIST(obj != NULL);
+ if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
+ fail = ISC_FALSE;
+ check = ISC_TRUE;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
+ fail = check = ISC_TRUE;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
+ fail = check = ISC_FALSE;
+ } else
+ INSIST(0);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRR, check);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
+
obj = NULL;
result = ns_config_get(maps, "check-mx", &obj);
INSIST(obj != NULL);
@@ -874,6 +1287,31 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(0);
dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn);
dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore);
+
+ obj = NULL;
+ result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
+ INSIST(obj != NULL);
+ dns_zone_setoption(zone, DNS_ZONEOPT_SECURETOINSECURE,
+ cfg_obj_asboolean(obj));
+
+ obj = NULL;
+ result = cfg_map_get(zoptions, "auto-dnssec", &obj);
+ if (result == ISC_R_SUCCESS) {
+ const char *arg = cfg_obj_asstring(obj);
+ if (strcasecmp(arg, "allow") == 0)
+ allow = ISC_TRUE;
+ else if (strcasecmp(arg, "maintain") == 0)
+ allow = maint = ISC_TRUE;
+ else if (strcasecmp(arg, "create") == 0)
+ allow = maint = create = ISC_TRUE;
+ else if (strcasecmp(arg, "off") == 0)
+ ;
+ else
+ INSIST(0);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, create);
+ }
}
/*
@@ -982,6 +1420,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
cfg_obj_asboolean(obj));
break;
+ case dns_zone_staticstub:
+ RETERR(configure_staticstub(zoptions, zone, zname,
+ default_dbtype));
+ break;
+
default:
break;
}
@@ -989,6 +1432,31 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_SUCCESS);
}
+
+#ifdef DLZ
+/*
+ * Set up a DLZ zone as writeable
+ */
+isc_result_t
+ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
+ dns_rdataclass_t rdclass, dns_name_t *name)
+{
+ dns_db_t *db = NULL;
+ isc_time_t now;
+ isc_result_t result;
+
+ TIME_NOW(&now);
+
+ dns_zone_settype(zone, dns_zone_dlz);
+ result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
+ if (result != ISC_R_SUCCESS)
+ return result;
+ result = dns_zone_dlzpostload(zone, db);
+ dns_db_detach(&db);
+ return result;
+}
+#endif
+
isc_boolean_t
ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
const cfg_obj_t *zoptions = NULL;
@@ -1001,6 +1469,13 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone))
return (ISC_FALSE);
+ /*
+ * We always reconfigure a static-stub zone for simplicity, assuming
+ * the amount of data to be loaded is small.
+ */
+ if (zonetype_fromconfig(zoptions) == dns_zone_staticstub)
+ return (ISC_FALSE);
+
obj = NULL;
(void)cfg_map_get(zoptions, "file", &obj);
if (obj != NULL)
diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in
index f7f6346c9d6..a65aad9162e 100644
--- a/bin/nsupdate/Makefile.in
+++ b/bin/nsupdate/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2006-2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.29 2008-08-29 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.36 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \
- ${ISC_INCLUDES} @DST_GSSAPI_INC@
+ ${ISC_INCLUDES} ${ISCCFG_INCLUDES} @DST_GSSAPI_INC@
CDEFINES = @USE_GSSAPI@
CWARNINGS =
@@ -33,6 +33,7 @@ LWRESLIBS = ../../lib/lwres/liblwres.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
@@ -43,7 +44,9 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS}
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} ${ISCCFGLIBS} @LIBS@
+LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -63,8 +66,14 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
+nsupdate.@O@: nsupdate.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DSESSION_KEYFILE=\"${localstatedir}/run/named/session.key\" \
+ -c ${srcdir}/nsupdate.c
+
nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsupdate.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nsupdate.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/nsupdate/nsupdate.1 b/bin/nsupdate/nsupdate.1
index 6c03486559e..9d82891dda9 100644
--- a/bin/nsupdate/nsupdate.1
+++ b/bin/nsupdate/nsupdate.1
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nsupdate.1,v 1.3.48.4 2010-07-10 02:06:17 tbox Exp $
+.\" $Id: nsupdate.1,v 1.13 2010-07-10 01:14:19 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: nsupdate
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1
-.\" Date: Jun 30, 2000
+.\" Date: Aug 25, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "NSUPDATE" "1" "Jun 30, 2000" "BIND9" "BIND9"
+.TH "NSUPDATE" "1" "Aug 25, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,11 +33,11 @@
nsupdate \- Dynamic DNS update utility
.SH "SYNOPSIS"
.HP 9
-\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
+\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-l\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
.SH "DESCRIPTION"
.PP
\fBnsupdate\fR
-is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.
+is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.
.PP
Zones that are under dynamic control via
\fBnsupdate\fR
@@ -60,7 +60,11 @@ option makes
report additional debugging information to
\fB\-d\fR.
.PP
-Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931 or GSS\-TSIG as described in RFC3645. TSIG relies on a shared secret that should only be known to
+The
+\fB\-L\fR
+option with an integer argument of zero or higher sets the logging debug level. If zero, logging is disabled.
+.PP
+Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS\-TSIG as described in RFC 3645. TSIG relies on a shared secret that should only be known to
\fBnsupdate\fR
and the name server. Currently, the only supported encryption algorithm for TSIG is HMAC\-MD5, which is defined in RFC 2104. Once other algorithms are defined for TSIG, applications will need to ensure they select the appropriate algorithm as well as the key when authenticating each other. For instance, suitable
\fBkey\fR
@@ -71,22 +75,22 @@ statements would be added to
so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server.
\fBnsupdate\fR
does not read
-\fI/etc/named.conf\fR. GSS\-TSIG uses Kerberos credentials.
+\fI/etc/named.conf\fR.
+.PP
+GSS\-TSIG uses Kerberos credentials. Standard GSS\-TSIG mode is switched on with the
+\fB\-g\fR
+flag. A non\-standards\-compliant variant of GSS\-TSIG used by Windows 2000 can be switched on with the
+\fB\-o\fR
+flag.
.PP
\fBnsupdate\fR
uses the
\fB\-y\fR
or
\fB\-k\fR
-option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive. With the
-\fB\-k\fR
-option,
-\fBnsupdate\fR
-reads the shared secret from the file
-\fIkeyfile\fR, whose name is of the form
-\fIK{name}.+157.+{random}.private\fR. For historical reasons, the file
-\fIK{name}.+157.+{random}.key\fR
-must also be present. When the
+option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive.
+.PP
+When the
\fB\-y\fR
option is used, a signature is generated from
[\fIhmac:\fR]\fIkeyname:secret.\fR
@@ -99,17 +103,37 @@ option is discouraged because the shared secret is supplied as a command line ar
\fBps\fR(1)
or in a history file maintained by the user's shell.
.PP
-The
+With the
+\fB\-k\fR
+option,
+\fBnsupdate\fR
+reads the shared secret from the file
+\fIkeyfile\fR. Keyfiles may be in two formats: a single file containing a
+\fInamed.conf\fR\-format
+\fBkey\fR
+statement, which may be generated automatically by
+\fBddns\-confgen\fR, or a pair of files whose names are of the format
+\fIK{name}.+157.+{random}.key\fR
+and
+\fIK{name}.+157.+{random}.private\fR, which can be generated by
+\fBdnssec\-keygen\fR. The
\fB\-k\fR
may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key.
.PP
-The
-\fB\-g\fR
-and
-\fB\-o\fR
-specify that GSS\-TSIG is to be used. The
-\fB\-o\fR
-should only be used with old Microsoft Windows 2000 servers.
+\fBnsupdate\fR
+can be run in a local\-host only mode using the
+\fB\-l\fR
+flag. This sets the server address to localhost (disabling the
+\fBserver\fR
+so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in
+\fI/var/run/named/session.key\fR, which is automatically generated by
+\fBnamed\fR
+if any local master zone has set
+\fBupdate\-policy\fR
+to
+\fBlocal\fR. The location of this key file can be overridden with the
+\fB\-k\fR
+option.
.PP
By default,
\fBnsupdate\fR
@@ -120,6 +144,10 @@ option makes
use a TCP connection. This may be preferable when a batch of update requests is made.
.PP
The
+\fB\-p\fR
+sets the default port number to use for connections to a name server. The default is 53.
+.PP
+The
\fB\-t\fR
option sets the maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout.
.PP
@@ -367,7 +395,7 @@ with IP address 172.16.1.1 is added. The newly\-added record has a 1 day TTL (86
.sp
.PP
The prerequisite condition gets the name server to check that there are no resource records of any type for
-\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)
+\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)
.SH "FILES"
.PP
\fB/etc/resolv.conf\fR
@@ -375,6 +403,11 @@ The prerequisite condition gets the name server to check that there are no resou
used to identify default name server
.RE
.PP
+\fB/var/run/named/session.key\fR
+.RS 4
+sets the default TSIG key for use in local\-only mode
+.RE
+.PP
\fBK{name}.+157.+{random}.key\fR
.RS 4
base\-64 encoding of HMAC\-MD5 key created by
@@ -388,14 +421,15 @@ base\-64 encoding of HMAC\-MD5 key created by
.RE
.SH "SEE ALSO"
.PP
-\fBRFC2136\fR(),
-\fBRFC3007\fR(),
-\fBRFC2104\fR(),
-\fBRFC2845\fR(),
-\fBRFC1034\fR(),
-\fBRFC2535\fR(),
-\fBRFC2931\fR(),
+RFC 2136,
+RFC 3007,
+RFC 2104,
+RFC 2845,
+RFC 1034,
+RFC 2535,
+RFC 2931,
\fBnamed\fR(8),
+\fBddns\-confgen\fR(8),
\fBdnssec\-keygen\fR(8).
.SH "BUGS"
.PP
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
index d9ee4884a60..9bbea4bc937 100644
--- a/bin/nsupdate/nsupdate.c
+++ b/bin/nsupdate/nsupdate.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsupdate.c,v 1.163.48.15 2010-12-09 04:30:57 tbox Exp $ */
+/* $Id: nsupdate.c,v 1.193 2011-01-10 05:32:03 marka Exp $ */
/*! \file */
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -50,6 +51,8 @@
#include
#include
+#include
+
#include
#include
#include
@@ -78,6 +81,7 @@
#ifdef GSSAPI
#include
+#include ISC_PLATFORM_KRB5HEADER
#endif
#include
@@ -106,6 +110,8 @@ extern int h_errno;
#define DNSDEFAULTPORT 53
+static isc_uint16_t dnsport = DNSDEFAULTPORT;
+
#ifndef RESOLV_CONF
#define RESOLV_CONF "/etc/resolv.conf"
#endif
@@ -119,6 +125,7 @@ static isc_boolean_t usevc = ISC_FALSE;
static isc_boolean_t usegsstsig = ISC_FALSE;
static isc_boolean_t use_win2k_gsstsig = ISC_FALSE;
static isc_boolean_t tried_other_gsstsig = ISC_FALSE;
+static isc_boolean_t local_only = ISC_FALSE;
static isc_taskmgr_t *taskmgr = NULL;
static isc_task_t *global_task = NULL;
static isc_event_t *global_event = NULL;
@@ -148,7 +155,8 @@ static isc_sockaddr_t *userserver = NULL;
static isc_sockaddr_t *localaddr = NULL;
static isc_sockaddr_t *serveraddr = NULL;
static isc_sockaddr_t tempaddr;
-static char *keystr = NULL, *keyfile = NULL;
+static const char *keyfile = NULL;
+static char *keystr = NULL;
static isc_entropy_t *entropy = NULL;
static isc_boolean_t shuttingdown = ISC_FALSE;
static FILE *input;
@@ -174,8 +182,10 @@ typedef struct nsu_requestinfo {
static void
sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_message_t *msg, dns_request_t **request);
-static void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
static void
debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
@@ -406,7 +416,7 @@ reset_system(void) {
if (tsigkey != NULL)
dns_tsigkey_detach(&tsigkey);
if (gssring != NULL)
- dns_tsigkeyring_destroy(&gssring);
+ dns_tsigkeyring_detach(&gssring);
tried_other_gsstsig = ISC_FALSE;
}
}
@@ -479,6 +489,19 @@ parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) {
return (digestbits);
}
+static int
+basenamelen(const char *file) {
+ int len = strlen(file);
+
+ if (len > 1 && file[len - 1] == '.')
+ len -= 1;
+ else if (len > 8 && strcmp(file + len - 8, ".private") == 0)
+ len -= 8;
+ else if (len > 4 && strcmp(file + len - 4, ".key") == 0)
+ len -= 4;
+ return (len);
+}
+
static void
setup_keystr(void) {
unsigned char *secret = NULL;
@@ -520,8 +543,7 @@ setup_keystr(void) {
isc_buffer_add(&keynamesrc, n - name);
debug("namefromtext");
- result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
secretlen = strlen(secretstr) * 3 / 4;
@@ -553,21 +575,67 @@ setup_keystr(void) {
isc_mem_free(mctx, secret);
}
-static int
-basenamelen(const char *file) {
- int len = strlen(file);
+/*
+ * Get a key from a named.conf format keyfile
+ */
+static isc_result_t
+read_sessionkey(isc_mem_t *mctx, isc_log_t *lctx) {
+ cfg_parser_t *pctx = NULL;
+ cfg_obj_t *sessionkey = NULL;
+ const cfg_obj_t *key = NULL;
+ const cfg_obj_t *secretobj = NULL;
+ const cfg_obj_t *algorithmobj = NULL;
+ const char *keyname;
+ const char *secretstr;
+ const char *algorithm;
+ isc_result_t result;
+ int len;
- if (len > 1 && file[len - 1] == '.')
- len -= 1;
- else if (len > 8 && strcmp(file + len - 8, ".private") == 0)
- len -= 8;
- else if (len > 4 && strcmp(file + len - 4, ".key") == 0)
- len -= 4;
- return (len);
+ if (! isc_file_exists(keyfile))
+ return (ISC_R_FILENOTFOUND);
+
+ result = cfg_parser_create(mctx, lctx, &pctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
+ &sessionkey);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_map_get(sessionkey, "key", &key);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ (void) cfg_map_get(key, "secret", &secretobj);
+ (void) cfg_map_get(key, "algorithm", &algorithmobj);
+ if (secretobj == NULL || algorithmobj == NULL)
+ fatal("key must have algorithm and secret");
+
+ keyname = cfg_obj_asstring(cfg_map_getname(key));
+ secretstr = cfg_obj_asstring(secretobj);
+ algorithm = cfg_obj_asstring(algorithmobj);
+
+ len = strlen(algorithm) + strlen(keyname) + strlen(secretstr) + 3;
+ keystr = isc_mem_allocate(mctx, len);
+ snprintf(keystr, len, "%s:%s:%s", algorithm, keyname, secretstr);
+ setup_keystr();
+
+ cleanup:
+ if (pctx != NULL) {
+ if (sessionkey != NULL)
+ cfg_obj_destroy(pctx, &sessionkey);
+ cfg_parser_destroy(&pctx);
+ }
+
+ if (keystr != NULL)
+ isc_mem_free(mctx, keystr);
+
+ return (result);
}
static void
-setup_keyfile(void) {
+setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) {
dst_key_t *dstkey = NULL;
isc_result_t result;
dns_name_t *hmacname = NULL;
@@ -577,15 +645,25 @@ setup_keyfile(void) {
if (sig0key != NULL)
dst_key_free(&sig0key);
- result = dst_key_fromnamedfile(keyfile,
+ /* Try reading the key from a K* pair */
+ result = dst_key_fromnamedfile(keyfile, NULL,
DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
&dstkey);
+
+ /* If that didn't work, try reading it as a session.key keyfile */
+ if (result != ISC_R_SUCCESS) {
+ result = read_sessionkey(mctx, lctx);
+ if (result == ISC_R_SUCCESS)
+ return;
+ }
+
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not read key from %.*s.{private,key}: "
"%s\n", basenamelen(keyfile), keyfile,
isc_result_totext(result));
return;
}
+
switch (dst_key_alg(dstkey)) {
case DST_ALG_HMACMD5:
hmacname = DNS_TSIG_HMACMD5_NAME;
@@ -746,7 +824,7 @@ setup_system(void) {
if (servers == NULL)
fatal("out of memory");
localhost.s_addr = htonl(INADDR_LOOPBACK);
- isc_sockaddr_fromin(&servers[0], &localhost, DNSDEFAULTPORT);
+ isc_sockaddr_fromin(&servers[0], &localhost, dnsport);
} else {
servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t));
if (servers == NULL)
@@ -755,12 +833,12 @@ setup_system(void) {
if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) {
struct in_addr in4;
memcpy(&in4, lwconf->nameservers[i].address, 4);
- isc_sockaddr_fromin(&servers[i], &in4, DNSDEFAULTPORT);
+ isc_sockaddr_fromin(&servers[i], &in4, dnsport);
} else {
struct in6_addr in6;
memcpy(&in6, lwconf->nameservers[i].address, 16);
isc_sockaddr_fromin6(&servers[i], &in6,
- DNSDEFAULTPORT);
+ dnsport);
}
}
}
@@ -827,8 +905,13 @@ setup_system(void) {
if (keystr != NULL)
setup_keystr();
- else if (keyfile != NULL)
- setup_keyfile();
+ else if (local_only) {
+ result = read_sessionkey(mctx, lctx);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't read key from %s: %s\n",
+ keyfile, isc_result_totext(result));
+ } else if (keyfile != NULL)
+ setup_keyfile(mctx, lctx);
}
static void
@@ -845,7 +928,7 @@ get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
INSIST(count == 1);
}
-#define PARSE_ARGS_FMT "dDMl:y:govk:rR::t:u:"
+#define PARSE_ARGS_FMT "dDML:y:ghlovk:p:rR::t:u:"
static void
pre_parse_args(int argc, char **argv) {
@@ -862,10 +945,11 @@ pre_parse_args(int argc, char **argv) {
break;
case '?':
+ case 'h':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
argv[0], isc_commandline_option);
- fprintf(stderr, "usage: nsupdate [-d] "
+ fprintf(stderr, "usage: nsupdate [-dD] [-L level] [-l]"
"[-g | -o | -y keyname:secret | -k keyfile] "
"[-v] [filename]\n");
exit(1);
@@ -897,6 +981,9 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
case 'M':
break;
case 'l':
+ local_only = ISC_TRUE;
+ break;
+ case 'L':
result = isc_parse_uint32(&i, isc_commandline_argument,
10);
if (result != ISC_R_SUCCESS) {
@@ -923,6 +1010,15 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_TRUE;
break;
+ case 'p':
+ result = isc_parse_uint16(&dnsport,
+ isc_commandline_argument, 10);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "bad port number "
+ "'%s'\n", isc_commandline_argument);
+ exit(1);
+ }
+ break;
case 't':
result = isc_parse_uint32(&timeout,
isc_commandline_argument, 10);
@@ -968,6 +1064,22 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
exit(1);
}
+ if (local_only) {
+ struct in_addr localhost;
+
+ if (keyfile == NULL)
+ keyfile = SESSION_KEYFILE;
+
+ if (userserver == NULL) {
+ userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t));
+ if (userserver == NULL)
+ fatal("out of memory");
+ }
+
+ localhost.s_addr = htonl(INADDR_LOOPBACK);
+ isc_sockaddr_fromin(userserver, &localhost, dnsport);
+ }
+
#ifdef GSSAPI
if (usegsstsig && (keyfile != NULL || keystr != NULL)) {
fprintf(stderr, "%s: cannot specify -g with -k or -y\n",
@@ -976,7 +1088,7 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
}
#else
if (usegsstsig) {
- fprintf(stderr, "%s: cannot specify -g or -o, " \
+ fprintf(stderr, "%s: cannot specify -g or -o, " \
"program not linked with GSS API Library\n",
argv[0]);
exit(1);
@@ -1022,8 +1134,7 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
dns_message_takebuffer(msg, &namebuf);
isc_buffer_init(&source, word, strlen(word));
isc_buffer_add(&source, strlen(word));
- result = dns_name_fromtext(*namep, &source, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
isc_buffer_invalidate(&source);
return (STATUS_MORE);
@@ -1225,6 +1336,11 @@ evaluate_server(char *cmdline) {
char *word, *server;
long port;
+ if (local_only) {
+ fprintf(stderr, "cannot reset server in localhost-only mode\n");
+ return (STATUS_SYNTAX);
+ }
+
word = nsu_strsep(&cmdline, " \t\r\n");
if (*word == 0) {
fprintf(stderr, "could not read server name\n");
@@ -1234,7 +1350,7 @@ evaluate_server(char *cmdline) {
word = nsu_strsep(&cmdline, " \t\r\n");
if (*word == 0)
- port = DNSDEFAULTPORT;
+ port = dnsport;
else {
char *endp;
port = strtol(word, &endp, 10);
@@ -1340,7 +1456,7 @@ evaluate_key(char *cmdline) {
isc_buffer_init(&b, namestr, strlen(namestr));
isc_buffer_add(&b, strlen(namestr));
- result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not parse key name\n");
return (STATUS_SYNTAX);
@@ -1397,8 +1513,7 @@ evaluate_zone(char *cmdline) {
userzone = dns_fixedname_name(&fuserzone);
isc_buffer_init(&b, word, strlen(word));
isc_buffer_add(&b, strlen(word));
- result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
userzone = NULL; /* Lest it point to an invalid name */
fprintf(stderr, "could not parse zone name\n");
@@ -1850,9 +1965,9 @@ get_next_command(void) {
"server address [port] (set master server for zone)\n"
"send (send the update request)\n"
"show (show the update request)\n"
-"answer (show the answer to the last request)\n"
+"answer (show the answer to the last request)\n"
"quit (quit, any pending update is not sent\n"
-"help (display this message_\n"
+"help (display this message_\n"
"key [hmac:]keyname secret (use TSIG to sign the request)\n"
"gsstsig (use GSS_TSIG to sign the request)\n"
"oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n"
@@ -2013,7 +2128,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master,
{
isc_result_t result;
dns_request_t *request = NULL;
- unsigned int options = 0;
+ unsigned int options = DNS_REQUESTOPT_CASE;
ddebug("send_update()");
@@ -2246,7 +2361,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
result = dns_name_totext(&master, ISC_TRUE, &buf);
check_result(result, "dns_name_totext");
serverstr[isc_buffer_usedlength(&buf)] = 0;
- get_address(serverstr, DNSDEFAULTPORT, &tempaddr);
+ get_address(serverstr, dnsport, &tempaddr);
serveraddr = &tempaddr;
}
dns_rdata_freestruct(&soa);
@@ -2317,9 +2432,60 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
}
#ifdef GSSAPI
+
+/*
+ * Get the realm from the users kerberos ticket if possible
+ */
static void
-start_gssrequest(dns_name_t *master)
+get_ticket_realm(isc_mem_t *mctx)
{
+ krb5_context ctx;
+ krb5_error_code rc;
+ krb5_ccache ccache;
+ krb5_principal princ;
+ char *name, *ticket_realm;
+
+ rc = krb5_init_context(&ctx);
+ if (rc != 0)
+ return;
+
+ rc = krb5_cc_default(ctx, &ccache);
+ if (rc != 0) {
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_cc_get_principal(ctx, ccache, &princ);
+ if (rc != 0) {
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_unparse_name(ctx, princ, &name);
+ if (rc != 0) {
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ ticket_realm = strrchr(name, '@');
+ if (ticket_realm != NULL) {
+ realm = isc_mem_strdup(mctx, ticket_realm);
+ }
+
+ free(name);
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ if (realm != NULL && debugging)
+ fprintf(stderr, "Found realm from ticket: %s\n", realm+1);
+}
+
+
+static void
+start_gssrequest(dns_name_t *master) {
gss_ctx_id_t context;
isc_buffer_t buf;
isc_result_t result;
@@ -2330,12 +2496,13 @@ start_gssrequest(dns_name_t *master)
dns_fixedname_t fname;
char namestr[DNS_NAME_FORMATSIZE];
char keystr[DNS_NAME_FORMATSIZE];
+ char *err_message = NULL;
debug("start_gssrequest");
usevc = ISC_TRUE;
if (gssring != NULL)
- dns_tsigkeyring_destroy(&gssring);
+ dns_tsigkeyring_detach(&gssring);
gssring = NULL;
result = dns_tsigkeyring_create(mctx, &gssring);
@@ -2350,13 +2517,16 @@ start_gssrequest(dns_name_t *master)
fatal("out of memory");
}
if (userserver == NULL)
- get_address(namestr, DNSDEFAULTPORT, kserver);
+ get_address(namestr, dnsport, kserver);
else
(void)memcpy(kserver, userserver, sizeof(isc_sockaddr_t));
dns_fixedname_init(&fname);
servname = dns_fixedname_name(&fname);
+ if (realm == NULL)
+ get_ticket_realm(mctx);
+
result = isc_string_printf(servicename, sizeof(servicename),
"DNS/%s%s", namestr, realm ? realm : "");
if (result != ISC_R_SUCCESS)
@@ -2364,8 +2534,7 @@ start_gssrequest(dns_name_t *master)
isc_result_totext(result));
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
- result = dns_name_fromtext(servname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(servname) failed: %s",
isc_result_totext(result));
@@ -2382,8 +2551,7 @@ start_gssrequest(dns_name_t *master)
isc_buffer_init(&buf, keystr, strlen(keystr));
isc_buffer_add(&buf, strlen(keystr));
- result = dns_name_fromtext(keyname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(keyname) failed: %s",
isc_result_totext(result));
@@ -2400,9 +2568,11 @@ start_gssrequest(dns_name_t *master)
/* Build first request. */
context = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
- &context, use_win2k_gsstsig);
+ &context, use_win2k_gsstsig,
+ mctx, &err_message);
if (result == ISC_R_FAILURE)
- fatal("Check your Kerberos ticket, it may have expired.");
+ fatal("tkey query failed: %s",
+ err_message != NULL ? err_message : "unknown error");
if (result != ISC_R_SUCCESS)
fatal("dns_tkey_buildgssquery failed: %s",
isc_result_totext(result));
@@ -2451,6 +2621,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
isc_buffer_t buf;
dns_name_t *servname;
dns_fixedname_t fname;
+ char *err_message = NULL;
UNUSED(task);
@@ -2533,14 +2704,14 @@ recvgss(isc_task_t *task, isc_event_t *event) {
servname = dns_fixedname_name(&fname);
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
- result = dns_name_fromtext(servname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
tsigkey = NULL;
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
&context, &tsigkey, gssring,
- use_win2k_gsstsig);
+ use_win2k_gsstsig,
+ &err_message);
switch (result) {
case DNS_R_CONTINUE:
@@ -2583,7 +2754,9 @@ recvgss(isc_task_t *task, isc_event_t *event) {
break;
default:
- fatal("dns_tkey_negotiategss: %s", isc_result_totext(result));
+ fatal("dns_tkey_negotiategss: %s %s",
+ isc_result_totext(result),
+ err_message != NULL ? err_message : "");
}
done:
@@ -2693,8 +2866,8 @@ cleanup(void) {
dns_tsigkey_detach(&tsigkey);
}
if (gssring != NULL) {
- ddebug("Destroying GSS-TSIG keyring");
- dns_tsigkeyring_destroy(&gssring);
+ ddebug("Detaching GSS-TSIG keyring");
+ dns_tsigkeyring_detach(&gssring);
}
if (kserver != NULL) {
isc_mem_put(mctx, kserver, sizeof(isc_sockaddr_t));
diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook
index 4069a2bb283..2a92af438da 100644
--- a/bin/nsupdate/nsupdate.docbook
+++ b/bin/nsupdate/nsupdate.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
- Jun 30, 2000
+ Aug 25, 2009nsupdate
@@ -61,6 +61,7 @@
+
@@ -76,7 +77,7 @@
DESCRIPTIONnsupdate
- is used to submit Dynamic DNS Update requests as defined in RFC2136
+ is used to submit Dynamic DNS Update requests as defined in RFC 2136
to a name server.
This allows resource records to be added or removed from a zone
without manually editing the zone file.
@@ -111,11 +112,15 @@
The option makes nsupdate
report additional debugging information to .
+
+ The option with an integer argument of zero or
+ higher sets the logging debug level. If zero, logging is disabled.
+
Transaction signatures can be used to authenticate the Dynamic
DNS updates. These use the TSIG resource record type described
- in RFC2845 or the SIG(0) record described in RFC3535 and
- RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on
+ in RFC 2845 or the SIG(0) record described in RFC 2535 and
+ RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on
a shared secret that should only be known to
nsupdate and the name server. Currently,
the only supported encryption algorithm for TSIG is HMAC-MD5,
@@ -132,46 +137,61 @@
record in a zone served by the name server.
nsupdate does not read
/etc/named.conf.
- GSS-TSIG uses Kerberos credentials.
+
+
+ GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode
+ is switched on with the flag. A
+ non-standards-compliant variant of GSS-TSIG used by Windows
+ 2000 can be switched on with the flag.
nsupdate
uses the or option
to provide the shared secret needed to generate a TSIG record
for authenticating Dynamic DNS update requests, default type
- HMAC-MD5. These options are mutually exclusive. With the
- option, nsupdate reads
- the shared secret from the file keyfile,
- whose name is of the form
- K{name}.+157.+{random}.private. For
- historical reasons, the file
- K{name}.+157.+{random}.key must also be
- present. When the option is used, a
- signature is generated from
- hmac:keyname:secret.
- keyname is the name of the key, and
- secret is the base64 encoded shared
- secret. Use of the option is discouraged
- because the shared secret is supplied as a command line
- argument in clear text. This may be visible in the output
- from
-
- ps1
- or in a history file maintained by the user's
- shell.
+ HMAC-MD5. These options are mutually exclusive.
+ When the option is used, a signature is
+ generated from
+ hmac:keyname:secret.
+ keyname is the name of the key, and
+ secret is the base64 encoded shared secret.
+ Use of the option is discouraged because the
+ shared secret is supplied as a command line argument in clear text.
+ This may be visible in the output from
+
+ ps1
+
+ or in a history file maintained by the user's shell.
+
+
+ With the
+ option, nsupdate reads
+ the shared secret from the file keyfile.
+ Keyfiles may be in two formats: a single file containing
+ a named.conf-format key
+ statement, which may be generated automatically by
+ ddns-confgen, or a pair of files whose names are
+ of the format K{name}.+157.+{random}.key and
+ K{name}.+157.+{random}.private, which can be
+ generated by dnssec-keygen.
The may also be used to specify a SIG(0) key used
to authenticate Dynamic DNS update requests. In this case, the key
specified is not an HMAC-MD5 key.
- The and specify that
- GSS-TSIG is to be used. The should only
- be used with old Microsoft Windows 2000 servers.
+ nsupdate can be run in a local-host only mode
+ using the flag. This sets the server address to
+ localhost (disabling the server so that the server
+ address cannot be overridden). Connections to the local server will
+ use a TSIG key found in /var/run/named/session.key,
+ which is automatically generated by named if any
+ local master zone has set update-policy to
+ local. The location of this key file can be
+ overridden with the option.
- By default,
- nsupdate
+ By default, nsupdate
uses UDP to send update requests to the name server unless they are too
large to fit in a UDP request in which case TCP will be used.
The
@@ -181,6 +201,10 @@
use a TCP connection.
This may be preferable when a batch of update requests is made.
+
+ The sets the default port number to use for
+ connections to a name server. The default is 53.
+
The option sets the maximum time an update request
can
@@ -650,9 +674,9 @@
If there are, the update request fails.
If this name does not exist, a CNAME for it is added.
This ensures that when the CNAME is added, it cannot conflict with the
- long-standing rule in RFC1034 that a name must not exist as any other
+ long-standing rule in RFC 1034 that a name must not exist as any other
record type if it exists as a CNAME.
- (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have
+ (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have
RRSIG, DNSKEY and NSEC records.)
@@ -670,6 +694,15 @@
+
+ /var/run/named/session.key
+
+
+ sets the default TSIG key for use in local-only mode
+
+
+
+
K{name}.+157.+{random}.key
@@ -699,36 +732,26 @@
SEE ALSO
-
- RFC2136
- ,
-
- RFC3007
- ,
-
- RFC2104
- ,
-
- RFC2845
- ,
-
- RFC1034
- ,
-
- RFC2535
- ,
-
- RFC2931
- ,
+
+ RFC 2136,
+ RFC 3007,
+ RFC 2104,
+ RFC 2845,
+ RFC 1034,
+ RFC 2535,
+ RFC 2931,
named8,
+
+ ddns-confgen8
+ ,
dnssec-keygen8.
-
+
BUGS
diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html
index a3836175f56..f48831573e1 100644
--- a/bin/nsupdate/nsupdate.html
+++ b/bin/nsupdate/nsupdate.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
@@ -29,12 +29,12 @@
nsupdate
- is used to submit Dynamic DNS Update requests as defined in RFC2136
+ is used to submit Dynamic DNS Update requests as defined in RFC 2136
to a name server.
This allows resource records to be added or removed from a zone
without manually editing the zone file.
@@ -69,11 +69,15 @@
The -D option makes nsupdate
report additional debugging information to -d.
+
+ The -L option with an integer argument of zero or
+ higher sets the logging debug level. If zero, logging is disabled.
+
Transaction signatures can be used to authenticate the Dynamic
DNS updates. These use the TSIG resource record type described
- in RFC2845 or the SIG(0) record described in RFC3535 and
- RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on
+ in RFC 2845 or the SIG(0) record described in RFC 2535 and
+ RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on
a shared secret that should only be known to
nsupdate and the name server. Currently,
the only supported encryption algorithm for TSIG is HMAC-MD5,
@@ -90,44 +94,59 @@
record in a zone served by the name server.
nsupdate does not read
/etc/named.conf.
- GSS-TSIG uses Kerberos credentials.
+
+
+ GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode
+ is switched on with the -g flag. A
+ non-standards-compliant variant of GSS-TSIG used by Windows
+ 2000 can be switched on with the -o flag.
nsupdate
uses the -y or -k option
to provide the shared secret needed to generate a TSIG record
for authenticating Dynamic DNS update requests, default type
- HMAC-MD5. These options are mutually exclusive. With the
- -k option, nsupdate reads
- the shared secret from the file keyfile,
- whose name is of the form
- K{name}.+157.+{random}.private. For
- historical reasons, the file
- K{name}.+157.+{random}.key must also be
- present. When the -y option is used, a
- signature is generated from
- [hmac:]keyname:secret.
- keyname is the name of the key, and
- secret is the base64 encoded shared
- secret. Use of the -y option is discouraged
- because the shared secret is supplied as a command line
- argument in clear text. This may be visible in the output
- from
- ps(1) or in a history file maintained by the user's
- shell.
+ HMAC-MD5. These options are mutually exclusive.
+ When the -y option is used, a signature is
+ generated from
+ [hmac:]keyname:secret.
+ keyname is the name of the key, and
+ secret is the base64 encoded shared secret.
+ Use of the -y option is discouraged because the
+ shared secret is supplied as a command line argument in clear text.
+ This may be visible in the output from
+ ps(1)
+ or in a history file maintained by the user's shell.
+
+
+ With the
+ -k option, nsupdate reads
+ the shared secret from the file keyfile.
+ Keyfiles may be in two formats: a single file containing
+ a named.conf-format key
+ statement, which may be generated automatically by
+ ddns-confgen, or a pair of files whose names are
+ of the format K{name}.+157.+{random}.key and
+ K{name}.+157.+{random}.private, which can be
+ generated by dnssec-keygen.
The -k may also be used to specify a SIG(0) key used
to authenticate Dynamic DNS update requests. In this case, the key
specified is not an HMAC-MD5 key.
- The -g and -o specify that
- GSS-TSIG is to be used. The -o should only
- be used with old Microsoft Windows 2000 servers.
+ nsupdate can be run in a local-host only mode
+ using the -l flag. This sets the server address to
+ localhost (disabling the server so that the server
+ address cannot be overridden). Connections to the local server will
+ use a TSIG key found in /var/run/named/session.key,
+ which is automatically generated by named if any
+ local master zone has set update-policy to
+ local. The location of this key file can be
+ overridden with the -k option.
- By default,
- nsupdate
+ By default, nsupdate
uses UDP to send update requests to the name server unless they are too
large to fit in a UDP request in which case TCP will be used.
The
@@ -137,6 +156,10 @@
use a TCP connection.
This may be preferable when a batch of update requests is made.
+
+ The -p sets the default port number to use for
+ connections to a name server. The default is 53.
+
The -t option sets the maximum time an update request
can
@@ -169,7 +192,7 @@
-
INPUT FORMAT
+
INPUT FORMAT
nsupdate
reads input from
filename
@@ -457,7 +480,7 @@
-
EXAMPLES
+
EXAMPLES
The examples below show how
nsupdate
@@ -504,19 +527,23 @@
If there are, the update request fails.
If this name does not exist, a CNAME for it is added.
This ensures that when the CNAME is added, it cannot conflict with the
- long-standing rule in RFC1034 that a name must not exist as any other
+ long-standing rule in RFC 1034 that a name must not exist as any other
record type if it exists as a CNAME.
- (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have
+ (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have
RRSIG, DNSKEY and NSEC records.)
-
FILES
+
FILES
/etc/resolv.conf
used to identify default name server
+
/var/run/named/session.key
+
+ sets the default TSIG key for use in local-only mode
+
K{name}.+157.+{random}.key
base-64 encoding of HMAC-MD5 key created by
@@ -530,20 +557,22 @@
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in
index 27d46111a4e..6c7c56f4abf 100644
--- a/bin/rndc/Makefile.in
+++ b/bin/rndc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.44 2007-06-18 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.49 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -32,6 +32,7 @@ CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
@@ -41,26 +42,23 @@ ISCDEPLIBS = ../../lib/isc/libisc.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
+
RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
-CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
-SRCS= rndc.c rndc-confgen.c
+SRCS= rndc.c
-SUBDIRS = unix
+TARGETS = rndc@EXEEXT@
-TARGETS = rndc@EXEEXT@ rndc-confgen@EXEEXT@
+MANPAGES = rndc.8 rndc.conf.5
-MANPAGES = rndc.8 rndc-confgen.8 rndc.conf.5
-
-HTMLPAGES = rndc.html rndc-confgen.html rndc.conf.html
+HTMLPAGES = rndc.html rndc.conf.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
-UOBJS = unix/os.@O@
-
@BIND9_MAKE_RULES@
rndc.@O@: rndc.c
@@ -70,18 +68,10 @@ rndc.@O@: rndc.c
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
-c ${srcdir}/rndc.c
-rndc-confgen.@O@: rndc-confgen.c
- ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
- -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
- -c ${srcdir}/rndc-confgen.c
-
rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc.@O@ util.@O@ \
- ${RNDCLIBS}
-
-rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ ${UOBJS} ${CONFDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \
- ${UOBJS} ${CONFLIBS}
+ export BASEOBJS="rndc.@O@ util.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
@@ -93,11 +83,9 @@ installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5
-install:: rndc@EXEEXT@ rndc-confgen@EXEEXT@ installdirs
+install:: rndc@EXEEXT@ installdirs
${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc@EXEEXT@ ${DESTDIR}${sbindir}
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir}
${INSTALL_DATA} ${srcdir}/rndc.8 ${DESTDIR}${mandir}/man8
- ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8
${INSTALL_DATA} ${srcdir}/rndc.conf.5 ${DESTDIR}${mandir}/man5
clean distclean maintainer-clean::
diff --git a/bin/rndc/include/rndc/os.h b/bin/rndc/include/rndc/os.h
index 9f96165d75a..91986cb0c1d 100644
--- a/bin/rndc/include/rndc/os.h
+++ b/bin/rndc/include/rndc/os.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.9.332.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: os.h,v 1.12 2009-06-10 00:27:21 each Exp $ */
/*! \file */
@@ -27,12 +27,6 @@
ISC_LANG_BEGINDECLS
-FILE *safe_create(const char *filename);
-/*%<
- * Open 'filename' for writing, truncate if necessary. If the file was
- * created ensure that only the owner can read/write it.
- */
-
int set_user(FILE *fd, const char *user);
/*%<
* Set the owner of the file referenced by 'fd' to 'user'.
diff --git a/bin/rndc/rndc.8 b/bin/rndc/rndc.8
index 285ca9b2eb6..e4d723bb519 100644
--- a/bin/rndc/rndc.8
+++ b/bin/rndc/rndc.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.8,v 1.42.214.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: rndc.8,v 1.43 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c
index 133103e3dc7..1976d9ce332 100644
--- a/bin/rndc/rndc.c
+++ b/bin/rndc/rndc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rndc.c,v 1.122.44.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: rndc.c,v 1.131.20.1.2.1 2011-06-02 23:47:28 tbox Exp $ */
/*! \file */
@@ -79,6 +79,7 @@ static unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
static isccc_region_t secret;
static isc_boolean_t failed = ISC_FALSE;
+static isc_boolean_t c_flag = ISC_FALSE;
static isc_mem_t *mctx;
static int sends, recvs, connects;
static char *command;
@@ -89,10 +90,13 @@ static isc_uint32_t serial;
static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task);
+ISC_PLATFORM_NORETURN_PRE static void
+usage(int status) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(int status) {
fprintf(stderr, "\
-Usage: %s [-c config] [-s server] [-p port]\n\
+Usage: %s [-b address] [-c config] [-s server] [-p port]\n\
[-k key-file ] [-y key] [-V] command\n\
\n\
command is one of the following:\n\
@@ -113,10 +117,16 @@ command is one of the following:\n\
notify zone [class [view]]\n\
Resend NOTIFY messages for the zone.\n\
reconfig Reload configuration file and new zones only.\n\
+ sign zone [class [view]]\n\
+ Update zone keys, and sign as needed.\n\
+ loadkeys zone [class [view]]\n\
+ Update keys without signing immediately.\n\
stats Write server statistics to the statistics file.\n\
querylog Toggle query logging.\n\
dumpdb [-all|-cache|-zones] [view ...]\n\
Dump cache(s) to the dump file (named_dump.db).\n\
+ secroots [view ...]\n\
+ Write security roots to the secroots file.\n\
stop Save pending updates to master files and stop the server.\n\
stop -p Save pending updates to master files and stop the server\n\
reporting process id.\n\
@@ -135,6 +145,10 @@ command is one of the following:\n\
validation newstate [view]\n\
Enable / disable DNSSEC validation.\n\
*restart Restart the server.\n\
+ addzone [\"file\"] zone [class [view]] { zone-options }\n\
+ Add zone to given view. Requires new-zone-file option.\n\
+ delzone [\"file\"] zone [class [view]]\n\
+ Removes zone from given view. Requires new-zone-file option.\n\
\n\
* == not yet implemented\n\
Version: %s\n",
@@ -455,6 +469,10 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
fatal("neither %s nor %s was found",
admin_conffile, admin_keyfile);
key_only = ISC_TRUE;
+ } else if (! c_flag && isc_file_exists(admin_keyfile)) {
+ fprintf(stderr, "WARNING: key file (%s) exists, but using "
+ "default configuration file (%s)\n",
+ admin_keyfile, admin_conffile);
}
DO("create parser", cfg_parser_create(mctx, log, pctxp));
@@ -709,6 +727,7 @@ main(int argc, char **argv) {
case 'c':
admin_conffile = isc_commandline_argument;
+ c_flag = ISC_TRUE;
break;
case 'k':
diff --git a/bin/rndc/rndc.conf.5 b/bin/rndc/rndc.conf.5
index d7ad81ea99d..54c4af9c21f 100644
--- a/bin/rndc/rndc.conf.5
+++ b/bin/rndc/rndc.conf.5
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.conf.5,v 1.38.366.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: rndc.conf.5,v 1.41 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/rndc/rndc.conf.html b/bin/rndc/rndc.conf.html
index 114cc15983b..463b99fd2c2 100644
--- a/bin/rndc/rndc.conf.html
+++ b/bin/rndc/rndc.conf.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
diff --git a/bin/rndc/rndc.html b/bin/rndc/rndc.html
index 0d91784b0ec..ecc0f318614 100644
--- a/bin/rndc/rndc.html
+++ b/bin/rndc/rndc.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-
+
diff --git a/bin/rndc/util.h b/bin/rndc/util.h
index c5da488d96d..8eba61a57ee 100644
--- a/bin/rndc/util.h
+++ b/bin/rndc/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: util.h,v 1.10 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: util.h,v 1.12 2009-09-29 23:48:03 tbox Exp $ */
#ifndef RNDC_UTIL_H
#define RNDC_UTIL_H 1
@@ -23,6 +23,7 @@
/*! \file */
#include
+#include
#include
@@ -43,8 +44,9 @@ ISC_LANG_BEGINDECLS
void
notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);
-void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
ISC_LANG_ENDDECLS
diff --git a/bin/tools/Makefile.in b/bin/tools/Makefile.in
new file mode 100644
index 00000000000..35b8285715d
--- /dev/null
+++ b/bin/tools/Makefile.in
@@ -0,0 +1,103 @@
+# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.13 2010-01-07 23:48:53 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
+ ${LWRES_INCLUDES} ${OMAPI_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+ISCLIBS = ../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
+ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
+LWRESLIBS = ../../lib/lwres/liblwres.@A@
+
+DNSDEPLIBS = ../../lib/dns/libdns.@A@
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
+LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
+
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = arpaname@EXEEXT@ named-journalprint@EXEEXT@ nsec3hash@EXEEXT@ \
+ genrandom@EXEEXT@ isc-hmac-fixup@EXEEXT@
+SRCS = arpaname.c named-journalprint.c nsec3hash.c genrandom.c \
+ isc-hmac-fixup.c
+
+MANPAGES = arpaname.1 named-journalprint.8 nsec3hash.8 genrandom.8 \
+ isc-hmac-fixup.8
+HTMLPAGES = arpaname.html named-journalprint.html nsec3hash.html \
+ genrandom.html isc-hmac-fixup.html
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+@BIND9_MAKE_RULES@
+
+arpaname@EXEEXT@: arpaname.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ arpaname.@O@ \
+ ${ISCLIBS} ${LIBS}
+
+named-journalprint@EXEEXT@: named-journalprint.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ export BASEOBJS="named-journalprint.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
+
+nsec3hash@EXEEXT@: nsec3hash.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ export BASEOBJS="nsec3hash.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
+
+isc-hmac-fixup@EXEEXT@: isc-hmac-fixup.@O@ ${ISCDEPLIBS}
+ export BASEOBJS="isc-hmac-fixup.@O@"; \
+ export LIBS0="${ISCLIBS}"; \
+ ${FINALBUILDCMD}
+
+genrandom@EXEEXT@: genrandom.@O@
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ genrandom.@O@ @GENRANDOMLIB@ ${LIBS}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
+
+install:: ${TARGETS} installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} arpaname@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-journalprint@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} nsec3hash@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} genrandom@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} isc-hmac-fixup@EXEEXT@ ${DESTDIR}${sbindir}
+ ${INSTALL_DATA} ${srcdir}/arpaname.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${srcdir}/isc-hmac-fixup.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/named-journalprint.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/nsec3hash.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/genrandom.8 ${DESTDIR}${mandir}/man8
+
+clean distclean::
+ rm -f ${TARGETS}
diff --git a/bin/tools/arpaname.1 b/bin/tools/arpaname.1
new file mode 100644
index 00000000000..66623801814
--- /dev/null
+++ b/bin/tools/arpaname.1
@@ -0,0 +1,48 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: arpaname.1,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: arpaname
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: March 4, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "ARPANAME" "1" "March 4, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+arpaname \- translate IP addresses to the corresponding ARPA names
+.SH "SYNOPSIS"
+.HP 9
+\fBarpaname\fR {\fIipaddress\ \fR...}
+.SH "DESCRIPTION"
+.PP
+\fBarpaname\fR
+translates IP addresses (IPv4 and IPv6) to the corresponding IN\-ADDR.ARPA or IP6.ARPA names.
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/arpaname.c b/bin/tools/arpaname.c
new file mode 100644
index 00000000000..e7f14345dfd
--- /dev/null
+++ b/bin/tools/arpaname.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: arpaname.c,v 1.4 2009-10-27 03:05:33 marka Exp $ */
+
+#include "config.h"
+
+#include
+
+#include
+
+#define UNUSED(x) (void)(x)
+
+int
+main(int argc, char *argv[]) {
+ unsigned char buf[16];
+ int i;
+
+ UNUSED(argc);
+
+ while (argv[1]) {
+ if (inet_pton(AF_INET6, argv[1], buf) == 1) {
+ for (i = 15; i >= 0; i--)
+ fprintf(stdout, "%X.%X.", buf[i] & 0xf,
+ (buf[i] >> 4) & 0xf);
+ fprintf(stdout, "IP6.ARPA\n");
+ argv++;
+ continue;
+ }
+ if (inet_pton(AF_INET, argv[1], buf) == 1) {
+ fprintf(stdout, "%u.%u.%u.%u.IN-ADDR.ARPA\n",
+ buf[3], buf[2], buf[1], buf[0]);
+ argv++;
+ continue;
+ }
+ return (1);
+ }
+ fflush(stdout);
+ return(ferror(stdout));
+}
diff --git a/bin/tools/arpaname.docbook b/bin/tools/arpaname.docbook
new file mode 100644
index 00000000000..a7eb79e9c3b
--- /dev/null
+++ b/bin/tools/arpaname.docbook
@@ -0,0 +1,76 @@
+]>
+
+
+
+
+
+ March 4, 2009
+
+
+
+ arpaname
+ 1
+ BIND9
+
+
+
+ arpaname
+ translate IP addresses to the corresponding ARPA names
+
+
+
+
+ 2009
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ arpaname
+ ipaddress
+
+
+
+
+ DESCRIPTION
+
+ arpaname translates IP addresses (IPv4 and
+ IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.
+
+
+
+
+ SEE ALSO
+
+ BIND 9 Administrator Reference Manual.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/arpaname.html b/bin/tools/arpaname.html
new file mode 100644
index 00000000000..e44cfbd782e
--- /dev/null
+++ b/bin/tools/arpaname.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+arpaname
+
+
+
+
+
+
Name
+
arpaname — translate IP addresses to the corresponding ARPA names
+
+
+
Synopsis
+
arpaname {ipaddress ...}
+
+
+
DESCRIPTION
+
+ arpaname translates IP addresses (IPv4 and
+ IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.
+
+
+
+
SEE ALSO
+
+ BIND 9 Administrator Reference Manual.
+
+
+
+
AUTHOR
+
Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/genrandom.8 b/bin/tools/genrandom.8
new file mode 100644
index 00000000000..32a4ff02efb
--- /dev/null
+++ b/bin/tools/genrandom.8
@@ -0,0 +1,69 @@
+.\" Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: genrandom.8,v 1.8 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: genrandom
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: Feb 19, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "GENRANDOM" "8" "Feb 19, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+genrandom \- generate a file containing random data
+.SH "SYNOPSIS"
+.HP 10
+\fBgenrandom\fR [\fB\-n\ \fR\fB\fInumber\fR\fR] {\fIsize\fR} {\fIfilename\fR}
+.SH "DESCRIPTION"
+.PP
+\fBgenrandom\fR
+generates a file or a set of files containing a specified quantity of pseudo\-random data, which can be used as a source of entropy for other commands on systems with no random device.
+.SH "ARGUMENTS"
+.PP
+\-n \fInumber\fR
+.RS 4
+In place of generating one file, generates
+\fBnumber\fR
+(from 2 to 9) files, appending
+\fBnumber\fR
+to the name.
+.RE
+.PP
+size
+.RS 4
+The size of the file, in kilobytes, to generate.
+.RE
+.PP
+domain
+.RS 4
+The file name into which random data should be written.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBrand\fR(3),
+\fBarc4random\fR(3)
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/genrandom.c b/bin/tools/genrandom.c
new file mode 100644
index 00000000000..8473be25940
--- /dev/null
+++ b/bin/tools/genrandom.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: genrandom.c,v 1.7 2010-05-17 23:51:04 tbox Exp $ */
+
+/*! \file */
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+const char *program = "genrandom";
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "usage: %s [-n 2..9] k file\n", program);
+ exit(1);
+}
+
+static void
+generate(char *filename, unsigned int bytes) {
+ FILE *fp;
+
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ printf("failed to open %s\n", filename);
+ exit(1);
+ }
+
+ while (bytes > 0) {
+#ifndef HAVE_ARC4RANDOM
+ unsigned short int x = (rand() & 0xFFFF);
+#else
+ unsigned short int x = (arc4random() & 0xFFFF);
+#endif
+ unsigned char c = x & 0xFF;
+ if (putc(c, fp) == EOF) {
+ printf("error writing to %s\n", filename);
+ exit(1);
+ }
+ c = x >> 8;
+ if (putc(c, fp) == EOF) {
+ printf("error writing to %s\n", filename);
+ exit(1);
+ }
+ bytes -= 2;
+ }
+ fclose(fp);
+}
+
+int
+main(int argc, char **argv) {
+ unsigned int bytes;
+ unsigned int k;
+ char *endp;
+ int c, i, n = 1;
+ size_t len;
+ char *name;
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((c = isc_commandline_parse(argc, argv, "hn:")) != EOF) {
+ switch (c) {
+ case 'n':
+ n = strtol(isc_commandline_argument, &endp, 10);
+ if ((*endp != 0) || (n <= 1) || (n > 9))
+ usage();
+ break;
+
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (isc_commandline_index + 2 != argc)
+ usage();
+
+ k = strtoul(argv[isc_commandline_index++], &endp, 10);
+ if (*endp != 0)
+ usage();
+ bytes = k << 10;
+
+#ifndef HAVE_ARC4RANDOM
+ srand(0x12345678);
+#endif
+ if (n == 1) {
+ generate(argv[isc_commandline_index], bytes);
+ return (0);
+ }
+
+ len = strlen(argv[isc_commandline_index]) + 2;
+ name = (char *) malloc(len);
+ if (name == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ for (i = 1; i <= n; i++) {
+ snprintf(name, len, "%s%d", argv[isc_commandline_index], i);
+ generate(name, bytes);
+ }
+ free(name);
+
+ return (0);
+}
diff --git a/bin/tools/genrandom.docbook b/bin/tools/genrandom.docbook
new file mode 100644
index 00000000000..84e45534a82
--- /dev/null
+++ b/bin/tools/genrandom.docbook
@@ -0,0 +1,119 @@
+]>
+
+
+
+
+
+ Feb 19, 2009
+
+
+
+ genrandom
+ 8
+ BIND9
+
+
+
+ genrandom
+ generate a file containing random data
+
+
+
+
+ 2009
+ 2010
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ genrandom
+
+ size
+ filename
+
+
+
+
+ DESCRIPTION
+
+ genrandom
+ generates a file or a set of files containing a specified quantity
+ of pseudo-random data, which can be used as a source of entropy for
+ other commands on systems with no random device.
+
+
+
+
+ ARGUMENTS
+
+
+ -n number
+
+
+ In place of generating one file, generates
+ (from 2 to 9) files, appending to the name.
+
+
+
+
+
+ size
+
+
+ The size of the file, in kilobytes, to generate.
+
+
+
+
+
+ domain
+
+
+ The file name into which random data should be written.
+
+
+
+
+
+
+
+ SEE ALSO
+
+
+ rand3
+ ,
+
+ arc4random3
+
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/genrandom.html b/bin/tools/genrandom.html
new file mode 100644
index 00000000000..c14af9bbd0e
--- /dev/null
+++ b/bin/tools/genrandom.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+genrandom
+
+
+
+
+
+
Name
+
genrandom — generate a file containing random data
+
+
+
Synopsis
+
genrandom [-n number] {size} {filename}
+
+
+
DESCRIPTION
+
+ genrandom
+ generates a file or a set of files containing a specified quantity
+ of pseudo-random data, which can be used as a source of entropy for
+ other commands on systems with no random device.
+
+
+
+
ARGUMENTS
+
+
-n number
+
+ In place of generating one file, generates number
+ (from 2 to 9) files, appending number to the name.
+
+
size
+
+ The size of the file, in kilobytes, to generate.
+
+
domain
+
+ The file name into which random data should be written.
+
+
+
+
+
SEE ALSO
+
+ rand(3),
+ arc4random(3)
+
+
+
+
AUTHOR
+
Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/isc-hmac-fixup.8 b/bin/tools/isc-hmac-fixup.8
new file mode 100644
index 00000000000..99c58c8304c
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.8
@@ -0,0 +1,61 @@
+.\" Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: isc-hmac-fixup.8,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: isc\-hmac\-fixup
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: January 5, 2010
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "ISC\-HMAC\-FIXUP" "1" "January 5, 2010" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+isc\-hmac\-fixup \- fixes HMAC keys generated by older versions of BIND
+.SH "SYNOPSIS"
+.HP 15
+\fBisc\-hmac\-fixup\fR {\fIalgorithm\fR} {\fIsecret\fR}
+.SH "DESCRIPTION"
+.PP
+Versions of BIND 9 up to and including BIND 9.6 had a bug causing HMAC\-SHA* TSIG keys which were longer than the digest length of the hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys longer than 256 bits, etc) to be used incorrectly, generating a message authentication code that was incompatible with other DNS implementations.
+.PP
+This bug has been fixed in BIND 9.7. However, the fix may cause incompatibility between older and newer versions of BIND, when using long keys.
+\fBisc\-hmac\-fixup\fR
+modifies those keys to restore compatibility.
+.PP
+To modify a key, run
+\fBisc\-hmac\-fixup\fR
+and specify the key's algorithm and secret on the command line. If the secret is longer than the digest length of the algorithm (64 bytes for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a new secret will be generated consisting of a hash digest of the old secret. (If the secret did not require conversion, then it will be printed without modification.)
+.SH "SECURITY CONSIDERATIONS"
+.PP
+Secrets that have been converted by
+\fBisc\-hmac\-fixup\fR
+are shortened, but as this is how the HMAC protocol works in operation anyway, it does not affect security. RFC 2104 notes, "Keys longer than [the digest length] are acceptable but the extra length would not significantly increase the function strength."
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual,
+RFC 2104.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/isc-hmac-fixup.c b/bin/tools/isc-hmac-fixup.c
new file mode 100644
index 00000000000..09cb85deeeb
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: isc-hmac-fixup.c,v 1.4 2010-03-10 02:17:52 marka Exp $ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define HMAC_LEN 64
+
+int
+main(int argc, char **argv) {
+ isc_buffer_t buf;
+ unsigned char key[1024];
+ char secret[1024];
+ char base64[(1024*4)/3];
+ isc_region_t r;
+ isc_result_t result;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage:\t%s algorithm secret\n", argv[0]);
+ fprintf(stderr, "\talgorithm: (MD5 | SHA1 | SHA224 | "
+ "SHA256 | SHA384 | SHA512)\n");
+ return (1);
+ }
+
+ isc_buffer_init(&buf, secret, sizeof(secret));
+ result = isc_base64_decodestring(argv[2], &buf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "error: %s\n", isc_result_totext(result));
+ return (1);
+ }
+ isc__buffer_usedregion(&buf, &r);
+
+ if (!strcasecmp(argv[1], "md5") ||
+ !strcasecmp(argv[1], "hmac-md5")) {
+ if (r.length > HMAC_LEN) {
+ isc_md5_t md5ctx;
+ isc_md5_init(&md5ctx);
+ isc_md5_update(&md5ctx, r.base, r.length);
+ isc_md5_final(&md5ctx, key);
+
+ r.base = key;
+ r.length = ISC_MD5_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha1") ||
+ !strcasecmp(argv[1], "hmac-sha1")) {
+ if (r.length > ISC_SHA1_DIGESTLENGTH) {
+ isc_sha1_t sha1ctx;
+ isc_sha1_init(&sha1ctx);
+ isc_sha1_update(&sha1ctx, r.base, r.length);
+ isc_sha1_final(&sha1ctx, key);
+
+ r.base = key;
+ r.length = ISC_SHA1_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha224") ||
+ !strcasecmp(argv[1], "hmac-sha224")) {
+ if (r.length > ISC_SHA224_DIGESTLENGTH) {
+ isc_sha224_t sha224ctx;
+ isc_sha224_init(&sha224ctx);
+ isc_sha224_update(&sha224ctx, r.base, r.length);
+ isc_sha224_final(key, &sha224ctx);
+
+ r.base = key;
+ r.length = ISC_SHA224_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha256") ||
+ !strcasecmp(argv[1], "hmac-sha256")) {
+ if (r.length > ISC_SHA256_DIGESTLENGTH) {
+ isc_sha256_t sha256ctx;
+ isc_sha256_init(&sha256ctx);
+ isc_sha256_update(&sha256ctx, r.base, r.length);
+ isc_sha256_final(key, &sha256ctx);
+
+ r.base = key;
+ r.length = ISC_SHA256_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha384") ||
+ !strcasecmp(argv[1], "hmac-sha384")) {
+ if (r.length > ISC_SHA384_DIGESTLENGTH) {
+ isc_sha384_t sha384ctx;
+ isc_sha384_init(&sha384ctx);
+ isc_sha384_update(&sha384ctx, r.base, r.length);
+ isc_sha384_final(key, &sha384ctx);
+
+ r.base = key;
+ r.length = ISC_SHA384_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha512") ||
+ !strcasecmp(argv[1], "hmac-sha512")) {
+ if (r.length > ISC_SHA512_DIGESTLENGTH) {
+ isc_sha512_t sha512ctx;
+ isc_sha512_init(&sha512ctx);
+ isc_sha512_update(&sha512ctx, r.base, r.length);
+ isc_sha512_final(key, &sha512ctx);
+
+ r.base = key;
+ r.length = ISC_SHA512_DIGESTLENGTH;
+ }
+ } else {
+ fprintf(stderr, "unknown hmac/digest algorithm: %s\n", argv[1]);
+ return (1);
+ }
+
+ isc_buffer_init(&buf, base64, sizeof(base64));
+ result = isc_base64_totext(&r, 0, "", &buf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "error: %s\n", isc_result_totext(result));
+ return (1);
+ }
+ fprintf(stdout, "%.*s\n", (int)isc_buffer_usedlength(&buf), base64);
+ return (0);
+}
diff --git a/bin/tools/isc-hmac-fixup.docbook b/bin/tools/isc-hmac-fixup.docbook
new file mode 100644
index 00000000000..a3039ee814d
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.docbook
@@ -0,0 +1,109 @@
+]>
+
+
+
+
+
+ January 5, 2010
+
+
+
+ isc-hmac-fixup
+ 1
+ BIND9
+
+
+
+ isc-hmac-fixup
+ fixes HMAC keys generated by older versions of BIND
+
+
+
+
+ 2010
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ isc-hmac-fixup
+ algorithm
+ secret
+
+
+
+
+ DESCRIPTION
+
+ Versions of BIND 9 up to and including BIND 9.6 had a bug causing
+ HMAC-SHA* TSIG keys which were longer than the digest length of the
+ hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys
+ longer than 256 bits, etc) to be used incorrectly, generating a
+ message authentication code that was incompatible with other DNS
+ implementations.
+
+
+ This bug has been fixed in BIND 9.7. However, the fix may
+ cause incompatibility between older and newer versions of
+ BIND, when using long keys. isc-hmac-fixup
+ modifies those keys to restore compatibility.
+
+
+ To modify a key, run isc-hmac-fixup and
+ specify the key's algorithm and secret on the command line. If the
+ secret is longer than the digest length of the algorithm (64 bytes
+ for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a
+ new secret will be generated consisting of a hash digest of the old
+ secret. (If the secret did not require conversion, then it will be
+ printed without modification.)
+
+
+
+
+ SECURITY CONSIDERATIONS
+
+ Secrets that have been converted by isc-hmac-fixup
+ are shortened, but as this is how the HMAC protocol works in
+ operation anyway, it does not affect security. RFC 2104 notes,
+ "Keys longer than [the digest length] are acceptable but the
+ extra length would not significantly increase the function
+ strength."
+
+
+
+
+ SEE ALSO
+
+ BIND 9 Administrator Reference Manual,
+ RFC 2104.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/isc-hmac-fixup.html b/bin/tools/isc-hmac-fixup.html
new file mode 100644
index 00000000000..8b70777cd79
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+isc-hmac-fixup
+
+
+
+
+
+
Name
+
isc-hmac-fixup — fixes HMAC keys generated by older versions of BIND
+
+
+
Synopsis
+
isc-hmac-fixup {algorithm} {secret}
+
+
+
DESCRIPTION
+
+ Versions of BIND 9 up to and including BIND 9.6 had a bug causing
+ HMAC-SHA* TSIG keys which were longer than the digest length of the
+ hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys
+ longer than 256 bits, etc) to be used incorrectly, generating a
+ message authentication code that was incompatible with other DNS
+ implementations.
+
+
+ This bug has been fixed in BIND 9.7. However, the fix may
+ cause incompatibility between older and newer versions of
+ BIND, when using long keys. isc-hmac-fixup
+ modifies those keys to restore compatibility.
+
+
+ To modify a key, run isc-hmac-fixup and
+ specify the key's algorithm and secret on the command line. If the
+ secret is longer than the digest length of the algorithm (64 bytes
+ for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a
+ new secret will be generated consisting of a hash digest of the old
+ secret. (If the secret did not require conversion, then it will be
+ printed without modification.)
+
+
+
+
SECURITY CONSIDERATIONS
+
+ Secrets that have been converted by isc-hmac-fixup
+ are shortened, but as this is how the HMAC protocol works in
+ operation anyway, it does not affect security. RFC 2104 notes,
+ "Keys longer than [the digest length] are acceptable but the
+ extra length would not significantly increase the function
+ strength."
+
+
diff --git a/bin/tools/named-journalprint.8 b/bin/tools/named-journalprint.8
new file mode 100644
index 00000000000..347b67b1bac
--- /dev/null
+++ b/bin/tools/named-journalprint.8
@@ -0,0 +1,60 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: named-journalprint.8,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: named\-journalprint
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: Feb 18, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "NAMED\-JOURNALPRINT" "8" "Feb 18, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+named\-journalprint \- print zone journal in human\-readable form
+.SH "SYNOPSIS"
+.HP 19
+\fBnamed\-journalprint\fR {\fIjournal\fR}
+.SH "DESCRIPTION"
+.PP
+\fBnamed\-journalprint\fR
+prints the contents of a zone journal file in a human\-readable form.
+.PP
+Journal files are automatically created by
+\fBnamed\fR
+when changes are made to dynamic zones (e.g., by
+\fBnsupdate\fR). They record each addition or deletion of a resource record, in binary format, allowing the changes to be re\-applied to the zone when the server is restarted after a shutdown or crash. By default, the name of the journal file is formed by appending the extension
+\fI.jnl\fR
+to the name of the corresponding zone file.
+.PP
+\fBnamed\-journalprint\fR
+converts the contents of a given journal file into a human\-readable text format. Each line begins with "add" or "del", to indicate whether the record was added or deleted, and continues with the resource record in master\-file format.
+.SH "SEE ALSO"
+.PP
+\fBnamed\fR(8),
+\fBnsupdate\fR(8),
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/named-journalprint.c b/bin/tools/named-journalprint.c
new file mode 100644
index 00000000000..8a00aa7a85d
--- /dev/null
+++ b/bin/tools/named-journalprint.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: named-journalprint.c,v 1.2 2009-12-04 21:59:23 marka Exp $ */
+
+/*! \file */
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+/*
+ * Setup logging to use stderr.
+ */
+static isc_result_t
+setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
+ isc_logdestination_t destination;
+ isc_logconfig_t *logconfig = NULL;
+ isc_log_t *log = NULL;
+
+ RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS);
+ isc_log_setcontext(log);
+ dns_log_init(log);
+ dns_log_setcontext(log);
+
+ destination.file.stream = errout;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr",
+ ISC_LOG_TOFILEDESC,
+ ISC_LOG_DYNAMIC,
+ &destination, 0) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr",
+ NULL, NULL) == ISC_R_SUCCESS);
+
+ *logp = log;
+ return (ISC_R_SUCCESS);
+}
+
+int
+main(int argc, char **argv) {
+ char *file;
+ isc_mem_t *mctx = NULL;
+ isc_result_t result;
+ isc_log_t *lctx = NULL;
+
+ if (argc != 2) {
+ printf("usage: %s journal\n", argv[0]);
+ return(1);
+ }
+
+ file = argv[1];
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(setup_logging(mctx, stderr, &lctx) == ISC_R_SUCCESS);
+
+ result = dns_journal_print(mctx, file, stdout);
+ if (result == DNS_R_NOJOURNAL)
+ fprintf(stderr, "%s\n", dns_result_totext(result));
+ isc_log_destroy(&lctx);
+ isc_mem_detach(&mctx);
+ return(result != ISC_R_SUCCESS ? 1 : 0);
+}
diff --git a/bin/tools/named-journalprint.docbook b/bin/tools/named-journalprint.docbook
new file mode 100644
index 00000000000..d523f8c1aff
--- /dev/null
+++ b/bin/tools/named-journalprint.docbook
@@ -0,0 +1,101 @@
+]>
+
+
+
+
+
+ Feb 18, 2009
+
+
+
+ named-journalprint
+ 8
+ BIND9
+
+
+
+ named-journalprint
+ print zone journal in human-readable form
+
+
+
+
+ 2009
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ named-journalprint
+ journal
+
+
+
+
+ DESCRIPTION
+
+ named-journalprint
+ prints the contents of a zone journal file in a human-readable
+ form.
+
+
+ Journal files are automatically created by named
+ when changes are made to dynamic zones (e.g., by
+ nsupdate). They record each addition
+ or deletion of a resource record, in binary format, allowing the
+ changes to be re-applied to the zone when the server is
+ restarted after a shutdown or crash. By default, the name of
+ the journal file is formed by appending the extension
+ .jnl to the name of the corresponding
+ zone file.
+
+
+ named-journalprint converts the contents of a given
+ journal file into a human-readable text format. Each line begins
+ with "add" or "del", to indicate whether the record was added or
+ deleted, and continues with the resource record in master-file
+ format.
+
+
+
+
+ SEE ALSO
+
+
+ named8
+ ,
+
+ nsupdate8
+ ,
+ BIND 9 Administrator Reference Manual.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/named-journalprint.html b/bin/tools/named-journalprint.html
new file mode 100644
index 00000000000..8878fc50655
--- /dev/null
+++ b/bin/tools/named-journalprint.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+named-journalprint
+
+
+
+
+
+
Name
+
named-journalprint — print zone journal in human-readable form
+
+
+
Synopsis
+
named-journalprint {journal}
+
+
+
DESCRIPTION
+
+ named-journalprint
+ prints the contents of a zone journal file in a human-readable
+ form.
+
+
+ Journal files are automatically created by named
+ when changes are made to dynamic zones (e.g., by
+ nsupdate). They record each addition
+ or deletion of a resource record, in binary format, allowing the
+ changes to be re-applied to the zone when the server is
+ restarted after a shutdown or crash. By default, the name of
+ the journal file is formed by appending the extension
+ .jnl to the name of the corresponding
+ zone file.
+
+
+ named-journalprint converts the contents of a given
+ journal file into a human-readable text format. Each line begins
+ with "add" or "del", to indicate whether the record was added or
+ deleted, and continues with the resource record in master-file
+ format.
+
+
diff --git a/bin/tools/nsec3hash.8 b/bin/tools/nsec3hash.8
new file mode 100644
index 00000000000..6fba8c886cf
--- /dev/null
+++ b/bin/tools/nsec3hash.8
@@ -0,0 +1,70 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: nsec3hash.8,v 1.5 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: nsec3hash
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1
+.\" Date: Feb 18, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "NSEC3HASH" "8" "Feb 18, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+nsec3hash \- generate NSEC3 hash
+.SH "SYNOPSIS"
+.HP 10
+\fBnsec3hash\fR {\fIsalt\fR} {\fIalgorithm\fR} {\fIiterations\fR} {\fIdomain\fR}
+.SH "DESCRIPTION"
+.PP
+\fBnsec3hash\fR
+generates an NSEC3 hash based on a set of NSEC3 parameters. This can be used to check the validity of NSEC3 records in a signed zone.
+.SH "ARGUMENTS"
+.PP
+salt
+.RS 4
+The salt provided to the hash algorithm.
+.RE
+.PP
+algorithm
+.RS 4
+A number indicating the hash algorithm. Currently the only supported hash algorithm for NSEC3 is SHA\-1, which is indicated by the number 1; consequently "1" is the only useful value for this argument.
+.RE
+.PP
+iterations
+.RS 4
+The number of additional times the hash should be performed.
+.RE
+.PP
+domain
+.RS 4
+The domain name to be hashed.
+.RE
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual,
+RFC 5155.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/nsec3hash.c b/bin/tools/nsec3hash.c
new file mode 100644
index 00000000000..0e2a910c915
--- /dev/null
+++ b/bin/tools/nsec3hash.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: nsec3hash.c,v 1.6 2009-10-06 21:20:44 each Exp $ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+const char *program = "nsec3hash";
+
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *format, ...) ISC_PLATFORM_NORETURN_POST;
+
+static void
+fatal(const char *format, ...) {
+ va_list args;
+
+ fprintf(stderr, "%s: ", program);
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static void
+check_result(isc_result_t result, const char *message) {
+ if (result != ISC_R_SUCCESS)
+ fatal("%s: %s", message, isc_result_totext(result));
+}
+
+static void
+usage() {
+ fatal("salt hash iterations domain");
+}
+
+int
+main(int argc, char **argv) {
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ isc_buffer_t buffer;
+ isc_region_t region;
+ isc_result_t result;
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH];
+ unsigned char salt[DNS_NSEC3_SALTSIZE];
+ unsigned char text[1024];
+ unsigned int hash_alg;
+ unsigned int length;
+ unsigned int iterations;
+ unsigned int salt_length;
+
+ if (argc != 5)
+ usage();
+
+ if (strcmp(argv[1], "-") == 0) {
+ salt_length = 0;
+ salt[0] = 0;
+ } else {
+ isc_buffer_init(&buffer, salt, sizeof(salt));
+ result = isc_hex_decodestring(argv[1], &buffer);
+ check_result(result, "isc_hex_decodestring(salt)");
+ salt_length = isc_buffer_usedlength(&buffer);
+ if (salt_length > DNS_NSEC3_SALTSIZE)
+ fatal("salt too long");
+ }
+ hash_alg = atoi(argv[2]);
+ if (hash_alg > 255U)
+ fatal("hash algorithm too large");
+ iterations = atoi(argv[3]);
+ if (iterations > 0xffffU)
+ fatal("iterations to large");
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ isc_buffer_init(&buffer, argv[4], strlen(argv[4]));
+ isc_buffer_add(&buffer, strlen(argv[4]));
+ result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL);
+ check_result(result, "dns_name_fromtext() failed");
+
+ dns_name_downcase(name, name, NULL);
+ length = isc_iterated_hash(hash, hash_alg, iterations, salt,
+ salt_length, name->ndata, name->length);
+ if (length == 0)
+ fatal("isc_iterated_hash failed");
+ region.base = hash;
+ region.length = length;
+ isc_buffer_init(&buffer, text, sizeof(text));
+ isc_base32hex_totext(®ion, 1, "", &buffer);
+ fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n",
+ (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations);
+ return(0);
+}
diff --git a/bin/tools/nsec3hash.docbook b/bin/tools/nsec3hash.docbook
new file mode 100644
index 00000000000..48eb4afb41c
--- /dev/null
+++ b/bin/tools/nsec3hash.docbook
@@ -0,0 +1,125 @@
+]>
+
+
+
+
+
+ Feb 18, 2009
+
+
+
+ nsec3hash
+ 8
+ BIND9
+
+
+
+ nsec3hash
+ generate NSEC3 hash
+
+
+
+
+ 2009
+ Internet Systems Consortium, Inc. ("ISC")
+
+
+
+
+
+ nsec3hash
+ salt
+ algorithm
+ iterations
+ domain
+
+
+
+
+ DESCRIPTION
+
+ nsec3hash generates an NSEC3 hash based on
+ a set of NSEC3 parameters. This can be used to check the validity
+ of NSEC3 records in a signed zone.
+
+
+
+
+ ARGUMENTS
+
+
+ salt
+
+
+ The salt provided to the hash algorithm.
+
+
+
+
+
+ algorithm
+
+
+ A number indicating the hash algorithm. Currently the
+ only supported hash algorithm for NSEC3 is SHA-1, which is
+ indicated by the number 1; consequently "1" is the only
+ useful value for this argument.
+
+
+
+
+
+ iterations
+
+
+ The number of additional times the hash should be performed.
+
+
+
+
+
+ domain
+
+
+ The domain name to be hashed.
+
+
+
+
+
+
+
+ SEE ALSO
+
+ BIND 9 Administrator Reference Manual,
+ RFC 5155.
+
+
+
+
+ AUTHOR
+ Internet Systems Consortium
+
+
+
+
diff --git a/bin/tools/nsec3hash.html b/bin/tools/nsec3hash.html
new file mode 100644
index 00000000000..e6c09959f15
--- /dev/null
+++ b/bin/tools/nsec3hash.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+nsec3hash
+
+
+
+ nsec3hash generates an NSEC3 hash based on
+ a set of NSEC3 parameters. This can be used to check the validity
+ of NSEC3 records in a signed zone.
+
+
+
+
ARGUMENTS
+
+
salt
+
+ The salt provided to the hash algorithm.
+
+
algorithm
+
+ A number indicating the hash algorithm. Currently the
+ only supported hash algorithm for NSEC3 is SHA-1, which is
+ indicated by the number 1; consequently "1" is the only
+ useful value for this argument.
+
+
iterations
+
+ The number of additional times the hash should be performed.
+
+
diff --git a/config.guess b/config.guess
index c79aebcb566..f8d6eac4e84 100644
--- a/config.guess
+++ b/config.guess
@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-timestamp='2004-09-07'
+timestamp='2009-01-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
diff --git a/config.h.in b/config.h.in
index aa1ba81a248..01f8b166acb 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,6 +1,6 @@
/* config.h.in. Generated from configure.in by autoheader. */
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h.in,v 1.106.40.24 2010-12-21 04:33:58 marka Exp $ */
+/* $Id: config.h.in,v 1.143.8.1 2011-02-03 05:52:35 marka Exp $ */
/*! \file */
@@ -147,6 +147,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
+/* Define to enable the "filter-aaaa-on-v4" option. */
+#undef ALLOW_FILTER_AAAA_ON_V4
+
/* Define if recvmsg() does not meet all of the BSD socket API specifications.
*/
#undef BROKEN_RECVMSG
@@ -157,6 +160,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to enable "rrset-order fixed" syntax. */
#undef DNS_RDATASET_FIXED
+/* Define to enable rpz-nsdname rules. */
+#undef ENABLE_RPZ_NSDNAME
+
+/* Define to enable rpz-nsip rules. */
+#undef ENABLE_RPZ_NSIP
+
/* Solaris hack to get select_large_fdset. */
#undef FD_SETSIZE
@@ -175,9 +184,18 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the header file. */
#undef HAVE_DEVPOLL_H
+/* Define to 1 if you have the `dlclose' function. */
+#undef HAVE_DLCLOSE
+
/* Define to 1 if you have the header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the `dlsym' function. */
+#undef HAVE_DLSYM
+
/* Define to 1 if you have the `EVP_sha256' function. */
#undef HAVE_EVP_SHA256
@@ -190,9 +208,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the header file. */
#undef HAVE_GSSAPI_GSSAPI_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_GSSAPI_GSSAPI_KRB5_H
+
/* Define to 1 if you have the header file. */
#undef HAVE_GSSAPI_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_GSSAPI_KRB5_H
+
/* Define to 1 if you have the header file. */
#undef HAVE_INTTYPES_H
@@ -211,9 +235,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the `cap' library (-lcap). */
#undef HAVE_LIBCAP
+/* if system have backtrace function */
+#undef HAVE_LIBCTRACE
+
/* Define to 1 if you have the `c_r' library (-lc_r). */
#undef HAVE_LIBC_R
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
@@ -247,9 +277,27 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the header file. */
#undef HAVE_NET_IF6_H
+/* Define if your OpenSSL version supports GOST. */
+#undef HAVE_OPENSSL_GOST
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_REGEX_H
+
+/* Define to 1 if you have the `setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
+/* Define to 1 if you have the `setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define to 1 if you have the `setresuid' function. */
+#undef HAVE_SETRESUID
+
/* Define to 1 if you have the header file. */
#undef HAVE_STDINT_H
@@ -304,6 +352,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
+/* return type of gai_strerror */
+#undef IRS_GAISTRERROR_RETURN_T
+
+/* Define to the buffer length type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_BUFLEN_T
+
+/* Define to the flags type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_FLAGS_T
+
/* Defined if extern char *optarg is not declared. */
#undef NEED_OPTARG
@@ -361,11 +418,8 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
+/* Define to empty if your compiler does not support "static inline". */
#undef inline
-#endif
/* Define to `unsigned int' if does not define. */
#undef size_t
diff --git a/configure.in b/configure.in
index 08f0bf33dc7..d5fb15cfb90 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.457.26.28 $)
+AC_REVISION($Revision: 1.512.8.1 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
@@ -36,6 +36,7 @@ case $build_os in
sunos*)
# Just set the maximum command line length for sunos as it otherwise
# takes a exceptionally long time to work it out. Required for libtool.
+
lt_cv_sys_max_cmd_len=4096;
;;
esac
@@ -61,7 +62,6 @@ It is available from http://www.isc.org as a separate download.])
;;
esac
-
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
@@ -111,6 +111,8 @@ AC_SUBST(ETAGS)
#
# Perl is optional; it is used only by some of the system test scripts.
+# Note: the backtrace feature (see below) uses perl to build the symbol table,
+# but it still compiles without perl, in which case an empty table will be used.
#
AC_PATH_PROGS(PERL, perl5 perl)
AC_SUBST(PERL)
@@ -269,7 +271,7 @@ esac
AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
+AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
[$ac_includes_default
#ifdef HAVE_SYS_PARAM_H
# include
@@ -282,6 +284,12 @@ AC_C_VOLATILE
AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME))
AC_C_FLEXIBLE_ARRAY_MEMBER
+#
+# Older versions of HP/UX don't define seteuid() and setegid()
+#
+AC_CHECK_FUNCS(seteuid setresuid)
+AC_CHECK_FUNCS(setegid setresgid)
+
#
# UnixWare 7.1.1 with the feature supplement to the UDK compiler
# is reported to not support "static inline" (RT #1212).
@@ -300,7 +308,7 @@ AC_TRY_COMPILE(, [
],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
- AC_DEFINE(inline, )])
+ AC_DEFINE(inline, ,[Define to empty if your compiler does not support "static inline".])])
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
@@ -331,6 +339,20 @@ AC_TRY_COMPILE([],[long long i = 0; return (0);],
ISC_PLATFORM_HAVELONGLONG="#undef ISC_PLATFORM_HAVELONGLONG"])
AC_SUBST(ISC_PLATFORM_HAVELONGLONG)
+#
+# check for GCC noreturn attribute
+#
+AC_MSG_CHECKING(for GCC noreturn attribute)
+AC_TRY_COMPILE([],[void foo() __attribute__((noreturn));],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE"
+ ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST __attribute__((noreturn))"],
+ [AC_MSG_RESULT(no)
+ ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE"
+ ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST"])
+AC_SUBST(ISC_PLATFORM_NORETURN_PRE)
+AC_SUBST(ISC_PLATFORM_NORETURN_POST)
+
#
# check if we have lifconf
#
@@ -495,6 +517,7 @@ then
fi
done
fi
+OPENSSL_GOST=""
case "$use_openssl" in
no)
AC_MSG_RESULT(no)
@@ -650,6 +673,42 @@ esac
AC_MSG_RESULT(no)
fi
AC_CHECK_FUNCS(EVP_sha256 EVP_sha512)
+
+ AC_MSG_CHECKING(for OpenSSL GOST support)
+ have_gost=""
+ AC_TRY_RUN([
+#include
+#include
+int main() {
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+ ENGINE *e;
+
+ OPENSSL_config(NULL);
+
+ e = ENGINE_by_id("gost");
+ if (e == NULL)
+ return (1);
+ if (ENGINE_init(e) <= 0)
+ return (1);
+ return (0);
+#else
+ return (1);
+#endif
+}
+],
+ [AC_MSG_RESULT(yes)
+ have_gost="yes"],
+ [AC_MSG_RESULT(no)
+ have_gost="no"])
+ case $have_gost in
+ yes)
+ OPENSSL_GOST="yes"
+ AC_DEFINE(HAVE_OPENSSL_GOST, 1,
+ [Define if your OpenSSL version supports GOST.])
+ ;;
+ *)
+ ;;
+ esac
CFLAGS="$saved_cflags"
LIBS="$saved_libs"
OPENSSLLINKOBJS='${OPENSSLLINKOBJS}'
@@ -667,8 +726,33 @@ AC_SUBST(USE_OPENSSL)
AC_SUBST(DST_OPENSSL_INC)
AC_SUBST(OPENSSLLINKOBJS)
AC_SUBST(OPENSSLLINKSRCS)
+AC_SUBST(OPENSSL_GOST)
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
+#
+# Use OpenSSL for hash functions
+#
+
+AC_ARG_ENABLE(openssl-hash,
+ [ --enable-openssl-hash use OpenSSL for hash functions [[default=no]]],
+ want_openssl_hash="$enableval", want_openssl_hash="no")
+case $want_openssl_hash in
+ yes)
+ if test "$USE_OPENSSL" = ""
+ then
+ AC_MSG_ERROR([No OpenSSL for hash functions])
+ fi
+ ISC_PLATFORM_OPENSSLHASH="#define ISC_PLATFORM_OPENSSLHASH 1"
+ ISC_OPENSSL_INC="$DST_OPENSSL_INC"
+ ;;
+ no)
+ ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH"
+ ISC_OPENSSL_INC=""
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_OPENSSLHASH)
+AC_SUBST(ISC_OPENSSL_INC)
+
#
# PKCS11 (aka crypto hardware) support
#
@@ -677,21 +761,37 @@ DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
AC_MSG_CHECKING(for PKCS11 support)
AC_ARG_WITH(pkcs11,
-[ --with-pkcs11 Build with PKCS11 support],
- use_pkcs11="yes", use_pkcs11="no")
+[ --with-pkcs11[=PATH] Build with PKCS11 support [yes|no|path]
+ (PATH is for the PKCS11 provider)],
+ use_pkcs11="$withval", use_pkcs11="no")
case "$use_pkcs11" in
- no)
+ no|'')
AC_MSG_RESULT(disabled)
- USE_PKCS11=""
+ USE_PKCS11=''
+ PKCS11_TOOLS=''
;;
- yes)
+ yes|*)
AC_MSG_RESULT(using OpenSSL with PKCS11 support)
USE_PKCS11='-DUSE_PKCS11'
+ PKCS11_TOOLS=pkcs11
;;
esac
-
AC_SUBST(USE_PKCS11)
+AC_SUBST(PKCS11_TOOLS)
+
+AC_MSG_CHECKING(for PKCS11 tools)
+case "$use_pkcs11" in
+ no|yes|'')
+ AC_MSG_RESULT(disabled)
+ PKCS11_PROVIDER="undefined"
+ ;;
+ *)
+ AC_MSG_RESULT(PKCS11 provider is "$use_pkcs11")
+ PKCS11_PROVIDER="$use_pkcs11"
+ ;;
+esac
+AC_SUBST(PKCS11_PROVIDER)
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
@@ -731,6 +831,9 @@ case "$use_gssapi" in
AC_MSG_ERROR([gssapi.h not found])
fi
+ AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h,
+ [ISC_PLATFORM_GSSAPI_KRB5_HEADER="#define ISC_PLATFORM_GSSAPI_KRB5_HEADER <$ac_header>"])
+
AC_CHECK_HEADERS(krb5.h krb5/krb5.h kerberosv5/krb5.h,
[ISC_PLATFORM_KRB5HEADER="#define ISC_PLATFORM_KRB5HEADER <$ac_header>"])
@@ -775,7 +878,12 @@ case "$use_gssapi" in
# -L/usr/local/lib to LIBS, which can make the
# -lgssapi_krb5 test succeed with shared libraries even
# when you are trying to build with KTH in /usr/lib.
- LIBS="-L$use_gssapi/lib $TRY_LIBS"
+ if test "$use_gssapi" = "/usr"
+ then
+ LIBS="$TRY_LIBS"
+ else
+ LIBS="-L$use_gssapi/lib $TRY_LIBS"
+ fi
AC_MSG_CHECKING(linking as $TRY_LIBS)
AC_TRY_LINK( , [gss_acquire_cred();krb5_init_context()],
gssapi_linked=yes, gssapi_linked=no)
@@ -839,6 +947,7 @@ esac
AC_SUBST(ISC_PLATFORM_HAVEGSSAPI)
AC_SUBST(ISC_PLATFORM_GSSAPIHEADER)
+AC_SUBST(ISC_PLATFORM_GSSAPI_KRB5_HEADER)
AC_SUBST(ISC_PLATFORM_KRB5HEADER)
AC_SUBST(USE_GSSAPI)
@@ -1303,6 +1412,65 @@ case $use_libtool in
;;
esac
+#
+# enable/disable dumping stack backtrace. Also check if the system supports
+# glibc-compatible backtrace() function.
+#
+AC_ARG_ENABLE(backtrace,
+[ --enable-backtrace log stack backtrace on abort [[default=yes]]],
+ want_backtrace="$enableval", want_backtrace="yes")
+case $want_backtrace in
+yes)
+ ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1"
+ AC_TRY_LINK([#include ],
+ [return (backtrace((void **)0, 0));],
+ [AC_DEFINE([HAVE_LIBCTRACE], [], [if system have backtrace function])],)
+ ;;
+*)
+ ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE"
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_USEBACKTRACE)
+
+AC_ARG_ENABLE(symtable,
+[ --enable-symtable use internal symbol table for backtrace
+ [[all|minimal(default)|none]]],
+ want_symtable="$enableval", want_symtable="minimal")
+case $want_symtable in
+yes|all|minimal) # "yes" is a hidden value equivalent to "minimal"
+ if test "$PERL" = ""
+ then
+ AC_MSG_ERROR([Internal symbol table requires perl but no perl is found.
+Install perl or explicitly disable the feature by --disable-symtable.])
+ fi
+ if test "$use_libtool" = "yes"; then
+ AC_MSG_WARN([Internal symbol table does not work with libtool. Disabling symbol table.])
+ else
+ # we generate the internal symbol table only for those systems
+ # known to work to avoid unexpected build failure. Also, warn
+ # about unsupported systems when the feature is enabled
+ # manually.
+ case $host_os in
+ freebsd*|netbsd*|openbsd*|linux*|solaris*|darwin*)
+ MKSYMTBL_PROGRAM="$PERL"
+ if test $want_symtable = all; then
+ ALWAYS_MAKE_SYMTABLE="yes"
+ fi
+ ;;
+ *)
+ if test $want_symtable = yes -o $want_symtable = all
+ then
+ AC_MSG_WARN([this system is not known to generate internal symbol table safely; disabling it])
+ fi
+ esac
+ fi
+ ;;
+*)
+ ;;
+esac
+AC_SUBST(MKSYMTBL_PROGRAM)
+AC_SUBST(ALWAYS_MAKE_SYMTABLE)
+
#
# File name extension for static archive files, for those few places
# where they are treated differently from dynamic ones.
@@ -1319,6 +1487,54 @@ AC_SUBST(LIBTOOL_MODE_LINK)
AC_SUBST(LIBTOOL_ALLOW_UNDEFINED)
AC_SUBST(LIBTOOL_IN_MAIN)
+#
+# build exportable DNS library?
+#
+AC_ARG_ENABLE(exportlib,
+ [ --enable-exportlib build exportable library (GNU make required)
+ [[default=no]]])
+case "$enable_exportlib" in
+ yes)
+ gmake=
+ for x in gmake gnumake make; do
+ if $x --version 2>/dev/null | grep GNU > /dev/null; then
+ gmake=$x
+ break;
+ fi
+ done
+ if test -z "$gmake"; then
+ AC_MSG_ERROR([exportlib requires GNU make. Install it or disable the feature.])
+ fi
+ LIBEXPORT=lib/export
+ AC_SUBST(LIBEXPORT)
+ BIND9_CO_RULE="%.$O: \${srcdir}/%.c"
+ ;;
+ no|*)
+ BIND9_CO_RULE=".c.$O:"
+ ;;
+esac
+AC_SUBST(BIND9_CO_RULE)
+
+AC_ARG_WITH(export-libdir,
+ [ --with-export-libdir[=PATH]
+ installation directory for the export library
+ [[EPREFIX/lib/bind9]]],
+ export_libdir="$withval",)
+if test -z "$export_libdir"; then
+ export_libdir="\${exec_prefix}/lib/bind9/"
+fi
+AC_SUBST(export_libdir)
+
+AC_ARG_WITH(export-includedir,
+ [ --with-export-includedir[=PATH]
+ installation directory for the header files of the
+ export library [[PREFIX/include/bind9]]],
+ export_includedir="$withval",)
+if test -z "$export_includedir"; then
+ export_includedir="\${prefix}/include/bind9/"
+fi
+AC_SUBST(export_includedir)
+
#
# Here begins a very long section to determine the system's networking
# capabilities. The order of the tests is significant.
@@ -1703,10 +1919,13 @@ AC_TRY_COMPILE([
[struct addrinfo a; return (0);],
[AC_MSG_RESULT(yes)
ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO"
+ ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO"
AC_DEFINE(HAVE_ADDRINFO)],
[AC_MSG_RESULT(no)
- ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"])
+ ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"
+ ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1"])
AC_SUBST(ISC_LWRES_NEEDADDRINFO)
+AC_SUBST(ISC_IRS_NEEDADDRINFO)
#
# Check for rrsetinfo
@@ -1793,6 +2012,53 @@ AC_TRY_COMPILE([
ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"])
AC_SUBST(ISC_LWRES_NEEDHERRNO)
+#
+# Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch
+# known variations here:
+#
+AC_MSG_CHECKING(for getnameinfo prototype definitions)
+AC_TRY_COMPILE([
+#include
+#include
+#include
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ socklen_t, char *, socklen_t, unsigned int);],
+[ return (0);],
+ [AC_MSG_RESULT(socklen_t for buflen; u_int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t,
+ [Define to the buffer length type used by getnameinfo(3).])
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, unsigned int,
+ [Define to the flags type used by getnameinfo(3).])],
+[AC_TRY_COMPILE([
+#include
+#include
+#include
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);],
+[ return (0);],
+ [AC_MSG_RESULT(size_t for buflen; int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t)
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)
+AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t)
+AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)])])
+
+#
+# ...and same for gai_strerror().
+#
+AC_MSG_CHECKING(for gai_strerror prototype definitions)
+AC_TRY_COMPILE([
+#include
+#include
+#include
+char *gai_strerror(int ecode);],
+[ return (0); ],
+ [AC_MSG_RESULT(returning char *)
+ AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [char *],
+ [return type of gai_strerror])],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)
+AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [const char *])])
+
AC_CHECK_FUNC(getipnodebyname,
[ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"],
[ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"])
@@ -1807,6 +2073,7 @@ AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR))
AC_SUBST(ISC_LWRES_GETIPNODEPROTO)
AC_SUBST(ISC_LWRES_GETADDRINFOPROTO)
AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
+AC_SUBST(ISC_IRS_GETNAMEINFOSOCKLEN)
AC_ARG_ENABLE(getifaddrs,
[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
@@ -2140,6 +2407,8 @@ AC_SUBST(ISC_PLATFORM_USEDECLSPEC)
ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC"
AC_SUBST(LWRES_PLATFORM_USEDECLSPEC)
LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC"
+AC_SUBST(IRS_PLATFORM_USEDECLSPEC)
+IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC"
#
# Random remaining OS-specific issues involving compiler warnings.
@@ -2460,6 +2729,61 @@ case "$enable_fixed" in
;;
esac
+#
+# Enable response policy rewriting using NS IP addresses
+#
+AC_ARG_ENABLE(rpz-nsip,
+ [ --enable-rpz-nsip enable rpz-nsip rules [[default=no]]],
+ enable_nsip="$enableval",
+ enable_nsip="no")
+case "$enable_nsip" in
+ yes)
+ AC_DEFINE(ENABLE_RPZ_NSIP, 1,
+ [Define to enable rpz-nsip rules.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
+#
+# Enable response policy rewriting using NS name
+#
+AC_ARG_ENABLE(rpz-nsdname,
+ [ --enable-rpz-nsdname enable rpz-nsdname rules [[default=no]]],
+ enable_nsdname="$enableval",
+ enable_nsdname="no")
+case "$enable_nsdname" in
+ yes)
+ AC_DEFINE(ENABLE_RPZ_NSDNAME, 1,
+ [Define to enable rpz-nsdname rules.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
+#
+# Activate "filter-aaaa-on-v4" or not?
+#
+AC_ARG_ENABLE(filter-aaaa,
+ [ --enable-filter-aaaa enable filtering of AAAA records over IPv4
+ [[default=no]]],
+ enable_filter="$enableval",
+ enable_filter="no")
+case "$enable_filter" in
+ yes)
+ AC_DEFINE(ALLOW_FILTER_AAAA_ON_V4, 1,
+ [Define to enable the "filter-aaaa-on-v4" option.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
#
# The following sets up how non-blocking i/o is established.
# Sunos, cygwin and solaris 2.x (x<5) require special handling.
@@ -2780,6 +3104,9 @@ LIBBIND9_API=$srcdir/lib/bind9/api
AC_SUBST_FILE(LIBLWRES_API)
LIBLWRES_API=$srcdir/lib/lwres/api
+AC_SUBST_FILE(LIBIRS_API)
+LIBIRS_API=$srcdir/lib/irs/api
+
#
# Configure any DLZ drivers.
#
@@ -2947,37 +3274,115 @@ AC_CONFIG_COMMANDS(
#
AC_CONFIG_FILES([
+ make/Makefile
+ make/mkdep
Makefile
- make/Makefile
- make/mkdep
+ bin/Makefile
+ bin/check/Makefile
+ bin/confgen/Makefile
+ bin/confgen/unix/Makefile
+ bin/dig/Makefile
+ bin/dnssec/Makefile
+ bin/named/Makefile
+ bin/named/unix/Makefile
+ bin/nsupdate/Makefile
+ bin/pkcs11/Makefile
+ bin/rndc/Makefile
+ bin/tests/Makefile
+ bin/tests/atomic/Makefile
+ bin/tests/db/Makefile
+ bin/tests/dst/Makefile
+ bin/tests/hashes/Makefile
+ bin/tests/headerdep_test.sh
+ bin/tests/master/Makefile
+ bin/tests/mem/Makefile
+ bin/tests/names/Makefile
+ bin/tests/net/Makefile
+ bin/tests/rbt/Makefile
+ bin/tests/resolver/Makefile
+ bin/tests/sockaddr/Makefile
+ bin/tests/system/Makefile
+ bin/tests/system/conf.sh
+ bin/tests/system/filter-aaaa/Makefile
+ bin/tests/system/gost/prereq.sh
+ bin/tests/system/lwresd/Makefile
+ bin/tests/system/rpz/Makefile
+ bin/tests/system/tkey/Makefile
+ bin/tests/tasks/Makefile
+ bin/tests/timers/Makefile
+ bin/tests/virtual-time/Makefile
+ bin/tests/virtual-time/conf.sh
+ bin/tools/Makefile
+ contrib/check-secure-delegation.pl
+ contrib/zone-edit.sh
+ doc/Makefile
+ doc/arm/Makefile
+ doc/doxygen/Doxyfile
+ doc/doxygen/Makefile
+ doc/doxygen/doxygen-input-filter
+ doc/misc/Makefile
+ doc/xsl/Makefile
+ doc/xsl/isc-docbook-chunk.xsl
+ doc/xsl/isc-docbook-html.xsl
+ doc/xsl/isc-docbook-latex.xsl
+ doc/xsl/isc-manpage.xsl
+ isc-config.sh
lib/Makefile
+ lib/bind9/Makefile
+ lib/bind9/include/Makefile
+ lib/bind9/include/bind9/Makefile
+ lib/dns/Makefile
+ lib/dns/include/Makefile
+ lib/dns/include/dns/Makefile
+ lib/dns/include/dst/Makefile
+ lib/export/Makefile
+ lib/export/dns/Makefile
+ lib/export/dns/include/Makefile
+ lib/export/dns/include/dns/Makefile
+ lib/export/dns/include/dst/Makefile
+ lib/export/irs/Makefile
+ lib/export/irs/include/Makefile
+ lib/export/irs/include/irs/Makefile
+ lib/export/isc/$thread_dir/Makefile
+ lib/export/isc/$thread_dir/include/Makefile
+ lib/export/isc/$thread_dir/include/isc/Makefile
+ lib/export/isc/Makefile
+ lib/export/isc/include/Makefile
+ lib/export/isc/include/isc/Makefile
+ lib/export/isc/nls/Makefile
+ lib/export/isc/unix/Makefile
+ lib/export/isc/unix/include/Makefile
+ lib/export/isc/unix/include/isc/Makefile
+ lib/export/isccfg/Makefile
+ lib/export/isccfg/include/Makefile
+ lib/export/isccfg/include/isccfg/Makefile
+ lib/export/samples/Makefile
+ lib/export/samples/Makefile-postinstall
+ lib/irs/Makefile
+ lib/irs/include/Makefile
+ lib/irs/include/irs/Makefile
+ lib/irs/include/irs/netdb.h
+ lib/irs/include/irs/platform.h
+ lib/isc/$arch/Makefile
+ lib/isc/$arch/include/Makefile
+ lib/isc/$arch/include/isc/Makefile
+ lib/isc/$thread_dir/Makefile
+ lib/isc/$thread_dir/include/Makefile
+ lib/isc/$thread_dir/include/isc/Makefile
lib/isc/Makefile
lib/isc/include/Makefile
lib/isc/include/isc/Makefile
lib/isc/include/isc/platform.h
+ lib/isc/nls/Makefile
lib/isc/unix/Makefile
lib/isc/unix/include/Makefile
lib/isc/unix/include/isc/Makefile
- lib/isc/nls/Makefile
- lib/isc/$thread_dir/Makefile
- lib/isc/$thread_dir/include/Makefile
- lib/isc/$thread_dir/include/isc/Makefile
- lib/isc/$arch/Makefile
- lib/isc/$arch/include/Makefile
- lib/isc/$arch/include/isc/Makefile
lib/isccc/Makefile
lib/isccc/include/Makefile
lib/isccc/include/isccc/Makefile
lib/isccfg/Makefile
lib/isccfg/include/Makefile
lib/isccfg/include/isccfg/Makefile
- lib/dns/Makefile
- lib/dns/include/Makefile
- lib/dns/include/dns/Makefile
- lib/dns/include/dst/Makefile
- lib/bind9/Makefile
- lib/bind9/include/Makefile
- lib/bind9/include/bind9/Makefile
lib/lwres/Makefile
lib/lwres/include/Makefile
lib/lwres/include/lwres/Makefile
@@ -2990,44 +3395,6 @@ AC_CONFIG_FILES([
lib/tests/Makefile
lib/tests/include/Makefile
lib/tests/include/tests/Makefile
- bin/Makefile
- bin/check/Makefile
- bin/named/Makefile
- bin/named/unix/Makefile
- bin/rndc/Makefile
- bin/rndc/unix/Makefile
- bin/dig/Makefile
- bin/nsupdate/Makefile
- bin/tests/Makefile
- bin/tests/names/Makefile
- bin/tests/master/Makefile
- bin/tests/rbt/Makefile
- bin/tests/db/Makefile
- bin/tests/tasks/Makefile
- bin/tests/timers/Makefile
- bin/tests/dst/Makefile
- bin/tests/mem/Makefile
- bin/tests/hashes/Makefile
- bin/tests/net/Makefile
- bin/tests/sockaddr/Makefile
- bin/tests/system/Makefile
- bin/tests/system/conf.sh
- bin/tests/system/lwresd/Makefile
- bin/tests/system/tkey/Makefile
- bin/tests/headerdep_test.sh
- bin/dnssec/Makefile
- doc/Makefile
- doc/arm/Makefile
- doc/misc/Makefile
- isc-config.sh
- doc/xsl/Makefile
- doc/xsl/isc-docbook-chunk.xsl
- doc/xsl/isc-docbook-html.xsl
- doc/xsl/isc-docbook-latex.xsl
- doc/xsl/isc-manpage.xsl
- doc/doxygen/Doxyfile
- doc/doxygen/Makefile
- doc/doxygen/doxygen-input-filter
])
#
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 0013c2e7f68..c3517843175 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[]>
-
+
BIND 9 Administrator Reference Manual
@@ -31,6 +31,7 @@
200820092010
+ 2011Internet Systems Consortium, Inc. ("ISC")
@@ -69,7 +70,7 @@
- This version of the manual corresponds to BIND version 9.6.
+ This version of the manual corresponds to BIND version 9.7.
@@ -644,9 +645,9 @@
ISC BIND 9 compiles and runs on a large
number
- of Unix-like operating systems and on NT-derived versions of
- Microsoft Windows such as Windows 2000 and Windows XP. For an
- up-to-date
+ of Unix-like operating systems and on
+ Microsoft Windows Server 2003 and 2008, and Windows XP and Vista.
+ For an up-to-date
list of supported systems, see the README file in the top level
directory
of the BIND 9 source distribution.
@@ -680,10 +681,13 @@
// Two corporate subnets we wish to allow queries from.
acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
options {
- directory "/etc/namedb"; // Working directory
+ // Working directory
+ directory "/etc/namedb";
+
allow-query { corpnets; };
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -703,13 +707,18 @@ zone "0.0.127.in-addr.arpa" {
options {
- directory "/etc/namedb"; // Working directory
- allow-query-cache { none; }; // Do not allow access to cache
- allow-query { any; }; // This is the default
- recursion no; // Do not provide recursive service
+ // Working directory
+ directory "/etc/namedb";
+ // Do not allow access to cache
+ allow-query-cache { none; };
+ // This is the default
+ allow-query { any; };
+ // Do not provide recursive service
+ recursion no;
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -719,7 +728,8 @@ zone "0.0.127.in-addr.arpa" {
zone "example.com" {
type master;
file "example.com.db";
- // IP addresses of slave servers allowed to transfer example.com
+ // IP addresses of slave servers allowed to
+ // transfer example.com
allow-transfer {
192.168.4.14;
192.168.5.53;
@@ -881,7 +891,7 @@ zone "eng.example.com" {
For more detail on ordering responses, check the
- rrset-order substatement in the
+ rrset-order sub-statement in the
options statement, see
.
@@ -1162,7 +1172,62 @@ zone "eng.example.com" {
+ sign zone
+ class
+ view
+
+
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ key-directory in
+ ). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. If the DNSKEY RRset
+ is changed, then the zone is automatically
+ re-signed with the new key set.
+
+
+ This command requires that the
+ auto-dnssec zone option to be set
+ to allow,
+ maintain, or
+ create, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See for
+ more details.
+
+
+
+
+ loadkeys zone
+ class
+ view
+
+
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ key-directory in
+ ). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. Unlike rndc
+ sign, however, the zone is not
+ immediately re-signed by the new keys, but is
+ allowed to incrementally re-sign over time.
+
+
+ This command requires that the
+ auto-dnssec zone option to
+ be set to maintain or
+ create, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See for
+ more details.
+
+
+
+
+ freeze
zoneclass
@@ -1270,6 +1335,19 @@ zone "eng.example.com" {
+
+ secroots
+ view ...
+
+
+ Dump the server's security roots to the secroots
+ file for the specified views. If no view is
+ specified, security roots for all
+ views are dumped.
+
+
+
+
stop -p
@@ -1383,6 +1461,65 @@ zone "eng.example.com" {
+
+ addzone
+ zone
+ class
+ view
+ configuration
+
+
+
+ Add a zone while the server is running. This
+ command requires the
+ allow-new-zones option to be set
+ to yes. The
+ configuration string
+ specified on the command line is the zone
+ configuration text that would ordinarily be
+ placed in named.conf.
+
+
+ The configuration is saved in a file called
+ hash.nzf,
+ where hash is a
+ cryptographic hash generated from the name of
+ the view. When named is
+ restarted, the file will be loaded into the view
+ configuration, so that zones that were added
+ can persist after a restart.
+
+
+ This sample addzone command
+ would add the zone example.com
+ to the default view:
+
+
+$ rndc addzone example.com '{ type master; file "example.com.db"; };'
+
+
+ (Note the brackets and semi-colon around the zone
+ configuration text.)
+
+
+
+
+
+ delzone
+ zone
+ class
+ view
+
+
+
+ Delete a zone while the server is running.
+ Only zones that were originally added via
+ rndc addzone can be deleted
+ in this matter.
+
+
+
+
@@ -1488,7 +1625,8 @@ zone "eng.example.com" {
key rndc_key {
algorithm "hmac-md5";
- secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
+ secret
+ "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
options {
default-server 127.0.0.1;
@@ -1514,7 +1652,8 @@ options {
controls {
- inet 127.0.0.1 allow { localhost; } keys { rndc_key; };
+ inet 127.0.0.1
+ allow { localhost; } keys { rndc_key; };
};
@@ -1641,14 +1780,27 @@ controls {
Dynamic update is enabled by including an
- allow-update or update-policy
- clause in the zone statement. The
- tkey-gssapi-credential and
- tkey-domain clauses in the
- options statement enable the
- server to negotiate keys that can be matched against those
- in update-policy or
- allow-update.
+ allow-update or an update-policy
+ clause in the zone statement.
+
+
+
+ If the zone's update-policy is set to
+ local, updates to the zone
+ will be permitted for the key local-ddns,
+ which will be generated by named at startup.
+ See for more details.
+
+
+
+ Dynamic updates using Kerberos signed requests can be made
+ using the TKEY/GSS protocol by setting either the
+ tkey-gssapi-keytab option, or alternatively
+ by setting both the tkey-gssapi-credential
+ and tkey-domain options. Once enabled,
+ Kerberos signed requests will be matched against the update
+ policies for the zone, using the Kerberos principal as the
+ signer for the request.
@@ -1660,7 +1812,7 @@ controls {
- The journal file
+ The journal file
All changes made to a zone using dynamic update are stored
@@ -1814,7 +1966,7 @@ controls {
and site2.example.com, to the servers
in the
DMZ. These internal servers will have complete sets of information
- for site1.example.com, site2.example.com,site1.internal,
+ for site1.example.com, site2.example.com, site1.internal,
and site2.internal.
@@ -1927,26 +2079,32 @@ options {
...
...
forward only;
- forwarders { // forward to external servers
+ // forward to external servers
+ forwarders {
bastion-ips-go-here;
};
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { internals; externals; }; // restrict query access
- allow-recursion { internals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // restrict query access
+ allow-query { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; };
...
...
};
-zone "site1.example.com" { // sample master zone
+// sample master zone
+zone "site1.example.com" {
type master;
file "m/site1.example.com";
- forwarders { }; // do normal iterative
- // resolution (do not forward)
+ // do normal iterative resolution (do not forward)
+ forwarders { };
allow-query { internals; externals; };
allow-transfer { internals; };
};
-zone "site2.example.com" { // sample slave zone
+// sample slave zone
+zone "site2.example.com" {
type slave;
file "s/site2.example.com";
masters { 172.16.72.3; };
@@ -1985,15 +2143,20 @@ acl externals { bastion-ips-go-here; };
options {
...
...
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { any; }; // default query access
- allow-query-cache { internals; externals; }; // restrict cache access
- allow-recursion { internals; externals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // default query access
+ allow-query { any; };
+ // restrict cache access
+ allow-query-cache { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; externals; };
...
...
};
-zone "site1.example.com" { // sample slave zone
+// sample slave zone
+zone "site1.example.com" {
type master;
file "m/site1.foo.com";
allow-transfer { internals; externals; };
@@ -2187,9 +2350,8 @@ allow-update { key host1-host2. ;};
- You may want to read about the more powerful
- update-policy statement in
- .
+ See for a discussion of
+ the more flexible update-policy statement.
@@ -2453,12 +2615,23 @@ allow-update { key host1-host2. ;};
To enable named to validate answers from
- other servers, the dnssec-enable and
- dnssec-validation options must both be
- set to yes (the default setting in BIND 9.5
- and later), and at least one trust anchor must be configured
- with a trusted-keys statement in
- named.conf.
+ other servers, the dnssec-enable option
+ must be set to yes, and the
+ dnssec-validation options must be set to
+ yes or auto.
+
+
+
+ If dnssec-validation is set to
+ auto, then a default
+ trust anchor for the DNS root zone will be used.
+ If it is set to yes, however,
+ then at least one trust anchor must be configured
+ with a trusted-keys or
+ managed-keys statement in
+ named.conf, or DNSSEC validation
+ will not occur. The default setting is
+ yes.
@@ -2471,7 +2644,14 @@ allow-update { key host1-host2. ;};
- trusted-keys are described in more detail
+ managed-keys are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+
+
+
+ trusted-keys and
+ managed-keys are described in more detail
later in this document.
@@ -2484,45 +2664,59 @@ allow-update { key host1-host2. ;};
After DNSSEC gets established, a typical DNSSEC configuration
- will look something like the following. It has a one or
+ will look something like the following. It has one or
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that named is immune
- to compromises in the DNSSEC components of the security
- of parent zones.
+ controls. These are here to ensure that named
+ is immune to compromises in the DNSSEC components of the security
+ of parent zones.
-trusted-keys {
-
+managed-keys {
/* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwSJxrGkxJWoZu6I7PzJu/
- E9gx4UC1zGAHlXKdE4zYIpRhaBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3
- zy2Xy4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYghf+6fElrmLkdaz
- MQ2OCnACR817DF4BBa7UR/beDHyp5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M
- /lUUVRbkeg1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq66gKodQj+M
- iA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ97S+LKUTpQcq27R7AT3/V5hRQxScI
- Nqwcz4jYqZD2fQdgxbcDTClU0CRBdiieyLMNzXG3";
+ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
+ JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
+ aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
+ 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
+ hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
+ 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
+ g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
+ 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
+ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
+ dgxbcDTClU0CRBdiieyLMNzXG3";
+};
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM65KbhTjrW1ZaARmPhEZZe
- 3Y9ifgEuq7vZ/zGZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb4JKUbb
- OTcM8pwXlj0EiX3oDFVmjHO444gLkBO UKUf/mC7HvfwYH/Be22GnC
- lrinKJp1Og4ywzO9WglMk7jbfW33gUKvirTHr25GL7STQUzBb5Usxt
- 8lgnyTUHs1t3JwCY5hKZ6CqFxmAVZP20igTixin/1LcrgX/KMEGd/b
- iuvF4qJCyduieHukuY3H4XMAcR+xia2 nIUPvm/oyWR8BW/hWdzOvn
- SCThlHf3xiYleDbt/o1OTQ09A0=";
+trusted-keys {
+ /* Key for our organization's forward zone */
+ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
+ 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
+ GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
+ 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
+ kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
+ g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
+ TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
+ FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
+ F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
+ /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
+ 1OTQ09A0=";
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwcxOdNax071L18QqZnQQQA
- VVr+iLhGTnNGp3HoWQLUIzKrJVZ3zggy3WwNT6kZo6c0
- tszYqbtvchmgQC8CzKojM/W16i6MG/ea fGU3siaOdS0
- yOI6BgPsw+YZdzlYMaIJGf4M4dyoKIhzdZyQ2bYQrjyQ
- 4LB0lC7aOnsMyYKHHYeRv PxjIQXmdqgOJGq+vsevG06
- zW+1xgYJh9rCIfnm1GX/KMgxLPG2vXTD/RnLX+D3T3UL
- 7HJYHJhAZD5L59VvjSPsZJHeDCUyWYrvPZesZDIRvhDD
- 52SKvbheeTJUm6EhkzytNN2SN96QRk8j/iI8ib";
+ /* Key for our reverse zone. */
+ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
+ xOdNax071L18QqZnQQQAVVr+i
+ LhGTnNGp3HoWQLUIzKrJVZ3zg
+ gy3WwNT6kZo6c0tszYqbtvchm
+ gQC8CzKojM/W16i6MG/eafGU3
+ siaOdS0yOI6BgPsw+YZdzlYMa
+ IJGf4M4dyoKIhzdZyQ2bYQrjy
+ Q4LB0lC7aOnsMyYKHHYeRvPxj
+ IQXmdqgOJGq+vsevG06zW+1xg
+ YJh9rCIfnm1GX/KMgxLPG2vXT
+ D/RnLX+D3T3UL7HJYHJhAZD5L
+ 59VvjSPsZJHeDCUyWYrvPZesZ
+ DIRvhDD52SKvbheeTJUm6Ehkz
+ ytNN2SN96QRk8j/iI8ib";
};
options {
@@ -2575,6 +2769,13 @@ options {
+
+
+
+
+
+
+
IPv6 Support in BIND 9
@@ -2653,7 +2854,8 @@ host 3600 IN AAAA 2001:db8::1
$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com.
+1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR (
+ host.example.com. )
@@ -2828,6 +3030,19 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
+
+
+
+ namelist
+
+
+
+
+ A list of one or more domain_name
+ elements.
+
+
+
@@ -3224,7 +3439,8 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
/* This is a BIND comment as in C */// This is a BIND comment as in C++
- # This is a BIND comment as in common UNIX shells and perl
+ # This is a BIND comment as in common UNIX shells
+# and perl
@@ -3437,6 +3653,17 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
+
+
+ managed-keys
+
+
+
+ lists DNSSEC keys to be kept up to date
+ using RFC 5011 trust anchor maintenance.
+
+
+ view
@@ -3559,10 +3786,12 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
controls Statement Grammarcontrols {
- [ inet ( ip_addr | * ) [ port ip_port ] allow { address_match_list }
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ allow { address_match_list }
keys { key_list }; ]
[ inet ...; ]
- [ unix path perm number owner number group number keys { key_list }; ]
+ [ unix path perm number owner number group number
+ keys { key_list }; ]
[ unix ...; ]
};
@@ -4031,32 +4260,30 @@ notrace. All debugging messages in the server have a debug
channel default_syslog {
- syslog daemon; // send to syslog's daemon
- // facility
- severity info; // only send priority info
- // and higher
-};
+ // send to syslog's daemon facility
+ syslog daemon;
+ // only send priority info and higher
+ severity info;
channel default_debug {
- file "named.run"; // write to named.run in
- // the working directory
- // Note: stderr is used instead
- // of "named.run"
- // if the server is started
- // with the '-f' option.
- severity dynamic; // log at the server's
- // current debug level
+ // write to named.run in the working directory
+ // Note: stderr is used instead of "named.run" if
+ // the server is started with the '-f' option.
+ file "named.run";
+ // log at the server's current debug level
+ severity dynamic;
};
channel default_stderr {
- stderr; // writes to stderr
- severity info; // only send priority info
- // and higher
+ // writes to stderr
+ stderr;
+ // only send priority info and higher
+ severity info;
};
channel null {
- null; // toss anything sent to
- // this channel
+ // toss anything sent to this channel
+ null;
};
@@ -4308,12 +4535,14 @@ category notify { null; };
The query log entry reports the client's IP
address and port number, and the query name,
- class and type. It also reports whether the
+ class and type. Next it reports whether the
Recursion Desired flag was set (+ if set, -
if not set), if the query was signed (S),
- EDNS was in use (E), if DO (DNSSEC Ok) was
- set (D), or if CD (Checking Disabled) was set
- (C).
+ EDNS was in use (E), if TCP was used (T), if
+ DO (DNSSEC Ok) was set (D), or if CD (Checking
+ Disabled) was set (C). After this the
+ destination address the query was sent to is
+ reported.
@@ -4453,7 +4682,13 @@ category notify { null; };
The log message will look like as follows:
- fetch completed at resolver.c:2970 for www.example.com/A in 30.000183: timed out/success [domain:example.com,referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,badresp:1,adberr:0,findfail:0,valfail:0]
+
+
+fetch completed at resolver.c:2970 for www.example.com/A
+in 30.000183: timed out/success [domain:example.com,
+referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,
+badresp:1,adberr:0,findfail:0,valfail:0]
+
The first part before the colon shows that a recursive
@@ -4485,8 +4720,8 @@ category notify { null; };
-
-
+
+
@@ -4651,7 +4886,8 @@ category notify { null; };
lwres {
- listen-on { ip_addrport ip_port ; ip_addrport ip_port ; ... };
+ listen-on { ip_addrport ip_port ;
+ ip_addrport ip_port ; ... }; view view_name; search { domain_name ; domain_name ; ... }; ndots number;
@@ -4718,7 +4954,8 @@ category notify { null; };
masters Statement Grammar
-mastersnameport ip_port { ( masters_list | ip_addrport ip_portkey key ) ; ... };
+mastersnameport ip_port { ( masters_list |
+ ip_addrport ip_portkey key ) ; ... };
@@ -4741,17 +4978,21 @@ category notify { null; };
options {
+ attach-cache cache_name; version version_string; hostname hostname_string; server-id server_id_string; directory path_name; key-directory path_name;
+ managed-keys-directory path_name; named-xfer path_name;
+ tkey-gssapi-keytab path_name; tkey-gssapi-credential principal; tkey-domain domainname; tkey-dhkey key_namekey_tag; cache-file path_name; dump-file path_name;
+ bindkeys-file path_name; memstatistics yes_or_no; memstatistics-file path_name; pid-file path_name;
@@ -4776,8 +5017,9 @@ category notify { null; };
maintain-ixfr-base yes_or_no; ixfr-from-differences (yes_or_no | master | slave); dnssec-enable yes_or_no;
- dnssec-validation yes_or_no;
- dnssec-lookaside domain trust-anchor domain;
+ dnssec-validation (yes_or_no | auto);
+ dnssec-lookaside ( auto |
+ domain trust-anchor domain ); dnssec-must-be-secure domain yes_or_no; dnssec-accept-expired yes_or_no; forward ( only | first );
@@ -4788,12 +5030,14 @@ category notify { null; };
... };
check-names ( master | slave | response )
( warn | fail | ignore );
+ check-dup-records ( warn | fail | ignore ); check-mx ( warn | fail | ignore ); check-wildcard yes_or_no; check-integrity yes_or_no; check-mx-cname ( warn | fail | ignore ); check-srv-cname ( warn | fail | ignore ); check-sibling yes_or_no;
+ allow-new-zones { yes_or_no }; allow-notify { address_match_list }; allow-query { address_match_list }; allow-query-on { address_match_list };
@@ -4805,6 +5049,8 @@ category notify { null; };
allow-update { address_match_list }; allow-update-forwarding { address_match_list }; update-check-ksk yes_or_no;
+ dnssec-dnskey-kskonly yes_or_no;
+ dnssec-secure-to-insecure yes_or_no ; try-tcp-refresh yes_or_no; allow-v6-synthesis { address_match_list }; blackhole { address_match_list };
@@ -4816,12 +5062,12 @@ category notify { null; };
listen-on-v6 port ip_port { address_match_list }; query-source ( ( ip4_addr | * )
port ( ip_port | * ) |
- address ( ip4_addr | * )
- port ( ip_port | * ) ) ;
+ address ( ip4_addr | * )
+ port ( ip_port | * ) ) ;
query-source-v6 ( ( ip6_addr | * )
- port ( ip_port | * ) |
- address ( ip6_addr | * )
- port ( ip_port | * ) ) ;
+ port ( ip_port | * ) |
+ address ( ip6_addr | * )
+ port ( ip_port | * ) ) ;
use-queryport-pool yes_or_no; queryport-pool-ports number; queryport-pool-updateinterval number;
@@ -4842,13 +5088,15 @@ category notify { null; };
transfer-source (ip4_addr | *) port ip_port ; transfer-source-v6 (ip6_addr | *) port ip_port ; alt-transfer-source (ip4_addr | *) port ip_port ;
- alt-transfer-source-v6 (ip6_addr | *) port ip_port ;
+ alt-transfer-source-v6 (ip6_addr | *)
+ port ip_port ; use-alt-transfer-source yes_or_no; notify-delay seconds ; notify-source (ip4_addr | *) port ip_port ; notify-source-v6 (ip6_addr | *) port ip_port ; notify-to-soa yes_or_no ;
- also-notify { ip_addrport ip_port ; ip_addrport ip_port ; ... };
+ also-notify { ip_addrport ip_port ;
+ ip_addrport ip_port ; ... }; max-ixfr-log-size number; max-journal-size size_spec; coresize size_spec ;
@@ -4884,12 +5132,25 @@ category notify { null; };
random-device path_name ; max-cache-size size_spec ; match-mapped-addresses yes_or_no;
+ filter-aaaa-on-v4 ( yes_or_no | break-dnssec );
+ filter-aaaa { address_match_list };
+ dns64 IPv6-prefix {
+ clients { address_match_list };
+ mapped { address_match_list };
+ exclude { address_match_list };
+ suffix IPv6-address;
+ recursive-only yes_or_no;
+ break-dnssec yes_or_no;
+ }; ;
+ dns64-server name
+ dns64-contact name preferred-glue ( A | AAAA | NONE ); edns-udp-size number; max-udp-size number; root-delegation-only exclude { namelist } ; querylog yes_or_no ;
- disable-algorithms domain { algorithm; algorithm; };
+ disable-algorithms domain { algorithm;
+ algorithm; }; acache-enable yes_or_no ; acache-cleaning-interval number; max-acache-size size_spec ;
@@ -4902,6 +5163,10 @@ category notify { null; };
disable-empty-zone zone_name ; zero-no-soa-ttl yes_or_no ; zero-no-soa-ttl-cache yes_or_no ;
+ resolver-query-timeout number ;
+ deny-answer-addresses { address_match_list } except-from { namelist } ;
+ deny-answer-aliases { namelist } except-from { namelist } ;
+ response-policy { zone_name policy given | no-op | nxdomain | nodata | cname domain ; } ;
};
@@ -4923,6 +5188,102 @@ category notify { null; };
+
+ attach-cache
+
+
+ Allows multiple views to share a single cache
+ database.
+ Each view has its own cache database by default, but
+ if multiple views have the same operational policy
+ for name resolution and caching, those views can
+ share a single cache to save memory and possibly
+ improve resolution efficiency by using this option.
+
+
+
+ The attach-cache option
+ may also be specified in view
+ statements, in which case it overrides the
+ global attach-cache option.
+
+
+
+ The cache_name specifies
+ the cache to be shared.
+ When the named server configures
+ views which are supposed to share a cache, it
+ creates a cache with the specified name for the
+ first view of these sharing views.
+ The rest of the views will simply refer to the
+ already created cache.
+
+
+
+ One common configuration to share a cache would be to
+ allow all views to share a single cache.
+ This can be done by specifying
+ the attach-cache as a global
+ option with an arbitrary name.
+
+
+
+ Another possible operation is to allow a subset of
+ all views to share a cache while the others to
+ retain their own caches.
+ For example, if there are three views A, B, and C,
+ and only A and B should share a cache, specify the
+ attach-cache option as a view A (or
+ B)'s option, referring to the other view name:
+
+
+
+ view "A" {
+ // this view has its own cache
+ ...
+ };
+ view "B" {
+ // this view refers to A's cache
+ attach-cache "A";
+ };
+ view "C" {
+ // this view has its own cache
+ ...
+ };
+
+
+
+ Views that share a cache must have the same policy
+ on configurable parameters that may affect caching.
+ The current implementation requires the following
+ configurable options be consistent among these
+ views:
+ check-names,
+ cleaning-interval,
+ dnssec-accept-expired,
+ dnssec-validation,
+ max-cache-ttl,
+ max-ncache-ttl,
+ max-cache-size, and
+ zero-no-soa-ttl.
+
+
+
+ Note that there may be other parameters that may
+ cause confusion if they are inconsistent for
+ different views that share a single cache.
+ For example, if these views define different sets of
+ forwarders that can return different answers for the
+ same question, sharing the answer does not make
+ sense or could even be harmful.
+ It is administrator's responsibility to ensure
+ configuration differences in different views do
+ not cause disruption with a shared cache.
+
+
+
+
+
directory
@@ -4950,10 +5311,24 @@ category notify { null; };
When performing dynamic update of secure zones, the
directory where the public and private DNSSEC key files
should be found, if different than the current working
- directory. The directory specified must be an absolute
- path. (Note that this option has no effect on the paths
- for files containing non-DNSSEC keys such as the
- rndc.key.
+ directory. (Note that this option has no effect on the
+ paths for files containing non-DNSSEC keys such as
+ bind.keys,
+ rndc.key or
+ session.key.)
+
+
+
+
+
+ managed-keys-directory
+
+
+ The directory used to hold the files used to track managed keys.
+ By default it is the working directory. It there are no
+ views then the file managed-keys.bind
+ otherwise a SHA256 hash of the view name is used with
+ .mkeys extension added.
@@ -4972,6 +5347,18 @@ category notify { null; };
+
+ tkey-gssapi-keytab
+
+
+ The KRB5 keytab file to use for GSS-TSIG updates. If
+ this option is set and tkey-gssapi-credential is not
+ set, then updates will be allowed with any key
+ matching a principal in the specified keytab.
+
+
+
+
tkey-gssapi-credential
@@ -4979,13 +5366,15 @@ category notify { null; };
The security credential with which the server should
authenticate keys requested by the GSS-TSIG protocol.
Currently only Kerberos 5 authentication is available
- and the credential is a Kerberos principal which
- the server can acquire through the default system
- key file, normally /etc/krb5.keytab.
- Normally this principal is of the form
- "DNS/server.domain".
- To use GSS-TSIG, tkey-domain
- must also be set.
+ and the credential is a Kerberos principal which the
+ server can acquire through the default system key
+ file, normally /etc/krb5.keytab.
+ The location keytab file can be overridden using the
+ tkey-gssapi-keytab option. Normally this principal is
+ of the form "DNS/server.domain".
+ To use GSS-TSIG, tkey-domain must
+ also be set if a specific keytab is not set with
+ tkey-gssapi-keytab.
@@ -5007,7 +5396,8 @@ category notify { null; };
should be the server's domain name, or an otherwise
non-existent subdomain like
"_tkey.domainname". If you are
- using GSS-TSIG, this variable must be defined.
+ using GSS-TSIG, this variable must be defined, unless
+ you specify a specific keytab using tkey-gssapi-keytab.
@@ -5105,6 +5495,84 @@ category notify { null; };
+
+ bindkeys-file
+
+
+ The pathname of a file to override the built-in trusted
+ keys provided by named.
+ See the discussion of dnssec-lookaside
+ and dnssec-validation for details.
+ If not specified, the default is
+ /etc/bind.keys.
+
+
+
+
+
+ secroots-file
+
+
+ The pathname of the file the server dumps
+ security roots to when instructed to do so with
+ rndc secroots.
+ If not specified, the default is named.secroots.
+
+
+
+
+
+ session-keyfile
+
+
+ The pathname of the file into which to write a TSIG
+ session key generated by named for use by
+ nsupdate -l. If not specified, the
+ default is /var/run/named/session.key.
+ (See , and in
+ particular the discussion of the
+ update-policy statement's
+ local option for more
+ information about this feature.)
+
+
+
+
+
+ session-keyname
+
+
+ The key name to use for the TSIG session key.
+ If not specified, the default is "local-ddns".
+
+
+
+
+
+ session-keyalg
+
+
+ The algorithm to use for the TSIG session key.
+ Valid values are hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384, hmac-sha512 and hmac-md5. If not
+ specified, the default is hmac-sha256.
+
+
+
+
+
+ session-keyfile
+
+
+ The pathname of the file into which to write a session TSIG
+ key for use by nsupdate -l. (See the
+ discussion of the update-policy
+ statement's local option for more
+ details on this feature.)
+
+
+
+
port
@@ -5167,14 +5635,14 @@ category notify { null; };
DS queries are expected to be made to and be answered by
delegation only zones. Such queries and responses are
- treated as a exception to delegation-only processing
+ treated as an exception to delegation-only processing
and are not converted to NXDOMAIN responses provided
a CNAME is not discovered at the query name.
If a delegation only zone server also serves a child
zone it is not always possible to determine whether
- a answer comes from the delegation only zone or the
+ an answer comes from the delegation only zone or the
child zone. SOA NS and DNSKEY records are apex
only records and a matching response that contains
these records or DS is treated as coming from a
@@ -5223,21 +5691,46 @@ options {
dnssec-lookaside
- When set, dnssec-lookaside
- provides the
- validator with an alternate method to validate DNSKEY records
- at the
- top of a zone. When a DNSKEY is at or below a domain
- specified by the
- deepest dnssec-lookaside, and
- the normal DNSSEC validation
- has left the key untrusted, the trust-anchor will be append to
- the key
- name and a DLV record will be looked up to see if it can
- validate the
- key. If the DLV record validates a DNSKEY (similarly to the
- way a DS
+ When set, dnssec-lookaside provides the
+ validator with an alternate method to validate DNSKEY
+ records at the top of a zone. When a DNSKEY is at or
+ below a domain specified by the deepest
+ dnssec-lookaside, and the normal DNSSEC
+ validation has left the key untrusted, the trust-anchor
+ will be appended to the key name and a DLV record will be
+ looked up to see if it can validate the key. If the DLV
+ record validates a DNSKEY (similarly to the way a DS
record does) the DNSKEY RRset is deemed to be trusted.
+
+
+ If dnssec-lookaside is set to
+ auto, then built-in default
+ values for the DLV domain and trust anchor will be
+ used, along with a built-in key for validation.
+
+
+ The default DLV key is stored in the file
+ bind.keys;
+ named will load that key at
+ startup if dnssec-lookaside is set to
+ auto. A copy of the file is
+ installed along with BIND 9, and is
+ current as of the release date. If the DLV key expires, a
+ new copy of bind.keys can be downloaded
+ from https://www.isc.org/solutions/dlv.
+
+
+ (To prevent problems if bind.keys is
+ not found, the current key is also compiled in to
+ named. Relying on this is not
+ recommended, however, as it requires named
+ to be recompiled with a new key when the DLV key expires.)
+
+
+ NOTE: named only loads certain specific
+ keys from bind.keys: those for the
+ DLV zone and for the DNS root zone. The file cannot be
+ used to store keys for other zones.
@@ -5246,21 +5739,86 @@ options {
dnssec-must-be-secure
- Specify hierarchies which must be or may not be secure (signed and
- validated).
- If yes, then named will only accept
- answers if they
- are secure.
- If no, then normal DNSSEC validation
- applies
- allowing for insecure answers to be accepted.
- The specified domain must be under a trusted-key or
- dnssec-lookaside must be
- active.
+ Specify hierarchies which must be or may not be secure
+ (signed and validated). If yes,
+ then named will only accept answers if
+ they are secure. If no, then normal
+ DNSSEC validation applies allowing for insecure answers to
+ be accepted. The specified domain must be under a
+ trusted-keys or
+ managed-keys statement, or
+ dnssec-lookaside must be active.
+
+ dns64
+
+
+ This directive instructs named to
+ return mapped IPv4 addresses to AAAA queries when
+ there are no AAAA records. It is intended to be
+ used in conjunction with a NAT64. Each
+ dns64 defines one DNS64 prefix.
+ Multiple DNS64 prefixes can be defined.
+
+
+ Compatible IPv6 prefixes have lengths of 32, 40, 48, 56,
+ 64 and 96 as per RFC 6052.
+
+
+ Additionally a reverse IP6.ARPA zone will be created for
+ the prefix to provide a mapping from the IP6.ARPA names
+ to the corresponding IN-ADDR.ARPA names using synthesized
+ CNAMEs. dns64-server and
+ dns64-contact can be used to specify
+ the name of the server and contact for the zones. These
+ are settable at the view / options level. These are
+ not settable on a per-prefix basis.
+
+
+ Each dns64 supports an optional
+ clients ACL that determines which
+ clients are affected by this directive. If not defined,
+ it defaults to any;.
+
+
+ Each dns64 supports an optional
+ mapped ACL that selects which
+ IPv4 addresses are to be mapped in the corresponding
+ A RRset. If not defined it defaults to
+ any;.
+
+
+ Each dns64 supports an optional
+ exclude ACL that selects which
+ IPv6 addresses will be ignored for the purposes
+ of determining whether dns64 is to be applied.
+ Any non-matching address will prevent further
+ DNS64 processing from occurring for this client.
+
+
+ A optional suffix can also
+ be defined to set the bits trailing the mapped
+ IPv4 address bits. By default these bits are
+ set to ::. The bits
+ matching the prefix and mapped IPv4 address
+ must be zero.
+
+
+ acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+ dns64 64:FF9B::/96 {
+ clients { any; };
+ mapped { !rfc1918; any; };
+ exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
+ suffix ::;
+ };
+
+
+
+
@@ -5268,6 +5826,18 @@ options {
+
+ allow-new-zones
+
+
+ If yes, then zones can be
+ added at runtime via rndc addzone
+ or deleted via rndc delzone.
+ The default is no.
+
+
+
+
auth-nxdomain
@@ -5755,6 +6325,7 @@ options {
off
on a per-zone basis by specifying zone-statistics no
in the zone statement).
+ The default is no.
These statistics may be accessed
using rndc stats, which will
dump them to the file listed
@@ -5927,6 +6498,60 @@ options {
+
+ filter-aaaa-on-v4
+
+
+ This option is only available when
+ BIND 9 is compiled with the
+ --enable-filter-aaaa option on the
+ "configure" command line. It is intended to help the
+ transition from IPv4 to IPv6 by not giving IPv6 addresses
+ to DNS clients unless they have connections to the IPv6
+ Internet. This is not recommended unless absolutely
+ necessary. The default is no.
+ The filter-aaaa-on-v4 option
+ may also be specified in view statements
+ to override the global filter-aaaa-on-v4
+ option.
+
+
+ If yes,
+ the DNS client is at an IPv4 address, in filter-aaaa,
+ and if the response does not include DNSSEC signatures,
+ then all AAAA records are deleted from the response.
+ This filtering applies to all responses and not only
+ authoritative responses.
+
+
+ If break-dnssec,
+ then AAAA records are deleted even when dnssec is enabled.
+ As suggested by the name, this makes the response not verify,
+ because the DNSSEC protocol is designed detect deletions.
+
+
+ This mechanism can erroneously cause other servers to
+ not give AAAA records to their clients.
+ A recursing server with both IPv6 and IPv4 network connections
+ that queries an authoritative server using this mechanism
+ via IPv4 will be denied AAAA records even if its client is
+ using IPv6.
+
+
+ This mechanism is applied to authoritative as well as
+ non-authoritative records.
+ A client using IPv4 that is not allowed recursion can
+ erroneously be given AAAA records because the server is not
+ allowed to check for A records.
+
+
+ Some AAAA records are given to IPv4 clients in glue records.
+ IPv4 clients that are servers can then erroneously
+ answer requests for AAAA records received via IPv4.
+
+
+
+
ixfr-from-differences
@@ -5996,7 +6621,15 @@ options {
Enable DNSSEC validation in named.
Note dnssec-enable also needs to be
set to yes to be effective.
- The default is yes.
+ If set to no, DNSSEC validation
+ is disabled. If set to auto,
+ DNSSEC validation is enabled, and a default
+ trust-anchor for the DNS root zone is used. If set to
+ yes, DNSSEC validation is enabled,
+ but a trust anchor must be manually configured using
+ a trusted-keys or
+ managed-keys statement. The default
+ is yes.
@@ -6007,7 +6640,9 @@ options {
Accept expired signatures when verifying DNSSEC signatures.
The default is no.
- Setting this option to "yes" leaves named vulnerable to replay attacks.
+ Setting this option to yes
+ leaves named vulnerable to
+ replay attacks.
@@ -6056,6 +6691,19 @@ options {
+
+ check-dup-records
+
+
+ Check master zones for records that are treated as different
+ by DNSSEC but are semantically equal in plain DNS. The
+ default is to warn. Other possible
+ values are fail and
+ ignore.
+
+
+
+
check-mx
@@ -6161,13 +6809,49 @@ options {
update-check-ksk
- When regenerating the RRSIGs following a UPDATE
- request to a secure zone, check the KSK flag on
- the DNSKEY RR to determine if this key should be
- used to generate the RRSIG. This flag is ignored
- if there are not DNSKEY RRs both with and without
- a KSK.
- The default is yes.
+ When set to the default value of yes,
+ check the KSK bit in each key to determine how the key
+ should be used when generating RRSIGs for a secure zone.
+
+
+ Ordinarily, zone-signing keys (that is, keys without the
+ KSK bit set) are used to sign the entire zone, while
+ key-signing keys (keys with the KSK bit set) are only
+ used to sign the DNSKEY RRset at the zone apex.
+ However, if this option is set to no,
+ then the KSK bit is ignored; KSKs are treated as if they
+ were ZSKs and are used to sign the entire zone. This is
+ similar to the dnssec-signzone -z
+ command line option.
+
+
+ When this option is set to yes, there
+ must be at least two active keys for every algorithm
+ represented in the DNSKEY RRset: at least one KSK and one
+ ZSK per algorithm. If there is any algorithm for which
+ this requirement is not met, this option will be ignored
+ for that algorithm.
+
+
+
+
+
+ dnssec-dnskey-kskonly
+
+
+ When this option and update-check-ksk
+ are both set to yes, only key-signing
+ keys (that is, keys with the KSK bit set) will be used
+ to sign the DNSKEY RRset at the zone apex. Zone-signing
+ keys (keys without the KSK bit set) will be used to sign
+ the remainder of the zone, but not the DNSKEY RRset.
+ This is similar to the
+ dnssec-signzone -x command line option.
+
+
+ The default is no. If
+ update-check-ksk is set to
+ no, this option is ignored.
@@ -6183,6 +6867,34 @@ options {
+
+ dnssec-secure-to-insecure
+
+
+ Allow a dynamic zone to transition from secure to
+ insecure (i.e., signed to unsigned) by deleting all
+ of the DNSKEY records. The default is no.
+ If set to yes, and if the DNSKEY RRset
+ at the zone apex is deleted, all RRSIG and NSEC records
+ will be removed from the zone as well.
+
+
+ If the zone uses NSEC3, then it is also necessary to
+ delete the NSEC3PARAM RRset from the zone apex; this will
+ cause the removal of all corresponding NSEC3 records.
+ (It is expected that this requirement will be eliminated
+ in a future release.)
+
+
+ Note that if a zone has been configured with
+ auto-dnssec maintain and the
+ private keys remain accessible in the key repository,
+ then the zone will be automatically signed again the
+ next time named is started.
+
+
+
+
@@ -6495,6 +7207,29 @@ options {
+
+ filter-aaaa
+
+
+ Specifies a list of addresses to which
+ filter-aaaa-on-v4
+ is applies. The default is any.
+
+
+
+
+
+ resolver-query-timeout
+
+
+ The amount of time the resolver will spend attempting
+ to resolve a recursive query before failing. The
+ default is 10 and the maximum is
+ 30. Setting it to 0
+ will result in the default being used.
+
+
+
@@ -7542,20 +8277,26 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
sortlist {
- { localhost; // IF the local host
- { localnets; // THEN first fit on the
- 192.168.1/24; // following nets
+ // IF the local host
+ // THEN first fit on the following nets
+ { localhost;
+ { localnets;
+ 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.1/24; // IF on class C 192.168.1
- { 192.168.1/24; // THEN use .1, or .2 or .3
+ // IF on class C 192.168.1 THEN use .1, or .2 or .3
+ { 192.168.1/24;
+ { 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.2/24; // IF on class C 192.168.2
- { 192.168.2/24; // THEN use .2, or .1 or .3
+ // IF on class C 192.168.2 THEN use .2, or .1 or .3
+ { 192.168.2/24;
+ { 192.168.2/24;
{ 192.168.1/24; 192.168.3/24; }; }; };
- { 192.168.3/24; // IF on class C 192.168.3
- { 192.168.3/24; // THEN use .3, or .1 or .2
+ // IF on class C 192.168.3 THEN use .3, or .1 or .2
+ { 192.168.3/24;
+ { 192.168.3/24;
{ 192.168.1/24; 192.168.2/24; }; }; };
- { { 192.168.4/24; 192.168.5/24; }; // if .4 or .5, prefer that net
+ // IF .4 or .5 THEN prefer that net
+ { { 192.168.4/24; 192.168.5/24; };
};
};
@@ -7772,7 +8513,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
DNSSEC signatures automatically generated as a
result of dynamic updates () will expire. There
- is a optional second field which specifies how
+ is an optional second field which specifies how
long before expiry that the signatures will be
regenerated. If not specified, the signatures will
be regenerated at 1/4 of base interval. The second
@@ -7877,7 +8618,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
Sets the advertised EDNS UDP buffer size in bytes
to control the size of packets received.
- Valid values are 512 to 4096 (values outside this range
+ Valid values are 1024 to 4096 (values outside this range
will be silently adjusted). The default value
is 4096. The usual reason for setting
edns-udp-size to a non-default
@@ -7885,24 +8626,36 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
firewalls that block fragmented packets and/or
block UDP packets that are greater than 512 bytes.
+
+ named will fallback to using 512 bytes
+ if it get a series of timeout at the initial value. 512
+ bytes is not being offered to encourage sites to fix their
+ firewalls. Small EDNS UDP sizes will result in the
+ excessive use of TCP.
+ max-udp-size
-
-
- Sets the maximum EDNS UDP message size named will
- send in bytes. Valid values are 512 to 4096 (values outside
- this range will be silently adjusted). The default
+
+
+ Sets the maximum EDNS UDP message size
+ named will send in bytes.
+ Valid values are 512 to 4096 (values outside this
+ range will be silently adjusted). The default
value is 4096. The usual reason for setting
- max-udp-size to a non-default value is to get UDP
- answers to pass through broken firewalls that
- block fragmented packets and/or block UDP packets
- that are greater than 512 bytes.
+ max-udp-size to a non-default
+ value is to get UDP answers to pass through broken
+ firewalls that block fragmented packets and/or
+ block UDP packets that are greater than 512 bytes.
This is independent of the advertised receive
buffer (edns-udp-size).
+
+ Setting this to a low value will encourage additional
+ TCP traffic to the nameserver.
+
@@ -8081,7 +8834,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
Named will attempt to determine if a built-in zone already exists
or is active (covered by a forward-only forwarding declaration)
- and will not create a empty zone in that case.
+ and will not create an empty zone in that case.
The current list of empty zones is:
@@ -8308,6 +9061,282 @@ XXX: end of RFC1918 addresses #defined out -->
+
+ Content Filtering
+
+ BIND 9 provides the ability to filter
+ out DNS responses from external DNS servers containing
+ certain types of data in the answer section.
+ Specifically, it can reject address (A or AAAA) records if
+ the corresponding IPv4 or IPv6 addresses match the given
+ address_match_list of the
+ deny-answer-addresses option.
+ It can also reject CNAME or DNAME records if the "alias"
+ name (i.e., the CNAME alias or the substituted query name
+ due to DNAME) matches the
+ given namelist of the
+ deny-answer-aliases option, where
+ "match" means the alias name is a subdomain of one of
+ the name_list elements.
+ If the optional namelist is specified
+ with except-from, records whose query name
+ matches the list will be accepted regardless of the filter
+ setting.
+ Likewise, if the alias name is a subdomain of the
+ corresponding zone, the deny-answer-aliases
+ filter will not apply;
+ for example, even if "example.com" is specified for
+ deny-answer-aliases,
+
+www.example.com. CNAME xxx.example.com.
+
+
+ returned by an "example.com" server will be accepted.
+
+
+
+ In the address_match_list of the
+ deny-answer-addresses option, only
+ ip_addr
+ and ip_prefix
+ are meaningful;
+ any key_id will be silently ignored.
+
+
+
+ If a response message is rejected due to the filtering,
+ the entire message is discarded without being cached, and
+ a SERVFAIL error will be returned to the client.
+
+
+
+ This filtering is intended to prevent "DNS rebinding attacks," in
+ which an attacker, in response to a query for a domain name the
+ attacker controls, returns an IP address within your own network or
+ an alias name within your own domain.
+ A naive web browser or script could then serve as an
+ unintended proxy, allowing the attacker
+ to get access to an internal node of your local network
+ that couldn't be externally accessed otherwise.
+ See the paper available at
+
+ http://portal.acm.org/citation.cfm?id=1315245.1315298
+
+ for more details about the attacks.
+
+
+
+ For example, if you own a domain named "example.net" and
+ your internal network uses an IPv4 prefix 192.0.2.0/24,
+ you might specify the following rules:
+
+
+deny-answer-addresses { 192.0.2.0/24; } except-from { "example.net"; };
+deny-answer-aliases { "example.net"; };
+
+
+
+ If an external attacker lets a web browser in your local
+ network look up an IPv4 address of "attacker.example.com",
+ the attacker's DNS server would return a response like this:
+
+
+attacker.example.com. A 192.0.2.1
+
+
+ in the answer section.
+ Since the rdata of this record (the IPv4 address) matches
+ the specified prefix 192.0.2.0/24, this response will be
+ ignored.
+
+
+
+ On the other hand, if the browser looks up a legitimate
+ internal web server "www.example.net" and the
+ following response is returned to
+ the BIND 9 server
+
+
+www.example.net. A 192.0.2.2
+
+
+ it will be accepted since the owner name "www.example.net"
+ matches the except-from element,
+ "example.net".
+
+
+
+ Note that this is not really an attack on the DNS per se.
+ In fact, there is nothing wrong for an "external" name to
+ be mapped to your "internal" IP address or domain name
+ from the DNS point of view.
+ It might actually be provided for a legitimate purpose,
+ such as for debugging.
+ As long as the mapping is provided by the correct owner,
+ it is not possible or does not make sense to detect
+ whether the intent of the mapping is legitimate or not
+ within the DNS.
+ The "rebinding" attack must primarily be protected at the
+ application that uses the DNS.
+ For a large site, however, it may be difficult to protect
+ all possible applications at once.
+ This filtering feature is provided only to help such an
+ operational environment;
+ it is generally discouraged to turn it on unless you are
+ very sure you have no other choice and the attack is a
+ real threat for your applications.
+
+
+
+ Care should be particularly taken if you want to use this
+ option for addresses within 127.0.0.0/8.
+ These addresses are obviously "internal", but many
+ applications conventionally rely on a DNS mapping from
+ some name to such an address.
+ Filtering out DNS records containing this address
+ spuriously can break such applications.
+
+
+
+
+ Response Policy Zone (RPZ) Rewriting
+
+ BIND 9 includes an intentionally limited
+ mechanism to modify DNS responses for recursive requests
+ similar to email anti-spam DNS blacklists.
+ All response policy zones are named in the
+ response-policy option for the view or among the
+ global options if there is no response-policy option for the view.
+
+
+
+ The rules encoded in a response policy zone (RPZ) are applied
+ only to responses to queries that ask for recursion (RD=1).
+ RPZs are normal DNS zones containing RRsets
+ that can be queried normally if allowed.
+ It is usually best to restrict those queries with something like
+ allow-query {none; }; or
+ allow-query { 127.0.0.1; };.
+
+
+
+ There are four kinds of RPZ rewrite rules. QNAME rules are
+ applied to query names in requests and to targets of CNAME
+ records resolved in the process of generating the response.
+ The owner name of a QNAME rule is the query name relativized
+ to the RPZ.
+ The records in a rewrite rule are usually A, AAAA, or special
+ CNAMEs, but can be any type except DNAME.
+
+
+
+ IP rules are triggered by addresses in A and AAAA records.
+ All IP addresses in A or AAAA RRsets are tested and the rule
+ longest prefix is applied. Ties between rules with equal prefixes
+ are broken in favor of the first RPZ mentioned in the
+ response-policy option.
+ The rule matching the smallest IP address is chosen among equal
+ prefix rules from a single RPZ.
+ IP rules are expressed in RRsets with owner names that are
+ subdomains of rpz-ip and encoding an IP address block, reversed
+ as in IN-ARPA.
+ prefix.B.B.B.B with prefix between 1 and 32 and B between 1 and 255
+ encodes an IPv4 address.
+ IPv6 addresses are encoded by with prefix.W.W.W.W.W.W.W.W or
+ prefix.WORDS.zz.WORDS. The words in the standard IPv6 text
+ representation are reversed, "::" is replaced with ".zz.",
+ and ":" becomes ".".
+
+
+
+ NSDNAME rules match names in NS RRsets for the response or a
+ parent. They are encoded as subdomains of rpz-nsdomain relativized
+ to the RPZ origin name.
+
+
+
+ NSIP rules match IP addresses in A and AAAA RRsets for names of
+ responsible servers or the names that can be matched by NSDNAME
+ rules. The are encoded like IP rules except as subdomains of
+ rpz-nsip.
+
+
+
+ Authority verification issues and variations in authority data in
+ the current version of BIND 9 can cause
+ inconsistent results from NSIP and NSDNAME. So they are available
+ only when BIND is built with the
+ --enable-rpz-nsip or
+ --enable-rpz-nsdname options
+ on the "configure" command line.
+
+
+
+ Four policies can be expressed.
+ The NXDOMAIN policy causes a NXDOMAIN response
+ and is expressed with an RRset consisting of a single CNAME
+ whose target is the root domain (.).
+ NODATA generates NODATA or ANCOUNT=1 regardless
+ of query type.
+ It is expressed with a CNAME whose target is the wildcard
+ top-level domain (*.).
+ The NO-OP policy does not change the response
+ and is used to "poke holes" in policies for larger CIDR blocks or in
+ zones named later in the response-policy option.
+ The NO-OP policy is expressed by a CNAME with a target consisting
+ of the variable part of the owner name, such as "example.com." for
+ a QNAME rule or "128.1.0.0.127." for an IP rule.
+ The CNAME policy is used to replace the RRsets
+ of response.
+ A and AAAA RRsets are most common and useful to capture
+ an evil domain in a walled garden, but any valid set of RRsets
+ is possible.
+
+
+
+ All of the policies in an RPZ can be overridden with a
+ policy clause.
+ given says "do not override."
+ no-op says "do nothing" regardless of the policy
+ in RPZ records.
+ nxdomain causes all RPZ rules to generate
+ NXDOMAIN results.
+ nodata gives nodata.
+ cname domain causes all RPZ rules to act as if
+ the consisted of a "cname domain" record.
+
+
+
+ For example, you might use this option statement
+
+response-policy { zone "bl"; };
+
+ and this zone statement
+
+zone "bl" {type master; file "example/bl"; allow-query {none;}; };
+
+ with this zone file
+
+$TTL 1H
+@ SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h)
+
+; QNAME rules
+nxdomain.domain.com CNAME .
+nodata.domain.com CNAME *.
+bad.domain.com A 10.0.0.1
+ AAAA 2001:2::1
+ok.domain.com CNAME ok.domain.com.
+*.badzone.domain.com CNAME garden.example.com.
+
+; IP rules rewriting all answers for 127/8 except 127.0.0.1
+8.0.0.0.127.ip CNAME .
+32.1.0.0.127.ip CNAME 32.1.0.0.127.
+
+; NSDNAME and NSIP rules
+ns.domain.com.rpz-nsdname CNAME .
+48.zz.2.2001.rpz-nsip CNAME .
+
+
@@ -8327,8 +9356,10 @@ XXX: end of RFC1918 addresses #defined out -->
transfer-source-v6 (ip6_addr | *) port ip_port ; notify-source (ip4_addr | *) port ip_port ; notify-source-v6 (ip6_addr | *) port ip_port ;
- query-source address ( ip_addr | * ) port ( ip_port | * ) ;
- query-source-v6 address ( ip_addr | * ) port ( ip_port | * ) ;
+ query-source address ( ip_addr | * )
+ port ( ip_port | * ) ;
+ query-source-v6 address ( ip_addr | * )
+ port ( ip_port | * ) ; use-queryport-pool yes_or_no; queryport-pool-ports number; queryport-pool-updateinterval number;
@@ -8526,7 +9557,8 @@ XXX: end of RFC1918 addresses #defined out -->
statistics-channels Statement Grammarstatistics-channels {
- [ inet ( ip_addr | * ) [ port ip_port ] [allow { address_match_list } ]; ]
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ [ allow { address_match_list } ]; ]
[ inet ...; ]
};
@@ -8590,7 +9622,7 @@ XXX: end of RFC1918 addresses #defined out -->
-
+ trusted-keys Statement Grammartrusted-keys {
@@ -8632,6 +9664,136 @@ XXX: end of RFC1918 addresses #defined out -->
in the key data, so the configuration may be split up into
multiple lines.
+
+ trusted-keys may be set at the top level
+ of named.conf or within a view. If it is
+ set in both places, they are additive: keys defined at the top
+ level are inherited by all views, but keys defined in a view
+ are only used within that view.
+
+
+
+
+ managed-keys Statement Grammar
+
+managed-keys {
+ string initial-key numbernumbernumberstring ;
+ string initial-key numbernumbernumberstring ; ...
+};
+
+
+
+
+ managed-keys Statement Definition
+ and Usage
+
+ The managed-keys statement, like
+ trusted-keys, defines DNSSEC
+ security roots. The difference is that
+ managed-keys can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+
+
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ trusted-keys statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ trusted-keys statement with the new key.
+
+
+ If, however, the zone were listed in a
+ managed-keys statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ named would store the stand-by key, and
+ when the original key was revoked, named
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+
+
+ A managed-keys statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ BIND 9.7.0) is initial-key.
+ This means the managed-keys statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+
+
+ Consequently, a managed-keys statement
+ appears similar to a trusted-keys, differing
+ in the presence of the second field, containing the keyword
+ initial-key. The difference is, whereas the
+ keys listed in a trusted-keys continue to be
+ trusted until they are removed from
+ named.conf, an initializing key listed
+ in a managed-keys statement is only trusted
+ once: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+
+
+ The first time named runs with a managed key
+ configured in named.conf, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the managed-keys
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+
+
+ From that point on, whenever named runs, it
+ sees the managed-keys statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the managed-keys is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+
+
+ The next time named runs after a name
+ has been removed from the
+ managed-keys statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+
+
+ named only maintains a single managed keys
+ database; consequently, unlike trusted-keys,
+ managed-keys may only be set at the top
+ level of named.conf, not within a view.
+
+
+ In the current implementation, the managed keys database is
+ stored as a master-format zone file called
+ managed-keys.bind. When the key database
+ is changed, the zone is updated. As with any other dynamic
+ zone, changes will be written into a journal file,
+ managed-keys.bind.jnl. They are committed
+ to the master file as soon as possible afterward; in the case
+ of the managed key database, this will usually occur within 30
+ seconds. So, whenever named is using
+ automatic key maintenance, those two files can be expected to
+ exist in the working directory. (For this reason among others,
+ the working directory should be always be writable by
+ named.)
+
+
+ If the dnssec-lookaside option is
+ set to auto, named
+ will automatically initialize a managed key for the
+ zone dlv.isc.org. The key that is
+ used to initialize the key maintenance process is built
+ into named, and can be overridden
+ from bindkeys-file.
+
@@ -8746,11 +9908,12 @@ XXX: end of RFC1918 addresses #defined out -->
// This should match our internal networks.
match-clients { 10.0.0.0/8; };
- // Provide recursive service to internal clients only.
+ // Provide recursive service to internal
+ // clients only.
recursion yes;
- // Provide a complete view of the example.com zone
- // including addresses of internal hosts.
+ // Provide a complete view of the example.com
+ // zone including addresses of internal hosts.
zone "example.com" {
type master;
file "example-internal.db";
@@ -8758,14 +9921,15 @@ XXX: end of RFC1918 addresses #defined out -->
};
view "external" {
- // Match all clients not matched by the previous view.
+ // Match all clients not matched by the
+ // previous view.
match-clients { any; };
// Refuse recursive service to external clients.
recursion no;
- // Provide a restricted view of the example.com zone
- // containing only publicly accessible hosts.
+ // Provide a restricted view of the example.com
+ // zone containing only publicly accessible hosts.
zone "example.com" {
type master;
file "example-external.db";
@@ -8784,8 +9948,9 @@ view "external" {
allow-query-on { address_match_list }; allow-transfer { address_match_list }; allow-update { address_match_list };
- update-policy { update_policy_rule... };
- also-notify { ip_addrport ip_port ; ip_addrport ip_port ; ... };
+ update-policy local | { update_policy_rule... };
+ also-notify { ip_addrport ip_port ;
+ ip_addrport ip_port ; ... }; check-names (warn|fail|ignore) ; check-mx (warn|fail|ignore) ; check-wildcard yes_or_no;
@@ -8821,6 +9986,7 @@ view "external" {
min-retry-time number ; max-retry-time number ; key-directory path_name;
+ auto-dnssec allow|maintain|create|off; zero-no-soa-ttl yes_or_no ;
};
@@ -8832,8 +9998,11 @@ zone zone_nameclass allow-transfer { address_match_list }; allow-update-forwarding { address_match_list }; update-check-ksk yes_or_no;
+ dnssec-dnskey-kskonly yes_or_no;
+ dnssec-secure-to-insecure yes_or_no ; try-tcp-refresh yes_or_no;
- also-notify { ip_addrport ip_port ; ip_addrport ip_port ; ... };
+ also-notify { ip_addrport ip_port ;
+ ip_addrport ip_port ; ... }; check-names (warn|fail|ignore) ; dialup dialup_option ; file string ;
@@ -8846,7 +10015,9 @@ zone zone_nameclass ixfr-from-differences yes_or_no; ixfr-tmp-file string ; maintain-ixfr-base yes_or_no ;
- masters port ip_port { ( masters_list | ip_addrport ip_portkey key ) ; ... };
+ masters port ip_port { ( masters_list | ip_addr
+ port ip_port
+ key key ) ; ... }; max-ixfr-log-size number ; max-transfer-idle-in number ; max-transfer-idle-out number ;
@@ -8859,7 +10030,8 @@ zone zone_nameclass transfer-source (ip4_addr | *) port ip_port ; transfer-source-v6 (ip6_addr | *) port ip_port ; alt-transfer-source (ip4_addr | *) port ip_port ;
- alt-transfer-source-v6 (ip6_addr | *) port ip_port ;
+ alt-transfer-source-v6 (ip6_addr | *)
+ port ip_port ; use-alt-transfer-source yes_or_no; notify-source (ip4_addr | *) port ip_port ; notify-source-v6 (ip6_addr | *) port ip_port ;
@@ -8877,7 +10049,7 @@ zone zone_nameclassstring ;
delegation-only yes_or_no ;
- check-names (warn|fail|ignore) ; // Not Implemented.
+ check-names (warn|fail|ignore) ; // Not Implemented.
};
zone zone_nameclass {
@@ -8891,14 +10063,18 @@ zone zone_nameclass masterfile-format (text|raw) ; forward (only|first) ; forwarders { ip_addrport ip_port ; ... };
- masters port ip_port { ( masters_list | ip_addrport ip_portkey key ) ; ... };
+ masters port ip_port { ( masters_list | ip_addr
+ port ip_port
+ key key ) ; ... }; max-transfer-idle-in number ; max-transfer-time-in number ; pubkey numbernumbernumberstring ; transfer-source (ip4_addr | *) port ip_port ;
- transfer-source-v6 (ip6_addr | *) port ip_port ;
+ transfer-source-v6 (ip6_addr | *)
+ port ip_port ; alt-transfer-source (ip4_addr | *) port ip_port ;
- alt-transfer-source-v6 (ip6_addr | *) port ip_port ;
+ alt-transfer-source-v6 (ip6_addr | *)
+ port ip_port ; use-alt-transfer-source yes_or_no; zone-statistics yes_or_no ; database string ;
@@ -8909,6 +10085,14 @@ zone zone_nameclass multi-master yes_or_no ;
};
+zone zone_nameclass {
+ type static-stub;
+ allow-query { address_match_list };
+ server-addresses { ip_addr ; ... };
+ server-names { namelist };
+ zone-statistics yes_or_no ;
+};
+
zone zone_nameclass {
type forward;
forward (only|first) ;
@@ -9053,6 +10237,55 @@ zone zone_nameclass
+
+
+
+ static-stub
+
+
+
+
+ A static-stub zone is similar to a stub zone
+ with the following exceptions:
+ the zone data is statically configured, rather
+ than transferred from a master server;
+ when recursion is necessary for a query that
+ matches a static-stub zone, the locally
+ configured data (nameserver names and glue addresses)
+ is always used even if different authoritative
+ information is cached.
+
+
+ Zone data is configured via the
+ server-addresses and
+ server-names zone options.
+
+
+ The zone data is maintained in the form of NS
+ and (if necessary) glue A or AAAA RRs
+ internally, which can be seen by dumping zone
+ databases by rndc dumpdb -all.
+ The configured RRs are considered local configuration
+ parameters rather than public data.
+ Non recursive queries (i.e., those with the RD
+ bit off) to a static-stub zone are therefore
+ prohibited and will be responded with REFUSED.
+
+
+ Since the data is statically configured, no
+ zone maintenance action takes place for a static-stub
+ zone.
+ For example, there is no periodic refresh
+ attempt, and an incoming notify message
+ will be rejected with an rcode of NOTAUTH.
+
+
+ Each static-stub zone is configured with
+ internally generated NS and (if necessary)
+ glue A or AAAA RRs
+
+
+
@@ -9270,6 +10503,7 @@ zone zone_nameclassmaster zones the default is fail. For slave
zones the default is warn.
+ It is not implemented for hint zones.
@@ -9334,6 +10568,16 @@ zone zone_nameclass
+
+ dnssec-dnskey-kskonly
+
+
+ See the description of
+ dnssec-dnskey-kskonly in .
+
+
+
+
try-tcp-refresh
@@ -9568,6 +10812,84 @@ zone zone_nameclass
+
+ server-addresses
+
+
+ Only meaningful for static-stub zones.
+ This is a list of IP addresses to which queries
+ should be sent in recursive resolution for the
+ zone.
+ A non empty list for this option will internally
+ configure the apex NS RR with associated glue A or
+ AAAA RRs.
+
+
+ For example, if "example.com" is configured as a
+ static-stub zone with 192.0.2.1 and 2001:db8::1234
+ in a server-addresses option,
+ the following RRs will be internally configured.
+
+example.com. NS example.com.
+example.com. A 192.0.2.1
+example.com. AAAA 2001:db8::1234
+
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ will initiate recursive resolution and send
+ queries to 192.0.2.1 and/or 2001:db8::1234.
+
+
+
+
+
+ server-names
+
+
+ Only meaningful for static-stub zones.
+ This is a list of domain names of nameservers that
+ act as authoritative servers of the static-stub
+ zone.
+ These names will be resolved to IP addresses when
+ named needs to send queries to
+ these servers.
+ To make this supplemental resolution successful,
+ these names must not be a subdomain of the origin
+ name of static-stub zone.
+ That is, when "example.net" is the origin of a
+ static-stub zone, "ns.example" and
+ "master.example.com" can be specified in the
+ server-names option, but
+ "ns.example.net" cannot, and will be rejected by
+ the configuration parser.
+
+
+ A non empty list for this option will internally
+ configure the apex NS RR with the specified names.
+ For example, if "example.com" is configured as a
+ static-stub zone with "ns1.example.net" and
+ "ns2.example.net"
+ in a server-names option,
+ the following RRs will be internally configured.
+
+example.com. NS ns1.example.net.
+example.com. NS ns2.example.net.
+
+
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ initiate recursive resolution,
+ resolve "ns1.example.net" and/or
+ "ns2.example.net" to IP addresses, and then send
+ queries to (one or more of) these addresses.
+
+
+
+
sig-validity-interval
@@ -9715,6 +11037,51 @@ zone zone_nameclass
+
+ auto-dnssec
+
+
+ Zones configured for dynamic DNS may also use this
+ option to allow varying levels of automatic DNSSEC key
+ management. There are four possible settings:
+
+
+ auto-dnssec allow; permits
+ keys to be updated and the zone fully re-signed
+ whenever the user issues the command rndc sign
+ zonename.
+
+
+ auto-dnssec maintain; includes the
+ above, but also automatically adjusts the zone's DNSSEC
+ keys on schedule, according to the keys' timing metadata
+ (see and
+ ). The command
+ rndc sign
+ zonename causes
+ named to load keys from the key
+ repository and sign the zone with all keys that are
+ active.
+ rndc loadkeys
+ zonename causes
+ named to load keys from the key
+ repository and schedule key maintenance events to occur
+ in the future, but it does not sign the full zone
+ immediately.
+
+
+ auto-dnssec create; includes the
+ above, but also allows named
+ to create new keys in the key repository when needed.
+ (NOTE: This option is not yet implemented; the syntax is
+ being reserved for future use.)
+
+
+ The default setting is auto-dnssec off.
+
+
+
+
multi-master
@@ -9735,6 +11102,16 @@ zone zone_nameclass
+
+ dnssec-secure-to-insecure
+
+
+ See the description of
+ dnssec-secure-to-insecure in .
+
+
+
+
@@ -9753,15 +11130,14 @@ zone zone_nameclass
- The update-policy clause is new
- in BIND 9 and allows more fine-grained
- control over what updates are allowed. A set of rules
- is specified, where each rule either grants or denies
- permissions for one or more names to be updated by
- one or more identities. If the dynamic update request
- message is signed (that is, it includes either a TSIG
- or SIG(0) record), the identity of the signer can be
- determined.
+ The update-policy clause
+ allows more fine-grained control over what updates are
+ allowed. A set of rules is specified, where each rule
+ either grants or denies permissions for one or more
+ names to be updated by one or more identities. If
+ the dynamic update request message is signed (that is,
+ it includes either a TSIG or SIG(0) record), the
+ identity of the signer can be determined.
Rules are specified in the update-policy
@@ -9773,24 +11149,53 @@ zone zone_nameclass
+
+ There is a pre-defined update-policy
+ rule which can be switched on with the command
+ update-policy local;.
+ Switching on this rule in a zone causes
+ named to generate a TSIG session
+ key and place it in a file, and to allow that key
+ to update the zone. (By default, the file is
+ /var/run/named/session.key, the key
+ name is "local-ddns" and the key algorithm is HMAC-SHA256,
+ but these values are configurable with the
+ session-keyfile,
+ session-keyname and
+ session-keyalg options, respectively).
+
+
+ A client running on the local system, and with appropriate
+ permissions, may read that file and use the key to sign update
+ requests. The zone's update policy will be set to allow that
+ key to change any record within the zone. Assuming the
+ key name is "local-ddns", this policy is equivalent to:
+
+
+ update-policy { grant local-ddns zonesub any; };
+
- This is how a rule definition looks:
+ The command nsupdate -l sends update
+ requests to localhost, and signs them using the session key.
+
+
+
+ Other rule definitions look like this:
-( grant | deny ) identitynametypenametypes
+( grant | deny ) identitynametypenametypes
Each rule grants or denies privileges. Once a message has
successfully matched a rule, the operation is immediately
- granted
- or denied and no further rules are examined. A rule is matched
- when the signer matches the identity field, the name matches the
- name field in accordance with the nametype field, and the type
- matches
- the types specified in the type field.
+ granted or denied and no further rules are examined. A rule
+ is matched when the signer matches the identity field, the
+ name matches the name field in accordance with the nametype
+ field, and the type matches the types specified in the type
+ field.
No signer is required for tcp-self
@@ -9817,7 +11222,7 @@ zone zone_nameclass
- The nametype field has 12
+ The nametype field has 13
values:
name, subdomain,
wildcard, self,
@@ -9825,7 +11230,8 @@ zone zone_nameclasskrb5-self, ms-self,
krb5-subdomain,
ms-subdomain,
- tcp-self and 6to4-self.
+ tcp-self, 6to4-self,
+ zonesub, and external.
@@ -9860,6 +11266,28 @@ zone zone_nameclass
+
+
+
+ zonesub
+
+
+
+ This rule is similar to subdomain, except that
+ it matches when the name being updated is a
+ subdomain of the zone in which the
+ update-policy statement
+ appears. This obviates the need to type the zone
+ name twice, and enables the use of a standard
+ update-policy statement in
+ multiple zones without modification.
+
+
+ When this rule is used, the
+ name field is omitted.
+
+
+
@@ -9950,7 +11378,7 @@ zone zone_nameclass
Allow the 6to4 prefix to be update by any TCP
- conection from the 6to4 network or from the
+ connection from the 6to4 network or from the
corresponding IPv4 address. This is intended
to allow NS or DNAME RRsets to be added to the
reverse tree.
@@ -9961,14 +11389,56 @@ zone zone_nameclass
+
+
+
+ external
+
+
+
+ This rule allows named
+ to defer the decision of whether to allow a
+ given update to an external daemon.
+
+
+ The method of communicating with the daemon is
+ specified in the identity
+ field, the format of which is
+ "local:path",
+ where path is the location
+ of a UNIX-domain socket. (Currently, "local" is the
+ only supported mechanism.)
+
+
+ Requests to the external daemon are sent over the
+ UNIX-domain socket as datagrams with the following
+ format:
+
+
+ Protocol version number (4 bytes, network byte order, currently 1)
+ Request length (4 bytes, network byte order)
+ Signer (null-terminated string)
+ Name (null-terminated string)
+ TCP source address (null-terminated string)
+ Rdata type (null-terminated string)
+ Key (null-terminated string)
+ TKEY token length (4 bytes, network byte order)
+ TKEY token (remainder of packet)
+
+ The daemon replies with a four-byte value in
+ network byte order, containing either 0 or 1; 0
+ indicates that the specified update is not
+ permitted, and 1 indicates that it is.
+
+
+
In all cases, the name
- field must
- specify a fully-qualified domain name.
+ field must specify a fully-qualified domain name.
@@ -11381,7 +12851,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
$ORIGIN 0.0.192.IN-ADDR.ARPA.
-$GENERATE 1-2 0 NS SERVER$.EXAMPLE.
+$GENERATE 1-2 @ NS SERVER$.EXAMPLE.
$GENERATE 1-127 $ CNAME $.0
@@ -11394,6 +12864,32 @@ $GENERATE 1-127 $ CNAME $.0
2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA.
...
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.
+
+
+
+ Generate a set of A and MX records. Note the MX's right hand
+ side is a quoted string. The quotes will be stripped when the
+ right hand side is processed.
+
+
+
+$ORIGIN EXAMPLE.
+$GENERATE 1-127 HOST-$ A 1.2.3.$
+$GENERATE 1-127 HOST-$ MX "0 ."
+
+
+ is equivalent to
+
+
+HOST-1.EXAMPLE. A 1.2.3.1
+HOST-1.EXAMPLE. MX 0 .
+HOST-2.EXAMPLE. A 1.2.3.2
+HOST-2.EXAMPLE. MX 0 .
+HOST-3.EXAMPLE. A 1.2.3.3
+HOST-3.EXAMPLE. MX 0 .
+...
+HOST-127.EXAMPLE. A 1.2.3.127
+HOST-127.EXAMPLE. MX 0 .
@@ -11445,20 +12941,30 @@ $GENERATE 1-127 $ CNAME $.0
Available output forms are decimal
(d), octal
- (o) and hexadecimal
+ (o), hexadecimal
(x or X
- for uppercase). The default modifier is
+ for uppercase) and nibble
+ (n or N\
+ for uppercase). The default modifier is
${0,0,d}. If the
lhs is not absolute, the
current $ORIGIN is appended
to the name.
-
- For compatibility with earlier versions, $$ is still
- recognized as indicating a literal $ in the output.
-
-
-
+
+ In nibble mode the value will be treated as
+ if it was a reversed hexadecimal string
+ with each hexadecimal digit as a separate
+ label. The width field includes the label
+ separator.
+
+
+ For compatibility with earlier versions,
+ $$ is still recognized as
+ indicating a literal $ in the output.
+
+
+
ttl
@@ -11497,8 +13003,7 @@ $GENERATE 1-127 $ CNAME $.0
- At present the only supported types are
- PTR, CNAME, DNAME, A, AAAA and NS.
+ Any valid type.
@@ -11508,8 +13013,7 @@ $GENERATE 1-127 $ CNAME $.0
- rhs is a domain name. It is processed
- similarly to lhs.
+ rhs, optionally, quoted string.
@@ -11668,9 +13172,12 @@ $GENERATE 1-127 $ CNAME $.0
- The number of RRsets per RR type (positive
- or negative) and nonexistent names stored in the
- cache database.
+ The number of RRsets per RR type and nonexistent
+ names stored in the cache database.
+ If the exclamation mark (!) is printed for a RR
+ type, it means that particular type of RRset is
+ known to be nonexistent (this is also known as
+ "NXRRSET").
Maintained per view.
@@ -12639,6 +14146,13 @@ $GENERATE 1-127 $ CNAME $.0
Mismatch responses received.
+ The DNS ID, response's source address,
+ and/or the response's source port does not
+ match what was expected.
+ (The port must be 53 or as defined by
+ the port option.)
+ This may be an indication of a cache
+ poisoning attempt.
@@ -13106,14 +14620,17 @@ $GENERATE 1-127 $ CNAME $.0
-// Set up an ACL named "bogusnets" that will block RFC1918 space
-// and some reserved space, which is commonly used in spoofing attacks.
+// Set up an ACL named "bogusnets" that will block
+// RFC1918 space and some reserved space, which is
+// commonly used in spoofing attacks.
acl bogusnets {
- 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
- 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
+ 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24;
+ 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12;
+ 192.168.0.0/16;
};
-// Set up an ACL called our-nets. Replace this with the real IP numbers.
+// Set up an ACL called our-nets. Replace this with the
+// real IP numbers.
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
options {
...
@@ -14756,8 +16273,12 @@ zone "example.com" {
+
+
+
+
Manual pages
@@ -14765,15 +16286,23 @@ zone "example.com" {
+
+
+
-
+
+
+
+
+
+
diff --git a/doc/arm/Bv9ARM.ch01.html b/doc/arm/Bv9ARM.ch01.html
index 4cdfb09427c..ff2c5ceec6e 100644
--- a/doc/arm/Bv9ARM.ch01.html
+++ b/doc/arm/Bv9ARM.ch01.html
@@ -1,5 +1,5 @@
-
+
@@ -45,17 +45,17 @@
The Berkeley Internet Name Domain
(BIND) implements a
@@ -82,12 +82,12 @@
system administrators.
- This version of the manual corresponds to BIND version 9.6.
+ This version of the manual corresponds to BIND version 9.7.
-Organization of This Document
+Organization of This Document
In this document, Chapter 1 introduces
the basic DNS and BIND concepts. Chapter 2
@@ -116,7 +116,7 @@
-Conventions Used in This Document
+Conventions Used in This Document
In this document, we use the following general typographic
conventions:
@@ -243,7 +243,7 @@
-The Domain Name System (DNS)
+The Domain Name System (DNS)
The purpose of this document is to explain the installation
and upkeep of the BIND (Berkeley Internet
@@ -253,7 +253,7 @@
-DNS Fundamentals
+DNS Fundamentals
The Domain Name System (DNS) is a hierarchical, distributed
database. It stores information for mapping Internet host names to
@@ -275,7 +275,7 @@
-Domains and Domain Names
+Domains and Domain Names
The data stored in the DNS is identified by domain names that are organized as a tree according to
organizational or administrative boundaries. Each node of the tree,
@@ -321,7 +321,7 @@
-Zones
+Zones
To properly operate a name server, it is important to understand
the difference between a zone
@@ -374,7 +374,7 @@
-Authoritative Name Servers
+Authoritative Name Servers
Each zone is served by at least
one authoritative name server,
@@ -391,7 +391,7 @@
-The Primary Master
+The Primary Master
The authoritative server where the master copy of the zone
data is maintained is called the
@@ -411,7 +411,7 @@
-Slave Servers
+Slave Servers
The other authoritative servers, the slave
servers (also known as secondary servers)
@@ -427,7 +427,7 @@
-Stealth Servers
+Stealth Servers
Usually all of the zone's authoritative servers are listed in
NS records in the parent zone. These NS records constitute
@@ -462,7 +462,7 @@
-Caching Name Servers
+Caching Name Servers
The resolver libraries provided by most operating systems are
stub resolvers, meaning that they are not
@@ -489,7 +489,7 @@
-Forwarding
+Forwarding
Even a caching name server does not necessarily perform
the complete recursive lookup itself. Instead, it can
@@ -516,7 +516,7 @@
-Name Servers in Multiple Roles
+Name Servers in Multiple Roles
The BIND name server can
simultaneously act as
diff --git a/doc/arm/Bv9ARM.ch02.html b/doc/arm/Bv9ARM.ch02.html
index 5181a2a6cd4..a9fde322a12 100644
--- a/doc/arm/Bv9ARM.ch02.html
+++ b/doc/arm/Bv9ARM.ch02.html
@@ -1,5 +1,5 @@
-
+
DNS hardware requirements have
traditionally been quite modest.
@@ -73,7 +73,7 @@
-CPU Requirements
+CPU Requirements
CPU requirements for BIND 9 range from
i486-class machines
@@ -84,7 +84,7 @@
-Memory Requirements
+Memory Requirements
The memory of the server has to be large enough to fit the
cache and zones loaded off disk. The max-cache-size
@@ -107,7 +107,7 @@
-Name Server Intensive Environment Issues
+Name Server Intensive Environment Issues
For name server intensive environments, there are two alternative
configurations that may be used. The first is where clients and
@@ -124,13 +124,13 @@
-Supported Operating Systems
+Supported Operating Systems
ISC BIND 9 compiles and runs on a large
number
- of Unix-like operating systems and on NT-derived versions of
- Microsoft Windows such as Windows 2000 and Windows XP. For an
- up-to-date
+ of Unix-like operating systems and on
+ Microsoft Windows Server 2003 and 2008, and Windows XP and Vista.
+ For an up-to-date
list of supported systems, see the README file in the top level
directory
of the BIND 9 source distribution.
diff --git a/doc/arm/Bv9ARM.ch03.html b/doc/arm/Bv9ARM.ch03.html
index 454fdd63d2c..e01d69ec299 100644
--- a/doc/arm/Bv9ARM.ch03.html
+++ b/doc/arm/Bv9ARM.ch03.html
@@ -1,5 +1,5 @@
-
+
The following sample configuration is appropriate for a caching-only
name server for use by clients internal to a corporation. All
@@ -82,10 +82,13 @@
// Two corporate subnets we wish to allow queries from.
acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
options {
- directory "/etc/namedb"; // Working directory
+ // Working directory
+ directory "/etc/namedb";
+
allow-query { corpnets; };
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -95,7 +98,7 @@ zone "0.0.127.in-addr.arpa" {
-An Authoritative-only Name Server
+An Authoritative-only Name Server
This sample configuration is for an authoritative-only server
that is the master server for "example.com"
@@ -103,13 +106,18 @@ zone "0.0.127.in-addr.arpa" {
options {
- directory "/etc/namedb"; // Working directory
- allow-query-cache { none; }; // Do not allow access to cache
- allow-query { any; }; // This is the default
- recursion no; // Do not provide recursive service
+ // Working directory
+ directory "/etc/namedb";
+ // Do not allow access to cache
+ allow-query-cache { none; };
+ // This is the default
+ allow-query { any; };
+ // Do not provide recursive service
+ recursion no;
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -119,7 +127,8 @@ zone "0.0.127.in-addr.arpa" {
zone "example.com" {
type master;
file "example.com.db";
- // IP addresses of slave servers allowed to transfer example.com
+ // IP addresses of slave servers allowed to
+ // transfer example.com
allow-transfer {
192.168.4.14;
192.168.5.53;
@@ -137,7 +146,7 @@ zone "eng.example.com" {
-Load Balancing
+Load Balancing
A primitive form of load balancing can be achieved in
the DNS by using multiple records
@@ -273,17 +282,17 @@ zone "eng.example.com" {
For more detail on ordering responses, check the
- rrset-order substatement in the
+ rrset-order sub-statement in the
options statement, see
RRset Ordering.
-Name Server Operations
+Name Server Operations
-Tools for Use With the Name Server Daemon
+Tools for Use With the Name Server Daemon
This section describes several indispensable diagnostic,
administrative and monitoring tools available to the system
@@ -463,6 +472,60 @@ zone "eng.example.com" {
Retransfer the given zone from the master.
+
sign zone
+ [class
+ [view]]
+
+
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ key-directory in
+ the section called “options Statement Definition and
+ Usage”). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. If the DNSKEY RRset
+ is changed, then the zone is automatically
+ re-signed with the new key set.
+
+
+ This command requires that the
+ auto-dnssec zone option to be set
+ to allow,
+ maintain, or
+ create, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See the section called “Dynamic Update Policies” for
+ more details.
+
+
+
loadkeys zone
+ [class
+ [view]]
+
+
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ key-directory in
+ the section called “options Statement Definition and
+ Usage”). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. Unlike rndc
+ sign, however, the zone is not
+ immediately re-signed by the new keys, but is
+ allowed to incrementally re-sign over time.
+
+
+ This command requires that the
+ auto-dnssec zone option to
+ be set to maintain or
+ create, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See the section called “Dynamic Update Policies” for
+ more details.
+
+
freeze
[zone
[class
@@ -536,6 +599,14 @@ zone "eng.example.com" {
specified, all
views are dumped.
+
secroots
+ [view ...]
+
+ Dump the server's security roots to the secroots
+ file for the specified views. If no view is
+ specified, security roots for all
+ views are dumped.
+
stop [-p]
Stop the server, making sure any recent changes
@@ -599,6 +670,57 @@ zone "eng.example.com" {
set to yes to be effective.
It defaults to enabled.
+
addzone
+ zone
+ [class
+ [view]]
+ configuration
+
+
+
+ Add a zone while the server is running. This
+ command requires the
+ allow-new-zones option to be set
+ to yes. The
+ configuration string
+ specified on the command line is the zone
+ configuration text that would ordinarily be
+ placed in named.conf.
+
+
+ The configuration is saved in a file called
+ hash.nzf,
+ where hash is a
+ cryptographic hash generated from the name of
+ the view. When named is
+ restarted, the file will be loaded into the view
+ configuration, so that zones that were added
+ can persist after a restart.
+
+
+ This sample addzone command
+ would add the zone example.com
+ to the default view:
+
Certain UNIX signals cause the name server to take specific
actions, as described in the following table. These signals can
diff --git a/doc/arm/Bv9ARM.ch04.html b/doc/arm/Bv9ARM.ch04.html
index 7b8a200d8e5..77b74cb43ad 100644
--- a/doc/arm/Bv9ARM.ch04.html
+++ b/doc/arm/Bv9ARM.ch04.html
@@ -1,5 +1,5 @@
-
+
Dynamic update is enabled by including an
- allow-update or update-policy
- clause in the zone statement. The
- tkey-gssapi-credential and
- tkey-domain clauses in the
- options statement enable the
- server to negotiate keys that can be matched against those
- in update-policy or
- allow-update.
+ allow-update or an update-policy
+ clause in the zone statement.
+
+
+ If the zone's update-policy is set to
+ local, updates to the zone
+ will be permitted for the key local-ddns,
+ which will be generated by named at startup.
+ See the section called “Dynamic Update Policies” for more details.
+
+
+ Dynamic updates using Kerberos signed requests can be made
+ using the TKEY/GSS protocol by setting either the
+ tkey-gssapi-keytab option, or alternatively
+ by setting both the tkey-gssapi-credential
+ and tkey-domain options. Once enabled,
+ Kerberos signed requests will be matched against the update
+ policies for the zone, using the Kerberos principal as the
+ signer for the request.
Updating of secure zones (zones using DNSSEC) follows RFC
@@ -215,7 +256,7 @@
-Split DNS
+Split DNS
Setting up different views, or visibility, of the DNS space to
internal and external resolvers is usually referred to as a
@@ -245,7 +286,7 @@
-Example split DNS setup
+Example split DNS setup
Let's say a company named Example, Inc.
(example.com)
@@ -275,7 +316,7 @@
and site2.example.com, to the servers
in the
DMZ. These internal servers will have complete sets of information
- for site1.example.com, site2.example.com,site1.internal,
+ for site1.example.com, site2.example.com, site1.internal,
and site2.internal.
A shared secret is generated to be shared between host1 and host2.
An arbitrary key name is chosen: "host1-host2.". The key name must
@@ -499,7 +551,7 @@ nameserver 172.16.72.4
-Automatic Generation
+Automatic Generation
The following command will generate a 128-bit (16 byte) HMAC-SHA256
key as described above. Longer keys are better, but shorter keys
@@ -523,7 +575,7 @@ nameserver 172.16.72.4
-Manual Generation
+Manual Generation
The shared secret is simply a random sequence of bits, encoded
in base-64. Most ASCII strings are valid base-64 strings (assuming
@@ -538,7 +590,7 @@ nameserver 172.16.72.4
-Copying the Shared Secret to Both Machines
+Copying the Shared Secret to Both Machines
This is beyond the scope of DNS. A secure transport mechanism
should be used. This could be secure FTP, ssh, telephone, etc.
@@ -546,7 +598,7 @@ nameserver 172.16.72.4
-Informing the Servers of the Key's Existence
+Informing the Servers of the Key's Existence
Imagine host1 and host 2
are
@@ -573,7 +625,7 @@ key host1-host2. {
-Instructing the Server to Use the Key
+Instructing the Server to Use the Key
Since keys are shared between two hosts only, the server must
be told when keys are to be used. The following is added to the named.conf file
@@ -605,7 +657,7 @@ server 10.1.2.3 {
-TSIG Key Based Access Control
+TSIG Key Based Access Control
BIND allows IP addresses and ranges
to be specified in ACL
@@ -626,14 +678,13 @@ allow-update { key host1-host2. ;};
was signed by a key named "host1-host2.".
The processing of TSIG signed messages can result in
several errors. If a signed message is sent to a non-TSIG aware
@@ -659,7 +710,7 @@ allow-update { key host1-host2. ;};
-TKEY
+TKEY
TKEY
is a mechanism for automatically generating a shared secret
between two hosts. There are several "modes" of
@@ -695,7 +746,7 @@ allow-update { key host1-host2. ;};
-SIG(0)
+SIG(0)
BIND 9 partially supports DNSSEC SIG(0)
transaction signatures as specified in RFC 2535 and RFC 2931.
@@ -756,7 +807,7 @@ allow-update { key host1-host2. ;};
-Generating Keys
+Generating Keys
The dnssec-keygen program is used to
generate keys.
@@ -812,7 +863,7 @@ allow-update { key host1-host2. ;};
-Signing the Zone
+Signing the Zone
The dnssec-signzone program is used
to sign a zone.
@@ -854,7 +905,7 @@ allow-update { key host1-host2. ;};
-Configuring Servers
+Configuring Servers
To enable named to respond appropriately
to DNS requests from DNSSEC aware clients,
@@ -863,12 +914,22 @@ allow-update { key host1-host2. ;};
To enable named to validate answers from
- other servers, the dnssec-enable and
- dnssec-validation options must both be
- set to yes (the default setting in BIND 9.5
- and later), and at least one trust anchor must be configured
- with a trusted-keys statement in
- named.conf.
+ other servers, the dnssec-enable option
+ must be set to yes, and the
+ dnssec-validation options must be set to
+ yes or auto.
+
+
+ If dnssec-validation is set to
+ auto, then a default
+ trust anchor for the DNS root zone will be used.
+ If it is set to yes, however,
+ then at least one trust anchor must be configured
+ with a trusted-keys or
+ managed-keys statement in
+ named.conf, or DNSSEC validation
+ will not occur. The default setting is
+ yes.
trusted-keys are copies of DNSKEY RRs
@@ -879,7 +940,13 @@ allow-update { key host1-host2. ;};
to validated the DNSKEY RRset that they are from.
- trusted-keys are described in more detail
+ managed-keys are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+
+
+ trusted-keys and
+ managed-keys are described in more detail
later in this document.
After DNSSEC gets established, a typical DNSSEC configuration
- will look something like the following. It has a one or
+ will look something like the following. It has one or
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that named is immune
- to compromises in the DNSSEC components of the security
+ controls. These are here to ensure that named
+ is immune to compromises in the DNSSEC components of the security
of parent zones.
As of BIND 9.7.0 it is possible to change a dynamic zone
+ from insecure to signed and back again. A secure zone can use
+ either NSEC or NSEC3 chains.
+
+Converting from insecure to secure
+
Changing a zone from insecure to secure can be done in two
+ ways: using a dynamic DNS update, or the
+ auto-dnssec zone option.
+
For either method, you need to configure
+ named so that it can see the
+ K* files which contain the public and private
+ parts of the keys that will be used to sign the zone. These files
+ will have been generated by
+ dnssec-keygen. You can do this by placing them
+ in the key-directory, as specified in
+ named.conf:
+
+ zone example.net {
+ type master;
+ update-policy local;
+ file "dynamic/example.net/example.net";
+ key-directory "dynamic/example.net";
+ };
+
+
If one KSK and one ZSK DNSKEY key have been generated, this
+ configuration will cause all records in the zone to be signed
+ with the ZSK, and the DNSKEY RRset to be signed with the KSK as
+ well. An NSEC chain will be generated as part of the initial
+ signing process.
While the update request will complete almost immediately,
+ the zone will not be completely signed until
+ named has had time to walk the zone and
+ generate the NSEC and RRSIG records. The NSEC record at the apex
+ will be added last, to signal that there is a complete NSEC
+ chain.
+
If you wish to sign using NSEC3 instead of NSEC, you should
+ add an NSEC3PARAM record to the initial update request. If you
+ wish the NSEC3 chain to have the OPTOUT bit set, set it in the
+ flags field of the NSEC3PARAM record.
Again, this update request will complete almost
+ immediately; however, the record won't show up until
+ named has had a chance to build/remove the
+ relevant chain. A private type record will be created to record
+ the state of the operation (see below for more details), and will
+ be removed once the operation completes.
+
While the initial signing and NSEC/NSEC3 chain generation
+ is happening, other updates are possible as well.
+
+Fully automatic zone signing
+
To enable automatic signing, add the
+ auto-dnssec option to the zone statement in
+ named.conf.
+ auto-dnssec has two possible arguments:
+ allow or
+ maintain.
+
With
+ auto-dnssec allow,
+ named can search the key directory for keys
+ matching the zone, insert them into the zone, and use them to
+ sign the zone. It will do so only when it receives an
+ rndc sign <zonename> or
+ rndc loadkeys <zonename> command.
+
+
+ auto-dnssec maintain includes the above
+ functionality, but will also automatically adjust the zone's
+ DNSKEY records on schedule according to the keys' timing metadata.
+ (See dnssec-keygen(8) and
+ dnssec-settime(8) for more information.)
+ If keys are present in the key directory the first time the zone
+ is loaded, it will be signed immediately, without waiting for an
+ rndc sign or rndc loadkeys
+ command. (Those commands can still be used when there are unscheduled
+ key changes, however.)
+
+
Using the
+ auto-dnssec option requires the zone to be
+ configured to allow dynamic updates, by adding an
+ allow-update or
+ update-policy statement to the zone
+ configuration. If this has not been done, the configuration will
+ fail.
+
+Private-type records
+
The state of the signing process is signaled by
+ private-type records (with a default type value of 65534). When
+ signing is complete, these records will have a nonzero value for
+ the final octet (for those records which have a nonzero initial
+ octet).
+
The private type record format: If the first octet is
+ non-zero then the record indicates that the zone needs to be
+ signed with the key matching the record, or that all signatures
+ that match the record should be removed.
+
+
+
+
+ algorithm (octet 1)
+ key id in network order (octet 2 and 3)
+ removal flag (octet 4)
+ complete flag (octet 5)
+
+
+
+
Only records flagged as "complete" can be removed via
+ dynamic update. Attempts to remove other private type records
+ will be silently ignored.
+
If the first octet is zero (this is a reserved algorithm
+ number that should never appear in a DNSKEY record) then the
+ record indicates changes to the NSEC3 chains are in progress. The
+ rest of the record contains an NSEC3PARAM record. The flag field
+ tells what operation to perform based on the flag bits.
As with insecure-to-secure conversions, rolling DNSSEC
+ keys can be done in two ways: using a dynamic DNS update, or the
+ auto-dnssec zone option.
+
+Dynamic DNS update method
+
To perform key rollovers via dynamic update, you need to add
+ the K* files for the new keys so that
+ named can find them. You can then add the new
+ DNSKEY RRs via dynamic update.
+ named will then cause the zone to be signed
+ with the new keys. When the signing is complete the private type
+ records will be updated so that the last octet is non
+ zero.
+
If this is for a KSK you need to inform the parent and any
+ trust anchor repositories of the new KSK.
+
You should then wait for the maximum TTL in the zone before
+ removing the old DNSKEY. If it is a KSK that is being updated,
+ you also need to wait for the DS RRset in the parent to be
+ updated and its TTL to expire. This ensures that all clients will
+ be able to verify at least one signature when you remove the old
+ DNSKEY.
+
The old DNSKEY can be removed via UPDATE. Take care to
+ specify the correct key.
+ named will clean out any signatures generated
+ by the old key after the update completes.
+
+Automatic key rollovers
+
When a new key reaches its activation date (as set by
+ dnssec-keygen or dnssec-settime),
+ if the auto-dnssec zone option is set to
+ maintain, named will
+ automatically carry out the key rollover. If the key's algorithm
+ has not previously been used to sign the zone, then the zone will
+ be fully signed as quickly as possible. However, if the new key
+ is replacing an existing key of the same algorithm, then the
+ zone will be re-signed incrementally, with signatures from the
+ old key being replaced with signatures from the new key as their
+ signature validity periods expire. By default, this rollover
+ completes in 30 days, after which it will be safe to remove the
+ old key from the DNSKEY RRset.
+
+NSEC3PARAM rollovers via UPDATE
+
Add the new NSEC3PARAM record via dynamic update. When the
+ new NSEC3 chain has been generated, the NSEC3PARAM flag field
+ will be zero. At this point you can remove the old NSEC3PARAM
+ record. The old chain will be removed after the update request
+ completes.
+
+Converting from NSEC to NSEC3
+
To do this, you just need to add an NSEC3PARAM record. When
+ the conversion is complete, the NSEC chain will have been removed
+ and the NSEC3PARAM record will have a zero flag field. The NSEC3
+ chain will be generated before the NSEC chain is
+ destroyed.
+
+Converting from NSEC3 to NSEC
+
To do this, use nsupdate to
+ remove all NSEC3PARAM records with a zero flag
+ field. The NSEC chain will be generated before the NSEC3 chain is
+ removed.
+
+Converting from secure to insecure
+
To convert a signed zone to unsigned using dynamic DNS,
+ delete all the DNSKEY records from the zone apex using
+ nsupdate. All signatures, NSEC or NSEC3 chains,
+ and associated NSEC3PARAM records will be removed automatically.
+ This will take place after the update request completes.
+
This requires the
+ dnssec-secure-to-insecure option to be set to
+ yes in
+ named.conf.
+
In addition, if the auto-dnssec maintain
+ zone statement is used, it should be removed or changed to
+ allow instead (or it will re-sign).
+
+
+Periodic re-signing
+
In any secure zone which supports dynamic updates, named
+ will periodically re-sign RRsets which have not been re-signed as
+ a result of some update action. The signature lifetimes will be
+ adjusted so as to spread the re-sign load over time rather than
+ all at once.
+
+NSEC3 and OPTOUT
+
+ named only supports creating new NSEC3 chains
+ where all the NSEC3 records in the zone have the same OPTOUT
+ state.
+ named supports UPDATES to zones where the NSEC3
+ records in the chain have mixed OPTOUT state.
+ named does not support changing the OPTOUT
+ state of an individual NSEC3 record, the entire chain needs to be
+ changed if the OPTOUT state of an individual NSEC3 needs to be
+ changed.
+
+
+
+Dynamic Trust Anchor Management
+
BIND 9.7.0 introduces support for RFC 5011, dynamic trust
+ anchor management. Using this feature allows
+ named to keep track of changes to critical
+ DNSSEC keys without any need for the operator to make changes to
+ configuration files.
To set up an authoritative zone for RFC 5011 trust anchor
+ maintenance, generate two (or more) key signing keys (KSKs) for
+ the zone. Sign the zone with one of them; this is the "active"
+ KSK. All KSK's which do not sign the zone are "stand-by"
+ keys.
+
Any validating resolver which is configured to use the
+ active KSK as an RFC 5011-managed trust anchor will take note
+ of the stand-by KSKs in the zone's DNSKEY RRset, and store them
+ for future reference. The resolver will recheck the zone
+ periodically, and after 30 days, if the new key is still there,
+ then the key will be accepted by the resolver as a valid trust
+ anchor for the zone. Any time after this 30-day acceptance
+ timer has completed, the active KSK can be revoked, and the
+ zone can be "rolled over" to the newly accepted key.
+
The easiest way to place a stand-by key in a zone is to
+ use the "smart signing" features of
+ dnssec-keygen and
+ dnssec-signzone. If a key with a publication
+ date in the past, but an activation date which is unset or in
+ the future, "
+ dnssec-signzone -S" will include the DNSKEY
+ record in the zone, but will not sign with it:
+
+$ dnssec-keygen -K keys -f KSK -P now -A now+2y example.net
+$ dnssec-signzone -S -K keys example.net
+
+
To revoke a key, the new command
+ dnssec-revoke has been added. This adds the
+ REVOKED bit to the key flags and re-generates the
+ K*.key and
+ K*.private files.
+
After revoking the active key, the zone must be signed
+ with both the revoked KSK and the new active KSK. (Smart
+ signing takes care of this automatically.)
+
Once a key has been revoked and used to sign the DNSKEY
+ RRset in which it appears, that key will never again be
+ accepted as a valid trust anchor by the resolver. However,
+ validation can proceed using the new active key (which had been
+ accepted by the resolver when it was a stand-by key).
+
See RFC 5011 for more details on key rollover
+ scenarios.
+
When a key has been revoked, its key ID changes,
+ increasing by 128, and wrapping around at 65535. So, for
+ example, the key "Kexample.com.+005+10000" becomes
+ "Kexample.com.+005+10128".
+
If two keys have ID's exactly 128 apart, and one is
+ revoked, then the two key ID's will collide, causing several
+ problems. To prevent this,
+ dnssec-keygen will not generate a new key if
+ another key is present which may collide. This checking will
+ only occur if the new keys are written to the same directory
+ which holds all other keys in use for that zone.
+
Older versions of BIND 9 did not have this precaution.
+ Exercise caution if using key revocation on keys that were
+ generated by previous releases, or if using keys stored in
+ multiple directories or on multiple machines.
+
It is expected that a future release of BIND 9 will
+ address this problem in a different way, by storing revoked
+ keys with their original unrevoked key ID's.
+
+
+
+
+PKCS #11 (Cryptoki) support
+
PKCS #11 (Public Key Cryptography Standard #11) defines a
+ platform- independent API for the control of hardware security
+ modules (HSMs) and other cryptographic support devices.
+
BIND 9 is known to work with two HSMs: The Sun SCA 6000
+ cryptographic acceleration board, tested under Solaris x86, and
+ the AEP Keyper network-attached key storage device, tested with
+ Debian Linux, Solaris x86 and Windows Server 2003.
+
+
+Prerequisites
+
See the HSM vendor documentation for information about
+ installing, initializing, testing and troubleshooting the
+ HSM.
+
BIND 9 uses OpenSSL for cryptography, but stock OpenSSL
+ does not yet fully support PKCS #11. However, a PKCS #11 engine
+ for OpenSSL is available from the OpenSolaris project. It has
+ been modified by ISC to work with with BIND 9, and to provide
+ new features such as PIN management and key by
+ reference.
+
The patched OpenSSL depends on a "PKCS #11 provider".
+ This is a shared library object, providing a low-level PKCS #11
+ interface to the HSM hardware. It is dynamically loaded by
+ OpenSSL at runtime. The PKCS #11 provider comes from the HSM
+ vendor, and and is specific to the HSM to be controlled.
+
There are two "flavors" of PKCS #11 support provided by
+ the patched OpenSSL, one of which must be chosen at
+ configuration time. The correct choice depends on the HSM
+ hardware:
+
+
Use 'crypto-accelerator' with HSMs that have hardware
+ cryptographic acceleration features, such as the SCA 6000
+ board. This causes OpenSSL to run all supported
+ cryptographic operations in the HSM.
+
Use 'sign-only' with HSMs that are designed to
+ function primarily as secure key storage devices, but lack
+ hardware acceleration. These devices are highly secure, but
+ are not necessarily any faster at cryptography than the
+ system CPU — often, they are slower. It is therefore
+ most efficient to use them only for those cryptographic
+ functions that require access to the secured private key,
+ such as zone signing, and to use the system CPU for all
+ other computationally-intensive operations. The AEP Keyper
+ is an example of such a device.
+
+
The modified OpenSSL code is included in the BIND 9.7.0
+ release, in the form of a context diff against the latest OpenSSL.
+
+
+
Note
+ The latest OpenSSL version at the time of the BIND release
+ is 0.9.8l.
+ ISC will provide an updated patch as new versions of OpenSSL
+ are released. The version number in the following examples
+ is expected to change.
+
+ Before building BIND 9 with PKCS #11 support, it will be
+ necessary to build OpenSSL with this patch in place and inform
+ it of the path to the HSM-specific PKCS #11 provider
+ library.
(Note that the patch file may not be compatible with the
+ "patch" utility on all operating systems. You may need to
+ install GNU patch.)
+
When building OpenSSL, place it in a non-standard
+ location so that it does not interfere with OpenSSL libraries
+ elsewhere on the system. In the following examples, we choose
+ to install into "/opt/pkcs11/usr". We will use this location
+ when we configure BIND 9.
+
+
+Building OpenSSL for the AEP Keyper on Linux
+
The AEP Keyper is a highly secure key storage device,
+ but does not provide hardware cryptographic acceleration. It
+ can carry out cryptographic operations, but it is probably
+ slower than your system's CPU. Therefore, we choose the
+ 'sign-only' flavor when building OpenSSL.
+
The Keyper-specific PKCS #11 provider library is
+ delivered with the Keyper software. In this example, we place
+ it /opt/pkcs11/usr/lib:
This library is only available for Linux as a 32-bit
+ binary. If we are compiling on a 64-bit Linux system, it is
+ necessary to force a 32-bit build, by specifying -m32 in the
+ build options.
+
Finally, the Keyper library requires threads, so we
+ must specify -pthread.
After configuring, run "make"
+ and "make test". If "make
+ test" fails with "pthread_atfork() not found", you forgot to
+ add the -pthread above.
+
+
+
+Building OpenSSL for the SCA 6000 on Solaris
+
The SCA-6000 PKCS #11 provider is installed as a system
+ library, libpkcs11. It is a true crypto accelerator, up to 4
+ times faster than any CPU, so the flavor shall be
+ 'crypto-accelerator'.
+
In this example, we are building on Solaris x86 on an
+ AMD64 system.
(For a 32-bit build, use "solaris-x86-cc" and
+ /usr/lib/libpkcs11.so.)
+
After configuring, run
+ make and
+ make test.
+
Once you have built OpenSSL, run
+ "apps/openssl engine pkcs11" to confirm
+ that PKCS #11 support was compiled in correctly. The output
+ should be one of the following lines, depending on the flavor
+ selected:
+
+ (pkcs11) PKCS #11 engine support (sign only)
+
+
Or:
+
+ (pkcs11) PKCS #11 engine support (crypto accelerator)
+
+
Next, run
+ "apps/openssl engine pkcs11 -t". This will
+ attempt to initialize the PKCS #11 engine. If it is able to
+ do so successfully, it will report
+ “[ available ]”.
+
If the output is correct, run
+ "make install" which will install the
+ modified OpenSSL suite to
+ /opt/pkcs11/usr.
+
+
+
+
+Building BIND 9 with PKCS#11
+
When building BIND 9, the location of the custom-built
+ OpenSSL library must be specified via configure.
+
+
+Configuring BIND 9 for Linux
+
To link with the PKCS #11 provider, threads must be
+ enabled in the BIND 9 build.
+
The PKCS #11 library for the AEP Keyper is currently
+ only available as a 32-bit binary. If we are building on a
+ 64-bit host, we must force a 32-bit build by adding "-m32" to
+ the CC options on the "configure" command line.
If configure complains about OpenSSL not working, you
+ may have a 32/64-bit architecture mismatch. Or, you may have
+ incorrectly specified the path to OpenSSL (it should be the
+ same as the --prefix argument to the OpenSSL
+ Configure).
+
+
After configuring, run
+ "make",
+ "make test" and
+ "make install".
+
+
+
+PKCS #11 Tools
+
BIND 9 includes a minimal set of tools to operate the
+ HSM, including
+ pkcs11-keygen to generate a new key pair
+ within the HSM,
+ pkcs11-list to list objects currently
+ available, and
+ pkcs11-destroy to remove objects.
+
In UNIX/Linux builds, these tools are built only if BIND
+ 9 is configured with the --with-pkcs11 option. (NOTE: If
+ --with-pkcs11 is set to "yes", rather than to the path of the
+ PKCS #11 provider, then the tools will be built but the
+ provider will be left undefined. Use the -m option or the
+ PKCS11_PROVIDER environment variable to specify the path to the
+ provider.)
+
+
+
+Using the HSM
+
First, we must set up the runtime environment so the
+ OpenSSL and PKCS #11 libraries can be loaded:
When operating an AEP Keyper, it is also necessary to
+ specify the location of the "machine" file, which stores
+ information about the Keyper for use by PKCS #11 provider
+ library. If the machine file is in
+ /opt/Keyper/PKCS11Provider/machine,
+ use:
These environment variables must be set whenever running
+ any tool that uses the HSM, including
+ pkcs11-keygen,
+ pkcs11-list,
+ pkcs11-destroy,
+ dnssec-keyfromlabel,
+ dnssec-signzone,
+ dnssec-keygen(which will use the HSM for
+ random number generation), and
+ named.
+
We can now create and use keys in the HSM. In this case,
+ we will create a 2048 bit key and give it the label
+ "sample-ksk":
Before using this key to sign a zone, we must create a
+ pair of BIND 9 key files. The "dnssec-keyfromlabel" utility
+ does this. In this case, we will be using the HSM key
+ "sample-ksk" as the key-signing key for "example.net":
The resulting K*.key and K*.private files can now be used
+ to sign the zone. Unlike normal K* files, which contain both
+ public and private key data, these files will contain only the
+ public key data, plus an identifier for the private key which
+ remains stored within the HSM. The HSM handles signing with the
+ private key.
+
If you wish to generate a second key in the HSM for use
+ as a zone-signing key, follow the same procedure above, using a
+ different keylabel, a smaller key size, and omitting "-f KSK"
+ from the dnssec-keyfromlabel arguments:
Alternatively, you may prefer to generate a conventional
+ on-disk key, using dnssec-keygen:
+
+$ dnssec-keygen example.net
+
+
This provides less security than an HSM key, but since
+ HSMs can be slow or cumbersome to use for security reasons, it
+ may be more efficient to reserve HSM keys for use in the less
+ frequent key-signing operation. The zone-signing key can be
+ rolled more frequently, if you wish, to compensate for a
+ reduction in key security.
+
Now you can sign the zone. (Note: If not using the -S
+ option to
+ dnssec-signzone, it will be necessary to add
+ the contents of both
+ K*.key files to the zone master file before
+ signing it.)
+
+$ dnssec-signzone -S example.net
+Enter PIN:
+Verifying the zone using the following algorithms:
+NSEC3RSASHA1.
+Zone signing complete:
+Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
+example.net.signed
+
+
+
+
+Specifying the engine on the command line
+
The OpenSSL engine can be specified in
+ named and all of the BIND
+ dnssec-* tools by using the "-E
+ <engine>" command line option. If BIND 9 is built with
+ the --with-pkcs11 option, this option defaults to "pkcs11".
+ Specifying the engine will generally not be necessary unless
+ for some reason you wish to use a different OpenSSL
+ engine.
+
If you wish to disable use of the "pkcs11" engine —
+ for troubleshooting purposes, or because the HSM is unavailable
+ — set the engine to the empty string. For example:
+
+$ dnssec-signzone -E '' -S example.net
+
+
This causes
+ dnssec-signzone to run as if it were compiled
+ without the --with-pkcs11 option.
+
+
+
+Running named with automatic zone re-signing
+
If you want
+ named to dynamically re-sign zones using HSM
+ keys, and/or to to sign new records inserted via nsupdate, then
+ named must have access to the HSM PIN. This can be accomplished
+ by placing the PIN into the openssl.cnf file (in the above
+ examples,
+ /opt/pkcs11/usr/ssl/openssl.cnf).
+
The location of the openssl.cnf file can be overridden by
+ setting the OPENSSL_CONF environment variable before running
+ named.
This will also allow the dnssec-* tools to access the HSM
+ without PIN entry. (The pkcs11-* tools access the HSM directly,
+ not via OpenSSL, so a PIN will still be required to use
+ them.)
+
+
Warning
+
Placing the HSM's PIN in a text file in
+ this manner may reduce the security advantage of using an
+ HSM. Be sure this is what you want to do before configuring
+ OpenSSL in this way.
+
+
+
+
+
+IPv6 Support in BIND 9
BIND 9 fully supports all currently
defined forms of IPv6 name to address and address to name
@@ -1017,7 +1789,7 @@ options {
-Address Lookups Using AAAA Records
+Address Lookups Using AAAA Records
The IPv6 AAAA record is a parallel to the IPv4 A record,
and, unlike the deprecated A6 record, specifies the entire
@@ -1036,7 +1808,7 @@ host 3600 IN AAAA 2001:db8::1
-Address to Name Lookups Using Nibble Format
+Address to Name Lookups Using Nibble Format
When looking up an address in nibble format, the address
components are simply reversed, just as in IPv4, and
@@ -1048,7 +1820,8 @@ host 3600 IN AAAA 2001:db8::1
$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com.
+1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR (
+ host.example.com. )
Traditionally applications have been linked with a stub resolver
library that sends recursive DNS queries to a local caching name
diff --git a/doc/arm/Bv9ARM.ch06.html b/doc/arm/Bv9ARM.ch06.html
index d969e4b3c04..35243484d12 100644
--- a/doc/arm/Bv9ARM.ch06.html
+++ b/doc/arm/Bv9ARM.ch06.html
@@ -1,5 +1,5 @@
-
+
-logging Statement Definition and
+logging Statement Definition and
Usage
The logging statement configures a
@@ -1158,7 +1188,7 @@
-The channel Phrase
+The channel Phrase
All log output goes to one or more channels;
you can make as many of them as you want.
@@ -1342,32 +1372,30 @@ notrace. All debugging messages in the server have a debug
used is described in the section called “The category Phrase”.
channel default_syslog {
- syslog daemon; // send to syslog's daemon
- // facility
- severity info; // only send priority info
- // and higher
-};
+ // send to syslog's daemon facility
+ syslog daemon;
+ // only send priority info and higher
+ severity info;
channel default_debug {
- file "named.run"; // write to named.run in
- // the working directory
- // Note: stderr is used instead
- // of "named.run"
- // if the server is started
- // with the '-f' option.
- severity dynamic; // log at the server's
- // current debug level
+ // write to named.run in the working directory
+ // Note: stderr is used instead of "named.run" if
+ // the server is started with the '-f' option.
+ file "named.run";
+ // log at the server's current debug level
+ severity dynamic;
};
channel default_stderr {
- stderr; // writes to stderr
- severity info; // only send priority info
- // and higher
+ // writes to stderr
+ stderr;
+ // only send priority info and higher
+ severity info;
};
channel null {
- null; // toss anything sent to
- // this channel
+ // toss anything sent to this channel
+ null;
};
The query log entry reports the client's IP
address and port number, and the query name,
- class and type. It also reports whether the
+ class and type. Next it reports whether the
Recursion Desired flag was set (+ if set, -
if not set), if the query was signed (S),
- EDNS was in use (E), if DO (DNSSEC Ok) was
- set (D), or if CD (Checking Disabled) was set
- (C).
+ EDNS was in use (E), if TCP was used (T), if
+ DO (DNSSEC Ok) was set (D), or if CD (Checking
+ Disabled) was set (C). After this the
+ destination address the query was sent to is
+ reported.
@@ -1723,7 +1753,7 @@ category notify { null; };
-The query-errors Category
+The query-errors Category
The query-errors category is
specifically intended for debugging purposes: To identify
@@ -1754,7 +1784,15 @@ category notify { null; };
The log message will look like as follows:
- fetch completed at resolver.c:2970 for www.example.com/A in 30.000183: timed out/success [domain:example.com,referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,badresp:1,adberr:0,findfail:0,valfail:0]
+
+
+
+fetch completed at resolver.c:2970 for www.example.com/A
+in 30.000183: timed out/success [domain:example.com,
+referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,
+badresp:1,adberr:0,findfail:0,valfail:0]
+
+
The first part before the colon shows that a recursive
@@ -1943,13 +1981,14 @@ category notify { null; };
-lwres Statement Grammar
+lwres Statement Grammar
This is the grammar of the lwres
statement in the named.conf file:
+ Allows multiple views to share a single cache
+ database.
+ Each view has its own cache database by default, but
+ if multiple views have the same operational policy
+ for name resolution and caching, those views can
+ share a single cache to save memory and possibly
+ improve resolution efficiency by using this option.
+
+
+ The attach-cache option
+ may also be specified in view
+ statements, in which case it overrides the
+ global attach-cache option.
+
+
+ The cache_name specifies
+ the cache to be shared.
+ When the named server configures
+ views which are supposed to share a cache, it
+ creates a cache with the specified name for the
+ first view of these sharing views.
+ The rest of the views will simply refer to the
+ already created cache.
+
+
+ One common configuration to share a cache would be to
+ allow all views to share a single cache.
+ This can be done by specifying
+ the attach-cache as a global
+ option with an arbitrary name.
+
+
+ Another possible operation is to allow a subset of
+ all views to share a cache while the others to
+ retain their own caches.
+ For example, if there are three views A, B, and C,
+ and only A and B should share a cache, specify the
+ attach-cache option as a view A (or
+ B)'s option, referring to the other view name:
+
+
+ view "A" {
+ // this view has its own cache
+ ...
+ };
+ view "B" {
+ // this view refers to A's cache
+ attach-cache "A";
+ };
+ view "C" {
+ // this view has its own cache
+ ...
+ };
+
+
+ Views that share a cache must have the same policy
+ on configurable parameters that may affect caching.
+ The current implementation requires the following
+ configurable options be consistent among these
+ views:
+ check-names,
+ cleaning-interval,
+ dnssec-accept-expired,
+ dnssec-validation,
+ max-cache-ttl,
+ max-ncache-ttl,
+ max-cache-size, and
+ zero-no-soa-ttl.
+
+
+ Note that there may be other parameters that may
+ cause confusion if they are inconsistent for
+ different views that share a single cache.
+ For example, if these views define different sets of
+ forwarders that can return different answers for the
+ same question, sharing the answer does not make
+ sense or could even be harmful.
+ It is administrator's responsibility to ensure
+ configuration differences in different views do
+ not cause disruption with a shared cache.
+
+
directory
The working directory of the server.
@@ -2229,10 +2382,19 @@ category notify { null; };
When performing dynamic update of secure zones, the
directory where the public and private DNSSEC key files
should be found, if different than the current working
- directory. The directory specified must be an absolute
- path. (Note that this option has no effect on the paths
- for files containing non-DNSSEC keys such as the
- rndc.key.
+ directory. (Note that this option has no effect on the
+ paths for files containing non-DNSSEC keys such as
+ bind.keys,
+ rndc.key or
+ session.key.)
+
+
managed-keys-directory
+
+ The directory used to hold the files used to track managed keys.
+ By default it is the working directory. It there are no
+ views then the file managed-keys.bind
+ otherwise a SHA256 hash of the view name is used with
+ .mkeys extension added.
named-xfer
@@ -2243,18 +2405,27 @@ category notify { null; };
named-xfer program is needed;
its functionality is built into the name server.
+
tkey-gssapi-keytab
+
+ The KRB5 keytab file to use for GSS-TSIG updates. If
+ this option is set and tkey-gssapi-credential is not
+ set, then updates will be allowed with any key
+ matching a principal in the specified keytab.
+
tkey-gssapi-credential
The security credential with which the server should
authenticate keys requested by the GSS-TSIG protocol.
Currently only Kerberos 5 authentication is available
- and the credential is a Kerberos principal which
- the server can acquire through the default system
- key file, normally /etc/krb5.keytab.
- Normally this principal is of the form
- "DNS/server.domain".
- To use GSS-TSIG, tkey-domain
- must also be set.
+ and the credential is a Kerberos principal which the
+ server can acquire through the default system key
+ file, normally /etc/krb5.keytab.
+ The location keytab file can be overridden using the
+ tkey-gssapi-keytab option. Normally this principal is
+ of the form "DNS/server.domain".
+ To use GSS-TSIG, tkey-domain must
+ also be set if a specific keytab is not set with
+ tkey-gssapi-keytab.
tkey-domain
@@ -2271,7 +2442,8 @@ category notify { null; };
should be the server's domain name, or an otherwise
non-existent subdomain like
"_tkey.domainname". If you are
- using GSS-TSIG, this variable must be defined.
+ using GSS-TSIG, this variable must be defined, unless
+ you specify a specific keytab using tkey-gssapi-keytab.
+ The pathname of a file to override the built-in trusted
+ keys provided by named.
+ See the discussion of dnssec-lookaside
+ and dnssec-validation for details.
+ If not specified, the default is
+ /etc/bind.keys.
+
+
secroots-file
+
+ The pathname of the file the server dumps
+ security roots to when instructed to do so with
+ rndc secroots.
+ If not specified, the default is named.secroots.
+
+
session-keyfile
+
+ The pathname of the file into which to write a TSIG
+ session key generated by named for use by
+ nsupdate -l. If not specified, the
+ default is /var/run/named/session.key.
+ (See the section called “Dynamic Update Policies”, and in
+ particular the discussion of the
+ update-policy statement's
+ local option for more
+ information about this feature.)
+
+
session-keyname
+
+ The key name to use for the TSIG session key.
+ If not specified, the default is "local-ddns".
+
+
session-keyalg
+
+ The algorithm to use for the TSIG session key.
+ Valid values are hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384, hmac-sha512 and hmac-md5. If not
+ specified, the default is hmac-sha256.
+
+
session-keyfile
+
+ The pathname of the file into which to write a session TSIG
+ key for use by nsupdate -l. (See the
+ discussion of the update-policy
+ statement's local option for more
+ details on this feature.)
+
port
The UDP/TCP port number the server uses for
@@ -2379,14 +2599,14 @@ category notify { null; };
DS queries are expected to be made to and be answered by
delegation only zones. Such queries and responses are
- treated as a exception to delegation-only processing
+ treated as an exception to delegation-only processing
and are not converted to NXDOMAIN responses provided
a CNAME is not discovered at the query name.
If a delegation only zone server also serves a child
zone it is not always possible to determine whether
- a answer comes from the delegation only zone or the
+ an answer comes from the delegation only zone or the
child zone. SOA NS and DNSKEY records are apex
only records and a matching response that contains
these records or DS is treated as coming from a
@@ -2423,42 +2643,138 @@ options {
Only the most specific will be applied.
dnssec-lookaside
-
- When set, dnssec-lookaside
- provides the
- validator with an alternate method to validate DNSKEY records
- at the
- top of a zone. When a DNSKEY is at or below a domain
- specified by the
- deepest dnssec-lookaside, and
- the normal DNSSEC validation
- has left the key untrusted, the trust-anchor will be append to
- the key
- name and a DLV record will be looked up to see if it can
- validate the
- key. If the DLV record validates a DNSKEY (similarly to the
- way a DS
+
+
+ When set, dnssec-lookaside provides the
+ validator with an alternate method to validate DNSKEY
+ records at the top of a zone. When a DNSKEY is at or
+ below a domain specified by the deepest
+ dnssec-lookaside, and the normal DNSSEC
+ validation has left the key untrusted, the trust-anchor
+ will be appended to the key name and a DLV record will be
+ looked up to see if it can validate the key. If the DLV
+ record validates a DNSKEY (similarly to the way a DS
record does) the DNSKEY RRset is deemed to be trusted.
-
+
+
+ If dnssec-lookaside is set to
+ auto, then built-in default
+ values for the DLV domain and trust anchor will be
+ used, along with a built-in key for validation.
+
+
+ The default DLV key is stored in the file
+ bind.keys;
+ named will load that key at
+ startup if dnssec-lookaside is set to
+ auto. A copy of the file is
+ installed along with BIND 9, and is
+ current as of the release date. If the DLV key expires, a
+ new copy of bind.keys can be downloaded
+ from https://www.isc.org/solutions/dlv.
+
+
+ (To prevent problems if bind.keys is
+ not found, the current key is also compiled in to
+ named. Relying on this is not
+ recommended, however, as it requires named
+ to be recompiled with a new key when the DLV key expires.)
+
+
+ NOTE: named only loads certain specific
+ keys from bind.keys: those for the
+ DLV zone and for the DNS root zone. The file cannot be
+ used to store keys for other zones.
+
+
dnssec-must-be-secure
- Specify hierarchies which must be or may not be secure (signed and
- validated).
- If yes, then named will only accept
- answers if they
- are secure.
- If no, then normal DNSSEC validation
- applies
- allowing for insecure answers to be accepted.
- The specified domain must be under a trusted-key or
- dnssec-lookaside must be
- active.
+ Specify hierarchies which must be or may not be secure
+ (signed and validated). If yes,
+ then named will only accept answers if
+ they are secure. If no, then normal
+ DNSSEC validation applies allowing for insecure answers to
+ be accepted. The specified domain must be under a
+ trusted-keys or
+ managed-keys statement, or
+ dnssec-lookaside must be active.
+
dns64
+
+
+ This directive instructs named to
+ return mapped IPv4 addresses to AAAA queries when
+ there are no AAAA records. It is intended to be
+ used in conjunction with a NAT64. Each
+ dns64 defines one DNS64 prefix.
+ Multiple DNS64 prefixes can be defined.
+
+
+ Compatible IPv6 prefixes have lengths of 32, 40, 48, 56,
+ 64 and 96 as per RFC 6052.
+
+
+ Additionally a reverse IP6.ARPA zone will be created for
+ the prefix to provide a mapping from the IP6.ARPA names
+ to the corresponding IN-ADDR.ARPA names using synthesized
+ CNAMEs. dns64-server and
+ dns64-contact can be used to specify
+ the name of the server and contact for the zones. These
+ are settable at the view / options level. These are
+ not settable on a per-prefix basis.
+
+
+ Each dns64 supports an optional
+ clients ACL that determines which
+ clients are affected by this directive. If not defined,
+ it defaults to any;.
+
+
+ Each dns64 supports an optional
+ mapped ACL that selects which
+ IPv4 addresses are to be mapped in the corresponding
+ A RRset. If not defined it defaults to
+ any;.
+
+
+ Each dns64 supports an optional
+ exclude ACL that selects which
+ IPv6 addresses will be ignored for the purposes
+ of determining whether dns64 is to be applied.
+ Any non-matching address will prevent further
+ DNS64 processing from occurring for this client.
+
+
+ A optional suffix can also
+ be defined to set the bits trailing the mapped
+ IPv4 address bits. By default these bits are
+ set to ::. The bits
+ matching the prefix and mapped IPv4 address
+ must be zero.
+
+ If yes, then zones can be
+ added at runtime via rndc addzone
+ or deleted via rndc delzone.
+ The default is no.
+
auth-nxdomain
If yes, then the AA bit
@@ -2863,6 +3179,7 @@ options {
off
on a per-zone basis by specifying zone-statistics no
in the zone statement).
+ The default is no.
These statistics may be accessed
using rndc stats, which will
dump them to the file listed
@@ -3006,6 +3323,57 @@ options {
internally. The use of this option is discouraged.
+
filter-aaaa-on-v4
+
+
+ This option is only available when
+ BIND 9 is compiled with the
+ --enable-filter-aaaa option on the
+ "configure" command line. It is intended to help the
+ transition from IPv4 to IPv6 by not giving IPv6 addresses
+ to DNS clients unless they have connections to the IPv6
+ Internet. This is not recommended unless absolutely
+ necessary. The default is no.
+ The filter-aaaa-on-v4 option
+ may also be specified in view statements
+ to override the global filter-aaaa-on-v4
+ option.
+
+
+ If yes,
+ the DNS client is at an IPv4 address, in filter-aaaa,
+ and if the response does not include DNSSEC signatures,
+ then all AAAA records are deleted from the response.
+ This filtering applies to all responses and not only
+ authoritative responses.
+
+
+ If break-dnssec,
+ then AAAA records are deleted even when dnssec is enabled.
+ As suggested by the name, this makes the response not verify,
+ because the DNSSEC protocol is designed detect deletions.
+
+
+ This mechanism can erroneously cause other servers to
+ not give AAAA records to their clients.
+ A recursing server with both IPv6 and IPv4 network connections
+ that queries an authoritative server using this mechanism
+ via IPv4 will be denied AAAA records even if its client is
+ using IPv6.
+
+
+ This mechanism is applied to authoritative as well as
+ non-authoritative records.
+ A client using IPv4 that is not allowed recursion can
+ erroneously be given AAAA records because the server is not
+ allowed to check for A records.
+
+
+ Some AAAA records are given to IPv4 clients in glue records.
+ IPv4 clients that are servers can then erroneously
+ answer requests for AAAA records received via IPv4.
+
+
ixfr-from-differences
@@ -3060,13 +3428,23 @@ options {
Enable DNSSEC validation in named.
Note dnssec-enable also needs to be
set to yes to be effective.
- The default is yes.
+ If set to no, DNSSEC validation
+ is disabled. If set to auto,
+ DNSSEC validation is enabled, and a default
+ trust-anchor for the DNS root zone is used. If set to
+ yes, DNSSEC validation is enabled,
+ but a trust anchor must be manually configured using
+ a trusted-keys or
+ managed-keys statement. The default
+ is yes.
dnssec-accept-expired
Accept expired signatures when verifying DNSSEC signatures.
The default is no.
- Setting this option to "yes" leaves named vulnerable to replay attacks.
+ Setting this option to yes
+ leaves named vulnerable to
+ replay attacks.
querylog
@@ -3104,6 +3482,14 @@ options {
(the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT).
+
check-dup-records
+
+ Check master zones for records that are treated as different
+ by DNSSEC but are semantically equal in plain DNS. The
+ default is to warn. Other possible
+ values are fail and
+ ignore.
+
check-mx
Check whether the MX record appears to refer to a IP address.
@@ -3166,26 +3552,86 @@ options {
The default is no.
update-check-ksk
-
- When regenerating the RRSIGs following a UPDATE
- request to a secure zone, check the KSK flag on
- the DNSKEY RR to determine if this key should be
- used to generate the RRSIG. This flag is ignored
- if there are not DNSKEY RRs both with and without
- a KSK.
- The default is yes.
-
+
+
+ When set to the default value of yes,
+ check the KSK bit in each key to determine how the key
+ should be used when generating RRSIGs for a secure zone.
+
+
+ Ordinarily, zone-signing keys (that is, keys without the
+ KSK bit set) are used to sign the entire zone, while
+ key-signing keys (keys with the KSK bit set) are only
+ used to sign the DNSKEY RRset at the zone apex.
+ However, if this option is set to no,
+ then the KSK bit is ignored; KSKs are treated as if they
+ were ZSKs and are used to sign the entire zone. This is
+ similar to the dnssec-signzone -z
+ command line option.
+
+
+ When this option is set to yes, there
+ must be at least two active keys for every algorithm
+ represented in the DNSKEY RRset: at least one KSK and one
+ ZSK per algorithm. If there is any algorithm for which
+ this requirement is not met, this option will be ignored
+ for that algorithm.
+
+
+
dnssec-dnskey-kskonly
+
+
+ When this option and update-check-ksk
+ are both set to yes, only key-signing
+ keys (that is, keys with the KSK bit set) will be used
+ to sign the DNSKEY RRset at the zone apex. Zone-signing
+ keys (keys without the KSK bit set) will be used to sign
+ the remainder of the zone, but not the DNSKEY RRset.
+ This is similar to the
+ dnssec-signzone -x command line option.
+
+
+ The default is no. If
+ update-check-ksk is set to
+ no, this option is ignored.
+
+
try-tcp-refresh
Try to refresh the zone using TCP if UDP queries fail.
For BIND 8 compatibility, the default is
yes.
+
dnssec-secure-to-insecure
+
+
+ Allow a dynamic zone to transition from secure to
+ insecure (i.e., signed to unsigned) by deleting all
+ of the DNSKEY records. The default is no.
+ If set to yes, and if the DNSKEY RRset
+ at the zone apex is deleted, all RRSIG and NSEC records
+ will be removed from the zone as well.
+
+
+ If the zone uses NSEC3, then it is also necessary to
+ delete the NSEC3PARAM RRset from the zone apex; this will
+ cause the removal of all corresponding NSEC3 records.
+ (It is expected that this requirement will be eliminated
+ in a future release.)
+
+
+ Note that if a zone has been configured with
+ auto-dnssec maintain and the
+ private keys remain accessible in the key repository,
+ then the zone will be automatically signed again the
+ next time named is started.
+
+
-Forwarding
+Forwarding
The forwarding facility can be used to create a large site-wide
cache on a few servers, reducing traffic over links to external
@@ -3229,7 +3675,7 @@ options {
-Dual-stack Servers
+Dual-stack Servers
Dual-stack servers are used as servers of last resort to work
around
@@ -3422,11 +3868,25 @@ options {
from these addresses will not be responded to. The default
is none.
+
filter-aaaa
+
+ Specifies a list of addresses to which
+ filter-aaaa-on-v4
+ is applies. The default is any.
+
+
resolver-query-timeout
+
+ The amount of time the resolver will spend attempting
+ to resolve a recursive query before failing. The
+ default is 10 and the maximum is
+ 30. Setting it to 0
+ will result in the default being used.
+
-Interfaces
+Interfaces
The interfaces and ports that the server will answer queries
from may be specified using the listen-on option. listen-on takes
@@ -3878,7 +4338,7 @@ avoid-v6-udp-ports {};
The server's usage of many system resources can be limited.
Scaled values are allowed when specifying resource limits. For
@@ -4082,7 +4542,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
-Periodic Task Intervals
+Periodic Task Intervals
cleaning-interval
@@ -4252,20 +4712,26 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
their directly connected networks.
sortlist {
- { localhost; // IF the local host
- { localnets; // THEN first fit on the
- 192.168.1/24; // following nets
+ // IF the local host
+ // THEN first fit on the following nets
+ { localhost;
+ { localnets;
+ 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.1/24; // IF on class C 192.168.1
- { 192.168.1/24; // THEN use .1, or .2 or .3
+ // IF on class C 192.168.1 THEN use .1, or .2 or .3
+ { 192.168.1/24;
+ { 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.2/24; // IF on class C 192.168.2
- { 192.168.2/24; // THEN use .2, or .1 or .3
+ // IF on class C 192.168.2 THEN use .2, or .1 or .3
+ { 192.168.2/24;
+ { 192.168.2/24;
{ 192.168.1/24; 192.168.3/24; }; }; };
- { 192.168.3/24; // IF on class C 192.168.3
- { 192.168.3/24; // THEN use .3, or .1 or .2
+ // IF on class C 192.168.3 THEN use .3, or .1 or .2
+ { 192.168.3/24;
+ { 192.168.3/24;
{ 192.168.1/24; 192.168.2/24; }; }; };
- { { 192.168.4/24; 192.168.5/24; }; // if .4 or .5, prefer that net
+ // IF .4 or .5 THEN prefer that net
+ { { 192.168.4/24; 192.168.5/24; };
};
};
@@ -4456,7 +4922,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
Specifies the number of days into the future when
DNSSEC signatures automatically generated as a
result of dynamic updates (the section called “Dynamic Update”) will expire. There
- is a optional second field which specifies how
+ is an optional second field which specifies how
long before expiry that the signatures will be
regenerated. If not specified, the signatures will
be regenerated at 1/4 of base interval. The second
@@ -4537,30 +5003,46 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
edns-udp-size
-
+
+
Sets the advertised EDNS UDP buffer size in bytes
to control the size of packets received.
- Valid values are 512 to 4096 (values outside this range
+ Valid values are 1024 to 4096 (values outside this range
will be silently adjusted). The default value
is 4096. The usual reason for setting
edns-udp-size to a non-default
value is to get UDP answers to pass through broken
firewalls that block fragmented packets and/or
block UDP packets that are greater than 512 bytes.
-
+
+
+ named will fallback to using 512 bytes
+ if it get a series of timeout at the initial value. 512
+ bytes is not being offered to encourage sites to fix their
+ firewalls. Small EDNS UDP sizes will result in the
+ excessive use of TCP.
+
+
max-udp-size
-
- Sets the maximum EDNS UDP message size named will
- send in bytes. Valid values are 512 to 4096 (values outside
- this range will be silently adjusted). The default
+
+
+ Sets the maximum EDNS UDP message size
+ named will send in bytes.
+ Valid values are 512 to 4096 (values outside this
+ range will be silently adjusted). The default
value is 4096. The usual reason for setting
- max-udp-size to a non-default value is to get UDP
- answers to pass through broken firewalls that
- block fragmented packets and/or block UDP packets
- that are greater than 512 bytes.
+ max-udp-size to a non-default
+ value is to get UDP answers to pass through broken
+ firewalls that block fragmented packets and/or
+ block UDP packets that are greater than 512 bytes.
This is independent of the advertised receive
buffer (edns-udp-size).
-
+
+
+ Setting this to a low value will encourage additional
+ TCP traffic to the nameserver.
+
+
masterfile-format
Specifies
the file format of zone files (see
@@ -4705,7 +5187,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
Named will attempt to determine if a built-in zone already exists
or is active (covered by a forward-only forwarding declaration)
- and will not create a empty zone in that case.
+ and will not create an empty zone in that case.
The current list of empty zones is:
@@ -4873,6 +5355,260 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
+
+
+Content Filtering
+
+ BIND 9 provides the ability to filter
+ out DNS responses from external DNS servers containing
+ certain types of data in the answer section.
+ Specifically, it can reject address (A or AAAA) records if
+ the corresponding IPv4 or IPv6 addresses match the given
+ address_match_list of the
+ deny-answer-addresses option.
+ It can also reject CNAME or DNAME records if the "alias"
+ name (i.e., the CNAME alias or the substituted query name
+ due to DNAME) matches the
+ given namelist of the
+ deny-answer-aliases option, where
+ "match" means the alias name is a subdomain of one of
+ the name_list elements.
+ If the optional namelist is specified
+ with except-from, records whose query name
+ matches the list will be accepted regardless of the filter
+ setting.
+ Likewise, if the alias name is a subdomain of the
+ corresponding zone, the deny-answer-aliases
+ filter will not apply;
+ for example, even if "example.com" is specified for
+ deny-answer-aliases,
+
+
www.example.com. CNAME xxx.example.com.
+
+ returned by an "example.com" server will be accepted.
+
+
+ In the address_match_list of the
+ deny-answer-addresses option, only
+ ip_addr
+ and ip_prefix
+ are meaningful;
+ any key_id will be silently ignored.
+
+
+ If a response message is rejected due to the filtering,
+ the entire message is discarded without being cached, and
+ a SERVFAIL error will be returned to the client.
+
+
+ This filtering is intended to prevent "DNS rebinding attacks," in
+ which an attacker, in response to a query for a domain name the
+ attacker controls, returns an IP address within your own network or
+ an alias name within your own domain.
+ A naive web browser or script could then serve as an
+ unintended proxy, allowing the attacker
+ to get access to an internal node of your local network
+ that couldn't be externally accessed otherwise.
+ See the paper available at
+
+ http://portal.acm.org/citation.cfm?id=1315245.1315298
+
+ for more details about the attacks.
+
+
+ For example, if you own a domain named "example.net" and
+ your internal network uses an IPv4 prefix 192.0.2.0/24,
+ you might specify the following rules:
+
+ If an external attacker lets a web browser in your local
+ network look up an IPv4 address of "attacker.example.com",
+ the attacker's DNS server would return a response like this:
+
+
attacker.example.com. A 192.0.2.1
+
+ in the answer section.
+ Since the rdata of this record (the IPv4 address) matches
+ the specified prefix 192.0.2.0/24, this response will be
+ ignored.
+
+
+ On the other hand, if the browser looks up a legitimate
+ internal web server "www.example.net" and the
+ following response is returned to
+ the BIND 9 server
+
+
www.example.net. A 192.0.2.2
+
+ it will be accepted since the owner name "www.example.net"
+ matches the except-from element,
+ "example.net".
+
+
+ Note that this is not really an attack on the DNS per se.
+ In fact, there is nothing wrong for an "external" name to
+ be mapped to your "internal" IP address or domain name
+ from the DNS point of view.
+ It might actually be provided for a legitimate purpose,
+ such as for debugging.
+ As long as the mapping is provided by the correct owner,
+ it is not possible or does not make sense to detect
+ whether the intent of the mapping is legitimate or not
+ within the DNS.
+ The "rebinding" attack must primarily be protected at the
+ application that uses the DNS.
+ For a large site, however, it may be difficult to protect
+ all possible applications at once.
+ This filtering feature is provided only to help such an
+ operational environment;
+ it is generally discouraged to turn it on unless you are
+ very sure you have no other choice and the attack is a
+ real threat for your applications.
+
+
+ Care should be particularly taken if you want to use this
+ option for addresses within 127.0.0.0/8.
+ These addresses are obviously "internal", but many
+ applications conventionally rely on a DNS mapping from
+ some name to such an address.
+ Filtering out DNS records containing this address
+ spuriously can break such applications.
+
+
+
+
+Response Policy Zone (RPZ) Rewriting
+
+ BIND 9 includes an intentionally limited
+ mechanism to modify DNS responses for recursive requests
+ similar to email anti-spam DNS blacklists.
+ All response policy zones are named in the
+ response-policy option for the view or among the
+ global options if there is no response-policy option for the view.
+
+
+ The rules encoded in a response policy zone (RPZ) are applied
+ only to responses to queries that ask for recursion (RD=1).
+ RPZs are normal DNS zones containing RRsets
+ that can be queried normally if allowed.
+ It is usually best to restrict those queries with something like
+ allow-query {none; }; or
+ allow-query { 127.0.0.1; };.
+
+
+ There are four kinds of RPZ rewrite rules. QNAME rules are
+ applied to query names in requests and to targets of CNAME
+ records resolved in the process of generating the response.
+ The owner name of a QNAME rule is the query name relativized
+ to the RPZ.
+ The records in a rewrite rule are usually A, AAAA, or special
+ CNAMEs, but can be any type except DNAME.
+
+
+ IP rules are triggered by addresses in A and AAAA records.
+ All IP addresses in A or AAAA RRsets are tested and the rule
+ longest prefix is applied. Ties between rules with equal prefixes
+ are broken in favor of the first RPZ mentioned in the
+ response-policy option.
+ The rule matching the smallest IP address is chosen among equal
+ prefix rules from a single RPZ.
+ IP rules are expressed in RRsets with owner names that are
+ subdomains of rpz-ip and encoding an IP address block, reversed
+ as in IN-ARPA.
+ prefix.B.B.B.B with prefix between 1 and 32 and B between 1 and 255
+ encodes an IPv4 address.
+ IPv6 addresses are encoded by with prefix.W.W.W.W.W.W.W.W or
+ prefix.WORDS.zz.WORDS. The words in the standard IPv6 text
+ representation are reversed, "::" is replaced with ".zz.",
+ and ":" becomes ".".
+
+
+ NSDNAME rules match names in NS RRsets for the response or a
+ parent. They are encoded as subdomains of rpz-nsdomain relativized
+ to the RPZ origin name.
+
+
+ NSIP rules match IP addresses in A and AAAA RRsets for names of
+ responsible servers or the names that can be matched by NSDNAME
+ rules. The are encoded like IP rules except as subdomains of
+ rpz-nsip.
+
+
+ Authority verification issues and variations in authority data in
+ the current version of BIND 9 can cause
+ inconsistent results from NSIP and NSDNAME. So they are available
+ only when BIND is built with the
+ --enable-rpz-nsip or
+ --enable-rpz-nsdname options
+ on the "configure" command line.
+
+
+ Four policies can be expressed.
+ The NXDOMAIN policy causes a NXDOMAIN response
+ and is expressed with an RRset consisting of a single CNAME
+ whose target is the root domain (.).
+ NODATA generates NODATA or ANCOUNT=1 regardless
+ of query type.
+ It is expressed with a CNAME whose target is the wildcard
+ top-level domain (*.).
+ The NO-OP policy does not change the response
+ and is used to "poke holes" in policies for larger CIDR blocks or in
+ zones named later in the response-policy option.
+ The NO-OP policy is expressed by a CNAME with a target consisting
+ of the variable part of the owner name, such as "example.com." for
+ a QNAME rule or "128.1.0.0.127." for an IP rule.
+ The CNAME policy is used to replace the RRsets
+ of response.
+ A and AAAA RRsets are most common and useful to capture
+ an evil domain in a walled garden, but any valid set of RRsets
+ is possible.
+
+
+ All of the policies in an RPZ can be overridden with a
+ policy clause.
+ given says "do not override."
+ no-op says "do nothing" regardless of the policy
+ in RPZ records.
+ nxdomain causes all RPZ rules to generate
+ NXDOMAIN results.
+ nodata gives nodata.
+ cname domain causes all RPZ rules to act as if
+ the consisted of a "cname domain" record.
+
+
+ For example, you might use this option statement
+
+
response-policy { zone "bl"; };
+
+ and this zone statement
+
+
zone "bl" {type master; file "example/bl"; allow-query {none;}; };
-trusted-keys Statement Definition
+trusted-keys Statement Definition
and Usage
The trusted-keys statement defines
@@ -5169,6 +5908,135 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
in the key data, so the configuration may be split up into
multiple lines.
+
+ trusted-keys may be set at the top level
+ of named.conf or within a view. If it is
+ set in both places, they are additive: keys defined at the top
+ level are inherited by all views, but keys defined in a view
+ are only used within that view.
+
+ The managed-keys statement, like
+ trusted-keys, defines DNSSEC
+ security roots. The difference is that
+ managed-keys can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+
+
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ trusted-keys statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ trusted-keys statement with the new key.
+
+
+ If, however, the zone were listed in a
+ managed-keys statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ named would store the stand-by key, and
+ when the original key was revoked, named
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+
+
+ A managed-keys statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ BIND 9.7.0) is initial-key.
+ This means the managed-keys statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+
+
+ Consequently, a managed-keys statement
+ appears similar to a trusted-keys, differing
+ in the presence of the second field, containing the keyword
+ initial-key. The difference is, whereas the
+ keys listed in a trusted-keys continue to be
+ trusted until they are removed from
+ named.conf, an initializing key listed
+ in a managed-keys statement is only trusted
+ once: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+
+
+ The first time named runs with a managed key
+ configured in named.conf, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the managed-keys
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+
+
+ From that point on, whenever named runs, it
+ sees the managed-keys statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the managed-keys is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+
+
+ The next time named runs after a name
+ has been removed from the
+ managed-keys statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+
+
+ named only maintains a single managed keys
+ database; consequently, unlike trusted-keys,
+ managed-keys may only be set at the top
+ level of named.conf, not within a view.
+
+
+ In the current implementation, the managed keys database is
+ stored as a master-format zone file called
+ managed-keys.bind. When the key database
+ is changed, the zone is updated. As with any other dynamic
+ zone, changes will be written into a journal file,
+ managed-keys.bind.jnl. They are committed
+ to the master file as soon as possible afterward; in the case
+ of the managed key database, this will usually occur within 30
+ seconds. So, whenever named is using
+ automatic key maintenance, those two files can be expected to
+ exist in the working directory. (For this reason among others,
+ the working directory should be always be writable by
+ named.)
+
+
+ If the dnssec-lookaside option is
+ set to auto, named
+ will automatically initialize a managed key for the
+ zone dlv.isc.org. The key that is
+ used to initialize the key maintenance process is built
+ into named, and can be overridden
+ from bindkeys-file.
+
+ A static-stub zone is similar to a stub zone
+ with the following exceptions:
+ the zone data is statically configured, rather
+ than transferred from a master server;
+ when recursion is necessary for a query that
+ matches a static-stub zone, the locally
+ configured data (nameserver names and glue addresses)
+ is always used even if different authoritative
+ information is cached.
+
+
+ Zone data is configured via the
+ server-addresses and
+ server-names zone options.
+
+
+ The zone data is maintained in the form of NS
+ and (if necessary) glue A or AAAA RRs
+ internally, which can be seen by dumping zone
+ databases by rndc dumpdb -all.
+ The configured RRs are considered local configuration
+ parameters rather than public data.
+ Non recursive queries (i.e., those with the RD
+ bit off) to a static-stub zone are therefore
+ prohibited and will be responded with REFUSED.
+
+
+ Since the data is statically configured, no
+ zone maintenance action takes place for a static-stub
+ zone.
+ For example, there is no periodic refresh
+ attempt, and an incoming notify message
+ will be rejected with an rcode of NOTAUTH.
+
+
+ Each static-stub zone is configured with
+ internally generated NS and (if necessary)
+ glue A or AAAA RRs
+
+
+
+
forward
@@ -5665,7 +6604,7 @@ zone zone_name [
-Class
+Class
The zone's name may optionally be followed by a class. If
a class is not specified, class IN (for Internet),
@@ -5687,7 +6626,7 @@ zone zone_name [
-Zone Options
+Zone Options
allow-notify
@@ -5752,6 +6691,7 @@ zone zone_name [master zones the default is fail. For slave
zones the default is warn.
+ It is not implemented for hint zones.
See the description of
@@ -5926,6 +6871,78 @@ zone zone_name [statistics-file defined in
the server options.
+
server-addresses
+
+
+ Only meaningful for static-stub zones.
+ This is a list of IP addresses to which queries
+ should be sent in recursive resolution for the
+ zone.
+ A non empty list for this option will internally
+ configure the apex NS RR with associated glue A or
+ AAAA RRs.
+
+
+ For example, if "example.com" is configured as a
+ static-stub zone with 192.0.2.1 and 2001:db8::1234
+ in a server-addresses option,
+ the following RRs will be internally configured.
+
+
example.com. NS example.com.
+example.com. A 192.0.2.1
+example.com. AAAA 2001:db8::1234
+
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ will initiate recursive resolution and send
+ queries to 192.0.2.1 and/or 2001:db8::1234.
+
+
+
server-names
+
+
+ Only meaningful for static-stub zones.
+ This is a list of domain names of nameservers that
+ act as authoritative servers of the static-stub
+ zone.
+ These names will be resolved to IP addresses when
+ named needs to send queries to
+ these servers.
+ To make this supplemental resolution successful,
+ these names must not be a subdomain of the origin
+ name of static-stub zone.
+ That is, when "example.net" is the origin of a
+ static-stub zone, "ns.example" and
+ "master.example.com" can be specified in the
+ server-names option, but
+ "ns.example.net" cannot, and will be rejected by
+ the configuration parser.
+
+
+ A non empty list for this option will internally
+ configure the apex NS RR with the specified names.
+ For example, if "example.com" is configured as a
+ static-stub zone with "ns1.example.net" and
+ "ns2.example.net"
+ in a server-names option,
+ the following RRs will be internally configured.
+
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ initiate recursive resolution,
+ resolve "ns1.example.net" and/or
+ "ns2.example.net" to IP addresses, and then send
+ queries to (one or more of) these addresses.
+
+
sig-validity-interval
See the description of
@@ -6003,6 +7020,48 @@ zone zone_name [the section called “options Statement Definition and
Usage”.
+
auto-dnssec
+
+
+ Zones configured for dynamic DNS may also use this
+ option to allow varying levels of automatic DNSSEC key
+ management. There are four possible settings:
+
+
+ auto-dnssec allow; permits
+ keys to be updated and the zone fully re-signed
+ whenever the user issues the command rndc sign
+ zonename.
+
+
+ auto-dnssec maintain; includes the
+ above, but also automatically adjusts the zone's DNSSEC
+ keys on schedule, according to the keys' timing metadata
+ (see dnssec-keygen(8) and
+ dnssec-settime(8)). The command
+ rndc sign
+ zonename causes
+ named to load keys from the key
+ repository and sign the zone with all keys that are
+ active.
+ rndc loadkeys
+ zonename causes
+ named to load keys from the key
+ repository and schedule key maintenance events to occur
+ in the future, but it does not sign the full zone
+ immediately.
+
+
+ auto-dnssec create; includes the
+ above, but also allows named
+ to create new keys in the key repository when needed.
+ (NOTE: This option is not yet implemented; the syntax is
+ being reserved for future use.)
+
+
+ The default setting is auto-dnssec off.
+
+
multi-master
See the description of multi-master in
@@ -6013,6 +7072,11 @@ zone zone_name [masterfile-format
in the section called “Tuning”.
- The update-policy clause is new
- in BIND 9 and allows more fine-grained
- control over what updates are allowed. A set of rules
- is specified, where each rule either grants or denies
- permissions for one or more names to be updated by
- one or more identities. If the dynamic update request
- message is signed (that is, it includes either a TSIG
- or SIG(0) record), the identity of the signer can be
- determined.
+ The update-policy clause
+ allows more fine-grained control over what updates are
+ allowed. A set of rules is specified, where each rule
+ either grants or denies permissions for one or more
+ names to be updated by one or more identities. If
+ the dynamic update request message is signed (that is,
+ it includes either a TSIG or SIG(0) record), the
+ identity of the signer can be determined.
Rules are specified in the update-policy
@@ -6052,20 +7115,47 @@ zone zone_name [
- This is how a rule definition looks:
+ There is a pre-defined update-policy
+ rule which can be switched on with the command
+ update-policy local;.
+ Switching on this rule in a zone causes
+ named to generate a TSIG session
+ key and place it in a file, and to allow that key
+ to update the zone. (By default, the file is
+ /var/run/named/session.key, the key
+ name is "local-ddns" and the key algorithm is HMAC-SHA256,
+ but these values are configurable with the
+ session-keyfile,
+ session-keyname and
+ session-keyalg options, respectively).
+
+
+ A client running on the local system, and with appropriate
+ permissions, may read that file and use the key to sign update
+ requests. The zone's update policy will be set to allow that
+ key to change any record within the zone. Assuming the
+ key name is "local-ddns", this policy is equivalent to:
+
+
update-policy { grant local-ddns zonesub any; };
+
+
+ The command nsupdate -l sends update
+ requests to localhost, and signs them using the session key.
+
+
+ Other rule definitions look like this:
-( grant | deny ) identitynametypename [types]
+( grant | deny ) identitynametype [name] [types]
Each rule grants or denies privileges. Once a message has
successfully matched a rule, the operation is immediately
- granted
- or denied and no further rules are examined. A rule is matched
- when the signer matches the identity field, the name matches the
- name field in accordance with the nametype field, and the type
- matches
- the types specified in the type field.
+ granted or denied and no further rules are examined. A rule
+ is matched when the signer matches the identity field, the
+ name matches the name field in accordance with the nametype
+ field, and the type matches the types specified in the type
+ field.
No signer is required for tcp-self
@@ -6091,7 +7181,7 @@ zone zone_name [
- The nametype field has 12
+ The nametype field has 13
values:
name, subdomain,
wildcard, self,
@@ -6099,7 +7189,8 @@ zone zone_name [krb5-self, ms-self,
krb5-subdomain,
ms-subdomain,
- tcp-self and 6to4-self.
+ tcp-self, 6to4-self,
+ zonesub, and external.
@@ -6138,6 +7229,29 @@ zone zone_name [
+
+
+ zonesub
+
+
+
+
+ This rule is similar to subdomain, except that
+ it matches when the name being updated is a
+ subdomain of the zone in which the
+ update-policy statement
+ appears. This obviates the need to type the zone
+ name twice, and enables the use of a standard
+ update-policy statement in
+ multiple zones without modification.
+
+
+ When this rule is used, the
+ name field is omitted.
+
+
+
+
wildcard
@@ -6233,7 +7347,7 @@ zone zone_name [
Allow the 6to4 prefix to be update by any TCP
- conection from the 6to4 network or from the
+ connection from the 6to4 network or from the
corresponding IPv4 address. This is intended
to allow NS or DNAME RRsets to be added to the
reverse tree.
@@ -6245,12 +7359,55 @@ zone zone_name [
+
+
+
+ external
+
+
+
+
+ This rule allows named
+ to defer the decision of whether to allow a
+ given update to an external daemon.
+
+
+ The method of communicating with the daemon is
+ specified in the identity
+ field, the format of which is
+ "local:path",
+ where path is the location
+ of a UNIX-domain socket. (Currently, "local" is the
+ only supported mechanism.)
+
+
+ Requests to the external daemon are sent over the
+ UNIX-domain socket as datagrams with the following
+ format:
+
+
+ Protocol version number (4 bytes, network byte order, currently 1)
+ Request length (4 bytes, network byte order)
+ Signer (null-terminated string)
+ Name (null-terminated string)
+ TCP source address (null-terminated string)
+ Rdata type (null-terminated string)
+ Key (null-terminated string)
+ TKEY token length (4 bytes, network byte order)
+ TKEY token (remainder of packet)
+
+ The daemon replies with a four-byte value in
+ network byte order, containing either 0 or 1; 0
+ indicates that the specified update is not
+ permitted, and 1 indicates that it is.
+
+
+
In all cases, the name
- field must
- specify a fully-qualified domain name.
+ field must specify a fully-qualified domain name.
If no types are explicitly specified, this rule matches
@@ -6266,7 +7423,7 @@ zone zone_name [
-Zone File
+Zone File
Types of Resource Records and When to Use Them
@@ -6279,7 +7436,7 @@ zone zone_name [
-Resource Records
+Resource Records
A domain name identifies a node. Each node has a set of
resource information, which may be empty. The set of resource
@@ -7016,7 +8173,7 @@ zone zone_name [
-Textual expression of RRs
+Textual expression of RRs
RRs are represented in binary form in the packets of the DNS
protocol, and are usually represented in highly encoded form
@@ -7219,7 +8376,7 @@ zone zone_name [
-Discussion of MX Records
+Discussion of MX Records
As described above, domain servers store information as a
series of resource records, each of which contains a particular
@@ -7475,7 +8632,7 @@ zone zone_name [
-Inverse Mapping in IPv4
+Inverse Mapping in IPv4
Reverse name resolution (that is, translation from IP address
to name) is achieved by means of the in-addr.arpa domain
@@ -7536,7 +8693,7 @@ zone zone_name [
-Other Zone File Directives
+Other Zone File Directives
The Master File Format was initially defined in RFC 1035 and
has subsequently been extended. While the Master File Format
@@ -7551,7 +8708,7 @@ zone zone_name [
-The @ (at-sign)
+The @ (at-sign)
When used in the label (or name) field, the asperand or
at-sign (@) symbol represents the current origin.
@@ -7562,7 +8719,7 @@ zone zone_name [
is equivalent to
@@ -7678,6 +8835,28 @@ $GENERATE 1-127 $ CNAME $.0
...
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.
+
+ Generate a set of A and MX records. Note the MX's right hand
+ side is a quoted string. The quotes will be stripped when the
+ right hand side is processed.
+
HOST-1.EXAMPLE. A 1.2.3.1
+HOST-1.EXAMPLE. MX 0 .
+HOST-2.EXAMPLE. A 1.2.3.2
+HOST-2.EXAMPLE. MX 0 .
+HOST-3.EXAMPLE. A 1.2.3.3
+HOST-3.EXAMPLE. MX 0 .
+...
+HOST-127.EXAMPLE. A 1.2.3.127
+HOST-127.EXAMPLE. MX 0 .
+
@@ -7728,8 +8907,10 @@ $GENERATE 1-127 $ CNAME $.0
Available output forms are decimal
(d), octal
- (o) and hexadecimal
+ (o), hexadecimal
(x or X
+ for uppercase) and nibble
+ (n or N\
for uppercase). The default modifier is
${0,0,d}. If the
lhs is not absolute, the
@@ -7737,8 +8918,16 @@ $GENERATE 1-127 $ CNAME $.0
to the name.
- For compatibility with earlier versions, $$ is still
- recognized as indicating a literal $ in the output.
+ In nibble mode the value will be treated as
+ if it was a reversed hexadecimal string
+ with each hexadecimal digit as a separate
+ label. The width field includes the label
+ separator.
+
+
+ For compatibility with earlier versions,
+ $$ is still recognized as
+ indicating a literal $ in the output.
@@ -7780,8 +8969,7 @@ $GENERATE 1-127 $ CNAME $.0
- At present the only supported types are
- PTR, CNAME, DNAME, A, AAAA and NS.
+ Any valid type.
@@ -7791,8 +8979,7 @@ $GENERATE 1-127 $ CNAME $.0
- rhs is a domain name. It is processed
- similarly to lhs.
+ rhs, optionally, quoted string.
- The number of RRsets per RR type (positive
- or negative) and nonexistent names stored in the
- cache database.
+ The number of RRsets per RR type and nonexistent
+ names stored in the cache database.
+ If the exclamation mark (!) is printed for a RR
+ type, it means that particular type of RRset is
+ known to be nonexistent (this is also known as
+ "NXRRSET").
Maintained per view.
Mismatch responses received.
+ The DNS ID, response's source address,
+ and/or the response's source port does not
+ match what was expected.
+ (The port must be 53 or as defined by
+ the port option.)
+ This may be an indication of a cache
+ poisoning attempt.
Socket I/O statistics counters are defined per socket
types, which are
@@ -9279,7 +10476,7 @@ $GENERATE 1-127 $ CNAME $.0
-Compatibility with BIND 8 Counters
+Compatibility with BIND 8 Counters
Most statistics counters that were available
in BIND 8 are also supported in
diff --git a/doc/arm/Bv9ARM.ch07.html b/doc/arm/Bv9ARM.ch07.html
index ce23cadf3b3..371f4a94eca 100644
--- a/doc/arm/Bv9ARM.ch07.html
+++ b/doc/arm/Bv9ARM.ch07.html
@@ -1,5 +1,5 @@
-
+
@@ -80,14 +80,17 @@
Here is an example of how to properly apply ACLs:
-// Set up an ACL named "bogusnets" that will block RFC1918 space
-// and some reserved space, which is commonly used in spoofing attacks.
+// Set up an ACL named "bogusnets" that will block
+// RFC1918 space and some reserved space, which is
+// commonly used in spoofing attacks.
acl bogusnets {
- 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
- 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
+ 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24;
+ 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12;
+ 192.168.0.0/16;
};
-// Set up an ACL called our-nets. Replace this with the real IP numbers.
+// Set up an ACL called our-nets. Replace this with the
+// real IP numbers.
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
options {
...
@@ -119,7 +122,7 @@ zone "example.com" {
-Chroot and Setuid
+Chroot and Setuid
On UNIX servers, it is possible to run BIND
@@ -145,7 +148,7 @@ zone "example.com" {
-The chroot Environment
+The chroot Environment
In order for a chroot environment
to
@@ -173,7 +176,7 @@ zone "example.com" {
-Using the setuid Function
+Using the setuid Function
Prior to running the named daemon,
use
diff --git a/doc/arm/Bv9ARM.ch08.html b/doc/arm/Bv9ARM.ch08.html
index bb9ecc84c64..0681e47ce1e 100644
--- a/doc/arm/Bv9ARM.ch08.html
+++ b/doc/arm/Bv9ARM.ch08.html
@@ -1,5 +1,5 @@
-
+
-It's not working; how can I figure out what's wrong?
+It's not working; how can I figure out what's wrong?
The best solution to solving installation and
configuration issues is to take preventative measures by setting
@@ -68,7 +68,7 @@
-Incrementing and Changing the Serial Number
+Incrementing and Changing the Serial Number
Zone serial numbers are just numbers — they aren't
date related. A lot of people set them to a number that
@@ -95,7 +95,7 @@
-Where Can I Get Help?
+Where Can I Get Help?
The Internet Systems Consortium
(ISC) offers a wide range
diff --git a/doc/arm/Bv9ARM.ch09.html b/doc/arm/Bv9ARM.ch09.html
index c5bd994e0be..fd532377bad 100644
--- a/doc/arm/Bv9ARM.ch09.html
+++ b/doc/arm/Bv9ARM.ch09.html
@@ -1,5 +1,5 @@
-
+
A Brief History of the DNS and BIND
@@ -162,7 +172,7 @@
-General DNS Reference Information
+General DNS Reference Information
IPv6 addresses (AAAA)
@@ -250,17 +260,17 @@
-Bibliography
+Bibliography
Standards
-
[RFC974] C.Partridge. Mail Routing and the Domain System. January 1986.
+
[RFC974] C.Partridge. Mail Routing and the Domain System. January 1986.
-
[RFC1034] P.V.Mockapetris. Domain Names — Concepts and Facilities. November 1987.
+
[RFC1034] P.V.Mockapetris. Domain Names — Concepts and Facilities. November 1987.
-
[RFC1035] P. V.Mockapetris. Domain Names — Implementation and
+
[RFC1035] P. V.Mockapetris. Domain Names — Implementation and
Specification. November 1987.
@@ -268,42 +278,42 @@
Proposed Standards
-
[RFC2181] R., R. BushElz. Clarifications to the DNS
+
[RFC2181] R., R. BushElz. Clarifications to the DNS
Specification. July 1997.
-
[RFC2308] M.Andrews. Negative Caching of DNS
+
[RFC2308] M.Andrews. Negative Caching of DNS
Queries. March 1998.
-
[RFC1995] M.Ohta. Incremental Zone Transfer in DNS. August 1996.
+
[RFC1995] M.Ohta. Incremental Zone Transfer in DNS. August 1996.
-
[RFC1996] P.Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.
+
[RFC1996] P.Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.
-
[RFC2136] P.Vixie, S.Thomson, Y.Rekhter, and J.Bound. Dynamic Updates in the Domain Name System. April 1997.
+
[RFC2136] P.Vixie, S.Thomson, Y.Rekhter, and J.Bound. Dynamic Updates in the Domain Name System. April 1997.
-
[RFC2671] P.Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.
+
[RFC2671] P.Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.
-
[RFC2672] M.Crawford. Non-Terminal DNS Name Redirection. August 1999.
+
[RFC2672] M.Crawford. Non-Terminal DNS Name Redirection. August 1999.
-
[RFC2845] P.Vixie, O.Gudmundsson, D.Eastlake, 3rd, and B.Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.
+
[RFC2845] P.Vixie, O.Gudmundsson, D.Eastlake, 3rd, and B.Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.
-
[RFC2930] D.Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.
+
[RFC2930] D.Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.
-
[RFC2931] D.Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.
+
[RFC2931] D.Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.
-
[RFC3007] B.Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.
+
[RFC3007] B.Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.
-
[RFC3645] S.Kwan, P.Garg, J.Gilroy, L.Esibov, J.Westhead, and R.Hall. Generic Security Service Algorithm for Secret
+
[RFC3645] S.Kwan, P.Garg, J.Gilroy, L.Esibov, J.Westhead, and R.Hall. Generic Security Service Algorithm for Secret
Key Transaction Authentication for DNS
(GSS-TSIG). October 2003.
@@ -312,19 +322,19 @@
DNS Security Proposed Standards
-
[RFC3225] D.Conrad. Indicating Resolver Support of DNSSEC. December 2001.
+
[RFC3225] D.Conrad. Indicating Resolver Support of DNSSEC. December 2001.
-
[RFC3833] D.Atkins and R.Austein. Threat Analysis of the Domain Name System (DNS). August 2004.
+
[RFC3833] D.Atkins and R.Austein. Threat Analysis of the Domain Name System (DNS). August 2004.
-
[RFC4033] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. DNS Security Introduction and Requirements. March 2005.
+
[RFC4033] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. DNS Security Introduction and Requirements. March 2005.
-
[RFC4034] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. Resource Records for the DNS Security Extensions. March 2005.
+
[RFC4034] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. Resource Records for the DNS Security Extensions. March 2005.
-
[RFC4035] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. Protocol Modifications for the DNS
+
[RFC4035] R.Arends, R.Austein, M.Larson, D.Massey, and S.Rose. Protocol Modifications for the DNS
Security Extensions. March 2005.
@@ -332,146 +342,146 @@
Other Important RFCs About DNS
Implementation
-
[RFC1535] E.Gavron. A Security Problem and Proposed Correction With Widely
+
[RFC1535] E.Gavron. A Security Problem and Proposed Correction With Widely
Deployed DNS Software.. October 1993.
-
[RFC1536] A.Kumar, J.Postel, C.Neuman, P.Danzig, and S.Miller. Common DNS Implementation
+
[RFC1536] A.Kumar, J.Postel, C.Neuman, P.Danzig, and S.Miller. Common DNS Implementation
Errors and Suggested Fixes. October 1993.
-
[RFC1982] R.Elz and R.Bush. Serial Number Arithmetic. August 1996.
+
[RFC1982] R.Elz and R.Bush. Serial Number Arithmetic. August 1996.
-
[RFC4074] Y.Morishita and T.Jinmei. Common Misbehaviour Against DNS
+
[RFC4074] Y.Morishita and T.Jinmei. Common Misbehaviour Against DNS
Queries for IPv6 Addresses. May 2005.
Resource Record Types
-
[RFC1183] C.F.Everhart, L. A.Mamakos, R.Ullmann, and P.Mockapetris. New DNS RR Definitions. October 1990.
+
[RFC1183] C.F.Everhart, L. A.Mamakos, R.Ullmann, and P.Mockapetris. New DNS RR Definitions. October 1990.
-
[RFC1706] B.Manning and R.Colella. DNS NSAP Resource Records. October 1994.
+
[RFC1706] B.Manning and R.Colella. DNS NSAP Resource Records. October 1994.
-
[RFC2168] R.Daniel and M.Mealling. Resolution of Uniform Resource Identifiers using
+
[RFC2168] R.Daniel and M.Mealling. Resolution of Uniform Resource Identifiers using
the Domain Name System. June 1997.
-
[RFC1876] C.Davis, P.Vixie, T., and I.Dickinson. A Means for Expressing Location Information in the
+
[RFC1876] C.Davis, P.Vixie, T., and I.Dickinson. A Means for Expressing Location Information in the
Domain
Name System. January 1996.
-
[RFC2052] A.Gulbrandsen and P.Vixie. A DNS RR for Specifying the
+
[RFC2052] A.Gulbrandsen and P.Vixie. A DNS RR for Specifying the
Location of
Services.. October 1996.
-
[RFC2163] A.Allocchio. Using the Internet DNS to
+
[RFC2163] A.Allocchio. Using the Internet DNS to
Distribute MIXER
Conformant Global Address Mapping. January 1998.
-
[RFC2230] R.Atkinson. Key Exchange Delegation Record for the DNS. October 1997.
+
[RFC2230] R.Atkinson. Key Exchange Delegation Record for the DNS. October 1997.
-
[RFC2536] D.Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.
+
[RFC2536] D.Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.
-
[RFC2537] D.Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.
+
[RFC2537] D.Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.
-
[RFC2538] D.Eastlake, 3rd and O.Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.
+
[RFC2538] D.Eastlake, 3rd and O.Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.
-
[RFC2539] D.Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.
+
[RFC2539] D.Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.
-
[RFC2540] D.Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.
+
[RFC2540] D.Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.
-
[RFC2782] A.Gulbrandsen. P.Vixie. L.Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.
+
[RFC2782] A.Gulbrandsen. P.Vixie. L.Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.
-
[RFC2915] M.Mealling. R.Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.
+
[RFC2915] M.Mealling. R.Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.
-
[RFC3110] D.Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.
+
[RFC3110] D.Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.
-
[RFC3123] P.Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.
+
[RFC3123] P.Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.
-
[RFC3596] S.Thomson, C.Huitema, V.Ksinant, and M.Souissi. DNS Extensions to support IP
+
[RFC3596] S.Thomson, C.Huitema, V.Ksinant, and M.Souissi. DNS Extensions to support IP
version 6. October 2003.
-
[RFC3597] A.Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.
+
[RFC3597] A.Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.
DNS and the Internet
-
[RFC1101] P. V.Mockapetris. DNS Encoding of Network Names
+
[RFC1101] P. V.Mockapetris. DNS Encoding of Network Names
and Other Types. April 1989.
-
[RFC1123] Braden. Requirements for Internet Hosts - Application and
+
[RFC1123] Braden. Requirements for Internet Hosts - Application and
Support. October 1989.
-
[RFC1591] J.Postel. Domain Name System Structure and Delegation. March 1994.
+
[RFC1591] J.Postel. Domain Name System Structure and Delegation. March 1994.
-
[RFC2317] H.Eidnes, G.de Groot, and P.Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.
+
[RFC2317] H.Eidnes, G.de Groot, and P.Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.
-
[RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.
+
[RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.
-
[RFC2929] D.Eastlake, 3rd, E.Brunner-Williams, and B.Manning. Domain Name System (DNS) IANA Considerations. September 2000.
+
[RFC2929] D.Eastlake, 3rd, E.Brunner-Williams, and B.Manning. Domain Name System (DNS) IANA Considerations. September 2000.
DNS Operations
-
[RFC1033] M.Lottor. Domain administrators operations guide.. November 1987.
+
[RFC1033] M.Lottor. Domain administrators operations guide.. November 1987.
-
[RFC1537] P.Beertema. Common DNS Data File
+
[RFC1537] P.Beertema. Common DNS Data File
Configuration Errors. October 1993.
-
[RFC1912] D.Barr. Common DNS Operational and
+
[RFC1912] D.Barr. Common DNS Operational and
Configuration Errors. February 1996.
-
[RFC2010] B.Manning and P.Vixie. Operational Criteria for Root Name Servers.. October 1996.
+
[RFC2010] B.Manning and P.Vixie. Operational Criteria for Root Name Servers.. October 1996.
-
[RFC2219] M.Hamilton and R.Wright. Use of DNS Aliases for
+
[RFC2219] M.Hamilton and R.Wright. Use of DNS Aliases for
Network Services.. October 1997.
Internationalized Domain Names
-
[RFC2825] IAB and R.Daigle. A Tangled Web: Issues of I18N, Domain Names,
+
[RFC2825] IAB and R.Daigle. A Tangled Web: Issues of I18N, Domain Names,
and the Other Internet protocols. May 2000.
-
[RFC3490] P.Faltstrom, P.Hoffman, and A.Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.
+
[RFC3490] P.Faltstrom, P.Hoffman, and A.Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.
-
[RFC3491] P.Hoffman and M.Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.
+
[RFC3491] P.Hoffman and M.Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.
-
[RFC3492] A.Costello. Punycode: A Bootstring encoding of Unicode
+
[RFC3492] A.Costello. Punycode: A Bootstring encoding of Unicode
for Internationalized Domain Names in
Applications (IDNA). March 2003.
@@ -487,47 +497,47 @@
-
[RFC1464] R.Rosenbaum. Using the Domain Name System To Store Arbitrary String
+
[RFC1464] R.Rosenbaum. Using the Domain Name System To Store Arbitrary String
Attributes. May 1993.
-
[RFC1713] A.Romao. Tools for DNS Debugging. November 1994.
+
[RFC1713] A.Romao. Tools for DNS Debugging. November 1994.
-
[RFC1794] T.Brisco. DNS Support for Load
+
[RFC1794] T.Brisco. DNS Support for Load
Balancing. April 1995.
-
[RFC2240] O.Vaughan. A Legal Basis for Domain Name Allocation. November 1997.
+
[RFC2240] O.Vaughan. A Legal Basis for Domain Name Allocation. November 1997.
-
[RFC2345] J.Klensin, T.Wolf, and G.Oglesby. Domain Names and Company Name Retrieval. May 1998.
+
[RFC2345] J.Klensin, T.Wolf, and G.Oglesby. Domain Names and Company Name Retrieval. May 1998.
-
[RFC2352] O.Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.
+
[RFC2352] O.Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.
-
[RFC3071] J.Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.
+
[RFC3071] J.Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.
-
[RFC3258] T.Hardie. Distributing Authoritative Name Servers via
+
[RFC3258] T.Hardie. Distributing Authoritative Name Servers via
Shared Unicast Addresses. April 2002.
-
[RFC3901] A.Durand and J.Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.
+
[RFC3901] A.Durand and J.Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.
Obsolete and Unimplemented Experimental RFC
-
[RFC1712] C.Farrell, M.Schulze, S.Pleitner, and D.Baldoni. DNS Encoding of Geographical
+
[RFC1712] C.Farrell, M.Schulze, S.Pleitner, and D.Baldoni. DNS Encoding of Geographical
Location. November 1994.
-
[RFC2673] M.Crawford. Binary Labels in the Domain Name System. August 1999.
+
[RFC2673] M.Crawford. Binary Labels in the Domain Name System. August 1999.
-
[RFC2874] M.Crawford and C.Huitema. DNS Extensions to Support IPv6 Address Aggregation
+
[RFC2874] M.Crawford and C.Huitema. DNS Extensions to Support IPv6 Address Aggregation
and Renumbering. July 2000.
@@ -541,39 +551,39 @@
-
[RFC2065] D.Eastlake, 3rd and C.Kaufman. Domain Name System Security Extensions. January 1997.
+
[RFC2065] D.Eastlake, 3rd and C.Kaufman. Domain Name System Security Extensions. January 1997.
-
[RFC2137] D.Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.
+
[RFC2137] D.Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.
-
[RFC2535] D.Eastlake, 3rd. Domain Name System Security Extensions. March 1999.
+
[RFC2535] D.Eastlake, 3rd. Domain Name System Security Extensions. March 1999.
-
[RFC3008] B.Wellington. Domain Name System Security (DNSSEC)
+
[RFC3008] B.Wellington. Domain Name System Security (DNSSEC)
Signing Authority. November 2000.
-
[RFC3090] E.Lewis. DNS Security Extension Clarification on Zone Status. March 2001.
+
[RFC3090] E.Lewis. DNS Security Extension Clarification on Zone Status. March 2001.
-
[RFC3445] D.Massey and S.Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.
+
[RFC3445] D.Massey and S.Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.
-
[RFC3655] B.Wellington and O.Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.
+
[RFC3655] B.Wellington and O.Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.
-
[RFC3658] O.Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.
+
[RFC3658] O.Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.
-
[RFC3755] S.Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.
+
[RFC3755] S.Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.
-
[RFC3757] O.Kolkman, J.Schlyter, and E.Lewis. Domain Name System KEY (DNSKEY) Resource Record
+
[RFC3757] O.Kolkman, J.Schlyter, and E.Lewis. Domain Name System KEY (DNSKEY) Resource Record
(RR) Secure Entry Point (SEP) Flag. April 2004.
-
[RFC3845] J.Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.
+
[RFC3845] J.Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.
@@ -594,18 +604,483 @@
-Other Documents About BIND
+Other Documents About BIND
This version of BIND 9 "exports" its internal libraries so
+ that they can be used by third-party applications more easily (we
+ call them "export" libraries in this document). In addition to
+ all major DNS-related APIs BIND 9 is currently using, the export
+ libraries provide the following features:
+
+
The newly created "DNS client" module. This is a higher
+ level API that provides an interface to name resolution,
+ single DNS transaction with a particular server, and dynamic
+ update. Regarding name resolution, it supports advanced
+ features such as DNSSEC validation and caching. This module
+ supports both synchronous and asynchronous mode.
+
The new "IRS" (Information Retrieval System) library.
+ It provides an interface to parse the traditional resolv.conf
+ file and more advanced, DNS-specific configuration file for
+ the rest of this package (see the description for the
+ dns.conf file below).
+
As part of the IRS library, newly implemented standard
+ address-name mapping functions, getaddrinfo() and
+ getnameinfo(), are provided. They use the DNSSEC-aware
+ validating resolver backend, and could use other advanced
+ features of the BIND 9 libraries such as caching. The
+ getaddrinfo() function resolves both A and AAAA RRs
+ concurrently (when the address family is unspecified).
+
An experimental framework to support other event
+ libraries than BIND 9's internal event task system.
+
+
+
+Prerequisite
+
GNU make is required to build the export libraries (other
+ part of BIND 9 can still be built with other types of make). In
+ the reminder of this document, "make" means GNU make. Note that
+ in some platforms you may need to invoke a different command name
+ than "make" (e.g. "gmake") to indicate it's GNU make.
+
+
+
+Compilation
+
+$ ./configure --enable-exportlib [other flags]
+$ make
+
+
+ This will create (in addition to usual BIND 9 programs) and a
+ separate set of libraries under the lib/export directory. For
+ example, lib/export/dns/libdns.a is the archive file of the
+ export version of the BIND 9 DNS library. Sample application
+ programs using the libraries will also be built under the
+ lib/export/samples directory (see below).
+
+
+
+Installation
+
+$ cd lib/export
+$ make install
+
+
+ This will install library object files under the directory
+ specified by the --with-export-libdir configure option (default:
+ EPREFIX/lib/bind9), and header files under the directory
+ specified by the --with-export-includedir configure option
+ (default: PREFIX/include/bind9).
+ Root privilege is normally required.
+ "make install" at the top directory will do the
+ same.
+
+
+ To see how to build your own
+ application after the installation, see
+ lib/export/samples/Makefile-postinstall.in.
+
+
+
+Known Defects/Restrictions
+
+
Currently, win32 is not supported for the export
+ library. (Normal BIND 9 application can be built as
+ before).
+
+
The "fixed" RRset order is not (currently) supported in
+ the export library. If you want to use "fixed" RRset order
+ for, e.g. named while still building the
+ export library even without the fixed order support, build
+ them separately:
+
+
+$ ./configure --enable-fixed-rrset [other flags, but not --enable-exportlib]
+$ make
+$ ./configure --enable-exportlib [other flags, but not --enable-fixed-rrset]
+$ cd lib/export
+$ make
+
+
+
+
+
The client module and the IRS library currently do not
+ support DNSSEC validation using DLV (the underlying modules
+ can handle it, but there is no tunable interface to enable
+ the feature).
+
RFC 5011 is not supported in the validating stub
+ resolver of the export library. In fact, it is not clear
+ whether it should: trust anchors would be a system-wide
+ configuration which would be managed by an administrator,
+ while the stub resolver will be used by ordinary applications
+ run by a normal user.
+
Not all common /etc/resolv.conf
+ options are supported
+ in the IRS library. The only available options in this
+ version are "debug" and "ndots".
+
+
+
+
+The dns.conf File
+
The IRS library supports an "advanced" configuration file
+ related to the DNS library for configuration parameters that
+ would be beyond the capability of the
+ resolv.conf file.
+ Specifically, it is intended to provide DNSSEC related
+ configuration parameters. By default the path to this
+ configuration file is /etc/dns.conf.
+ This module is very
+ experimental and the configuration syntax or library interfaces
+ may change in future versions. Currently, only the
+ trusted-keys
+ statement is supported, whose syntax is the same as the same name
+ of statement for named.conf. (See
+ the section called “trusted-keys Statement Grammar” for details.)
+
+
+
+Sample Applications
+
Some sample application programs using this API are
+ provided for reference. The following is a brief description of
+ these applications.
+
+
+
+sample: a simple stub resolver utility
+
+ It sends a query of a given name (of a given optional RR type) to a
+ specified recursive server, and prints the result as a list of
+ RRs. It can also act as a validating stub resolver if a trust
+ anchor is given via a set of command line options.
+ It sends a query to a specified server, and
+ prints the response with minimal processing. It doesn't act as a
+ "stub resolver": it stops the processing once it gets any
+ response from the server, whether it's a referral or an alias
+ (CNAME or DNAME) that would require further queries to get the
+ ultimate answer. In other words, this utility acts as a very
+ simplified dig.
+
+ specify the RR type of
+ the queries. The default is the A RR.
+
+
+ server_address
+
+
+ an IP(v4/v6)
+ address of the recursive server to which the query is sent.
+
+
+ hostname
+
+
+ the domain name for the query
+
+
+
+
+
+sample-gai: getaddrinfo() and getnameinfo() test code
+
+ This is a test program
+ to check getaddrinfo() and getnameinfo() behavior. It takes a
+ host name as an argument, calls getaddrinfo() with the given host
+ name, and calls getnameinfo() with the resulting IP addresses
+ returned by getaddrinfo(). If the dns.conf file exists and
+ defines a trust anchor, the underlying resolver will act as a
+ validating resolver, and getaddrinfo()/getnameinfo() will fail
+ with an EAI_INSECUREDATA error when DNSSEC validation fails.
+
+
+ Usage: sample-gai hostname
+
+
+
+
+sample-update: a simple dynamic update client program
+
+ It accepts a single update command as a
+ command-line argument, sends an update request message to the
+ authoritative server, and shows the response from the server. In
+ other words, this is a simplified nsupdate.
+
+ An IP address of the authoritative server that has authority
+ for the zone containing the update name. This should normally
+ be the primary authoritative server that accepts dynamic
+ updates. It can also be a secondary server that is configured
+ to forward update requests to the primary server.
+
+
+ -k keyfile
+
+
+ A TSIG key file to secure the update transaction. The keyfile
+ format is the same as that for the nsupdate utility.
+
+
+ -p prerequisite
+
+
+ A prerequisite for the update (only one prerequisite can be
+ specified). The prerequisite format is the same as that is
+ accepted by the nsupdate utility.
+
+
+ -r recursive_server
+
+
+ An IP address of a recursive server that this utility will
+ use. A recursive server may be necessary to identify the
+ authoritative server address to which the update request is
+ sent.
+
+
+ -z zonename
+
+
+ The domain name of the zone that contains
+
+
+ (add|delete)
+
+
+ Specify the type of update operation. Either "add" or "delete"
+ must be specified.
+
+
+ "update data"
+
+
+ Specify the data to be updated. A typical example of the data
+ would look like "name TTL RRtype RDATA".
+
+
+
+
Note
In practice, either -a or -r must be specified. Others can
+ be optional; the underlying library routine tries to identify the
+ appropriate server and the zone name for the update.
+
+ Examples: assuming the primary authoritative server of the
+ dynamic.example.com zone has an IPv6 address 2001:db8::1234,
+
+
+$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1"
+
+ adds an A RR for foo.dynamic.example.com using the given key.
+
+
+$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A"
+
+ removes all A RRs for foo.dynamic.example.com using the given key.
+
+
+$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com"
+
+ removes all RRs for foo.dynamic.example.com using the given key.
+
+
+
+
+nsprobe: domain/name server checker in terms of RFC 4074
+
+ It checks a set
+ of domains to see the name servers of the domains behave
+ correctly in terms of RFC 4074. This is included in the set of
+ sample programs to show how the export library can be used in a
+ DNS-related application.
+
+ run in the "debug" mode. with this option nsprobe will dump
+ every RRs it receives.
+
+
+ -v
+
+
+ increase verbosity of other normal log messages. This can be
+ specified multiple times
+
+
+ -c cache_address
+
+
+ specify an IP address of a recursive (caching) name server.
+ nsprobe uses this server to get the NS RRset of each domain and
+ the A and/or AAAA RRsets for the name servers. The default
+ value is 127.0.0.1.
+
+
+ input_file
+
+
+ a file name containing a list of domain (zone) names to be
+ probed. when omitted the standard input will be used. Each
+ line of the input file specifies a single domain name such as
+ "example.com". In general this domain name must be the apex
+ name of some DNS zone (unlike normal "host names" such as
+ "www.example.com"). nsprobe first identifies the NS RRsets for
+ the given domain name, and sends A and AAAA queries to these
+ servers for some "widely used" names under the zone;
+ specifically, adding "www" and "ftp" to the zone name.
+
+
+
+
+
+
+Library References
+
As of this writing, there is no formal "manual" of the
+ libraries, except this document, header files (some of them
+ provide pretty detailed explanations), and sample application
+ programs.