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 < /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