/* See if we can re-use an existing keydata zone. */
result = dns_viewlist_find(&named_g_server->viewlist,
- view->name, view->rdclass,
- &pview);
- if (result != ISC_R_NOTFOUND &&
- result != ISC_R_SUCCESS)
+ view->name, view->rdclass, &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) {
return (result);
+ }
+
+ if (pview != NULL) {
+ if (pview->managed_keys != NULL) {
+ dns_zone_synckeyzone(pview->managed_keys);
+ dns_zone_attach(pview->managed_keys,
+ &view->managed_keys);
+ dns_zone_setview(pview->managed_keys, view);
+ dns_view_detach(&pview);
+ return (ISC_R_SUCCESS);
+ }
- if (pview != NULL && pview->managed_keys != NULL) {
- dns_zone_attach(pview->managed_keys, &view->managed_keys);
- dns_zone_setview(pview->managed_keys, view);
dns_view_detach(&pview);
- dns_zone_synckeyzone(view->managed_keys);
- return (ISC_R_SUCCESS);
}
/* No existing keydata zone was found; create one */
dns_zone_setstats(zone, named_g_server->zonestats);
CHECK(setquerystats(zone, mctx, dns_zonestat_none));
- if (view->managed_keys != NULL)
+ if (view->managed_keys != NULL) {
dns_zone_detach(&view->managed_keys);
+ }
dns_zone_attach(zone, &view->managed_keys);
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
view->name, filename);
cleanup:
- if (zone != NULL)
+ if (zone != NULL) {
dns_zone_detach(&zone);
- if (none != NULL)
+ }
+ if (none != NULL) {
dns_acl_detach(&none);
+ }
return (result);
}
&named_g_addparser),
"creating additional configuration parser");
- CHECKFATAL(load_configuration(named_g_conffile, server,
- ISC_TRUE),
+ CHECKFATAL(load_configuration(named_g_conffile, server, ISC_TRUE),
"loading configuration");
isc_hash_init();
return (result);
}
+static isc_result_t
+mkey_destroy(named_server_t *server, dns_view_t *view, isc_buffer_t **text) {
+ isc_result_t result;
+ char msg[DNS_NAME_FORMATSIZE + 500] = "";
+ isc_boolean_t exclusive = ISC_FALSE;
+ const char *file = NULL;
+ dns_db_t *dbp = NULL;
+ dns_zone_t *mkzone = NULL;
+ isc_boolean_t removed = ISC_FALSE;
+
+ if (view->managed_keys == NULL) {
+ CHECK(ISC_R_NOTFOUND);
+ }
+
+ snprintf(msg, sizeof(msg),
+ "destroying managed-keys database for '%s'", view->name);
+ CHECK(putstr(text, msg));
+
+ result = isc_task_beginexclusive(server->task);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ exclusive = ISC_TRUE;
+
+ /* Remove and clean up managed keys zone from view */
+ mkzone = view->managed_keys;
+ view->managed_keys = NULL;
+ (void)dns_zone_flush(mkzone);
+
+ /* Unload zone database */
+ if (dns_zone_getdb(mkzone, &dbp) == ISC_R_SUCCESS) {
+ dns_db_detach(&dbp);
+ dns_zone_unload(mkzone);
+ }
+
+ /* Delete files */
+ file = dns_zone_getfile(mkzone);
+ result = isc_file_remove(file);
+ if (result == ISC_R_SUCCESS) {
+ removed = ISC_TRUE;
+ } else {
+ isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
+ NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "file %s not removed: %s",
+ file, isc_result_totext(result));
+ }
+
+ file = dns_zone_getjournal(mkzone);
+ result = isc_file_remove(file);
+ if (result == ISC_R_SUCCESS) {
+ removed = ISC_TRUE;
+ } else {
+ isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
+ NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "file %s not removed: %s",
+ file, isc_result_totext(result));
+ }
+
+ if (!removed) {
+ CHECK(putstr(text, "error: no files could be removed"));
+ CHECK(ISC_R_FAILURE);
+ }
+
+ dns_zone_detach(&mkzone);
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (exclusive) {
+ isc_task_endexclusive(server->task);
+ }
+ return (result);
+}
+
+
static isc_result_t
mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
dns_view_t *view = NULL;
dns_rdataclass_t rdclass;
char msg[DNS_NAME_FORMATSIZE + 500] = "";
- enum { NONE, STATUS, REFRESH, SYNC } opt = NONE;
+ enum { NONE, STATUS, REFRESH, SYNC, DESTROY } opt = NONE;
isc_boolean_t found = ISC_FALSE;
isc_boolean_t first = ISC_TRUE;
/* Skip rndc command name */
cmd = next_token(lex, text);
- if (cmd == NULL)
+ if (cmd == NULL) {
return (ISC_R_UNEXPECTEDEND);
+ }
/* Get managed-keys subcommand */
cmd = next_token(lex, text);
- if (cmd == NULL)
+ if (cmd == NULL) {
return (ISC_R_UNEXPECTEDEND);
+ }
- if (strcasecmp(cmd, "status") == 0)
+ if (strcasecmp(cmd, "status") == 0) {
opt = STATUS;
- else if (strcasecmp(cmd, "refresh") == 0)
+ } else if (strcasecmp(cmd, "refresh") == 0) {
opt = REFRESH;
- else if (strcasecmp(cmd, "sync") == 0)
+ } else if (strcasecmp(cmd, "sync") == 0) {
opt = SYNC;
- else {
+ } else if (strcasecmp(cmd, "destroy") == 0) {
+ opt = DESTROY;
+ } else {
snprintf(msg, sizeof(msg), "unknown command '%s'", cmd);
(void) putstr(text, msg);
result = ISC_R_UNEXPECTED;
if (viewtxt != NULL &&
(rdclass != view->rdclass ||
strcmp(view->name, viewtxt) != 0))
+ {
continue;
+ }
if (view->managed_keys == NULL) {
if (viewtxt != NULL) {
"view '%s': no managed keys", viewtxt);
CHECK(putstr(text, msg));
goto cleanup;
- } else
+ } else {
continue;
+ }
}
found = ISC_TRUE;
CHECK(mkey_refresh(view, text));
break;
case STATUS:
- if (!first)
+ if (!first) {
CHECK(putstr(text, "\n\n"));
+ }
CHECK(mkey_status(view, text));
first = ISC_FALSE;
break;
case SYNC:
CHECK(dns_zone_flush(view->managed_keys));
break;
+ case DESTROY:
+ CHECK(mkey_destroy(server, view, text));
+ break;
default:
INSIST(0);
}
- if (viewtxt != NULL)
+ if (viewtxt != NULL) {
break;
+ }
}
- if (!found)
+ if (!found) {
CHECK(putstr(text, "no views with managed keys"));
+ }
cleanup:
- if (isc_buffer_usedlength(*text) > 0)
+ if (isc_buffer_usedlength(*text) > 0) {
(void) putnull(text);
+ }
return (result);
}
</varlistentry>
<varlistentry>
- <term><userinput>managed-keys <replaceable>(status | refresh | sync)</replaceable> <optional><replaceable>class</replaceable> <optional><replaceable>view</replaceable></optional></optional></userinput></term>
+ <term><userinput>managed-keys <replaceable>(status | refresh | sync | destroy)</replaceable> <optional><replaceable>class</replaceable> <optional><replaceable>view</replaceable></optional></optional></userinput></term>
<listitem>
<para>
- When run with the "status" keyword, print the current
- status of the managed-keys database for the specified
- view, or for all views if none is specified. When run
- with the "refresh" keyword, force an immediate refresh
- of all the managed-keys in the specified view, or all
- views. When run with the "sync" keyword, force an
- immediate dump of the managed-keys database to disk (in
- the file <filename>managed-keys.bind</filename> or
- (<filename><replaceable>viewname</replaceable>.mkeys</filename>).
+ Inspect and control the "managed-keys" database which
+ handles RFC 5011 DNSSEC trust anchor maintenance. If a view
+ is specified, these commands are applied to that view;
+ otherwise they are applied to all views.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ When run with the <literal>status</literal> keyword, prints
+ the current status of the managed-keys database.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When run with the <literal>refresh</literal> keyword,
+ forces an immediate refresh query to be sent for all
+ the managed keys, updating the managed-keys database
+ if any new keys are found, without waiting the normal
+ refresh interval.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When run with the <literal>sync</literal> keyword, forces an
+ immediate dump of the managed-keys database to disk
+ (in the file <filename>managed-keys.bind</filename> or
+ (<filename><replaceable>viewname</replaceable>.mkeys</filename>).
+ This synchronizes the database with its journal file, so
+ that the database's current contents can be inspected
+ visually.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When run with the <literal>destroy</literal> keyword, the
+ managed-keys database is shut down and deleted, and all key
+ maintenance is terminated. This command should be used only
+ with extreme caution.
+ </para>
+ <para>
+ Existing keys that are already trusted are not deleted
+ from memory; DNSSEC validation can continue after this
+ command is used. However, key maintenance operations will
+ cease until <command>named</command> is restarted or
+ reconfigured, and all existing key maintenance state
+ will be deleted.
+ </para>
+ <para>
+ Running <command>rndc reconfig>/command> or restarting
+ <command>named</command> immediately after this command
+ will cause key maintenance to be reinitialized from scratch,
+ just as if the server were being started for the first time.
+ This is primarily intended for testing, but it may also be
+ used, for example, to jumpstart the acquisition of new keys
+ in the event of a trust anchor rollover, or as a
+ brute-force repair for key maintenance problems.
+ </para>
+ </listitem>
+ </itemizedlist>
</para>
</listitem>
</varlistentry>