]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1190. [func] Add the "rndc freeze" and"rndc unfreeze" commands.
authorBrian Wellington <source@isc.org>
Tue, 22 Jan 2002 22:05:59 +0000 (22:05 +0000)
committerBrian Wellington <source@isc.org>
Tue, 22 Jan 2002 22:05:59 +0000 (22:05 +0000)
[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.

CHANGES
bin/named/control.c
bin/named/include/named/control.h
bin/named/include/named/server.h
bin/named/server.c
bin/named/update.c
lib/dns/include/dns/zone.h
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 6797b52f2466b80a7aedc452b4626efb99907f61..b9688519d517aa81076be6025e2ada877c93f01b 100644 (file)
--- a/CHANGES
+++ b/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]
index b32005891b06d52caf3cfc159a2357350a260b36..2725a1cabcbd4faa2ecb12264c97d14ee5e768b6 100644 (file)
@@ -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,
index 9ff44a064bc4b7906b904144544062801fff3836..15678e5b19087298c47229753852a59a42679e43 100644 (file)
@@ -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);
index 7a1dd83c46ef66ea19dae0f21b2bd46e0e3ca2db..e5d0f475b3a738746d5a617e9845e3b6fe092eee 100644 (file)
@@ -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 */
index 487efa3f08d279a7c73d7d2f8a0926dff90eee65..20111acfa7f141030137393fc1bbc7e401513cb0 100644 (file)
@@ -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);
+}
index 0263d351eac773fe83c13f0f7f19bc22654bd1f1..2d1d0ffff48bbc38c9a64bf5b753f08dc431869e 100644 (file)
@@ -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 '/'")];
index 98f3a2d58ca7200ed071535b6b9d59f57a35ebbd..6cb8f96c832a46ccd8a34cd9799de9e0c9fbe592 100644 (file)
@@ -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);
 /*
index 96b7ab0c6d8cb7cef2e9fc13886584dd3056a584..b1f716e55eab89ab5aba84285181a5232888b597 100644 (file)
@@ -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) {