mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[master] max-zone-ttl
3746. [func] New "max-zone-ttl" option enforces maximum TTLs for zones. If loading a zone containing a higher TTL, the load fails. DDNS updates with higher TTLs are accepted but the TTL is truncated. (Note: Currently supported for master zones only; inline-signing slaves will be added.) [RT #38405]
This commit is contained in:
parent
880c48d818
commit
35f6a21f5f
33 changed files with 939 additions and 75 deletions
7
CHANGES
7
CHANGES
|
|
@ -1,3 +1,10 @@
|
|||
3746. [func] New "max-zone-ttl" option enforces maximum
|
||||
TTLs for zones. If loading a zone containing a
|
||||
higher TTL, the load fails. DDNS updates with
|
||||
higher TTLs are accepted but the TTL is truncated.
|
||||
(Note: Currently supported for master zones only;
|
||||
inline-signing slaves will be added.) [RT #38405]
|
||||
|
||||
3745. [func] "configure --with-tuning=large" adjusts various
|
||||
compiled-in constants and default settings to
|
||||
values suited to large servers with abundant
|
||||
|
|
|
|||
4
README
4
README
|
|
@ -123,6 +123,10 @@ BIND 9.10.0
|
|||
OpenSSL as an intermediary. This has been tested with the
|
||||
Thales nShield HSM and with SoftHSMv2 from the Open DNSSEC
|
||||
project.
|
||||
- The new "max-zone-ttl" option enforces maximum TTLs for
|
||||
zones. This can simplify the process of rolling DNSSEC keys
|
||||
by guaranteeing that cached signatures will have expired
|
||||
within the specified amount of time.
|
||||
- New "dnssec-coverage" tool to check DNSSEC key coverage
|
||||
for a zone and report if a lapse in signing coverage has
|
||||
been inadvertently scheduled.
|
||||
|
|
|
|||
|
|
@ -40,12 +40,17 @@
|
|||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
#include <dns/dbiterator.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatasetiter.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/types.h>
|
||||
#include <dns/zone.h>
|
||||
|
||||
|
|
@ -108,6 +113,7 @@ unsigned int zone_options = DNS_ZONEOPT_CHECKNS |
|
|||
DNS_ZONEOPT_CHECKWILDCARD |
|
||||
DNS_ZONEOPT_WARNMXCNAME |
|
||||
DNS_ZONEOPT_WARNSRVCNAME;
|
||||
unsigned int zone_options2 = 0;
|
||||
|
||||
/*
|
||||
* This needs to match the list in bin/named/log.c.
|
||||
|
|
@ -577,11 +583,93 @@ setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*% scan the zone for oversize TTLs */
|
||||
static isc_result_t
|
||||
check_ttls(dns_zone_t *zone, dns_ttl_t maxttl) {
|
||||
isc_result_t result;
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbversion_t *version = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_dbiterator_t *dbiter = NULL;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
||||
dns_zone_getdb(zone, &db);
|
||||
INSIST(db != NULL);
|
||||
|
||||
CHECK(dns_db_newversion(db, &version));
|
||||
CHECK(dns_db_createiterator(db, 0, &dbiter));
|
||||
|
||||
for (result = dns_dbiterator_first(dbiter);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_dbiterator_next(dbiter)) {
|
||||
result = dns_dbiterator_current(dbiter, &node, name);
|
||||
if (result == DNS_R_NEWORIGIN)
|
||||
result = ISC_R_SUCCESS;
|
||||
CHECK(result);
|
||||
|
||||
CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsiter));
|
||||
for (result = dns_rdatasetiter_first(rdsiter);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(rdsiter)) {
|
||||
dns_rdatasetiter_current(rdsiter, &rdataset);
|
||||
if (rdataset.ttl > maxttl) {
|
||||
char nbuf[DNS_NAME_FORMATSIZE];
|
||||
char tbuf[255];
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
|
||||
dns_name_format(name, nbuf, sizeof(nbuf));
|
||||
isc_buffer_init(&b, tbuf, sizeof(tbuf) - 1);
|
||||
CHECK(dns_rdatatype_totext(rdataset.type, &b));
|
||||
isc_buffer_usedregion(&b, &r);
|
||||
r.base[r.length] = 0;
|
||||
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"%s/%s TTL %d exceeds "
|
||||
"maximum TTL %d",
|
||||
nbuf, tbuf, rdataset.ttl, maxttl);
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
CHECK(ISC_R_RANGE);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
CHECK(result);
|
||||
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
if (rdsiter != NULL)
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
if (dbiter != NULL)
|
||||
dns_dbiterator_destroy(&dbiter);
|
||||
if (version != NULL)
|
||||
dns_db_closeversion(db, &version, ISC_FALSE);
|
||||
if (db != NULL)
|
||||
dns_db_detach(&db);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*% load the zone */
|
||||
isc_result_t
|
||||
load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
||||
dns_masterformat_t fileformat, const char *classname,
|
||||
dns_zone_t **zonep)
|
||||
dns_ttl_t maxttl, dns_zone_t **zonep)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rdataclass_t rdclass;
|
||||
|
|
@ -618,7 +706,11 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
|||
|
||||
dns_zone_setclass(zone, rdclass);
|
||||
dns_zone_setoption(zone, zone_options, ISC_TRUE);
|
||||
dns_zone_setoption2(zone, zone_options2, ISC_TRUE);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge);
|
||||
|
||||
dns_zone_setmaxttl(zone, maxttl);
|
||||
|
||||
if (docheckmx)
|
||||
dns_zone_setcheckmx(zone, checkmx);
|
||||
if (docheckns)
|
||||
|
|
@ -627,6 +719,15 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
|||
dns_zone_setchecksrv(zone, checksrv);
|
||||
|
||||
CHECK(dns_zone_load(zone));
|
||||
|
||||
/*
|
||||
* When loading map files we can't catch oversize TTLs during
|
||||
* load, so we check for them here.
|
||||
*/
|
||||
if (fileformat == dns_masterformat_map && maxttl != 0) {
|
||||
CHECK(check_ttls(zone, maxttl));
|
||||
}
|
||||
|
||||
if (zonep != NULL) {
|
||||
*zonep = zone;
|
||||
zone = NULL;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp);
|
|||
isc_result_t
|
||||
load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
||||
dns_masterformat_t fileformat, const char *classname,
|
||||
dns_zone_t **zonep);
|
||||
dns_ttl_t maxttl, dns_zone_t **zonep);
|
||||
|
||||
isc_result_t
|
||||
dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
|
||||
|
|
@ -56,6 +56,7 @@ extern isc_boolean_t docheckmx;
|
|||
extern isc_boolean_t docheckns;
|
||||
extern isc_boolean_t dochecksrv;
|
||||
extern unsigned int zone_options;
|
||||
extern unsigned int zone_options2;
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ configure_zone(const char *vclass, const char *view,
|
|||
const cfg_obj_t *obj = NULL;
|
||||
const cfg_obj_t *fmtobj = NULL;
|
||||
dns_masterformat_t masterformat;
|
||||
dns_ttl_t maxttl = 0;
|
||||
|
||||
zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS;
|
||||
|
||||
|
|
@ -373,11 +374,20 @@ configure_zone(const char *vclass, const char *view,
|
|||
masterformat = dns_masterformat_text;
|
||||
else if (strcasecmp(masterformatstr, "raw") == 0)
|
||||
masterformat = dns_masterformat_raw;
|
||||
else if (strcasecmp(masterformatstr, "map") == 0)
|
||||
masterformat = dns_masterformat_map;
|
||||
else
|
||||
INSIST(0);
|
||||
}
|
||||
|
||||
result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL);
|
||||
obj = NULL;
|
||||
if (get_maps(maps, "max-zone-ttl", &obj)) {
|
||||
maxttl = cfg_obj_asuint32(obj);
|
||||
zone_options2 |= DNS_ZONEOPT2_CHECKTTL;
|
||||
}
|
||||
|
||||
result = load_zone(mctx, zname, zfile, masterformat,
|
||||
zclass, maxttl, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass,
|
||||
dns_result_totext(result));
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ main(int argc, char **argv) {
|
|||
dns_masterformat_t outputformat = dns_masterformat_text;
|
||||
dns_masterrawheader_t header;
|
||||
isc_uint32_t rawversion = 1, serialnum = 0;
|
||||
dns_ttl_t maxttl = 0;
|
||||
isc_boolean_t snset = ISC_FALSE;
|
||||
isc_boolean_t logdump = ISC_FALSE;
|
||||
FILE *errout = stdout;
|
||||
|
|
@ -169,7 +170,7 @@ main(int argc, char **argv) {
|
|||
isc_commandline_errprint = ISC_FALSE;
|
||||
|
||||
while ((c = isc_commandline_parse(argc, argv,
|
||||
"c:df:hi:jJ:k:L:m:n:qr:s:t:o:vw:DF:M:S:T:W:"))
|
||||
"c:df:hi:jJ:k:L:l:m:n:qr:s:t:o:vw:DF:M:S:T:W:"))
|
||||
!= EOF) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
|
|
@ -263,6 +264,18 @@ main(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
zone_options2 |= DNS_ZONEOPT2_CHECKTTL;
|
||||
endp = NULL;
|
||||
maxttl = strtol(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0') {
|
||||
fprintf(stderr, "maximum TTL "
|
||||
"must be numeric");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'n':
|
||||
if (ARGCMP("ignore")) {
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKNS|
|
||||
|
|
@ -523,7 +536,7 @@ main(int argc, char **argv) {
|
|||
origin = argv[isc_commandline_index++];
|
||||
filename = argv[isc_commandline_index++];
|
||||
result = load_zone(mctx, origin, filename, inputformat, classname,
|
||||
&zone);
|
||||
maxttl, &zone);
|
||||
|
||||
if (snset) {
|
||||
dns_master_initrawheader(&header);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-M <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-l <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
|
||||
<arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
|
|
@ -102,6 +103,7 @@
|
|||
<arg><option>-k <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-l <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
|
||||
|
|
@ -301,6 +303,19 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l <replaceable class="parameter">ttl</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets a maximum permissible TTL for the input file.
|
||||
Any record with a TTL higher than this value will cause
|
||||
the zone to be rejected. This is similar to using the
|
||||
<command>max-zone-ttl</command> option in
|
||||
<filename>named.conf</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-L <replaceable class="parameter">serial</replaceable></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ static isc_boolean_t remove_orphansigs = ISC_FALSE;
|
|||
static isc_boolean_t remove_inactkeysigs = ISC_FALSE;
|
||||
static isc_boolean_t output_dnssec_only = ISC_FALSE;
|
||||
static isc_boolean_t output_stdout = ISC_FALSE;
|
||||
isc_boolean_t set_maxttl = ISC_FALSE;
|
||||
static dns_ttl_t maxttl = 0;
|
||||
|
||||
#define INCSTAT(counter) \
|
||||
if (printstats) { \
|
||||
|
|
@ -1232,6 +1234,10 @@ get_soa_ttls(void) {
|
|||
dns_rdataset_current(&soaset, &rdata);
|
||||
zone_soa_min_ttl = dns_soa_getminimum(&rdata);
|
||||
soa_ttl = soaset.ttl;
|
||||
if (set_maxttl) {
|
||||
zone_soa_min_ttl = ISC_MIN(zone_soa_min_ttl, maxttl);
|
||||
soa_ttl = ISC_MIN(soa_ttl, maxttl);
|
||||
}
|
||||
dns_rdataset_disassociate(&soaset);
|
||||
}
|
||||
|
||||
|
|
@ -2007,7 +2013,8 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
|
|||
rdatalist.rdclass = rdata.rdclass;
|
||||
rdatalist.type = rdata.type;
|
||||
rdatalist.covers = 0;
|
||||
rdatalist.ttl = rdataset.ttl;
|
||||
if (set_maxttl)
|
||||
rdatalist.ttl = ISC_MIN(rdataset.ttl, maxttl);
|
||||
ISC_LIST_INIT(rdatalist.rdata);
|
||||
dns_rdata_init(&delrdata);
|
||||
dns_rdata_clone(&rdata, &delrdata);
|
||||
|
|
@ -2038,13 +2045,17 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
|
|||
}
|
||||
|
||||
static void
|
||||
rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
|
||||
dns_diff_t *diff)
|
||||
rrset_cleanup(dns_name_t *name, dns_rdataset_t *rdataset,
|
||||
dns_diff_t *add, dns_diff_t *del)
|
||||
{
|
||||
dns_difftuple_t *tuple = NULL;
|
||||
isc_result_t result;
|
||||
unsigned int count1 = 0;
|
||||
dns_rdataset_t tmprdataset;
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
char typestr[TYPE_FORMATSIZE];
|
||||
|
||||
dns_name_format(name, namestr, sizeof(namestr));
|
||||
type_format(rdataset->type, typestr, sizeof(typestr));
|
||||
|
||||
dns_rdataset_init(&tmprdataset);
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
|
|
@ -2060,17 +2071,38 @@ rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&tmprdataset)) {
|
||||
dns_rdata_t rdata2 = DNS_RDATA_INIT;
|
||||
dns_difftuple_t *tuple = NULL;
|
||||
count2++;
|
||||
if (count1 >= count2)
|
||||
continue;
|
||||
dns_rdataset_current(&tmprdataset, &rdata2);
|
||||
if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
|
||||
if (count1 < count2 &&
|
||||
dns_rdata_casecompare(&rdata1, &rdata2) == 0)
|
||||
{
|
||||
vbprintf(2, "removing duplicate at %s/%s\n",
|
||||
namestr, typestr);
|
||||
result = dns_difftuple_create(mctx,
|
||||
DNS_DIFFOP_DELRESIGN,
|
||||
name, rdataset->ttl,
|
||||
&rdata2, &tuple);
|
||||
check_result(result, "dns_difftuple_create");
|
||||
dns_diff_append(diff, &tuple);
|
||||
dns_diff_append(del, &tuple);
|
||||
} else if (set_maxttl && rdataset->ttl > maxttl) {
|
||||
vbprintf(2, "reducing ttl of %s/%s "
|
||||
"from %d to %d\n",
|
||||
namestr, typestr,
|
||||
rdataset->ttl, maxttl);
|
||||
result = dns_difftuple_create(mctx,
|
||||
DNS_DIFFOP_DELRESIGN,
|
||||
name, rdataset->ttl,
|
||||
&rdata2, &tuple);
|
||||
check_result(result, "dns_difftuple_create");
|
||||
dns_diff_append(del, &tuple);
|
||||
tuple = NULL;
|
||||
result = dns_difftuple_create(mctx,
|
||||
DNS_DIFFOP_ADDRESIGN,
|
||||
name, maxttl,
|
||||
&rdata2, &tuple);
|
||||
check_result(result, "dns_difftuple_create");
|
||||
dns_diff_append(add, &tuple);
|
||||
}
|
||||
}
|
||||
dns_rdataset_disassociate(&tmprdataset);
|
||||
|
|
@ -2078,17 +2110,18 @@ rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
}
|
||||
|
||||
static void
|
||||
remove_duplicates(void) {
|
||||
cleanup_zone(void) {
|
||||
isc_result_t result;
|
||||
dns_dbiterator_t *dbiter = NULL;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
dns_diff_t diff;
|
||||
dns_diff_t add, del;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
|
||||
dns_diff_init(mctx, &diff);
|
||||
dns_diff_init(mctx, &add);
|
||||
dns_diff_init(mctx, &del);
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
|
@ -2108,7 +2141,7 @@ remove_duplicates(void) {
|
|||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(rdsiter)) {
|
||||
dns_rdatasetiter_current(rdsiter, &rdataset);
|
||||
rrset_remove_duplicates(name, &rdataset, &diff);
|
||||
rrset_cleanup(name, &rdataset, &add, &del);
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
|
|
@ -2119,11 +2152,14 @@ remove_duplicates(void) {
|
|||
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);
|
||||
result = dns_diff_applysilently(&del, gdb, gversion);
|
||||
check_result(result, "dns_diff_applysilently");
|
||||
|
||||
result = dns_diff_applysilently(&add, gdb, gversion);
|
||||
check_result(result, "dns_diff_applysilently");
|
||||
|
||||
dns_diff_clear(&del);
|
||||
dns_diff_clear(&add);
|
||||
dns_dbiterator_destroy(&dbiter);
|
||||
}
|
||||
|
||||
|
|
@ -2448,11 +2484,11 @@ loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
|
|||
goto cleanup;
|
||||
|
||||
if (set_keyttl && keyttl != rdataset.ttl) {
|
||||
fprintf(stderr, "User-specified TTL (%d) conflicts "
|
||||
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",
|
||||
"TTL %d instead.\n",
|
||||
rdataset.ttl);
|
||||
}
|
||||
keyttl = rdataset.ttl;
|
||||
|
|
@ -3065,9 +3101,9 @@ main(int argc, char *argv[]) {
|
|||
isc_boolean_t set_iter = ISC_FALSE;
|
||||
isc_boolean_t nonsecify = ISC_FALSE;
|
||||
|
||||
/* Unused letters: Bb G J M q Yy (and F is reserved). */
|
||||
/* Unused letters: Bb G J q Yy (and F is reserved). */
|
||||
#define CMDLINE_FLAGS \
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpQRr:s:ST:tuUv:X:xzZ:"
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:M:n:N:o:O:PpQRr:s:ST:tuUv:X:xzZ:"
|
||||
|
||||
/*
|
||||
* Process memory debugging argument first.
|
||||
|
|
@ -3240,6 +3276,17 @@ main(int argc, char *argv[]) {
|
|||
check_result(result, "dns_name_fromtext(dlv)");
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
endp = NULL;
|
||||
set_maxttl = ISC_TRUE;
|
||||
maxttl = strtol(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0') {
|
||||
fprintf(stderr, "maximum TTL "
|
||||
"must be numeric");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
break;
|
||||
|
||||
|
|
@ -3459,7 +3506,7 @@ main(int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
} else
|
||||
fatal("unknown file format: %s\n", outputformatstr);
|
||||
fatal("unknown file format: %s", outputformatstr);
|
||||
}
|
||||
|
||||
if (serialformatstr != NULL) {
|
||||
|
|
@ -3471,15 +3518,18 @@ main(int argc, char *argv[]) {
|
|||
else if (strcasecmp(serialformatstr, "unixtime") == 0)
|
||||
serialformat = SOA_SERIAL_UNIXTIME;
|
||||
else
|
||||
fatal("unknown soa serial format: %s\n",
|
||||
fatal("unknown soa serial format: %s",
|
||||
serialformatstr);
|
||||
}
|
||||
|
||||
if (output_dnssec_only && outputformat != dns_masterformat_text)
|
||||
fatal("option -D can only be used with \"-O text\"\n");
|
||||
fatal("option -D can only be used with \"-O text\"");
|
||||
|
||||
if (output_dnssec_only && serialformat != SOA_SERIAL_KEEP)
|
||||
fatal("option -D can only be used with \"-N keep\"\n");
|
||||
fatal("option -D can only be used with \"-N keep\"");
|
||||
|
||||
if (output_dnssec_only && set_maxttl)
|
||||
fatal("option -D cannot be used with -M");
|
||||
|
||||
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
|
||||
0, 24, 0, 0, 0, 8, mctx);
|
||||
|
|
@ -3492,6 +3542,13 @@ main(int argc, char *argv[]) {
|
|||
gclass = dns_db_class(gdb);
|
||||
get_soa_ttls();
|
||||
|
||||
if (set_maxttl && set_keyttl && keyttl > maxttl) {
|
||||
fprintf(stderr, "%s: warning: Specified key TTL %d "
|
||||
"exceeds maximum zone TTL; reducing to %d\n",
|
||||
program, keyttl, maxttl);
|
||||
keyttl = maxttl;
|
||||
}
|
||||
|
||||
if (!set_keyttl)
|
||||
keyttl = soa_ttl;
|
||||
|
||||
|
|
@ -3596,7 +3653,8 @@ main(int argc, char *argv[]) {
|
|||
break;
|
||||
}
|
||||
|
||||
remove_duplicates();
|
||||
/* Remove duplicates and cap TTLs at maxttl */
|
||||
cleanup_zone();
|
||||
|
||||
if (!nonsecify) {
|
||||
if (IS_NSEC3)
|
||||
|
|
@ -3725,7 +3783,7 @@ main(int argc, char *argv[]) {
|
|||
|
||||
result = isc_file_rename(tempfile, output);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("failed to rename temp file to %s: %s\n",
|
||||
fatal("failed to rename temp file to %s: %s",
|
||||
output, isc_result_totext(result));
|
||||
|
||||
printf("%s\n", output);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
<arg><option>-k <replaceable class="parameter">key</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
|
||||
<arg><option>-M <replaceable class="parameter">domain</replaceable></option></arg>
|
||||
<arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
|
||||
<arg><option>-I <replaceable class="parameter">input-format</replaceable></option></arg>
|
||||
<arg><option>-j <replaceable class="parameter">jitter</replaceable></option></arg>
|
||||
|
|
@ -235,6 +236,26 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-M <replaceable class="parameter">maxttl</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the maximum TTL for the signed zone.
|
||||
Any TTL higher than <replaceable>maxttl</replaceable> in the
|
||||
input zone will be reduced to <replaceable>maxttl</replaceable>
|
||||
in the output. This provides certainty as to the largest
|
||||
possible TTL in the signed zone, which is useful to know when
|
||||
rolling keys because it is the longest possible time before
|
||||
signatures that have been retrieved by resolvers will expire
|
||||
from resolver caches. Zones that are signed with this
|
||||
option should be configured to use a matching
|
||||
<option>max-zone-ttl</option> in <filename>named.conf</filename>.
|
||||
(Note: This option is incompatible with <option>-D</option>,
|
||||
because it modifies non-DNSSEC data in the output zone.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-s <replaceable class="parameter">start-time</replaceable></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -2434,7 +2434,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
update_event_t *uev = (update_event_t *) event;
|
||||
dns_zone_t *zone = uev->zone;
|
||||
ns_client_t *client = (ns_client_t *)event->ev_arg;
|
||||
|
||||
isc_result_t result;
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbversion_t *oldver = NULL;
|
||||
|
|
@ -2450,11 +2449,12 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
dns_ssutable_t *ssutable = NULL;
|
||||
dns_fixedname_t tmpnamefixed;
|
||||
dns_name_t *tmpname = NULL;
|
||||
unsigned int options;
|
||||
unsigned int options, options2;
|
||||
dns_difftuple_t *tuple;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
isc_boolean_t had_dnskey;
|
||||
dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
|
||||
dns_ttl_t maxttl = 0;
|
||||
|
||||
INSIST(event->ev_type == DNS_EVENT_UPDATE);
|
||||
|
||||
|
|
@ -2730,6 +2730,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
*/
|
||||
|
||||
options = dns_zone_getoptions(zone);
|
||||
options2 = dns_zone_getoptions2(zone);
|
||||
for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_message_nextname(request, DNS_SECTION_UPDATE))
|
||||
|
|
@ -2855,6 +2856,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
"a non-terminal wildcard", namestr);
|
||||
}
|
||||
|
||||
if ((options2 & DNS_ZONEOPT2_CHECKTTL) != 0) {
|
||||
maxttl = dns_zone_getmaxttl(zone);
|
||||
if (ttl > maxttl) {
|
||||
ttl = maxttl;
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
"reducing TTL to the "
|
||||
"configured max-zone-ttl %d",
|
||||
maxttl);
|
||||
}
|
||||
}
|
||||
|
||||
if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) {
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
char typestr[DNS_RDATATYPE_FORMATSIZE];
|
||||
|
|
|
|||
|
|
@ -880,7 +880,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
} else
|
||||
dns_zone_settype(zone, ztype);
|
||||
|
||||
|
||||
obj = NULL;
|
||||
result = cfg_map_get(zoptions, "database", &obj);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
|
|
@ -962,6 +961,21 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
INSIST(0);
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "max-zone-ttl", &obj);
|
||||
if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) {
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||
"zone '%s': 'max-zone-ttl' is not compatible "
|
||||
"with 'masterfile-format map'", zname);
|
||||
return (ISC_R_FAILURE);
|
||||
} else if (result == ISC_R_SUCCESS) {
|
||||
dns_ttl_t maxttl = cfg_obj_asuint32(obj);
|
||||
dns_zone_setmaxttl(zone, maxttl);
|
||||
if (raw != NULL)
|
||||
dns_zone_setmaxttl(raw, maxttl);
|
||||
}
|
||||
|
||||
if (raw != NULL && filename != NULL) {
|
||||
#define SIGNED ".signed"
|
||||
size_t signedlen = strlen(filename) + sizeof(SIGNED);
|
||||
|
|
|
|||
22
bin/tests/system/checkconf/bad-maxttlmap.conf
Normal file
22
bin/tests/system/checkconf/bad-maxttlmap.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
zone example {
|
||||
type master;
|
||||
masterfile-format map;
|
||||
file "example.db";
|
||||
max-zone-ttl 3600;
|
||||
};
|
||||
|
|
@ -14,7 +14,5 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: clean.sh,v 1.2 2011/05/07 05:55:17 each Exp $
|
||||
|
||||
rm -f good.conf.in good.conf.out badzero.conf
|
||||
rm -f good.conf.in good.conf.out badzero.conf *.out
|
||||
rm -rf test.keydir
|
||||
|
|
|
|||
38
bin/tests/system/checkconf/max-ttl.conf
Normal file
38
bin/tests/system/checkconf/max-ttl.conf
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
directory ".";
|
||||
max-zone-ttl 600;
|
||||
};
|
||||
|
||||
zone "maxttl1.example" {
|
||||
type master;
|
||||
file "maxttl-bad.db";
|
||||
};
|
||||
|
||||
zone "maxttl2.example" {
|
||||
type master;
|
||||
file "maxttl-bad.db";
|
||||
max-zone-ttl 300;
|
||||
};
|
||||
|
||||
zone "maxttl3.example" {
|
||||
type master;
|
||||
file "maxttl-bad.db";
|
||||
max-zone-ttl 120;
|
||||
};
|
||||
|
||||
27
bin/tests/system/checkconf/maxttl-bad.conf
Normal file
27
bin/tests/system/checkconf/maxttl-bad.conf
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
directory ".";
|
||||
max-zone-ttl 8000w;
|
||||
};
|
||||
|
||||
zone "maxttl.example" {
|
||||
type master;
|
||||
file "maxttl-bad.db";
|
||||
};
|
||||
|
||||
|
||||
28
bin/tests/system/checkconf/maxttl-bad.db
Normal file
28
bin/tests/system/checkconf/maxttl-bad.db
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
; Copyright (C) 2013 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.
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
NS ns2
|
||||
ns2 A 10.53.0.2
|
||||
MX 10 mail
|
||||
|
||||
a 600 A 10.0.0.1
|
||||
mail 900 A 10.0.0.2
|
||||
28
bin/tests/system/checkconf/maxttl.db
Normal file
28
bin/tests/system/checkconf/maxttl.db
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
; Copyright (C) 2013 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.
|
||||
|
||||
$TTL 600 ; 10 minutes
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
NS ns2
|
||||
ns2 A 10.53.0.2
|
||||
MX 10 mail
|
||||
|
||||
a A 10.0.0.1
|
||||
mail A 10.0.0.2
|
||||
|
|
@ -163,6 +163,20 @@ n=`$CHECKCONF warn-keydir.conf 2>&1 | grep "key-directory" | wc -l`
|
|||
[ $n -eq 0 ] || ret=1
|
||||
rm -rf test.keydir
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
|
||||
echo "I: checking that named-checkconf -z catches conflicting ttl with max-ttl"
|
||||
ret=0
|
||||
$CHECKCONF -z max-ttl.conf > check.out 2>&1
|
||||
grep 'TTL 900 exceeds configured max-zone-ttl 600' check.out > /dev/null 2>&1 || ret=1
|
||||
grep 'TTL 900 exceeds configured max-zone-ttl 600' check.out > /dev/null 2>&1 || ret=1
|
||||
grep 'TTL 900 exceeds configured max-zone-ttl 600' check.out > /dev/null 2>&1 || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I: checking that named-checkconf -z catches invalid max-ttl"
|
||||
ret=0
|
||||
$CHECKCONF -z max-ttl-bad.conf > /dev/null 2>&1 && ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:exit status: $status"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,4 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: clean.sh,v 1.2 2011/03/02 04:20:33 marka Exp $
|
||||
|
||||
rm -f test.*
|
||||
rm -f test.* good1.db.map good1.db.raw named-compilezone
|
||||
|
|
|
|||
24
bin/tests/system/checkzone/setup.sh
Normal file
24
bin/tests/system/checkzone/setup.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (C) 2014 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.
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
rm -f named-compilezone
|
||||
ln -s $CHECKZONE named-compilezone
|
||||
|
||||
./named-compilezone -D -F raw -o good1.db.raw example \
|
||||
zones/good1.db > /dev/null 2>&1
|
||||
./named-compilezone -D -F map -o good1.db.map example \
|
||||
zones/good1.db > /dev/null 2>&1
|
||||
|
|
@ -68,4 +68,29 @@ n=`expr $n + 1`
|
|||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking with max ttl (text) ($n)"
|
||||
ret=0
|
||||
$CHECKZONE -l 300 example zones/good1.db > test.out1.$n 2>&1 && ret=1
|
||||
$CHECKZONE -l 600 example zones/good1.db > test.out2.$n 2>&1 || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking with max ttl (raw) ($n)"
|
||||
ret=0
|
||||
$CHECKZONE -f raw -l 300 example good1.db.raw > test.out1.$n 2>&1 && ret=1
|
||||
$CHECKZONE -f raw -l 600 example good1.db.raw > test.out2.$n 2>&1 || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking with max ttl (map) ($n)"
|
||||
ret=0
|
||||
$CHECKZONE -f map -l 300 example good1.db.map > test.out1.$n 2>&1 && ret=1
|
||||
$CHECKZONE -f map -l 600 example good1.db.map > test.out2.$n 2>&1 || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:exit status: $status"
|
||||
exit $status
|
||||
|
|
|
|||
|
|
@ -1526,6 +1526,16 @@ awk '/IN *SOA/ {if (NF != 7) exit(1)}' signer/signer.out.4 || ret=1
|
|||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking TTLs are capped by dnssec-signzone -M ($n)"
|
||||
ret=0
|
||||
(
|
||||
cd signer
|
||||
$SIGNER -O full -f signer.out.8 -S -M 30 -o example example.db > /dev/null 2>&1
|
||||
) || ret=1
|
||||
awk '/^;/ { next; } $2 > 30 { exit 1; }' signer/signer.out.8 || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking validated data are not cached longer than originalttl ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
||||
|
|
|
|||
35
bin/tests/system/nsupdate/ns1/max-ttl.db
Normal file
35
bin/tests/system/nsupdate/ns1/max-ttl.db
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
; 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
|
||||
; 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: max-ttl.db,v 1.10 2009/01/21 23:47:27 tbox Exp $
|
||||
|
||||
$ORIGIN .
|
||||
$TTL 300 ; 5 minutes
|
||||
max-ttl.nil IN SOA ns1.max-ttl.nil. hostmaster.max-ttl.nil. (
|
||||
1 ; serial
|
||||
2000 ; refresh (2000 seconds)
|
||||
2000 ; retry (2000 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
max-ttl.nil. NS ns1.max-ttl.nil.
|
||||
ns1.max-ttl.nil. A 10.53.0.1
|
||||
max-ttl.nil. NS ns2.max-ttl.nil.
|
||||
ns2.max-ttl.nil. A 10.53.0.2
|
||||
|
||||
$ORIGIN max-ttl.nil.
|
||||
* MX 10 mail
|
||||
a TXT "foo foo foo"
|
||||
PTR foo.net.
|
||||
|
|
@ -58,6 +58,15 @@ zone "example.nil" {
|
|||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "max-ttl.nil" {
|
||||
type master;
|
||||
file "max-ttl.db";
|
||||
max-zone-ttl 300;
|
||||
check-integrity no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "other.nil" {
|
||||
type master;
|
||||
file "other.db";
|
||||
|
|
|
|||
17
bin/tests/system/nsupdate/tests.sh
Normal file → Executable file
17
bin/tests/system/nsupdate/tests.sh
Normal file → Executable file
|
|
@ -552,6 +552,23 @@ if [ $ret -ne 0 ]; then
|
|||
status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that ttl is capped by max-ttl ($n)"
|
||||
$NSUPDATE <<END > /dev/null || ret=1
|
||||
server 10.53.0.1 5300
|
||||
update add cap.max-ttl.nil. 600 A 10.10.10.3
|
||||
update add nocap.max-ttl.nil. 150 A 10.10.10.3
|
||||
send
|
||||
END
|
||||
sleep 2
|
||||
$DIG @10.53.0.1 -p 5300 cap.max-ttl.nil | grep "^cap.max-ttl.nil. 300" > /dev/null 2>&1 || ret=1
|
||||
$DIG @10.53.0.1 -p 5300 nocap.max-ttl.nil | grep "^nocap.max-ttl.nil. 150" > /dev/null 2>&1 || ret=1
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo "I:failed"
|
||||
status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:add a record which is truncated when logged. ($n)"
|
||||
|
|
|
|||
|
|
@ -4879,6 +4879,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||
<optional> lame-ttl <replaceable>number</replaceable>; </optional>
|
||||
<optional> max-ncache-ttl <replaceable>number</replaceable>; </optional>
|
||||
<optional> max-cache-ttl <replaceable>number</replaceable>; </optional>
|
||||
<optional> max-zone-ttl <replaceable>number</replaceable> ; </optional>
|
||||
<optional> sig-validity-interval <replaceable>number</replaceable> <optional><replaceable>number</replaceable></optional> ; </optional>
|
||||
<optional> sig-signing-nodes <replaceable>number</replaceable> ; </optional>
|
||||
<optional> sig-signing-signatures <replaceable>number</replaceable> ; </optional>
|
||||
|
|
@ -5693,6 +5694,34 @@ options {
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>max-zone-ttl</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies a maximum permissible TTL value.
|
||||
When loading a zone file using a
|
||||
<option>masterfile-format</option> of
|
||||
<constant>text</constant> or <constant>raw</constant>,
|
||||
any record encountered with a TTL higher than
|
||||
<option>max-zone-ttl</option> will cause the zone to
|
||||
be rejected.
|
||||
</para>
|
||||
<para>
|
||||
This is useful in DNSSEC-signed zones because when
|
||||
rolling to a new DNSKEY, the old key needs to remain
|
||||
available until RRSIG records have expired from
|
||||
caches. The<option>max-zone-ttl</option> option guarantees
|
||||
that the largest TTL in the zone will be no higher
|
||||
the set value.
|
||||
</para>
|
||||
<para>
|
||||
(NOTE: Because <constant>map</constant>-format files
|
||||
load directly into memory, this option cannot be
|
||||
used with them.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>zone-statistics</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
|
|
@ -10966,6 +10995,7 @@ view "external" {
|
|||
<optional> inline-signing <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> zero-no-soa-ttl <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> serial-update-method <constant>increment</constant>|<constant>unixtime</constant>; </optional>
|
||||
<optional> max-zone-ttl <replaceable>number</replaceable> ; </optional>
|
||||
};
|
||||
|
||||
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
|
||||
|
|
@ -11097,6 +11127,7 @@ zone <replaceable>"."</replaceable> <optional><replaceable>class</replaceable></
|
|||
file <replaceable>string</replaceable> ;
|
||||
<optional> masterfile-format (<constant>text</constant>|<constant>raw</constant>|<constant>map</constant>) ; </optional>
|
||||
<optional> allow-query { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> max-zone-ttl <replaceable>number</replaceable> ; </optional>
|
||||
};
|
||||
|
||||
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
|
||||
|
|
@ -12224,6 +12255,16 @@ example.com. NS ns2.example.net.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>max-zone-ttl</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
See the description of <command>max-zone-ttl</command>
|
||||
in <xref linkend="options"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dnssec-secure-to-insecure</command></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -1431,6 +1431,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
isc_boolean_t root = ISC_FALSE;
|
||||
const cfg_listelt_t *element;
|
||||
isc_boolean_t dlz;
|
||||
dns_masterformat_t masterformat;
|
||||
|
||||
static optionstable options[] = {
|
||||
{ "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE |
|
||||
|
|
@ -1460,6 +1461,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
{ "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
|
||||
{ "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
|
||||
{ "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
|
||||
{ "max-zone-ttl", MASTERZONE | REDIRECTZONE },
|
||||
{ "dnssec-secure-to-insecure", MASTERZONE },
|
||||
{ "sig-re-signing-interval", MASTERZONE | SLAVEZONE },
|
||||
{ "sig-signing-nodes", MASTERZONE | SLAVEZONE },
|
||||
|
|
@ -1858,12 +1860,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
if (root) {
|
||||
if (voptions != NULL)
|
||||
(void)cfg_map_get(voptions, "forwarders", &obj);
|
||||
if (obj == NULL) {
|
||||
const cfg_obj_t *options = NULL;
|
||||
(void)cfg_map_get(config, "options", &options);
|
||||
if (options != NULL)
|
||||
(void)cfg_map_get(options, "forwarders", &obj);
|
||||
}
|
||||
if (obj == NULL && goptions != NULL)
|
||||
(void)cfg_map_get(goptions, "forwarders", &obj);
|
||||
}
|
||||
if (check_forward(zoptions, obj, logctx) != ISC_R_SUCCESS)
|
||||
result = ISC_R_FAILURE;
|
||||
|
|
@ -1940,6 +1938,41 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check that max-zone-ttl isn't used with masterfile-format map
|
||||
*/
|
||||
masterformat = dns_masterformat_text;
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(zoptions, "masterfile-format", &obj);
|
||||
if (obj != NULL) {
|
||||
const char *masterformatstr = cfg_obj_asstring(obj);
|
||||
if (strcasecmp(masterformatstr, "text") == 0)
|
||||
masterformat = dns_masterformat_text;
|
||||
else if (strcasecmp(masterformatstr, "raw") == 0)
|
||||
masterformat = dns_masterformat_raw;
|
||||
else if (strcasecmp(masterformatstr, "map") == 0)
|
||||
masterformat = dns_masterformat_map;
|
||||
else
|
||||
INSIST(0);
|
||||
}
|
||||
|
||||
if (masterformat == dns_masterformat_map) {
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(zoptions, "max-zone-ttl", &obj);
|
||||
if (obj == NULL && voptions != NULL)
|
||||
(void)cfg_map_get(voptions, "max-zone-ttl", &obj);
|
||||
if (obj == NULL && goptions !=NULL)
|
||||
(void)cfg_map_get(goptions, "max-zone-ttl", &obj);
|
||||
if (obj != NULL) {
|
||||
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
|
||||
"zone '%s': 'max-zone-ttl' is not "
|
||||
"compatible with 'masterfile-format map'",
|
||||
znamestr);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Warn if key-directory doesn't exist
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#define DNS_MASTER_RESIGN 0x00002000
|
||||
#define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */
|
||||
#define DNS_MASTER_NOTTL 0x00008000 /*%< Don't require ttl. */
|
||||
#define DNS_MASTER_CHECKTTL 0x00010000 /*%< Check max-zone-ttl */
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
|
|
@ -159,6 +160,19 @@ dns_master_loadfile4(const char *master_file,
|
|||
void *include_arg, isc_mem_t *mctx,
|
||||
dns_masterformat_t format);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfile5(const char *master_file,
|
||||
dns_name_t *top,
|
||||
dns_name_t *origin,
|
||||
dns_rdataclass_t zclass,
|
||||
unsigned int options,
|
||||
isc_uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks,
|
||||
dns_masterincludecb_t include_cb,
|
||||
void *include_arg, isc_mem_t *mctx,
|
||||
dns_masterformat_t format,
|
||||
dns_ttl_t maxttl);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadstream(FILE *stream,
|
||||
dns_name_t *top,
|
||||
|
|
@ -236,6 +250,21 @@ dns_master_loadfileinc4(const char *master_file,
|
|||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfileinc5(const char *master_file,
|
||||
dns_name_t *top,
|
||||
dns_name_t *origin,
|
||||
dns_rdataclass_t zclass,
|
||||
unsigned int options,
|
||||
isc_uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks,
|
||||
isc_task_t *task,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loadctx_t **ctxp,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format,
|
||||
isc_uint32_t maxttl);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadstreaminc(FILE *stream,
|
||||
dns_name_t *top,
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ typedef enum {
|
|||
#define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */
|
||||
#define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */
|
||||
|
||||
/*
|
||||
* The following zone options are shifted left into the
|
||||
* higher-order 32 bits of the options.
|
||||
*/
|
||||
#define DNS_ZONEOPT2_CHECKTTL 0x00000001 /*%< check max-zone-ttl */
|
||||
|
||||
#ifndef NOMINUM_PUBLIC
|
||||
/*
|
||||
* Nominum specific options build down.
|
||||
|
|
@ -289,6 +295,30 @@ dns_zone_getfile(dns_zone_t *zone);
|
|||
*\li Pointer to null-terminated file name, or NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setmaxttl(dns_zone_t *zone, isc_uint32_t maxttl);
|
||||
/*%<
|
||||
* Sets the max ttl of the zone.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*
|
||||
* Returns:
|
||||
*\li void
|
||||
*/
|
||||
|
||||
dns_ttl_t
|
||||
dns_zone_getmaxttl(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Gets the max ttl of the zone.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*
|
||||
* Returns:
|
||||
*\li isc_uint32_t maxttl.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zone_load(dns_zone_t *zone);
|
||||
|
||||
|
|
@ -630,10 +660,19 @@ dns_zone_unload(dns_zone_t *zone);
|
|||
*/
|
||||
|
||||
void
|
||||
dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value);
|
||||
dns_zone_setoption(dns_zone_t *zone, unsigned int option,
|
||||
isc_boolean_t value);
|
||||
void
|
||||
dns_zone_setoption2(dns_zone_t *zone, unsigned int option,
|
||||
isc_boolean_t value);
|
||||
/*%<
|
||||
* Set given options on ('value' == ISC_TRUE) or off ('value' ==
|
||||
* #ISC_FALSE).
|
||||
* Set the given options on ('value' == ISC_TRUE) or off
|
||||
* ('value' == #ISC_FALSE).
|
||||
*
|
||||
* dns_zone_setoption2() has been introduced because the number
|
||||
* of options needed now exceeds the 32 bits in the zone->options
|
||||
* field; it should be used set options with names beginning
|
||||
* with DNS_ZONEOPT2_.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
|
|
@ -641,9 +680,17 @@ dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value);
|
|||
|
||||
unsigned int
|
||||
dns_zone_getoptions(dns_zone_t *zone);
|
||||
unsigned int
|
||||
dns_zone_getoptions2(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Returns the current zone options.
|
||||
*
|
||||
* Callers should be aware there is now more than one set of zone
|
||||
* options. dns_zone_getoptions2() has been introduced because the
|
||||
* number of options needed now exceeds the 32 bits in the
|
||||
* zone->options field. It returns the options whose names begin
|
||||
* with DNS_ZONEOPT2_.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ struct dns_loadctx {
|
|||
const char *filename);
|
||||
isc_result_t (*load)(dns_loadctx_t *lctx);
|
||||
|
||||
/* Members used by all formats */
|
||||
isc_uint32_t maxttl;
|
||||
|
||||
/* Members specific to the text format: */
|
||||
isc_lex_t *lex;
|
||||
isc_boolean_t keep_lex;
|
||||
|
|
@ -556,6 +559,8 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_ctx;
|
||||
|
||||
lctx->maxttl = 0;
|
||||
|
||||
lctx->format = format;
|
||||
switch (format) {
|
||||
default:
|
||||
|
|
@ -1605,8 +1610,9 @@ load_text(dns_loadctx_t *lctx) {
|
|||
GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
|
||||
|
||||
explicit_ttl = ISC_FALSE;
|
||||
if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl)
|
||||
== ISC_R_SUCCESS) {
|
||||
result = dns_ttl_fromtext(&token.value.as_textregion,
|
||||
&lctx->ttl);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
limit_ttl(callbacks, source, line, &lctx->ttl);
|
||||
explicit_ttl = ISC_TRUE;
|
||||
lctx->ttl_known = ISC_TRUE;
|
||||
|
|
@ -1953,6 +1959,17 @@ load_text(dns_loadctx_t *lctx) {
|
|||
lctx->ttl = this->ttl;
|
||||
}
|
||||
|
||||
if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 &&
|
||||
lctx->ttl > lctx->maxttl)
|
||||
{
|
||||
(callbacks->error)(callbacks,
|
||||
"dns_master_load: %s:%lu: "
|
||||
"TTL %d exceeds configured max-zone-ttl %d",
|
||||
source, line, lctx->ttl, lctx->maxttl);
|
||||
result = ISC_R_RANGE;
|
||||
goto log_and_cleanup;
|
||||
}
|
||||
|
||||
ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link);
|
||||
if (ictx->glue != NULL)
|
||||
ictx->glue_line = line;
|
||||
|
|
@ -2381,6 +2398,18 @@ load_raw(dns_loadctx_t *lctx) {
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 &&
|
||||
rdatalist.ttl > lctx->maxttl)
|
||||
{
|
||||
(callbacks->error)(callbacks,
|
||||
"dns_master_load: "
|
||||
"TTL %d exceeds configured "
|
||||
"max-zone-ttl %d",
|
||||
rdatalist.ttl, lctx->maxttl);
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Rdata contents. */
|
||||
if (rdcount > rdata_size) {
|
||||
dns_rdata_t *new_rdata = NULL;
|
||||
|
|
@ -2510,9 +2539,9 @@ dns_master_loadfile(const char *master_file, dns_name_t *top,
|
|||
dns_rdataclass_t zclass, unsigned int options,
|
||||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
||||
{
|
||||
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
|
||||
0, callbacks, NULL, NULL, mctx,
|
||||
dns_masterformat_text));
|
||||
return (dns_master_loadfile5(master_file, top, origin, zclass,
|
||||
options, 0, callbacks, NULL, NULL,
|
||||
mctx, dns_masterformat_text, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -2522,8 +2551,9 @@ dns_master_loadfile2(const char *master_file, dns_name_t *top,
|
|||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
|
||||
dns_masterformat_t format)
|
||||
{
|
||||
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
|
||||
0, callbacks, NULL, NULL, mctx, format));
|
||||
return (dns_master_loadfile5(master_file, top, origin, zclass,
|
||||
options, 0, callbacks, NULL, NULL,
|
||||
mctx, format, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -2533,9 +2563,9 @@ dns_master_loadfile3(const char *master_file, dns_name_t *top,
|
|||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
|
||||
dns_masterformat_t format)
|
||||
{
|
||||
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
|
||||
resign, callbacks, NULL, NULL, mctx,
|
||||
format));
|
||||
return (dns_master_loadfile5(master_file, top, origin, zclass,
|
||||
options, resign, callbacks, NULL, NULL,
|
||||
mctx, format, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -2545,6 +2575,21 @@ dns_master_loadfile4(const char *master_file, dns_name_t *top,
|
|||
dns_rdatacallbacks_t *callbacks,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format)
|
||||
{
|
||||
return (dns_master_loadfile5(master_file, top, origin, zclass,
|
||||
options, resign, callbacks,
|
||||
include_cb, include_arg,
|
||||
mctx, format, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfile5(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, isc_uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format,
|
||||
dns_ttl_t maxttl)
|
||||
{
|
||||
dns_loadctx_t *lctx = NULL;
|
||||
isc_result_t result;
|
||||
|
|
@ -2555,6 +2600,8 @@ dns_master_loadfile4(const char *master_file, dns_name_t *top,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
lctx->maxttl = maxttl;
|
||||
|
||||
result = (lctx->openfile)(lctx, master_file);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
|
@ -2618,6 +2665,24 @@ dns_master_loadfileinc4(const char *master_file, dns_name_t *top,
|
|||
void *done_arg, dns_loadctx_t **lctxp,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format)
|
||||
{
|
||||
options &= ~DNS_MASTER_CHECKTTL;
|
||||
return (dns_master_loadfileinc5(master_file, top, origin, zclass,
|
||||
options, resign, callbacks, task,
|
||||
done, done_arg, lctxp, include_cb,
|
||||
include_arg, mctx, format, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfileinc5(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, isc_uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks,
|
||||
isc_task_t *task, dns_loaddonefunc_t done,
|
||||
void *done_arg, dns_loadctx_t **lctxp,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format,
|
||||
isc_uint32_t maxttl)
|
||||
{
|
||||
dns_loadctx_t *lctx = NULL;
|
||||
isc_result_t result;
|
||||
|
|
@ -2631,6 +2696,8 @@ dns_master_loadfileinc4(const char *master_file, dns_name_t *top,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
lctx->maxttl = maxttl;
|
||||
|
||||
result = (lctx->openfile)(lctx, master_file);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
|
|
|||
|
|
@ -142,14 +142,14 @@ dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) {
|
|||
isc_result_t result;
|
||||
|
||||
result = bind_ttl(source, ttl);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_RANGE)
|
||||
result = DNS_R_BADTTL;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) {
|
||||
isc_uint32_t tmp = 0;
|
||||
isc_uint64_t tmp = 0ULL;
|
||||
isc_uint32_t n;
|
||||
char *s;
|
||||
char buf[64];
|
||||
|
|
@ -179,32 +179,32 @@ bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) {
|
|||
switch (*s) {
|
||||
case 'w':
|
||||
case 'W':
|
||||
tmp += n * 7 * 24 * 3600;
|
||||
tmp += (isc_uint64_t) n * 7 * 24 * 3600;
|
||||
s++;
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
tmp += n * 24 * 3600;
|
||||
tmp += (isc_uint64_t) n * 24 * 3600;
|
||||
s++;
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
tmp += n * 3600;
|
||||
tmp += (isc_uint64_t) n * 3600;
|
||||
s++;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
tmp += n * 60;
|
||||
tmp += (isc_uint64_t) n * 60;
|
||||
s++;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
tmp += n;
|
||||
tmp += (isc_uint64_t) n;
|
||||
s++;
|
||||
break;
|
||||
case '\0':
|
||||
/* Plain number? */
|
||||
if (tmp != 0)
|
||||
if (tmp != 0ULL)
|
||||
return (DNS_R_SYNTAX);
|
||||
tmp = n;
|
||||
break;
|
||||
|
|
@ -212,6 +212,10 @@ bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) {
|
|||
return (DNS_R_SYNTAX);
|
||||
}
|
||||
} while (*s != '\0');
|
||||
*ttl = tmp;
|
||||
|
||||
if (tmp > 0xffffffffULL)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
*ttl = (isc_uint32_t)(tmp & 0xffffffffUL);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ struct dns_zone {
|
|||
dns_zonetype_t type;
|
||||
unsigned int flags;
|
||||
unsigned int options;
|
||||
unsigned int options2;
|
||||
unsigned int db_argc;
|
||||
char **db_argv;
|
||||
isc_time_t expiretime;
|
||||
|
|
@ -395,6 +396,12 @@ struct dns_zone {
|
|||
|
||||
isc_boolean_t sourceserialset;
|
||||
isc_uint32_t sourceserial;
|
||||
|
||||
/*%
|
||||
* maximum zone ttl
|
||||
*/
|
||||
dns_ttl_t maxttl;
|
||||
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -460,6 +467,7 @@ typedef struct {
|
|||
#define DNS_ZONEFLG_SENDSECURE 0x40000000U
|
||||
|
||||
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
|
||||
#define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0)
|
||||
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
|
||||
|
||||
/* Flags for zone_load() */
|
||||
|
|
@ -909,6 +917,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||
zone->mastersok = NULL;
|
||||
zone->masterscnt = 0;
|
||||
zone->curmaster = 0;
|
||||
zone->maxttl = 0;
|
||||
zone->notify = NULL;
|
||||
zone->notifykeynames = NULL;
|
||||
zone->notifydscp = NULL;
|
||||
|
|
@ -1516,6 +1525,28 @@ dns_zone_getfile(dns_zone_t *zone) {
|
|||
return (zone->masterfile);
|
||||
}
|
||||
|
||||
dns_ttl_t
|
||||
dns_zone_getmaxttl(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return (zone->maxttl);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
if (maxttl != 0)
|
||||
zone->options2 |= DNS_ZONEOPT2_CHECKTTL;
|
||||
else
|
||||
zone->options2 &= ~DNS_ZONEOPT2_CHECKTTL;
|
||||
zone->maxttl = maxttl;
|
||||
UNLOCK_ZONE(zone);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
default_journal(dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
|
|
@ -2047,6 +2078,8 @@ get_master_options(dns_zone_t *zone) {
|
|||
options |= DNS_MASTER_CHECKMXFAIL;
|
||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
|
||||
options |= DNS_MASTER_CHECKWILDCARD;
|
||||
if (DNS_ZONE_OPTION2(zone, DNS_ZONEOPT2_CHECKTTL))
|
||||
options |= DNS_MASTER_CHECKTTL;
|
||||
return (options);
|
||||
}
|
||||
|
||||
|
|
@ -2103,7 +2136,7 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
options = get_master_options(load->zone);
|
||||
|
||||
result = dns_master_loadfileinc4(load->zone->masterfile,
|
||||
result = dns_master_loadfileinc5(load->zone->masterfile,
|
||||
dns_db_origin(load->db),
|
||||
dns_db_origin(load->db),
|
||||
load->zone->rdclass, options, 0,
|
||||
|
|
@ -2112,7 +2145,8 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
|
|||
&load->zone->lctx,
|
||||
zone_registerinclude,
|
||||
load->zone, load->zone->mctx,
|
||||
load->zone->masterformat);
|
||||
load->zone->masterformat,
|
||||
load->zone->maxttl);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
|
||||
result != DNS_R_SEENINCLUDE)
|
||||
goto fail;
|
||||
|
|
@ -2268,13 +2302,14 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
|
|||
zone_idetach(&callbacks.zone);
|
||||
return (result);
|
||||
}
|
||||
result = dns_master_loadfile4(zone->masterfile,
|
||||
result = dns_master_loadfile5(zone->masterfile,
|
||||
&zone->origin, &zone->origin,
|
||||
zone->rdclass, options, 0,
|
||||
&callbacks,
|
||||
zone_registerinclude,
|
||||
zone, zone->mctx,
|
||||
zone->masterformat);
|
||||
zone->masterformat,
|
||||
zone->maxttl);
|
||||
tresult = dns_db_endload(db, &callbacks);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
|
|
@ -4986,7 +5021,8 @@ dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
|
|||
}
|
||||
|
||||
void
|
||||
dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
|
||||
dns_zone_setoption(dns_zone_t *zone, unsigned int option,
|
||||
isc_boolean_t value)
|
||||
{
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
|
|
@ -4998,14 +5034,34 @@ dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
|
|||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setoption2(dns_zone_t *zone, unsigned int option,
|
||||
isc_boolean_t value)
|
||||
{
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
if (value)
|
||||
zone->options2 |= option;
|
||||
else
|
||||
zone->options2 &= ~option;
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dns_zone_getoptions(dns_zone_t *zone) {
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return (zone->options);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dns_zone_getoptions2(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return (zone->options2);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/ttl.h>
|
||||
#include <dns/result.h>
|
||||
|
||||
#include <isccfg/cfg.h>
|
||||
#include <isccfg/grammar.h>
|
||||
#include <isccfg/log.h>
|
||||
|
|
@ -111,6 +114,7 @@ static cfg_type_t cfg_type_logging;
|
|||
static cfg_type_t cfg_type_logseverity;
|
||||
static cfg_type_t cfg_type_lwres;
|
||||
static cfg_type_t cfg_type_masterselement;
|
||||
static cfg_type_t cfg_type_maxttl;
|
||||
static cfg_type_t cfg_type_nameportiplist;
|
||||
static cfg_type_t cfg_type_negated;
|
||||
static cfg_type_t cfg_type_notifytype;
|
||||
|
|
@ -1641,6 +1645,7 @@ zone_clauses[] = {
|
|||
{ "max-transfer-idle-out", &cfg_type_uint32, 0 },
|
||||
{ "max-transfer-time-in", &cfg_type_uint32, 0 },
|
||||
{ "max-transfer-time-out", &cfg_type_uint32, 0 },
|
||||
{ "max-zone-ttl", &cfg_type_maxttl, 0 },
|
||||
{ "min-refresh-time", &cfg_type_uint32, 0 },
|
||||
{ "min-retry-time", &cfg_type_uint32, 0 },
|
||||
{ "multi-master", &cfg_type_boolean, 0 },
|
||||
|
|
@ -3155,3 +3160,55 @@ static cfg_type_t cfg_type_masterselement = {
|
|||
"masters_element", parse_masterselement, NULL,
|
||||
doc_masterselement, NULL, NULL
|
||||
};
|
||||
|
||||
static isc_result_t
|
||||
parse_maxttlval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
isc_uint32_t ttl;
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
if (pctx->token.type != isc_tokentype_string) {
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_ttl_fromtext(&pctx->token.value.as_textregion, &ttl);
|
||||
if (result == ISC_R_RANGE ) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR, "TTL out of range ");
|
||||
return (result);
|
||||
} else if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj));
|
||||
obj->value.uint32 = ttl;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit");
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
* A size value (number + optional unit).
|
||||
*/
|
||||
static cfg_type_t cfg_type_maxttlval = {
|
||||
"maxttlval", parse_maxttlval, cfg_print_uint64, cfg_doc_terminal,
|
||||
&cfg_rep_uint64, NULL };
|
||||
|
||||
static isc_result_t
|
||||
parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
return (parse_enum_or_other(pctx, type, &cfg_type_maxttlval, ret));
|
||||
}
|
||||
|
||||
/*%
|
||||
* A size or "unlimited", but not "default".
|
||||
*/
|
||||
static const char *maxttl_enums[] = { "unlimited", NULL };
|
||||
static cfg_type_t cfg_type_maxttl = {
|
||||
"maxttl_no_default", parse_maxttl, cfg_print_ustring, cfg_doc_terminal,
|
||||
&cfg_rep_string, maxttl_enums
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue