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
pull/8467/head
Jason Ish 2 years ago committed by Victor Julien
parent 9cb0bc3332
commit fbb0d2b0f4

@ -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 * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * 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); Mangle(parent->val);
} }
} }
ConfNode *existing = ConfNodeLookupChild(parent, value);
if (existing != NULL) { if (strchr(value, '.') != NULL) {
if (!existing->final) { node = ConfNodeGetNodeOrCreate(parent, value, 0);
SCLogInfo("Configuration node '%s' redefined.", } else {
existing->name); ConfNode *existing = ConfNodeLookupChild(parent, value);
ConfNodePrune(existing); if (existing != NULL) {
} if (!existing->final) {
node = existing; SCLogInfo("Configuration node '%s' redefined.", existing->name);
} ConfNodePrune(existing);
else { }
node = ConfNodeNew(); node = existing;
node->name = SCStrdup(value); } else {
if (node->name && strchr(node->name, '_')) { node = ConfNodeNew();
if (!(parent->name && node->name = SCStrdup(value);
((strcmp(parent->name, "address-groups") == 0) || if (node->name && strchr(node->name, '_')) {
(strcmp(parent->name, "port-groups") == 0)))) { if (!(parent->name &&
Mangle(node->name); ((strcmp(parent->name, "address-groups") == 0) ||
if (mangle_errors < MANGLE_ERRORS_MAX) { (strcmp(parent->name, "port-groups") == 0)))) {
SCLogWarning("%s is deprecated. Please use %s on line %" PRIuMAX Mangle(node->name);
".", if (mangle_errors < MANGLE_ERRORS_MAX) {
value, node->name, (uintmax_t)parser->mark.line + 1); SCLogWarning(
mangle_errors++; "%s is deprecated. Please use %s on line %" PRIuMAX
if (mangle_errors >= MANGLE_ERRORS_MAX) ".",
SCLogWarning("not showing more " value, node->name,
"parameter name warnings."); (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; state = CONF_VAL;
} }

@ -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 * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * 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 * This function exits on memory failure as creating configuration
* nodes is usually part of application initialization. * 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 name The name of the configuration node to get.
* \param final Flag to set created nodes as final or not. * \param final Flag to set created nodes as final or not.
* *
* \retval The existing configuration node if it exists, or a newly * \retval The existing configuration node if it exists, or a newly
* created node for the provided name. On error, NULL will be returned. * 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; ConfNode *node = NULL;
char node_name[NODE_NAME_MAX]; char node_name[NODE_NAME_MAX];
char *key; char *key;
@ -105,6 +105,15 @@ end:
return node; 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. * \brief Initialize the configuration system.
*/ */

@ -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 * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * 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); ConfNode *ConfSetIfaceNode(const char *ifaces_node_name, const char *iface);
int ConfSetRootAndDefaultNodes( int ConfSetRootAndDefaultNodes(
const char *ifaces_node_name, const char *iface, ConfNode **if_root, ConfNode **if_default); 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__ */ #endif /* ! __CONF_H__ */

Loading…
Cancel
Save