]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
external validation: dump files follow zonefile templating and storage path
authorLibor Peltan <libor.peltan@nic.cz>
Wed, 18 Jun 2025 10:41:09 +0000 (12:41 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Fri, 1 Aug 2025 15:31:18 +0000 (17:31 +0200)
src/knot/conf/conf.c
src/knot/conf/conf.h
src/knot/conf/schema.c
src/knot/updates/zone-update.c
tests/knot/test_conf.c

index bd52e397ecd73f50b14d478614bedb2eede271be..720c704c9af21d92b4d597410cc6e18ff6831a69 100644 (file)
@@ -1072,13 +1072,15 @@ static int str_label(
        return str_zone(label, buff, buff_len);
 }
 
-static char* get_filename(
+char *conf_get_filename_txn(
        conf_t *conf,
        knot_db_txn_t *txn,
        const knot_dname_t *zone,
        const char *name)
 {
-       assert(name);
+       if (name == NULL) {
+               return NULL;
+       }
 
        const char *end = name + strlen(name);
        char out[1024] = "";
@@ -1189,7 +1191,7 @@ char* conf_zonefile_txn(
                file = "%s.zone";
        }
 
-       return get_filename(conf, txn, zone, file);
+       return conf_get_filename_txn(conf, txn, zone, file);
 }
 
 char* conf_db_txn(
index a253ba171be94110ca4bc790dfc9cb9d8fb371e7..1de23c6f79636414e4a3ba0f08480c61c3a739da 100644 (file)
@@ -664,6 +664,30 @@ void conf_free_mod_id(
        conf_mod_id_t *mod_id
 );
 
+/*!
+ * Get the absolute path in zonefile-like manner for given name/template.
+ *
+ * \param[in] conf    Configuration.
+ * \param[in] txn     Configuration DB transaction.
+ * \param[in] zone    Zone name.
+ * \param[in] name    File name or template (like %s.zonediff).
+ *
+ * \return Absolute zone file path string pointer.
+ */
+char *conf_get_filename_txn(
+       conf_t *conf,
+       knot_db_txn_t *txn,
+       const knot_dname_t *zone,
+       const char *name
+);
+static inline char* conf_get_filename(
+       conf_t *conf,
+       const knot_dname_t *zone,
+       const char *name)
+{
+       return conf_get_filename_txn(conf, &conf->read_txn, zone, name);
+}
+
 /*!
  * Gets the absolute zone file path.
  *
index 7d5e52502fd27eef4011b3ff60d03dbb0d9e1128..5e80ab437574b93d64e89d9153bbf7cfdb64821f 100644 (file)
@@ -458,9 +458,9 @@ static const yp_item_t desc_policy[] = {
 static const yp_item_t desc_external[] = {
        { C_ID,                  YP_TSTR,  YP_VNONE, CONF_IO_FREF },
        { C_TIMEOUT,             YP_TINT,  YP_VINT = { 0, UINT32_MAX, 300, YP_STIME } },
-       { C_DUMP_NEW,            YP_TSTR,  YP_VSTR = { "" } },
-       { C_DUMP_REM,            YP_TSTR,  YP_VSTR = { "" } },
-       { C_DUMP_ADD,            YP_TSTR,  YP_VSTR = { "" } },
+       { C_DUMP_NEW,            YP_TSTR,  YP_VNONE },
+       { C_DUMP_REM,            YP_TSTR,  YP_VNONE },
+       { C_DUMP_ADD,            YP_TSTR,  YP_VNONE },
        { NULL }
 };
 
index 5479932b4e291b534d9b7df7a9c07ea79ff57960..6d314f257417a6cff5a74030f635228522d5d843 100644 (file)
@@ -961,23 +961,31 @@ int zone_update_external(conf_t *conf, zone_update_t *update, conf_val_t *ev_id)
 {
        /* First: dump zone/diff files as/if configured. */
        conf_val_t val = conf_id_get(conf, C_EXTERNAL, C_DUMP_NEW, ev_id);
-       const char *f_new = conf_str(&val);
+       char *f_new = conf_get_filename(conf, update->zone->name, conf_str(&val));
        val = conf_id_get(conf, C_EXTERNAL, C_DUMP_REM, ev_id);
-       const char *f_rem = conf_str(&val);
+       char *f_rem = conf_get_filename(conf, update->zone->name, conf_str(&val));
        val = conf_id_get(conf, C_EXTERNAL, C_DUMP_ADD, ev_id);
-       const char *f_add = conf_str(&val);
+       char *f_add = conf_get_filename(conf, update->zone->name, conf_str(&val));
 
        int ret = KNOT_EOK;
-       if (*f_new != '\0' && ret == KNOT_EOK) {
+       if (f_new != NULL && ret == KNOT_EOK) {
                ret = zonefile_write(f_new, update->new_cont, NULL);
        }
-       if (*f_rem != '\0' && ret == KNOT_EOK) {
+       if (f_rem != NULL && ret == KNOT_EOK) {
                ret = dump_changeset_part(update, false, f_rem, "w");
        }
-       if (*f_add != '\0' && ret == KNOT_EOK) {
+       if (f_add != NULL && ret == KNOT_EOK) {
                const char *mode = (strcmp(f_rem, f_add) == 0) ? "a" : "w";
                ret = dump_changeset_part(update, true, f_add, mode);
        }
+       free(f_new);
+       free(f_rem);
+       free(f_add);
+       if (ret != KNOT_EOK) {
+               log_zone_error(update->zone->name,
+                              "failed to dump new zone version or zone diff for external validation (%s)",
+                              knot_strerror(ret));
+       }
 
        /* Second: wait on semaphore on user's interaction. */
        pthread_mutex_lock(&update->zone->cu_lock);
index ad1ae653bc73ff3f54e8bb1b1b21724f5a7f397a..b5d0c3af4ac32dd12b7ce860c62c6a798423ff92 100644 (file)
@@ -20,7 +20,7 @@ static void check_name(const char *zone, const char *name, const char *ref)
 {
        knot_dname_t *z = knot_dname_from_str_alloc(zone);
 
-       char *file = get_filename(conf(), NULL, z, name);
+       char *file = conf_get_filename_txn(conf(), NULL, z, name);
        ok(file != NULL, "Get zonefile path for %s", zone);
        if (file != NULL) {
                ok(strcmp(file, ref) == 0, "Zonefile path compare %s", name);
@@ -34,7 +34,7 @@ static void check_name_err(const char *zone, const char *name)
 {
        knot_dname_t *z = knot_dname_from_str_alloc(zone);
 
-       char *filename = get_filename(conf(), NULL, z, name);
+       char *filename = conf_get_filename_txn(conf(), NULL, z, name);
        ok(filename == NULL, "Invalid name %s", name);
        free(filename);