]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
config: allow fully qualified overrides
authorJason Ish <jason.ish@oisf.net>
Tue, 24 Jan 2023 22:57:47 +0000 (16:57 -0600)
committerVictor Julien <vjulien@oisf.net>
Thu, 26 Jan 2023 14:50:12 +0000 (15:50 +0100)
Allow configuration parameters to be overrided usually a fully
qualified name such as:

vars.address-groups.HOME_NET: "7.1.2.0/24"

In configuration files (including "include" files).  This allows the
overriding of a specific value deeply nested in the configuration
without having to redefine the complete top-layer object.

Ticket: 4783

src/conf-yaml-loader.c
src/conf.c
src/conf.h

index f20eeee868c43b4d3110726297db0841517408c1..d941db69f6a635c281175eb2fd54868de8b36920 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2023 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -302,35 +302,40 @@ ConfYamlParse(yaml_parser_t *parser, ConfNode *parent, int inseq, int rlevel)
                                 Mangle(parent->val);
                         }
                     }
-                    ConfNode *existing = ConfNodeLookupChild(parent, value);
-                    if (existing != NULL) {
-                        if (!existing->final) {
-                            SCLogInfo("Configuration node '%s' redefined.",
-                                existing->name);
-                            ConfNodePrune(existing);
-                        }
-                        node = existing;
-                    }
-                    else {
-                        node = ConfNodeNew();
-                        node->name = SCStrdup(value);
-                        if (node->name && strchr(node->name, '_')) {
-                            if (!(parent->name &&
-                                   ((strcmp(parent->name, "address-groups") == 0) ||
-                                    (strcmp(parent->name, "port-groups") == 0)))) {
-                                Mangle(node->name);
-                                if (mangle_errors < MANGLE_ERRORS_MAX) {
-                                    SCLogWarning("%s is deprecated. Please use %s on line %" PRIuMAX
-                                                 ".",
-                                            value, node->name, (uintmax_t)parser->mark.line + 1);
-                                    mangle_errors++;
-                                    if (mangle_errors >= MANGLE_ERRORS_MAX)
-                                        SCLogWarning("not showing more "
-                                                     "parameter name warnings.");
+
+                    if (strchr(value, '.') != NULL) {
+                        node = ConfNodeGetNodeOrCreate(parent, value, 0);
+                    } else {
+                        ConfNode *existing = ConfNodeLookupChild(parent, value);
+                        if (existing != NULL) {
+                            if (!existing->final) {
+                                SCLogInfo("Configuration node '%s' redefined.", existing->name);
+                                ConfNodePrune(existing);
+                            }
+                            node = existing;
+                        } else {
+                            node = ConfNodeNew();
+                            node->name = SCStrdup(value);
+                            if (node->name && strchr(node->name, '_')) {
+                                if (!(parent->name &&
+                                            ((strcmp(parent->name, "address-groups") == 0) ||
+                                                    (strcmp(parent->name, "port-groups") == 0)))) {
+                                    Mangle(node->name);
+                                    if (mangle_errors < MANGLE_ERRORS_MAX) {
+                                        SCLogWarning(
+                                                "%s is deprecated. Please use %s on line %" PRIuMAX
+                                                ".",
+                                                value, node->name,
+                                                (uintmax_t)parser->mark.line + 1);
+                                        mangle_errors++;
+                                        if (mangle_errors >= MANGLE_ERRORS_MAX)
+                                            SCLogWarning("not showing more "
+                                                         "parameter name warnings.");
+                                    }
                                 }
                             }
+                            TAILQ_INSERT_TAIL(&parent->head, node, next);
                         }
-                        TAILQ_INSERT_TAIL(&parent->head, node, next);
                     }
                     state = CONF_VAL;
                 }
index 75abcc9f28bf8cbf739a634d9b33ac474a7b4eac..9c6fa4b268f00db997b0edbb39627652c91bad4d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2023 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -56,15 +56,15 @@ static ConfNode *root_backup = NULL;
  * This function exits on memory failure as creating configuration
  * nodes is usually part of application initialization.
  *
+ * \param parent The node to use as the parent
  * \param name The name of the configuration node to get.
  * \param final Flag to set created nodes as final or not.
  *
  * \retval The existing configuration node if it exists, or a newly
  *   created node for the provided name.  On error, NULL will be returned.
  */
-static ConfNode *ConfGetNodeOrCreate(const char *name, int final)
+ConfNode *ConfNodeGetNodeOrCreate(ConfNode *parent, const char *name, int final)
 {
-    ConfNode *parent = root;
     ConfNode *node = NULL;
     char node_name[NODE_NAME_MAX];
     char *key;
@@ -105,6 +105,15 @@ end:
     return node;
 }
 
+/**
+ * \brief Wrapper function for ConfNodeGetNodeOrCreate that operates
+ *     on the current root node.
+ */
+static ConfNode *ConfGetNodeOrCreate(const char *name, int final)
+{
+    return ConfNodeGetNodeOrCreate(root, name, final);
+}
+
 /**
  * \brief Initialize the configuration system.
  */
index e2944d868f0c65e0357e2d4d878adbe117128cb8..0b278a0f608e5ff18d767d020598860b6243f7aa 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2023 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -97,5 +97,5 @@ int ConfNodeIsSequence(const ConfNode *node);
 ConfNode *ConfSetIfaceNode(const char *ifaces_node_name, const char *iface);
 int ConfSetRootAndDefaultNodes(
         const char *ifaces_node_name, const char *iface, ConfNode **if_root, ConfNode **if_default);
-
+ConfNode *ConfNodeGetNodeOrCreate(ConfNode *parent, const char *name, int final);
 #endif /* ! __CONF_H__ */