]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Process the 'version' record of the catalog zone first
authorAram Sargsyan <aram@isc.org>
Thu, 24 Mar 2022 20:24:00 +0000 (20:24 +0000)
committerAram Sargsyan <aram@isc.org>
Thu, 14 Apr 2022 10:56:24 +0000 (10:56 +0000)
When processing a new or updated catalog zone, the record datasets
from the database are being processed in order. This creates a
problem because we need to know the version of the catalog zone
schema to process some of the records differently, but we do not
know the version until the 'version' record gets processed.

Find the 'version' record and process it first, only then iterate over
the database to process the rest, making sure not to process the
'version' record twice.

lib/dns/catz.c

index 00540082c8e39be0bf9f32557a0b4c0f6e65ad96..20639e2256819a29b45883c26c79731abfcdcba5 100644 (file)
@@ -1819,12 +1819,14 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) {
        isc_result_t result;
        isc_region_t r;
        dns_dbnode_t *node = NULL;
+       const dns_dbnode_t *vers_node = NULL;
        dns_dbiterator_t *it = NULL;
        dns_fixedname_t fixname;
        dns_name_t *name;
        dns_rdatasetiter_t *rdsiter = NULL;
        dns_rdataset_t rdataset;
        char bname[DNS_NAME_FORMATSIZE];
+       bool is_vers_processed = false;
        uint32_t vers;
 
        REQUIRE(DNS_DB_VALID(db));
@@ -1884,16 +1886,38 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) {
        name = dns_fixedname_initname(&fixname);
 
        /*
-        * Iterate over database to fill the new zone.
+        * Take the version record to process first, because the other
+        * records might be processed differently depending on the version of
+        * the catalog zone's schema.
         */
-       result = dns_dbiterator_first(it);
+       result = dns_name_fromstring2(name, "version", &db->origin, 0, NULL);
        if (result != ISC_R_SUCCESS) {
+               dns_dbiterator_destroy(&it);
+               dns_catz_zone_detach(&newzone);
+               dns_db_closeversion(db, &oldzone->dbversion, false);
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
-                             "catz: failed to get db iterator - %s",
+                             "catz: failed to create name from string - %s",
                              isc_result_totext(result));
+               return;
+       }
+       result = dns_dbiterator_seek(it, name);
+       if (result != ISC_R_SUCCESS) {
+               dns_dbiterator_destroy(&it);
+               dns_catz_zone_detach(&newzone);
+               dns_db_closeversion(db, &oldzone->dbversion, false);
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+                             DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
+                             "catz: zone '%s' has no 'version' record (%s)",
+                             bname, isc_result_totext(result));
+               return;
        }
 
+       name = dns_fixedname_initname(&fixname);
+
+       /*
+        * Iterate over database to fill the new zone.
+        */
        while (result == ISC_R_SUCCESS) {
                result = dns_dbiterator_current(it, &node, name);
                if (result != ISC_R_SUCCESS) {
@@ -1904,6 +1928,16 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) {
                        break;
                }
 
+               if (!is_vers_processed) {
+                       /* Keep the version node to skip it later in the loop */
+                       vers_node = node;
+               } else if (node == vers_node) {
+                       /* Skip the already processed version node */
+                       dns_db_detachnode(db, &node);
+                       result = dns_dbiterator_next(it);
+                       continue;
+               }
+
                result = dns_db_allrdatasets(db, node, oldzone->dbversion, 0,
                                             &rdsiter);
                if (result != ISC_R_SUCCESS) {
@@ -1951,7 +1985,13 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) {
                dns_rdatasetiter_destroy(&rdsiter);
 
                dns_db_detachnode(db, &node);
-               result = dns_dbiterator_next(it);
+
+               if (!is_vers_processed) {
+                       is_vers_processed = true;
+                       result = dns_dbiterator_first(it);
+               } else {
+                       result = dns_dbiterator_next(it);
+               }
        }
 
        dns_dbiterator_destroy(&it);