From: Jason Ish Date: Tue, 24 Jan 2023 22:57:47 +0000 (-0600) Subject: config: allow fully qualified overrides X-Git-Tag: suricata-7.0.0-rc1~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbb0d2b0f4ccc873b74ec5db97c08cfa8a9ce251;p=thirdparty%2Fsuricata.git config: allow fully qualified overrides 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 --- diff --git a/src/conf-yaml-loader.c b/src/conf-yaml-loader.c index f20eeee868..d941db69f6 100644 --- a/src/conf-yaml-loader.c +++ b/src/conf-yaml-loader.c @@ -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; } diff --git a/src/conf.c b/src/conf.c index 75abcc9f28..9c6fa4b268 100644 --- a/src/conf.c +++ b/src/conf.c @@ -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. */ diff --git a/src/conf.h b/src/conf.h index e2944d868f..0b278a0f60 100644 --- a/src/conf.h +++ b/src/conf.h @@ -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__ */