]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
conf: check writability of storage and databases
authorLibor Peltan <libor.peltan@nic.cz>
Tue, 10 Aug 2021 15:47:10 +0000 (17:47 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Thu, 19 Aug 2021 17:52:34 +0000 (19:52 +0200)
src/knot/conf/conf.c
src/knot/conf/schema.c
src/knot/conf/tools.c
src/knot/conf/tools.h

index 35595bb4b3b54dedaf986665811cb329c8655d8e..5c0f6c63aa59d71786c1d991566f7ba185125a09 100644 (file)
@@ -1127,9 +1127,13 @@ char* conf_db_txn(
        const yp_name_t *db_type)
 {
        conf_val_t storage_val = conf_get_txn(conf, txn, C_DB, C_STORAGE);
-       conf_val_t db_val = conf_get_txn(conf, txn, C_DB, db_type);
-
        char *storage = conf_abs_path(&storage_val, NULL);
+
+       if (db_type == NULL) {
+               return storage;
+       }
+
+       conf_val_t db_val = conf_get_txn(conf, txn, C_DB, db_type);
        char *dbdir = conf_abs_path(&db_val, storage);
        free(storage);
 
index d87548b0de4f2dce4e7a3484b9425bf6fb3b3283..5292b7b10ebcfe7c4209e4f2b00fafb6977c3203 100644 (file)
@@ -460,7 +460,7 @@ const yp_item_t conf_schema[] = {
        { C_CTL,      YP_TGRP, YP_VGRP = { desc_control } },
        { C_LOG,      YP_TGRP, YP_VGRP = { desc_log }, YP_FMULTI | CONF_IO_FRLD_LOG },
        { C_STATS,    YP_TGRP, YP_VGRP = { desc_stats }, CONF_IO_FRLD_SRV },
-       { C_DB,       YP_TGRP, YP_VGRP = { desc_database }, CONF_IO_FRLD_SRV },
+       { C_DB,       YP_TGRP, YP_VGRP = { desc_database }, CONF_IO_FRLD_SRV, { check_database } },
        { C_KEYSTORE, YP_TGRP, YP_VGRP = { desc_keystore }, YP_FMULTI, { check_keystore } },
        { C_KEY,      YP_TGRP, YP_VGRP = { desc_key }, YP_FMULTI, { check_key } },
        { C_RMT,      YP_TGRP, YP_VGRP = { desc_remote }, YP_FMULTI, { check_remote } },
index f501dd5c0e4971d36e04223f90f8172ecfb60cf8..e028d5ee9cb527440b8b8d3b9f39d53994cf8ad1 100644 (file)
@@ -293,6 +293,64 @@ int check_xdp_listen(
 #endif
 }
 
+static int dir_exists(const char *dir)
+{
+       struct stat st;
+       if (stat(dir, &st) != 0) {
+               return knot_map_errno();
+       } else if (!S_ISDIR(st.st_mode)) {
+               return KNOT_ENOTDIR;
+       } else if (access(dir, W_OK) != 0) {
+               return knot_map_errno();
+       } else {
+               return KNOT_EOK;
+       }
+}
+
+static int dir_can_create(const char *dir)
+{
+       int ret = dir_exists(dir);
+       if (ret == KNOT_ENOENT) {
+               return KNOT_EOK;
+       } else {
+               return ret;
+       }
+}
+
+static int check_db(
+       knotd_conf_check_args_t *args,
+       const yp_name_t *db_type,
+       int (*check_fun)(const char *),
+       const char *desc,
+       int ret)
+{
+       if (ret != KNOT_EOK) {
+               return ret;
+       }
+
+       char *db = conf_db_txn(args->extra->conf, args->extra->txn, db_type);
+       ret = check_fun(db);
+       if (ret != KNOT_EOK) {
+               CONF_LOG(LOG_ERR, "%s '%s' not usable", desc, db);
+       }
+       free(db);
+       return ret;
+}
+
+int check_database(
+       knotd_conf_check_args_t *args)
+{
+       int ret = KNOT_EOK;
+
+       ret = check_db(args, NULL,         dir_exists,     "database storage", ret);
+       ret = check_db(args, C_TIMER_DB,   dir_can_create, "timer database",   ret);
+       ret = check_db(args, C_JOURNAL_DB, dir_can_create, "journal database", ret);
+       ret = check_db(args, C_KASP_DB,    dir_can_create, "KASP database",    ret);
+       ret = check_db(args, C_CATALOG_DB, dir_can_create, "catalog database", ret);
+
+       return ret;
+}
+
 int check_modref(
        knotd_conf_check_args_t *args)
 {
index 55d5b41755a2ca3b396cec0685093fc3ead1606e..61bc155aa35542085e5f2f9d2e0adadf7b45ae5a 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -78,6 +78,10 @@ int check_xdp_listen(
        knotd_conf_check_args_t *args
 );
 
+int check_database(
+       knotd_conf_check_args_t *args
+);
+
 int check_modref(
        knotd_conf_check_args_t *args
 );