Report information
The Basics
Id:
24903
Status:
resolved
Priority:
Medium/Medium
Queue:

People
Owner:
Nobody in particular
Cc:
AdminCc:

BugTracker
Version Fixed:
9.11.0
Version Found:
(no value)
Versions Affected:
(no value)
Versions Planned:
(no value)
Priority:
P2 Normal
Severity:
S2 Normal
CVSS Score:
(no value)
CVE ID:
(no value)
Component:
(no value)
Area:
feature

Dates
Created:Mon, 20 Jun 2011 17:41:11 -0400
Updated:Wed, 26 Jul 2017 01:57:37 -0400
Closed:Fri, 25 Apr 2014 16:59:56 -0400



This bug tracker is no longer active.

Please go to our Gitlab to submit issues (both feature requests and bug reports) for active projects maintained by Internet Systems Consortium (ISC).

Due to security and confidentiality requirements, full access is limited to the primary maintainers.

Subject: date-format serial numbers (YYYYMMDDNN)
Date: Mon, 20 Jun 2011 21:41:08 +0000
To: bind-suggest@isc.org
From: Evan Hunt <each@isc.org>
dnssec-signzone can generate a serial number in "unixtime" format (number of seconds since UNIX epoch). In RT #23849 we're adding this ability to named for DDNS updates as well. But neither one can generate serial numbers in the human-readable date format that's in common use: YYYYMMDDNN (where the Ys represent a four-digit year, Ms a two-digit month, Ds a two-digit day, and Ns a two-digit intraday serial number). That's a feature I've wanted for a long time, and I think it would be used by quite a few people if it were an option. Essentially, the algorithm would be: if (year * 1000000 + month * 10000 + day * 100 > current_serial + 1) serial = year * 1000000 + month * 10000 + day * 100; else serial = current_serial + 1; (Note: The above assumes serial-number arithmetic is used for the comparison.) If the zone was updated more than one hundred times in a day, then the serial number would just have to be incremented by one; this could result in the date as depicted in the serial number being "wrong", but would be otherwise harmless.
Subject: [PATCH] Date-format serial numbers
Date: Thu, 17 Apr 2014 05:41:44 +0000
To: "bind-bugs@isc.org" <bind-bugs@isc.org>
From: Bradley Forschinger <u5269257@anu.edu.au>
Hi, Here's a patch to allow YYYYMMDDVV-style serial numbers in the SOA. I'm not sure whether "Outlook Web App" will clobber my e-mail, so I'll also send it as an attachment. Regards, Brad CHANGES | 2 bin/named/zoneconf.c | 3 + bin/tests/system/nsupdate/clean.sh | 2 bin/tests/system/nsupdate/ns1/named.conf | 9 +++ bin/tests/system/nsupdate/setup.sh | 1 bin/tests/system/nsupdate/tests.sh | 16 ++++++ lib/dns/include/dns/types.h | 6 +- lib/dns/tests/update_test.c | 72 +++++++++++++++++++++++++++++++ lib/dns/update.c | 31 +++++++++++++ lib/isccfg/namedconf.c | 3 - 10 files changed, 140 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index ce4687f..d64eee2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3810. [func] Date-format serial numbers. [RT #24903] + 3809. [doc] Fix SIT and NSID documentation. 3808. [doc] Clean up "prefetch" documentation. [RT #35751] diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 3849399..a3dca45 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -1576,6 +1576,9 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0) dns_zone_setserialupdatemethod(zone, dns_updatemethod_unixtime); + else if (strcasecmp(cfg_obj_asstring(obj), "yyyymmddvv") == 0) + dns_zone_setserialupdatemethod(zone, + dns_updatemethod_yyyymmddvv); else dns_zone_setserialupdatemethod(zone, dns_updatemethod_increment); diff --git a/bin/tests/system/nsupdate/clean.sh b/bin/tests/system/nsupdate/clean.sh index aaefc02..424cdf4 100644 --- a/bin/tests/system/nsupdate/clean.sh +++ b/bin/tests/system/nsupdate/clean.sh @@ -20,7 +20,7 @@ # rm -f ns1/*.jnl ns2/*.jnl -rm -f ns1/example.db ns1/unixtime.db ns1/update.db ns1/other.db ns1/keytests.db +rm -f ns1/example.db ns1/unixtime.db ns1/yyyymmddvv.db ns1/update.db ns1/other.db ns1/keytests.db rm -f ns1/md5.key ns1/sha1.key ns1/sha224.key ns1/sha256.key ns1/sha384.key rm -f ns1/sha512.key ns1/ddns.key rm -f nsupdate.out diff --git a/bin/tests/system/nsupdate/ns1/named.conf b/bin/tests/system/nsupdate/ns1/named.conf index df99040..40afbe8 100644 --- a/bin/tests/system/nsupdate/ns1/named.conf +++ b/bin/tests/system/nsupdate/ns1/named.conf @@ -99,6 +99,15 @@ zone "unixtime.nil" { serial-update-method unixtime; }; +zone "yyyymmddvv.nil" { + type master; + file "yyyymmddvv.db"; + check-integrity no; + allow-update { any; }; + allow-transfer { any; }; + serial-update-method yyyymmddvv; +}; + include "md5.key"; include "sha1.key"; include "sha224.key"; diff --git a/bin/tests/system/nsupdate/setup.sh b/bin/tests/system/nsupdate/setup.sh index 31d1562..97c24f3 100644 --- a/bin/tests/system/nsupdate/setup.sh +++ b/bin/tests/system/nsupdate/setup.sh @@ -31,6 +31,7 @@ rm -f ns3/example.db.jnl cp -f ns1/example1.db ns1/example.db sed 's/example.nil/other.nil/g' ns1/example1.db > ns1/other.db sed 's/example.nil/unixtime.nil/g' ns1/example1.db > ns1/unixtime.db +sed 's/example.nil/yyyymmddvv.nil/g' ns1/example1.db > ns1/yyyymmddvv.db sed 's/example.nil/keytests.nil/g' ns1/example1.db > ns1/keytests.db cp -f ns3/example.db.in ns3/example.db diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 6a7b7b0..25d8659 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -581,5 +581,21 @@ if [ $ret -ne 0 ]; then status=1 fi +n=`expr $n + 1` +echo "I:check that yyyymmddvv serial number is correctly generated ($n)" +oldserial=`$DIG +short yyyymmddvv.nil. soa @10.53.0.1 -p 5300 | awk '{print $3}'` || ret=1 +$NSUPDATE <<END > /dev/null 2>&1 || ret=1 + server 10.53.0.1 5300 + ttl 600 + update add new.yyyymmddvv.nil in a 1.2.3.4 + send +END +now=`$PERL -e '@lt=localtime(); printf "%.4d%.2d%2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];'` +sleep 1 +serial=`$DIG +short yyyymmddvv.nil. soa @10.53.0.1 -p 5300 | awk '{print $3}'` || ret=1 +[ "$oldserial" -ne "$serial" ] || ret=1 +[ "$serial" -eq "$now" ] || ret=1 +[ $ret = 0 ] || { echo I:failed; status=1; } + echo "I:exit status: $status" exit $status diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 7324a97..40632bc 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -347,12 +347,12 @@ typedef enum { * \li _increment: Add one to the current serial, skipping 0. * \li _unixtime: Set to the seconds since 00:00 Jan 1, 1970, * if possible. - * \li _yyyymmvv: Set to Year, Month, Version, if possible. - * (Not yet implemented) + * \li _yyyymmddvv: Set to Year, Month, Day, Version */ typedef enum { dns_updatemethod_increment = 0, - dns_updatemethod_unixtime + dns_updatemethod_unixtime, + dns_updatemethod_yyyymmddvv } dns_updatemethod_t; /* diff --git a/lib/dns/tests/update_test.c b/lib/dns/tests/update_test.c index f5fa7bf..3823aaa 100644 --- a/lib/dns/tests/update_test.c +++ b/lib/dns/tests/update_test.c @@ -256,6 +256,75 @@ ATF_TC_BODY(unixtime_zero, tc) { dns_test_end(); } +ATF_TC(past_to_yyyymmddvv); +ATF_TC_HEAD(past_to_yyyymmddvv, tc) { + atf_tc_set_md_var(tc, "descr", "past to yyyymmddvv"); +} +ATF_TC_BODY(past_to_yyyymmddvv, tc) { + isc_uint32_t old; + isc_uint32_t new; + isc_result_t result; + + UNUSED(tc); + + set_mystdtime(2014, 4, 17); + old = mystdtime - 86400; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + new = dns_update_soaserial(old, dns_updatemethod_yyyymmddvv); + ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); + ATF_CHECK(new != 0); + ATF_REQUIRE_EQ(new, 2014041700); + dns_test_end(); +} + +ATF_TC(now_to_yyyymmddvv); +ATF_TC_HEAD(now_to_yyyymmddvv, tc) { + atf_tc_set_md_var(tc, "descr", "now to yyyymmddvv"); +} +ATF_TC_BODY(now_to_yyyymmddvv, tc) { + isc_uint32_t old; + isc_uint32_t new; + isc_result_t result; + + UNUSED(tc); + + set_mystdtime(2014, 4, 17); + old = mystdtime; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + new = dns_update_soaserial(old, dns_updatemethod_yyyymmddvv); + ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); + ATF_CHECK(new != 0); + ATF_REQUIRE_EQ(new, 2014041701); + dns_test_end(); +} + +ATF_TC(future_to_yyyymmddvv); +ATF_TC_HEAD(future_to_yyyymmddvv, tc) { + atf_tc_set_md_var(tc, "descr", "future to yyyymmddvv"); +} +ATF_TC_BODY(future_to_yyyymmddvv, tc) { + isc_uint32_t old; + isc_uint32_t new; + isc_result_t result; + + UNUSED(tc); + + set_mystdtime(2014, 4, 17); + old = mystdtime + 86400; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + new = dns_update_soaserial(old, dns_updatemethod_yyyymmddvv); + ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); + ATF_CHECK(new != 0); + ATF_REQUIRE_EQ(new, 2014041800 + 1); + dns_test_end(); +} + /* * Main */ @@ -269,6 +338,9 @@ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, undefined_plus1_to_unix); ATF_TP_ADD_TC(tp, undefined_minus1_to_unix); ATF_TP_ADD_TC(tp, unixtime_zero); + ATF_TP_ADD_TC(tp, past_to_yyyymmddvv); + ATF_TP_ADD_TC(tp, now_to_yyyymmddvv); + ATF_TP_ADD_TC(tp, future_to_yyyymmddvv); return (atf_no_error()); } diff --git a/lib/dns/update.c b/lib/dns/update.c index e727c34..111f8d0 100644 --- a/lib/dns/update.c +++ b/lib/dns/update.c @@ -1846,6 +1846,29 @@ dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, return (result); } +static isc_stdtime_t +epoch_to_yyyymmdd(isc_stdtime_t J) { + isc_stdtime_t f, e, g, h, D, M, Y; + + /* + * Convert to JD + */ + J = 2440588 + (J / 86400); + + /* + * Unpack the serial into its year, month, and day components + */ + f = J + 1401 + (((4 * J + 274277) / 146097) * 3) / 4 - 38; + e = 4 * f + 3; + g = e % 1461 / 4; + h = 5 * g + 2; + D = (h % 153) / 5 + 1; + M = (h / 153 + 2) % 12 + 1; + Y = e / 1461 - 4716 + (12 + 2 - M) / 12; + + return (Y * 10000 + M * 100 + D); +} + isc_uint32_t dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method) { isc_stdtime_t now; @@ -1854,6 +1877,14 @@ dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method) { isc_stdtime_get(&now); if (now != 0 && isc_serial_gt(now, serial)) return (now); + } else if (method == dns_updatemethod_yyyymmddvv) { + isc_uint32_t new_serial; + + isc_stdtime_get(&now); + new_serial = epoch_to_yyyymmdd(now) * 100; + + if (new_serial != 0 && isc_serial_gt(new_serial, serial)) + return (new_serial); } /* RFC1982 */ diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 911612f..06e6feb 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -594,7 +594,8 @@ static cfg_type_t cfg_type_dnssecupdatemode = { &cfg_rep_string, &dnssecupdatemode_enums }; -static const char *updatemethods_enums[] = { "increment", "unixtime", NULL }; +static const char *updatemethods_enums[] = { + "increment", "unixtime", "yyyymmddvv", NULL }; static cfg_type_t cfg_type_updatemethod = { "updatemethod", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &updatemethods_enums

Message body not shown because it is not plain text.

CC: undisclosed-recipients: ;
Subject: Re: [ISC-Bugs #35793] [PATCH] Date-format serial numbers
Date: Thu, 17 Apr 2014 20:52:34 +0000
To: Bradley Forschinger via RT <bind9-bugs@isc.org>
From: Evan Hunt <each@isc.org>
Thank you Bradley! Quite well done, both in terms of style and completeness; I particular appreciate your adding both ATF and system tests. Things I changed during review: - the command syntax "yyyymmddvv" seemed likely to be hard to remember, so I just replaced it with "date". - the unit tests weren't quite effective as written: the "old" serial number was being set incorrectly as a unixtime value, so the "new" serial never came into conflict with it. changing to, for instance: /* future to date */ set_mystdtime(2014, 4, 2); old = dns_update_soaserial(0, dns_updatemethod_date); set_mystdtime(2014, 4, 1); ... enables the test to correctly check the behavior of a serial number going forward or backward in time. - the julian date converter you used in epoch_to_yyyymmdd() is nifty, but a) I'm not capable of evaluating its correctness and b) it's inconsistent with the way we've done similar conversions elsewhere in BIND, so I switched it to use gmtime(). - there was no documentation; I added a paragraph to doc/arm/Bv9ARM-book.xml