* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.177.18.19 2006/02/21 23:53:34 marka Exp $ */
+/* $Id: dnssec-signzone.c,v 1.177.18.20 2006/04/13 18:09:46 dhankins Exp $ */
/*! \file */
#include <dns/rdatastruct.h>
#include <dns/rdatatype.h>
#include <dns/result.h>
+#include <dns/soa.h>
#include <dns/time.h>
#include <dst/dst.h>
#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0)
#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1)
+#define SOA_SERIAL_KEEP 0
+#define SOA_SERIAL_INCREMENT 1
+#define SOA_SERIAL_UNIXTIME 2
+
typedef struct signer_event sevent_t;
struct signer_event {
ISC_EVENT_COMMON(sevent_t);
static dns_name_t *dlv = NULL;
static dns_fixedname_t dlv_fixed;
static dns_master_style_t *dsstyle = NULL;
+static unsigned int serialformat = SOA_SERIAL_KEEP;
#define INCSTAT(counter) \
if (printstats) { \
return (ttl);
}
+/*%
+ * Increment (or set if nonzero) the SOA serial
+ */
+static isc_result_t
+setsoaserial(isc_uint32_t serial) {
+ isc_result_t result;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_uint32_t old_serial, new_serial;
+
+ result = dns_db_getoriginnode(gdb, &node);
+ if (result != ISC_R_SUCCESS)
+ return result;
+
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_findrdataset(gdb, node, gversion,
+ dns_rdatatype_soa, 0,
+ 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_rdataset_first(&rdataset);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ dns_rdataset_current(&rdataset, &rdata);
+
+ old_serial = dns_soa_getserial(&rdata);
+
+ if (serial) {
+ /* Set SOA serial to the value provided. */
+ new_serial = serial;
+ } else {
+ /* Increment SOA serial using RFC 1982 arithmetics */
+ new_serial = (old_serial + 1) & 0xFFFFFFFF;
+ if (new_serial == 0)
+ new_serial = 1;
+ }
+
+ /* If the new serial is not likely to cause a zone transfer
+ * (a/ixfr) from servers having the old serial, warn the user.
+ *
+ * RFC1982 section 7 defines the maximum increment to be
+ * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single
+ * comparison. (5 - 6 == (2^32)-1, not negative-one)
+ */
+ if (new_serial == old_serial ||
+ (new_serial - old_serial) > 0x7fffffffU)
+ fprintf(stderr, "%s: warning: Serial number not advanced, "
+ "zone may not transfer\n", program);
+
+ dns_soa_setserial(new_serial, &rdata);
+
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ dns_rdatatype_soa, 0);
+ check_result(result, "dns_db_deleterdataset");
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_db_addrdataset(gdb, node, gversion,
+ 0, &rdataset, 0, NULL);
+ check_result(result, "dns_db_addrdataset");
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(gdb, &node);
+ dns_rdata_reset(&rdata);
+
+ return (result);
+}
+
/*%
* Delete any RRSIG records at a node.
*/
fprintf(stderr, "\t\tfile format of input zonefile (text)\n");
fprintf(stderr, "\t-O format:\n");
fprintf(stderr, "\t\tfile format of signed zone file (text)\n");
+ fprintf(stderr, "\t-N format:\n");
+ fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n");
fprintf(stderr, "\t-r randomdev:\n");
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
char *startstr = NULL, *endstr = NULL, *classname = NULL;
char *origin = NULL, *file = NULL, *output = NULL;
char *inputformatstr = NULL, *outputformatstr = NULL;
+ char *serialformatstr = NULL;
char *dskeyfile[MAXDSKEYS];
int ndskeys = 0;
char *endp;
dns_result_register();
while ((ch = isc_commandline_parse(argc, argv,
- "ac:d:e:f:ghi:I:j:k:l:n:o:O:pr:s:Stv:z"))
+ "ac:d:e:f:ghi:I:j:k:l:n:N:o:O:pr:s:Stv:z"))
!= -1) {
switch (ch) {
case 'a':
fatal("number of cpus must be numeric");
break;
+ case 'N':
+ serialformatstr = isc_commandline_argument;
+ break;
+
case 'o':
origin = isc_commandline_argument;
break;
fatal("unknown file format: %s\n", outputformatstr);
}
+ if (serialformatstr != NULL) {
+ if (strcasecmp(serialformatstr, "keep") == 0)
+ serialformat = SOA_SERIAL_KEEP;
+ else if (strcasecmp(serialformatstr, "increment") == 0 ||
+ strcasecmp(serialformatstr, "incr") == 0)
+ serialformat = SOA_SERIAL_INCREMENT;
+ else if (strcasecmp(serialformatstr, "unixtime") == 0)
+ serialformat = SOA_SERIAL_UNIXTIME;
+ else
+ fatal("unknown soa serial format: %s\n", serialformatstr);
+ }
+
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
0, 24, 0, 0, 0, 8, mctx);
check_result(result, "dns_master_stylecreate");
result = dns_db_newversion(gdb, &gversion);
check_result(result, "dns_db_newversion()");
+ switch (serialformat) {
+ case SOA_SERIAL_INCREMENT:
+ setsoaserial(0);
+ break;
+ case SOA_SERIAL_UNIXTIME:
+ setsoaserial(now);
+ break;
+ case SOA_SERIAL_KEEP:
+ default:
+ /* do nothing */
+ break;
+ }
+
nsecify();
if (!nokeys) {
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.10.18.10 2005/07/19 05:55:43 marka Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.10.18.11 2006/04/13 18:09:46 dhankins Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
<date>June 30, 2000</date>
<refmeta>
<refentrytitle><application>dnssec-signzone</application></refentrytitle>
- <manvolnum>8</manvolnum>
+ <manvolnum>8</manvolnum>
<refmiscinfo>BIND9</refmiscinfo>
</refmeta>
<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>
- <arg><option>-n <replaceable class="parameter">nthreads</replaceable></option></arg>
+ <arg><option>-N <replaceable class="parameter">soa-serial-format</replaceable></option></arg>
<arg><option>-o <replaceable class="parameter">origin</replaceable></option></arg>
<arg><option>-O <replaceable class="parameter">output-format</replaceable></option></arg>
<arg><option>-p</option></arg>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>-N <replaceable class="parameter">soa-serial-format</replaceable></term>
+ <listitem>
+ <para>
+ The SOA serial number format of the signed zone.
+ Possible formats are <command>"keep"</command> (default),
+ <command>"increment"</commmand> and
+ <command>"unixtime"</command>.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><command>"keep"</command></term>
+ <listitem>
+ <para>Do not modify the SOA serial number.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>"increment"</command></term>
+ <listitem>
+ <para>Increment the SOA serial number using RFC 1982
+ arithmetics.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>"unixtime"</command></term>
+ <listitem>
+ <para>Set the SOA serial number to the number of seconds
+ since epoch.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>-o <replaceable class="parameter">origin</replaceable></term>
<listitem>