local function register_settings_cb()
for _,set in pairs(known_ids) do
- local s = set.settings
+ local s = set.settings.apply
local enabled_symbols = {}
+ local seen_enabled = false
local disabled_symbols = {}
+ local seen_disabled = false
-- Enabled map
if s.symbols_enabled then
for _,sym in ipairs(s.symbols_enabled) do
enabled_symbols[sym] = true
+ seen_enabled = true
end
end
if s.groups_enabled then
for _,gr in ipairs(s.groups_enabled) do
- local syms = rspamd_config:get_group_symbols()
+ local syms = rspamd_config:get_group_symbols(gr)
if syms then
for _,sym in ipairs(syms) do
enabled_symbols[sym] = true
+ seen_enabled = true
end
end
end
if s.symbols_disabled then
for _,sym in ipairs(s.symbols_disabled) do
disabled_symbols[sym] = true
+ seen_disabled = true
end
end
if s.groups_disabled then
for _,gr in ipairs(s.groups_disabled) do
- local syms = rspamd_config:get_group_symbols()
+ local syms = rspamd_config:get_group_symbols(gr)
if syms then
for _,sym in ipairs(syms) do
disabled_symbols[sym] = true
+ seen_disabled = true
end
end
end
end
+ -- Deal with complexity to avoid mess in C
+ if not seen_enabled then enabled_symbols = nil end
+ if not seen_disabled then disabled_symbols = nil end
+
rspamd_config:register_settings_id(set.name, enabled_symbols, disabled_symbols)
-- Remove to avoid clash
rspamd_config_free (struct rspamd_config *cfg)
{
struct rspamd_config_post_load_script *sc, *sctmp;
+ struct rspamd_config_settings_elt *set, *stmp;
struct rspamd_worker_log_pipe *lp, *ltmp;
DL_FOREACH_SAFE (cfg->finish_callbacks, sc, sctmp) {
g_free (sc);
}
+ DL_FOREACH_SAFE (cfg->setting_ids, set, stmp) {
+ REF_RELEASE (set);
+ }
+
rspamd_map_remove_all (cfg);
rspamd_mempool_destructors_enforce (cfg->cfg_pool);
guint64 h;
h = rspamd_cryptobox_fast_hash_specific (RSPAMD_CRYPTOBOX_XXHASH64,
- name, strlen (name), 0x0);
+ name, namelen, 0x0);
/* Take the lower part of hash as LE number */
return ((guint32)GUINT64_TO_LE (h));
}
}
REF_INIT_RETAIN (nelt, rspamd_config_settings_elt_dtor);
- msg_warn_config ("replace settings id %d (%s)", id, name);
+ msg_warn_config ("replace settings id %ud (%s)", id, name);
rspamd_symcache_process_settings_elt (cfg->cache, elt);
DL_APPEND (cfg->setting_ids, nelt);
elt->symbols_disabled = ucl_object_ref (symbols_disabled);
}
- msg_info_config ("register new settings id %d (%s)", id, name);
+ msg_info_config ("register new settings id %ud (%s)", id, name);
REF_INIT_RETAIN (elt, rspamd_config_settings_elt_dtor);
rspamd_symcache_process_settings_elt (cfg->cache, elt);
DL_APPEND (cfg->setting_ids, elt);
msg_warn_protocol ("unknown settings id: %V",
hv);
}
+ else {
+ msg_debug_protocol ("applied settings id %V -> %ud", hv,
+ task->settings_elt->id);
+ }
}
break;
case 'u':
rspamd_symcache_check_id_list (&item->forbidden_ids,
id)) {
msg_debug_cache_task ("deny execution of %s as it is forbidden for "
- "settings id %d",
+ "settings id %ud",
item->symbol,
id);
return FALSE;
!rspamd_symcache_check_id_list (&item->allowed_ids,
id)) {
msg_debug_cache_task ("deny execution of %s as it is not listed "
- "as allowed for settings id %d",
+ "as allowed for settings id %ud",
item->symbol,
id);
return FALSE;
}
else {
msg_debug_cache_task ("allow execution of %s for "
- "settings id %d as it can be only disabled explicitly",
+ "settings id %ud as it can be only disabled explicitly",
item->symbol,
id);
}
iter = NULL;
while ((cur = ucl_object_iterate (elt->symbols_disabled, &iter, true)) != NULL) {
- item = rspamd_symcache_find_filter (cache,
- ucl_object_tostring (cur), false);
-
- if (item->is_virtual) {
- /*
- * Virtual symbols are special:
- * we ignore them in symcache but prevent them from being
- * inserted.
- */
- msg_debug_cache ("skip virtual symbol %s for settings id %d (%s)",
- ucl_object_tostring (cur), id, elt->name);
+ const gchar *sym = ucl_object_key (cur);
+ item = rspamd_symcache_find_filter (cache, sym, false);
+
+ if (item) {
+ if (item->is_virtual) {
+ /*
+ * Virtual symbols are special:
+ * we ignore them in symcache but prevent them from being
+ * inserted.
+ */
+ msg_debug_cache ("skip virtual symbol %s for settings id %ud (%s)",
+ sym, id, elt->name);
+ }
+ else {
+ /* Normal symbol, disable it */
+ rspamd_symcache_add_id_to_list (cache->static_pool,
+ &item->forbidden_ids, id);
+ msg_debug_cache ("deny symbol %s for settings %ud (%s)",
+ sym, id, elt->name);
+ }
}
else {
- /* Normal symbol, disable it */
- rspamd_symcache_add_id_to_list (cache->static_pool,
- &item->forbidden_ids, id);
- msg_debug_cache ("deny symbol %s for settings %d (%s)",
- ucl_object_tostring (cur), id, elt->name);
+ msg_warn_cache ("cannot find a symbol to disable %s "
+ "when processing settings %ud (%s)",
+ sym, id, elt->name);
}
}
}
while ((cur = ucl_object_iterate (elt->symbols_enabled, &iter, true)) != NULL) {
/* Here, we resolve parent and explicitly allow it */
- item = rspamd_symcache_find_filter (cache,
- ucl_object_tostring (cur), true);
+ const gchar *sym = ucl_object_key (cur);
+ item = rspamd_symcache_find_filter (cache, sym, true);
- if (elt->symbols_disabled &&
+ if (item) {
+ if (elt->symbols_disabled &&
ucl_object_lookup (elt->symbols_disabled, item->symbol)) {
- msg_err_cache ("conflict in %s: cannot enable disabled symbol %s, "
- "wanted to enable symbol %s",
- elt->name, item->symbol, ucl_object_tostring (cur));
+ msg_err_cache ("conflict in %s: cannot enable disabled symbol %s, "
+ "wanted to enable symbol %s",
+ elt->name, item->symbol, sym);
+ }
+ else {
+ rspamd_symcache_add_id_to_list (cache->static_pool,
+ &item->allowed_ids, id);
+ msg_debug_cache ("allow execution of symbol %s for settings %ud (%s)",
+ sym, id, elt->name);
+ }
}
else {
- rspamd_symcache_add_id_to_list (cache->static_pool,
- &item->allowed_ids, id);
- msg_debug_cache ("allow execution of symbol %s for settings %d (%s)",
- ucl_object_tostring (cur), id, elt->name);
+ msg_warn_cache ("cannot find a symbol to enable %s "
+ "when processing settings %ud (%s)",
+ sym, id, elt->name);
}
}
}
sym_enabled = ucl_object_lua_import (L, 3);
- if (sym_enabled == NULL || ucl_object_type (sym_enabled) != UCL_ARRAY) {
+ if (sym_enabled != NULL && ucl_object_type (sym_enabled) != UCL_OBJECT) {
ucl_object_unref (sym_enabled);
return luaL_error (L, "invalid symbols enabled");
}
- sym_disabled = ucl_object_lua_import (L, 3);
+ sym_disabled = ucl_object_lua_import (L, 4);
- if (sym_disabled == NULL || ucl_object_type (sym_disabled) != UCL_ARRAY) {
+ if (sym_disabled != NULL && ucl_object_type (sym_disabled) != UCL_OBJECT) {
ucl_object_unref (sym_enabled);
ucl_object_unref (sym_disabled);
if (task != NULL && id != 0) {
if (task->settings_elt) {
- return luaL_error (L, "settings id has been already set to %d (%s)",
- task->settings_elt->id, task->settings_elt->name);
-
+ if (task->settings_elt->id != id) {
+ return luaL_error (L, "settings id has been already set to %d (%s)",
+ task->settings_elt->id, task->settings_elt->name);
+ }
}
else {
task->settings_elt = rspamd_config_find_settings_id_ref (task->cfg,
-- Can use xor here but more complicated for reading
if (result and not s.rule.inverse) or (not result and s.rule.inverse) then
- rspamd_logger.infox(task, "<%s> apply settings according to rule %s (%s matched)",
- task:get_message_id(), s.name, table.concat(matched, ','))
if s.rule['apply'] then
- apply_settings(task, s.rule.apply, s.rule.id)
+ if s.rule.id then
+ -- Extract static settings
+ local cached = lua_settings.settings_by_id(s.rule.id)
+
+ if not cached then
+ rspamd_logger.errx(task, 'unregistered settings id found: %s!', s.rule.id)
+ else
+ rspamd_logger.infox(task, "<%s> apply static settings %s (id = %s); %s matched",
+ task:get_message_id(),
+ cached.name, s.rule.id,
+ table.concat(matched, ','))
+ apply_settings(task, cached.settings, s.rule.id)
+ end
+
+ else
+ -- Dynamic settings
+ rspamd_logger.infox(task, "<%s> apply settings according to rule %s (%s matched)",
+ task:get_message_id(), s.name, table.concat(matched, ','))
+ apply_settings(task, s.rule.apply, nil)
+ end
+
applied = true
end
if s.rule['symbols'] then