]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix view's zones reverting bug during reconfiguration
authorAram Sargsyan <aram@isc.org>
Wed, 1 Mar 2023 12:30:46 +0000 (12:30 +0000)
committerAram Sargsyan <aram@isc.org>
Wed, 1 Mar 2023 15:40:33 +0000 (15:40 +0000)
During reconfiguration, the configure_view() function reverts the
configured zones to the previous view in case if there is an error.

It uses the 'zones_configured' boolean variable to decide whether
it is required to revert the zones, i.e. the error happened after
all the zones were successfully configured.

The problem is that it does not account for the case when an error
happens during the configuration of one of the zones (not the first),
in which case there are zones that are already configured for the
new view (and they need to be reverted), and there are zones that
are not (starting from the failed one).

Since 'zones_configured' remains 'false', the configured zones are
not reverted.

Replace the 'zones_configured' variable with a pointer to the latest
successfully configured zone configuration element, and when reverting,
revert up to and including that zone.

(cherry picked from commit 84c235a4b0477a34c0ac2054af98b39efc5b0df5)

bin/named/server.c

index 6b6f020017cb83fecf7f9cab3d88b01e44cea1ed..dd4d017d7dda366efdc1a9ca656a5ade37c88fb1 100644 (file)
@@ -4074,7 +4074,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        const cfg_obj_t *dyndb_list, *plugin_list;
        const cfg_obj_t *disabled;
        const cfg_obj_t *obj, *obj2;
-       const cfg_listelt_t *element;
+       const cfg_listelt_t *element = NULL;
+       const cfg_listelt_t *zone_element_latest = NULL;
        in_port_t port;
        dns_cache_t *cache = NULL;
        isc_result_t result;
@@ -4092,7 +4093,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        dns_dispatch_t *dispatch6 = NULL;
        bool rpz_configured = false;
        bool catz_configured = false;
-       bool zones_configured = false;
        bool shared_cache = false;
        int i = 0, j = 0, k = 0;
        const char *str;
@@ -4203,8 +4203,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
                                     viewlist, kasplist, actx, false,
                                     old_rpz_ok, false));
+               zone_element_latest = element;
        }
-       zones_configured = true;
 
        /*
         * Check that a primary or secondary zone was found for each
@@ -6075,7 +6075,7 @@ cleanup:
                        dns_view_detach(&pview);
                }
 
-               if (zones_configured) {
+               if (zone_element_latest != NULL) {
                        for (element = cfg_list_first(zonelist);
                             element != NULL; element = cfg_list_next(element))
                        {
@@ -6083,6 +6083,13 @@ cleanup:
                                        cfg_listelt_value(element);
                                configure_zone_setviewcommit(result, zconfig,
                                                             view);
+                               if (element == zone_element_latest) {
+                                       /*
+                                        * This was the latest element that was
+                                        * successfully configured earlier.
+                                        */
+                                       break;
+                               }
                        }
                }
        }