mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
1190. [func] Add the "rndc freeze" and"rndc unfreeze" commands.
[RT #2394] Basically, "freeze" disables dynamic updates to a zone, syncs the journal file into the master file, and removes the journal. This allows manual edits of a dynamic zone file without stopping the server, since the zone is temporarily considered non-dynamic. "unfreeze" re-enables dynamic updates to a zone. So, instead of the old: rndc stop edit master file remove journal restart server you can now do: rndc freeze zone edit master file rndc reload zone rndc unfreeze zone which doesn't require stopping the server. About everyone here at the secure dynamic update workshop wanted this. It will be documented soon.
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
||||
1190. [func] Add the "rndc freeze" and"rndc unfreeze" commands.
|
||||
[RT #2394]
|
||||
|
||||
1189. [bug] On some systems, malloc(0) returns NULL, which
|
||||
could cause the caller to report an out of memory
|
||||
error. [RT #2398]
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: control.c,v 1.10 2001/12/01 00:34:22 marka Exp $ */
|
||||
/* $Id: control.c,v 1.11 2002/01/22 22:05:46 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -117,6 +117,10 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
|
||||
result = ns_server_flushname(ns_g_server, command);
|
||||
} else if (command_compare(command, NS_COMMAND_STATUS)) {
|
||||
result = ns_server_status(ns_g_server, text);
|
||||
} else if (command_compare(command, NS_COMMAND_FREEZE)) {
|
||||
result = ns_server_freeze(ns_g_server, ISC_TRUE, command);
|
||||
} else if (command_compare(command, NS_COMMAND_UNFREEZE)) {
|
||||
result = ns_server_freeze(ns_g_server, ISC_FALSE, command);
|
||||
} else {
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: control.h,v 1.8 2001/11/27 04:06:10 marka Exp $ */
|
||||
/* $Id: control.h,v 1.9 2002/01/22 22:05:51 bwelling Exp $ */
|
||||
|
||||
#ifndef NAMED_CONTROL_H
|
||||
#define NAMED_CONTROL_H 1
|
||||
@@ -45,6 +45,8 @@
|
||||
#define NS_COMMAND_FLUSH "flush"
|
||||
#define NS_COMMAND_FLUSHNAME "flushname"
|
||||
#define NS_COMMAND_STATUS "status"
|
||||
#define NS_COMMAND_FREEZE "freeze"
|
||||
#define NS_COMMAND_UNFREEZE "unfreeze"
|
||||
|
||||
isc_result_t
|
||||
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.h,v 1.63 2001/11/27 04:06:11 marka Exp $ */
|
||||
/* $Id: server.h,v 1.64 2002/01/22 22:05:52 bwelling Exp $ */
|
||||
|
||||
#ifndef NAMED_SERVER_H
|
||||
#define NAMED_SERVER_H 1
|
||||
@@ -185,4 +185,10 @@ ns_server_flushname(ns_server_t *server, char *args);
|
||||
isc_result_t
|
||||
ns_server_status(ns_server_t *server, isc_buffer_t *text);
|
||||
|
||||
/*
|
||||
* Enable or disable updates for a zone.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args);
|
||||
|
||||
#endif /* NAMED_SERVER_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.c,v 1.367 2002/01/04 02:32:04 gson Exp $ */
|
||||
/* $Id: server.c,v 1.368 2002/01/22 22:05:48 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -2841,3 +2841,63 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
|
||||
isc_buffer_add(text, n);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Act on a "freeze" or "unfreeze" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zonetype_t type;
|
||||
char classstr[DNS_RDATACLASS_FORMATSIZE];
|
||||
char zonename[DNS_NAME_FORMATSIZE];
|
||||
dns_view_t *view;
|
||||
char *journal;
|
||||
const char *vname, *sep;
|
||||
|
||||
result = zone_from_args(server, args, &zone);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (zone == NULL)
|
||||
return (ISC_R_UNEXPECTEDEND);
|
||||
type = dns_zone_gettype(zone);
|
||||
if (type != dns_zone_master) {
|
||||
dns_zone_detach(&zone);
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
if (freeze) {
|
||||
result = dns_zone_flush(zone);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
journal = dns_zone_getjournal(zone);
|
||||
if (journal != NULL)
|
||||
(void)isc_file_remove(journal);
|
||||
}
|
||||
}
|
||||
if (result == ISC_R_SUCCESS)
|
||||
dns_zone_setupdatedisabled(zone, freeze);
|
||||
|
||||
view = dns_zone_getview(zone);
|
||||
if (strcmp(view->name, "_bind") == 0 ||
|
||||
strcmp(view->name, "_default") == 0)
|
||||
{
|
||||
vname = "";
|
||||
sep = "";
|
||||
} else {
|
||||
vname = view->name;
|
||||
sep = " ";
|
||||
}
|
||||
dns_rdataclass_format(dns_zone_getclass(zone), classstr,
|
||||
sizeof(classstr));
|
||||
dns_name_format(dns_zone_getorigin(zone),
|
||||
zonename, sizeof(zonename));
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
"%s zone '%s/%s'%s%s: %s",
|
||||
freeze ? "freezing" : "unfreezing",
|
||||
zonename, classstr, sep, vname,
|
||||
isc_result_totext(result));
|
||||
dns_zone_detach(&zone);
|
||||
return (result);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: update.c,v 1.95 2002/01/22 21:45:07 gson Exp $ */
|
||||
/* $Id: update.c,v 1.96 2002/01/22 22:05:49 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -2163,6 +2163,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* Check Requestor's Permissions. It seems a bit silly to do this
|
||||
* only after prerequisite testing, but that is what RFC2136 says.
|
||||
*/
|
||||
if (dns_zone_getupdatedisabled(zone))
|
||||
FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled");
|
||||
if (ssutable == NULL) {
|
||||
char msg[DNS_RDATACLASS_FORMATSIZE + DNS_NAME_FORMATSIZE
|
||||
+ sizeof("update '/'")];
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.h,v 1.110 2002/01/22 21:52:32 gson Exp $ */
|
||||
/* $Id: zone.h,v 1.111 2002/01/22 22:05:56 bwelling Exp $ */
|
||||
|
||||
#ifndef DNS_ZONE_H
|
||||
#define DNS_ZONE_H 1
|
||||
@@ -758,6 +758,12 @@ dns_zone_clearxfracl(dns_zone_t *zone);
|
||||
* 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_zone_getupdatedisabled(dns_zone_t *zone);
|
||||
|
||||
void
|
||||
dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state);
|
||||
|
||||
void
|
||||
dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity);
|
||||
/*
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.359 2002/01/21 11:00:20 bwelling Exp $ */
|
||||
/* $Id: zone.c,v 1.360 2002/01/22 22:05:53 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -185,6 +185,7 @@ struct dns_zone {
|
||||
dns_acl_t *notify_acl;
|
||||
dns_acl_t *query_acl;
|
||||
dns_acl_t *xfr_acl;
|
||||
isc_boolean_t update_disabled;
|
||||
dns_severity_t check_names;
|
||||
ISC_LIST(dns_notify_t) notifies;
|
||||
dns_request_t *request;
|
||||
@@ -537,6 +538,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
||||
zone->notify_acl = NULL;
|
||||
zone->query_acl = NULL;
|
||||
zone->xfr_acl = NULL;
|
||||
zone->update_disabled = ISC_FALSE;
|
||||
zone->check_names = dns_severity_ignore;
|
||||
zone->request = NULL;
|
||||
zone->lctx = NULL;
|
||||
@@ -908,8 +910,8 @@ zone_isdynamic(dns_zone_t *zone) {
|
||||
|
||||
return (ISC_TF(zone->type == dns_zone_slave ||
|
||||
zone->type == dns_zone_stub ||
|
||||
zone->ssutable != NULL ||
|
||||
(zone->update_acl != NULL &&
|
||||
(!zone->update_disabled && zone->ssutable != NULL) ||
|
||||
(!zone->update_disabled && zone->update_acl != NULL &&
|
||||
! (zone->update_acl->length == 1 &&
|
||||
zone->update_acl->elements[0].negative == ISC_TRUE
|
||||
&&
|
||||
@@ -4469,6 +4471,19 @@ dns_zone_clearxfracl(dns_zone_t *zone) {
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_zone_getupdatedisabled(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
return (zone->update_disabled);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->update_disabled = state;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
|
||||
|
||||
|
Reference in New Issue
Block a user