/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see . **/ #include "audit/zbxaudit_item.h" #include "audit/zbxaudit.h" #include "audit.h" #include "zbxdb.h" #include "zbxnum.h" #include "zbxalgo.h" #include "zbxstr.h" int zbx_audit_item_resource_is_only_item(int resource_type) { return ZBX_AUDIT_RESOURCE_ITEM == resource_type; } int zbx_audit_item_resource_is_only_item_prototype(int resource_type) { return ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE == resource_type; } int zbx_audit_item_resource_is_only_item_and_item_prototype(int resource_type) { return (ZBX_AUDIT_RESOURCE_ITEM == resource_type || ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE == resource_type); } int zbx_audit_item_resource_is_only_lld_rule_or_lld_rule_prototype(int resource_type) { return ZBX_AUDIT_RESOURCE_LLD_RULE == resource_type || ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE == resource_type; } int zbx_audit_item_flag_to_resource_type(int flag) { if (ZBX_FLAG_DISCOVERY_NORMAL == flag || ZBX_FLAG_DISCOVERY_CREATED == flag) { return ZBX_AUDIT_RESOURCE_ITEM; } else if (0 != (flag & ZBX_FLAG_DISCOVERY_PROTOTYPE)) { if (0 == (flag & ZBX_FLAG_DISCOVERY_RULE)) return ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE; return ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE; } else if (0 != (flag & ZBX_FLAG_DISCOVERY_RULE)) { return ZBX_AUDIT_RESOURCE_LLD_RULE; } else { THIS_SHOULD_NEVER_HAPPEN_MSG("unsupported item flag detected: %d", flag); exit(EXIT_FAILURE); } } const char *lld_audit_item_prop(int flags, const char *field, char *buf, size_t len) { int resource_type = zbx_audit_item_flag_to_resource_type(flags); size_t offset; switch (resource_type) { case ZBX_AUDIT_RESOURCE_ITEM: offset = zbx_strlcpy(buf, "item", len); break; case ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE: offset = zbx_strlcpy(buf, "itemprototype", len); break; case ZBX_AUDIT_RESOURCE_LLD_RULE: offset = zbx_strlcpy(buf, "discoveryrule", len); break; case ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE: offset = zbx_strlcpy(buf, "discoveryruleprototype", len); break; default: THIS_SHOULD_NEVER_HAPPEN_MSG("unsupported resource type: %d", resource_type); exit(EXIT_FAILURE); } if (offset < len - 1) { buf[offset++] = '.'; zbx_strlcpy(buf + offset, field, len - offset); } return buf; } void zbx_audit_item_create_entry(int audit_context_mode, int audit_action, zbx_uint64_t itemid, const char *name, int flags) { int resource_type; zbx_audit_entry_t local_audit_item_entry, **found_audit_item_entry; zbx_audit_entry_t *local_audit_item_entry_x = &local_audit_item_entry; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(flags); local_audit_item_entry.id = itemid; local_audit_item_entry.cuid = NULL; local_audit_item_entry.id_table = AUDIT_ITEM_ID; found_audit_item_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_item_entry_x)); if (NULL == found_audit_item_entry) { zbx_audit_entry_t *local_audit_item_entry_insert; local_audit_item_entry_insert = zbx_audit_entry_init(itemid, AUDIT_ITEM_ID, name, audit_action, resource_type); zbx_hashset_insert(zbx_get_audit_hashset(), &local_audit_item_entry_insert, sizeof(local_audit_item_entry_insert)); } } #define PREPARE_AUDIT_ITEM_UPDATE(resource, type1, type2) \ void zbx_audit_item_update_json_update_##resource(int audit_context_mode, zbx_uint64_t itemid, int flags, \ type1 resource##_old, type1 resource##_new) \ { \ char prop[AUDIT_DETAILS_KEY_LEN]; \ \ RETURN_IF_AUDIT_OFF(audit_context_mode); \ \ zbx_audit_update_json_update_##type2(itemid, AUDIT_ITEM_ID, \ lld_audit_item_prop(flags, #resource, prop, sizeof(prop)), \ resource##_old, resource##_new); \ } PREPARE_AUDIT_ITEM_UPDATE(interfaceid, zbx_uint64_t, uint64) PREPARE_AUDIT_ITEM_UPDATE(templateid, zbx_uint64_t, uint64) PREPARE_AUDIT_ITEM_UPDATE(name, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(type, int, int) PREPARE_AUDIT_ITEM_UPDATE(value_type, int, int) PREPARE_AUDIT_ITEM_UPDATE(delay, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(history, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(trends, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(status, int, int) PREPARE_AUDIT_ITEM_UPDATE(trapper_hosts, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(units, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(formula, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(logtimefmt, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(valuemapid, zbx_uint64_t, uint64) PREPARE_AUDIT_ITEM_UPDATE(params, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(ipmi_sensor, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(snmp_oid, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(authtype, int, int) PREPARE_AUDIT_ITEM_UPDATE(username, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(password, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(publickey, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(privatekey, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(flags, int, int) PREPARE_AUDIT_ITEM_UPDATE(description, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(inventory_link, int, int) PREPARE_AUDIT_ITEM_UPDATE(lifetime, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(lifetime_type, int, int) PREPARE_AUDIT_ITEM_UPDATE(enabled_lifetime, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(enabled_lifetime_type, int, int) PREPARE_AUDIT_ITEM_UPDATE(evaltype, int, int) PREPARE_AUDIT_ITEM_UPDATE(jmx_endpoint, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(master_itemid, zbx_uint64_t, uint64) PREPARE_AUDIT_ITEM_UPDATE(timeout, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(url, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(posts, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(status_codes, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(follow_redirects, int, int) PREPARE_AUDIT_ITEM_UPDATE(redirects, int, int) PREPARE_AUDIT_ITEM_UPDATE(post_type, int, int) PREPARE_AUDIT_ITEM_UPDATE(http_proxy, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(retrieve_mode, int, int) PREPARE_AUDIT_ITEM_UPDATE(request_method, int, int) PREPARE_AUDIT_ITEM_UPDATE(output_format, int, int) PREPARE_AUDIT_ITEM_UPDATE(ssl_cert_file, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(ssl_key_file, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(ssl_key_password, const char*, string) PREPARE_AUDIT_ITEM_UPDATE(verify_peer, int, int) PREPARE_AUDIT_ITEM_UPDATE(verify_host, int, int) PREPARE_AUDIT_ITEM_UPDATE(allow_traps, int, int) PREPARE_AUDIT_ITEM_UPDATE(discover, int, int) PREPARE_AUDIT_ITEM_UPDATE(key_, const char*, string) #undef PREPARE_AUDIT_ITEM_UPDATE /******************************************************************************** * * * Purpose: create audit events for items that are to be removed * * * ********************************************************************************/ void zbx_audit_item_delete(int audit_context_mode, zbx_vector_uint64_t *itemids) { zbx_db_large_query_t query; zbx_db_row_t row; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,name,flags from items where"); zbx_db_large_query_prepare_uint(&query, &sql, &sql_alloc, &sql_offset, "itemid", itemids); while (NULL != (row = zbx_db_large_query_fetch(&query))) { zbx_uint64_t itemid; ZBX_STR2UINT64(itemid, row[0]); zbx_audit_item_create_entry(audit_context_mode, ZBX_AUDIT_ACTION_DELETE, itemid, row[1], atoi(row[2])); } zbx_db_large_query_clear(&query); zbx_free(sql); } void zbx_audit_discovery_rule_update_json_add_filter_conditions(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t rule_conditionid, zbx_uint64_t op, const char *macro, const char *value) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_filter_conditions(audit_entry, rule_conditionid, op, macro, value); } void zbx_audit_discovery_rule_update_json_update_filter_conditions_create_entry(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t item_conditionid) { char buf[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(buf, sizeof(buf), "discoveryrule.filter[" ZBX_FS_UI64 "].conditions", item_conditionid); zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, buf); } void zbx_audit_discovery_rule_update_json_update_filter_conditions(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t item_conditionid, const char *resource, const char *value_old, const char *value_new) { char buf[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(buf, sizeof(buf), "discoveryrule.filter[" ZBX_FS_UI64 "].conditions.%s", item_conditionid, resource); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, buf, value_old, value_new); } #define PREPARE_AUDIT_DISCOVERY_RULE_UPDATE(resource, type1, type2) \ void zbx_audit_discovery_rule_update_json_update_filter_conditions_##resource(int audit_context_mode, \ zbx_uint64_t itemid, zbx_uint64_t item_conditionid, type1 resource##_old, type1 resource##_new) \ { \ char buf[AUDIT_DETAILS_KEY_LEN]; \ \ RETURN_IF_AUDIT_OFF(audit_context_mode); \ \ zbx_snprintf(buf, sizeof(buf), "discoveryrule.filter[" ZBX_FS_UI64 "].conditions."#resource, \ item_conditionid); \ \ zbx_audit_update_json_update_##type2(itemid, AUDIT_ITEM_ID, buf, resource##_old, resource##_new); \ } PREPARE_AUDIT_DISCOVERY_RULE_UPDATE(operator, int, int) PREPARE_AUDIT_DISCOVERY_RULE_UPDATE(macro, const char*, string) PREPARE_AUDIT_DISCOVERY_RULE_UPDATE(value, const char*, string) #undef PREPARE_AUDIT_DISCOVERY_RULE_UPDATE void zbx_audit_discovery_rule_update_json_delete_filter_conditions(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t item_conditionid) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_delete_filter_conditions(audit_entry, item_conditionid); } #define ITEM_RESOURCE_KEY_RESOLVE_PREPROC(resource, nested) \ if (ZBX_AUDIT_RESOURCE_ITEM == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "item.preprocessing[" \ ZBX_FS_UI64 "]"#nested#resource, preprocid); \ } \ else if (ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "itemprototype.preprocessing[" \ ZBX_FS_UI64 "]"#nested#resource, preprocid); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "discoveryrule.preprocessing[" \ ZBX_FS_UI64 "]"#nested#resource, preprocid); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), \ "discoveryruleprototype.preprocessing[" ZBX_FS_UI64 "]"#nested#resource, \ preprocid); \ } \ else \ { \ THIS_SHOULD_NEVER_HAPPEN; \ return; \ } void zbx_audit_item_update_json_add_item_preproc(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t preprocid, int item_flags, int step, int type, const char *params, int error_handler, const char *error_handler_params) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN], audit_key_step[AUDIT_DETAILS_KEY_LEN], audit_key_type[AUDIT_DETAILS_KEY_LEN], audit_key_params[AUDIT_DETAILS_KEY_LEN], audit_key_error_handler[AUDIT_DETAILS_KEY_LEN], audit_key_error_handler_params[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_PREPROC(,) ITEM_RESOURCE_KEY_RESOLVE_PREPROC(step, .) ITEM_RESOURCE_KEY_RESOLVE_PREPROC(type, .) ITEM_RESOURCE_KEY_RESOLVE_PREPROC(params, .) ITEM_RESOURCE_KEY_RESOLVE_PREPROC(error_handler, .) ITEM_RESOURCE_KEY_RESOLVE_PREPROC(error_handler_params, .) #define AUDIT_TABLE_NAME "item_preproc" zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_); zbx_audit_update_json_append_int(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_step, step, AUDIT_TABLE_NAME, "step"); zbx_audit_update_json_append_int(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_type, type, AUDIT_TABLE_NAME, "type"); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_params, params, AUDIT_TABLE_NAME, "params"); zbx_audit_update_json_append_int(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_error_handler, error_handler, AUDIT_TABLE_NAME, "error_handler"); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_error_handler_params, error_handler_params, AUDIT_TABLE_NAME, "error_handler_params"); #undef AUDIT_TABLE_NAME } void zbx_audit_item_update_json_update_item_preproc_create_entry(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t preprocid) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_PREPROC(,) zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key_); } #define PREPARE_AUDIT_ITEM_UPDATE_PREPROC(resource, type1, type2) \ void zbx_audit_item_update_json_update_item_preproc_##resource(int audit_context_mode, zbx_uint64_t itemid, \ int item_flags, zbx_uint64_t preprocid, type1 resource##_old, type1 resource##_new) \ { \ int resource_type; \ char audit_key_##resource[AUDIT_DETAILS_KEY_LEN]; \ \ RETURN_IF_AUDIT_OFF(audit_context_mode); \ resource_type = zbx_audit_item_flag_to_resource_type(item_flags); \ \ ITEM_RESOURCE_KEY_RESOLVE_PREPROC(resource,.) \ \ zbx_audit_update_json_update_##type2(itemid, AUDIT_ITEM_ID, audit_key_##resource, resource##_old, \ resource##_new); \ } PREPARE_AUDIT_ITEM_UPDATE_PREPROC(type, int, int) PREPARE_AUDIT_ITEM_UPDATE_PREPROC(params, const char*, string) PREPARE_AUDIT_ITEM_UPDATE_PREPROC(error_handler, int, int) PREPARE_AUDIT_ITEM_UPDATE_PREPROC(error_handler_params, const char*, string) #undef PREPARE_AUDIT_ITEM_UPDATE_PREPROC void zbx_audit_item_delete_preproc(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t preprocid) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_PREPROC(,) zbx_audit_update_json_delete(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_DELETE, audit_key_); } #define ITEM_RESOURCE_KEY_RESOLVE_TAG(resource, nested) \ if (ZBX_AUDIT_RESOURCE_ITEM == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "item.tag[" ZBX_FS_UI64 \ "]"#nested#resource, tagid); \ } \ else if (ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "itemprototype.tag[" \ ZBX_FS_UI64 "]"#nested#resource, tagid); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "discoveryrule.tag[" \ ZBX_FS_UI64 "]"#resource, tagid); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "discoveryruleprototype.tag[" \ ZBX_FS_UI64 "]"#resource, tagid); \ } \ else \ { \ THIS_SHOULD_NEVER_HAPPEN; \ return; \ } void zbx_audit_item_update_json_add_item_tag(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t tagid, int item_flags, const char *tag, const char *value) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN], audit_key_tag[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_TAG(,) ITEM_RESOURCE_KEY_RESOLVE_TAG(tag, .) ITEM_RESOURCE_KEY_RESOLVE_TAG(value, .) #define AUDIT_TABLE_NAME "item_tag" zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_tag, tag, AUDIT_TABLE_NAME, "tag"); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, value, AUDIT_TABLE_NAME, "value"); #undef AUDIT_TABLE_NAME } void zbx_audit_item_update_json_update_item_tag_create_entry(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t tagid) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_TAG(,) zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key_); } #define PREPARE_AUDIT_ITEM_UPDATE_TAG(resource, type1, type2) \ void zbx_audit_item_update_json_update_item_tag_##resource(int audit_context_mode, zbx_uint64_t itemid, \ int item_flags, zbx_uint64_t tagid, type1 resource##_old, type1 resource##_new) \ { \ int resource_type; \ char audit_key_##resource[AUDIT_DETAILS_KEY_LEN]; \ \ RETURN_IF_AUDIT_OFF(audit_context_mode); \ resource_type = zbx_audit_item_flag_to_resource_type(item_flags); \ \ ITEM_RESOURCE_KEY_RESOLVE_TAG(resource,.) \ \ zbx_audit_update_json_update_##type2(itemid, AUDIT_ITEM_ID, audit_key_##resource, resource##_old, \ resource##_new); \ } PREPARE_AUDIT_ITEM_UPDATE_TAG(tag, const char*, string) PREPARE_AUDIT_ITEM_UPDATE_TAG(value, const char*, string) #undef PREPARE_AUDIT_ITEM_UPDATE_TAG void zbx_audit_item_delete_tag(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t tagid) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE_TAG(,) zbx_audit_update_json_delete(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_DELETE, audit_key_); } #define ITEM_RESOURCE_KEY_RESOLVE(resource, nested) \ if (ZBX_AUDIT_RESOURCE_ITEM == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "item.parameters[" ZBX_FS_UI64 \ "]"#nested#resource, item_parameter_id); \ } \ else if (ZBX_AUDIT_RESOURCE_ITEM_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "itemprototype.parameters[" \ ZBX_FS_UI64 "]"#nested#resource, item_parameter_id); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "discoveryrule.parameters[" \ ZBX_FS_UI64 "]"#nested#resource, item_parameter_id); \ } \ else if (ZBX_AUDIT_RESOURCE_LLD_RULE_PROTOTYPE == resource_type) \ { \ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "discoveryruleprototype.parameters[" \ ZBX_FS_UI64 "]"#nested#resource, item_parameter_id); \ } \ else \ { \ THIS_SHOULD_NEVER_HAPPEN; \ return; \ } void zbx_audit_item_update_json_add_params(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t item_parameter_id, const char *name, const char *value) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN], audit_key_name[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE(,) ITEM_RESOURCE_KEY_RESOLVE(name, .) ITEM_RESOURCE_KEY_RESOLVE(value, .) #define AUDIT_TABLE_NAME "item_parameter" zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_name, name, AUDIT_TABLE_NAME, "name"); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, value, AUDIT_TABLE_NAME, "value"); #undef AUDIT_TABLE_NAME } void zbx_audit_item_update_json_update_params_create_entry(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t item_parameter_id) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE(,) zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key_); } #define PREPARE_AUDIT_ITEM_PARAMS_UPDATE(resource) \ void zbx_audit_item_update_json_update_params_##resource(int audit_context_mode, zbx_uint64_t itemid, \ int item_flags, zbx_uint64_t item_parameter_id, const char *resource##_orig, \ const char *resource) \ { \ int resource_type; \ char audit_key_##resource[AUDIT_DETAILS_KEY_LEN]; \ \ RETURN_IF_AUDIT_OFF(audit_context_mode); \ \ resource_type = zbx_audit_item_flag_to_resource_type(item_flags); \ ITEM_RESOURCE_KEY_RESOLVE(resource, .) \ \ zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key_##resource, resource##_orig, \ resource); \ } PREPARE_AUDIT_ITEM_PARAMS_UPDATE(name) PREPARE_AUDIT_ITEM_PARAMS_UPDATE(value) void zbx_audit_item_delete_params(int audit_context_mode, zbx_uint64_t itemid, int item_flags, zbx_uint64_t item_parameter_id) { int resource_type; char audit_key_[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); resource_type = zbx_audit_item_flag_to_resource_type(item_flags); ITEM_RESOURCE_KEY_RESOLVE(,) zbx_audit_update_json_delete(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_DELETE, audit_key_); } void zbx_audit_discovery_rule_update_json_add_lld_macro_path(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t lld_macro_pathid, const char *lld_macro, const char *path) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_macro_path(audit_entry, lld_macro_pathid, lld_macro, path); } void zbx_audit_discovery_rule_update_json_lld_macro_path_create_update_entry(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t lld_macro_pathid) { char buf[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(buf, sizeof(buf), "discoveryrule.lld_macro_paths[" ZBX_FS_UI64 "]", lld_macro_pathid); zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, buf); } void zbx_audit_discovery_rule_update_json_update_lld_macro_path(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t lld_macro_pathid, const char *resource, const char *value_old, const char *value_new) { char audit_key[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(audit_key, sizeof(audit_key), "discoveryrule.lld_macro_paths[" ZBX_FS_UI64 "].%s", lld_macro_pathid, resource); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key, value_old, value_new); } #define PREPARE_AUDIT_DISCOVERY_RULE_UPDATE_LLD_MACRO_PATH(resource) \ void zbx_audit_discovery_rule_update_json_update_lld_macro_path_##resource(int audit_context_mode, \ zbx_uint64_t itemid, zbx_uint64_t lld_macro_pathid, const char *resource##_old, \ const char *resource##_new) \ { \ zbx_audit_discovery_rule_update_json_update_lld_macro_path(audit_context_mode, itemid, lld_macro_pathid,\ #resource, resource##_old, resource##_new); \ } PREPARE_AUDIT_DISCOVERY_RULE_UPDATE_LLD_MACRO_PATH(lld_macro) PREPARE_AUDIT_DISCOVERY_RULE_UPDATE_LLD_MACRO_PATH(path) #undef PREPARE_AUDIT_DISCOVERY_RULE_UPDATE_LLD_MACRO_PATH void zbx_audit_discovery_rule_update_json_delete_lld_macro_path(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t lld_macro_pathid) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_audit_entry_update_json_delete_lld_macro_path(audit_entry, lld_macro_pathid); } void zbx_audit_discovery_rule_update_json_add_lld_override(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, const char *name, int step, int stop) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override(audit_entry, overrideid, name, step, stop); } void zbx_audit_discovery_rule_update_json_update_lld_override_str(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, const char *resource, const char *value_old, const char *value_new) { char audit_key[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(audit_key, sizeof(audit_key), "discoveryrule.overrides[" ZBX_FS_UI64 "].%s", overrideid, resource); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key, value_old, value_new); } void zbx_audit_discovery_rule_update_json_delete_lld_override(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_delete_lld_override(audit_entry, overrideid); } void zbx_audit_discovery_rule_update_json_add_lld_override_filter(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, int evaltype, const char *formula) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override_filter(audit_entry, overrideid, evaltype, formula); } void zbx_audit_discovery_rule_update_json_update_lld_override_filter_str(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, const char *resource, const char *value_old, const char *value_new) { char audit_key[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(audit_key, sizeof(audit_key), "discoveryrule.overrides[" ZBX_FS_UI64 "].filter.%s", overrideid, resource); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key, value_old, value_new); } void zbx_audit_discovery_rule_update_json_add_lld_override_condition(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t override_conditionid, int condition_operator, const char *macro, const char *value) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override_condition(audit_entry, overrideid, override_conditionid, condition_operator, macro, value); } void zbx_audit_discovery_rule_update_json_add_lld_override_operation(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t override_operationid, int operationobject, int condition_operator, const char *value) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override_operation(audit_entry, overrideid, override_operationid, operationobject, condition_operator, value); } #define PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(resource, type, type2, table, field) \ void zbx_audit_discovery_rule_update_json_add_lld_override_##resource(int audit_context_mode, \ zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t resource##_id, type resource) \ { \ char key[AUDIT_DETAILS_KEY_LEN]; \ \ zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); \ \ if (NULL == audit_entry) \ return; \ \ zbx_audit_lldrule_override_operation(overrideid, resource##_id, NULL, key, sizeof(key)); \ zbx_audit_entry_add(audit_entry, key); \ zbx_audit_lldrule_override_operation(overrideid, resource##_id, #field, key, sizeof(key)); \ zbx_audit_entry_add_##type2(audit_entry, table, #field, key, resource); \ } PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(opstatus, int, int, "lld_override_opstatus", status) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(opdiscover, int, int, "lld_override_opdiscover", discover) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(opperiod, const char*, string, "lld_override_opperiod", delay) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(optrends, const char*, string, "lld_override_optrends", trends) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(ophistory, const char*, string, "lld_override_ophistory", history) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(opseverity, int, int, "lld_override_opseverity", severity) PREPARE_AUDIT_DISCOVERY_RULE_OVERRIDE_ADD(opinventory, int, int, "lld_override_opinventory", inventory_mode) void zbx_audit_discovery_rule_update_json_add_lld_override_optag(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t override_operationid, zbx_uint64_t lld_override_optagid, const char *tag, const char *value) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override_optag(audit_entry, overrideid, override_operationid, lld_override_optagid, tag, value); } void zbx_audit_discovery_rule_update_json_update_lld_override_optag(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optagid, const char *resource, const char *value_old, const char *value_new) { char audit_key[AUDIT_DETAILS_KEY_LEN], buf[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(audit_key, sizeof(audit_key), "discoveryrule.overrides[" ZBX_FS_UI64 "].operations[" ZBX_FS_UI64 "].%s", overrideid, operationid, resource); zbx_snprintf(buf, sizeof(buf), "discoveryrule.overrides[" ZBX_FS_UI64 "].operations[" ZBX_FS_UI64 "].optag[" ZBX_FS_UI64 "].%s", overrideid, operationid, optagid, resource); zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, buf, value_old, value_new); } void zbx_audit_discovery_rule_update_json_add_lld_override_optemplate(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t lld_override_optemplateid, zbx_uint64_t templateid) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); zbx_audit_entry_update_json_add_lld_override_optemplate(audit_entry, overrideid, operationid, lld_override_optemplateid, templateid); } void zbx_audit_discovery_rule_update_json_update_lld_override_optemplate(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optemplateid, const char *resource, const char *value_old, const char *value_new) { char audit_key[AUDIT_DETAILS_KEY_LEN], buf[AUDIT_DETAILS_KEY_LEN]; RETURN_IF_AUDIT_OFF(audit_context_mode); zbx_snprintf(audit_key, sizeof(audit_key), "discoveryrule.overrides[" ZBX_FS_UI64 "].operations[" ZBX_FS_UI64 "].%s", overrideid, operationid, resource); zbx_snprintf(buf, sizeof(buf), "discoveryrule.overrides[" ZBX_FS_UI64 "].operations[" ZBX_FS_UI64 "].optemplate[" ZBX_FS_UI64 "].%s", overrideid, operationid, optemplateid, resource); zbx_audit_update_json_append_no_value(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, buf, value_old, value_new); } void zbx_audit_item_prototype_update_json_add_lldruleid(int audit_context_mode, zbx_uint64_t itemid, zbx_uint64_t parent_itemid) { zbx_audit_entry_t *audit_entry = zbx_audit_item_get_entry(audit_context_mode, itemid); if (NULL == audit_entry) return; zbx_audit_entry_add_uint64(audit_entry, NULL, NULL, "ruleid", parent_itemid); } void zbx_audit_item_update_json_add_query_fields_json(int audit_context_mode, zbx_uint64_t itemid, int flags, const char *val) { struct zbx_json_parse jp_array, jp_object; const char *element = NULL; char prop[AUDIT_DETAILS_KEY_LEN]; zbx_uint64_t index = 0; RETURN_IF_AUDIT_OFF(audit_context_mode); if (SUCCEED == audit_field_value_matches_db_default("items", "query_fields", val, 0)) return; if (SUCCEED != zbx_json_open(val, &jp_array)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", error: %s", itemid, zbx_json_strerror()); return; } if (NULL == (element = zbx_json_next(&jp_array, element))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", array is empty", itemid); return; } lld_audit_item_prop(flags, "query_fields", prop, sizeof(prop)); do { char name[MAX_STRING_LEN], value[MAX_STRING_LEN]; const char *member; index++; if (SUCCEED != zbx_json_brackets_open(element, &jp_object) || NULL == (member = zbx_json_pair_next(&jp_object, NULL, name, sizeof(name))) || NULL == zbx_json_decodevalue(member, value, sizeof(value), NULL)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", %s", itemid, zbx_json_strerror()); return; } char audit_key_op[AUDIT_DETAILS_KEY_LEN], audit_key_name[AUDIT_DETAILS_KEY_LEN], audit_key_sortorder[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s[" ZBX_FS_UI64 "].name", prop, index); zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_snprintf(audit_key_sortorder, sizeof(audit_key_sortorder), "%s[" ZBX_FS_UI64 "].sortorder", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Added", NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_name, name, NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, value, NULL, NULL); zbx_audit_update_json_append_uint64(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_sortorder, index, NULL, NULL); } while (NULL != (element = zbx_json_next(&jp_array, element))); } void zbx_audit_item_update_json_update_query_fields(int audit_context_mode, zbx_uint64_t itemid, int flags, const char *val_old, const char *val_new) { struct zbx_json_parse jp_array_old, jp_object_old, jp_array_new, jp_object_new; char name_old[MAX_STRING_LEN], value_old[MAX_STRING_LEN], name_new[MAX_STRING_LEN], value_new[MAX_STRING_LEN], prop[AUDIT_DETAILS_KEY_LEN]; const char *member_old, *element_old = NULL, *member_new, *element_new = NULL; RETURN_IF_AUDIT_OFF(audit_context_mode); if (0 == strcmp(val_old, val_new)) return; lld_audit_item_prop(flags, "query_fields", prop, sizeof(prop)); if ((0 != strcmp(val_old, "") && SUCCEED != zbx_json_open(val_old, &jp_array_old)) || (0 != strcmp(val_new, "") && SUCCEED != zbx_json_open(val_new, &jp_array_new))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", error: %s", itemid, zbx_json_strerror()); return; } if (0 != strcmp(val_old, "")) element_old = zbx_json_next(&jp_array_old, element_old); if (0 != strcmp(val_new, "")) element_new = zbx_json_next(&jp_array_new, element_new); zbx_uint64_t index = 0; do { index++; if (NULL != element_old) { if (SUCCEED != zbx_json_brackets_open(element_old, &jp_object_old) || NULL == (member_old = zbx_json_pair_next(&jp_object_old, NULL, name_old, sizeof(name_old))) || NULL == zbx_json_decodevalue(member_old, value_old, sizeof(value_old), NULL)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", error: %s", itemid, zbx_json_strerror()); return; } } if (NULL != element_new) { if (SUCCEED != zbx_json_brackets_open(element_new, &jp_object_new) || NULL == (member_new = zbx_json_pair_next(&jp_object_new, NULL, name_new, sizeof(name_new))) || NULL == zbx_json_decodevalue(member_new, value_new, sizeof(value_new), NULL)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", error: %s", itemid, zbx_json_strerror()); return; } } if (NULL != element_new && NULL != element_old) { if (0 != strcmp(name_old, name_new) || 0 != strcmp(value_old, value_new)) { char audit_key_op[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Updated", NULL, NULL); if (0 != strcmp(name_old, name_new)) { char audit_key_name[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s["ZBX_FS_UI64 "].name", prop, index); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key_name, name_old, name_new); } if (0 != strcmp(value_old, value_new)) { char audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key_value, value_old, value_new); } } } else { // more old values, need to mention they were deleted if (NULL != element_old) { char audit_key_op[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_audit_update_json_delete(itemid, AUDIT_ITEM_ID,AUDIT_DETAILS_ACTION_DELETE, audit_key_op); } else if (NULL != element_new) // more new values, need to mention they were added { char audit_key_op[AUDIT_DETAILS_KEY_LEN], audit_key_name[AUDIT_DETAILS_KEY_LEN], audit_key_sortorder[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s[" ZBX_FS_UI64 "].name", prop, index); zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_snprintf(audit_key_sortorder, sizeof(audit_key_sortorder), "%s[" ZBX_FS_UI64 "].sortorder", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Added", NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_name, name_new, NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, value_new, NULL, NULL); zbx_audit_update_json_append_uint64(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_sortorder, index, NULL, NULL); } } if (NULL != element_old) element_old = zbx_json_next(&jp_array_old, element_old); if (NULL != element_new) element_new = zbx_json_next(&jp_array_new, element_new); if (NULL == element_old && NULL == element_new) break; } while(1); } /* Multiple characters in strtok_r delimiter means several independent */ /* delimiters. In case of headers value, we need a single ": " delimiter. */ /* There seems to be no way for strtok_r to use multiple characters as a */ /* single delimiter. There are no good alternatives, but we can just */ /* specifically ignore this single extra space for a value. */ #define ZBX_NULL2EMPTY_STRTOK_R_VALUE(val) (NULL != (val) ? (val + 1) : "") /******************************************************************************* * * * Comment: * * * * Unlike query_fields headers are not stored in JSON, but instead they * * use their own 'special' format: * * * * query_fields * * -------------------------------- * * [{"qn1":"qv11"},{"qn3":"qv3"}] * * * * headers * * ------------- * * hn1: hv11\r+ * * hn2: hv2 * * * * This is intentional, so server needs to use special parsing for it. * * * *******************************************************************************/ void zbx_audit_item_update_json_add_headers(int audit_context_mode, zbx_uint64_t itemid, int flags, const char *val) { char *val_tmp, *val_mut, *element = NULL, prop[AUDIT_DETAILS_KEY_LEN]; zbx_uint64_t index = 0; RETURN_IF_AUDIT_OFF(audit_context_mode); if (SUCCEED == audit_field_value_matches_db_default("items", "headers", val, 0)) return; lld_audit_item_prop(flags, "headers", prop, sizeof(prop)); val_mut = zbx_strdup(NULL, val); if (NULL == (element = strtok_r(val_mut, "\r\n", &val_tmp))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 ", array is empty", itemid); goto out; } do { index++; char *val_tmp2, *name, *value; if (NULL == (name = strtok_r(element, ":", &val_tmp2))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 " for element %s", itemid, element); goto out; } value = strtok_r(NULL, ":", &val_tmp2); char audit_key_op[AUDIT_DETAILS_KEY_LEN], audit_key_name[AUDIT_DETAILS_KEY_LEN], audit_key_sortorder[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s[" ZBX_FS_UI64 "].name", prop, index); zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_snprintf(audit_key_sortorder, sizeof(audit_key_sortorder), "%s[" ZBX_FS_UI64 "].sortorder", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Added", NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_name, name, NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, ZBX_NULL2EMPTY_STRTOK_R_VALUE(value), NULL, NULL); zbx_audit_update_json_append_uint64(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_sortorder, index, NULL, NULL); } while (NULL != (element = strtok_r(NULL, "\r\n", &val_tmp))); out: zbx_free(val_mut); } void zbx_audit_item_update_json_update_headers(int audit_context_mode, zbx_uint64_t itemid, int flags, const char *val_old, const char *val_new) { char *val_old_tmp, *val_new_tmp, *val_old_mut, *val_new_mut, *element_old = NULL, *element_new = NULL, prop[AUDIT_DETAILS_KEY_LEN]; zbx_uint64_t index = 0; RETURN_IF_AUDIT_OFF(audit_context_mode); if (0 == strcmp(val_old, val_new)) return; lld_audit_item_prop(flags, "headers", prop, sizeof(prop)); val_old_mut = zbx_strdup(NULL, val_old); val_new_mut = zbx_strdup(NULL, val_new); element_old = strtok_r(val_old_mut, "\r\n", &val_old_tmp); element_new = strtok_r(val_new_mut, "\r\n", &val_new_tmp); do { index++; char *val_old_tmp2, *val_new_tmp2, *name_old, *value_old, *name_new, *value_new; if (NULL != element_old) { if (NULL == (name_old = strtok_r(element_old, ":", &val_old_tmp2))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 " for element: %s", itemid, element_old); goto out; } value_old = strtok_r(NULL, ":", &val_old_tmp2); } else value_old = NULL; if (NULL != element_new) { if (NULL == (name_new = strtok_r(element_new, ":", &val_new_tmp2))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 ", for element %s", itemid, element_new); goto out; } value_new = strtok_r(NULL, ":", &val_new_tmp2); } else value_new = NULL; if (NULL != element_new && NULL != element_old) { char audit_key_op[AUDIT_DETAILS_KEY_LEN]; if (0 != strcmp(name_old, name_new) || 0 != strcmp(ZBX_NULL2EMPTY_STR(value_old), ZBX_NULL2EMPTY_STR(value_new))) { zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Updated", NULL, NULL); if (0 != strcmp(name_old, name_new)) { char audit_key_name[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s["ZBX_FS_UI64 "].name", prop, index); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key_name, name_old, name_new); } if (0 != strcmp(ZBX_NULL2EMPTY_STR(value_old), ZBX_NULL2EMPTY_STR(value_new))) { char audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_audit_update_json_update_string(itemid, AUDIT_ITEM_ID, audit_key_value, ZBX_NULL2EMPTY_STRTOK_R_VALUE(value_old), ZBX_NULL2EMPTY_STRTOK_R_VALUE(value_new)); } } } else { // more old values, need to mention they were deleted if (NULL != element_old) { char audit_key_op[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_audit_update_json_delete(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_DELETE, audit_key_op); } else if (NULL != element_new) // more new values, need to mention they were added { char audit_key_op[AUDIT_DETAILS_KEY_LEN], audit_key_name[AUDIT_DETAILS_KEY_LEN], audit_key_sortorder[AUDIT_DETAILS_KEY_LEN], audit_key_value[AUDIT_DETAILS_KEY_LEN]; zbx_snprintf(audit_key_op, sizeof(audit_key_op), "%s[" ZBX_FS_UI64 "]", prop, index); zbx_snprintf(audit_key_name, sizeof(audit_key_name), "%s[" ZBX_FS_UI64 "].name", prop, index); zbx_snprintf(audit_key_value, sizeof(audit_key_value), "%s[" ZBX_FS_UI64 "].value", prop, index); zbx_snprintf(audit_key_sortorder, sizeof(audit_key_sortorder), "%s[" ZBX_FS_UI64 "].sortorder", prop, index); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_op, "Added", NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_name, name_new, NULL, NULL); zbx_audit_update_json_append_string(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_value, ZBX_NULL2EMPTY_STRTOK_R_VALUE(value_new), NULL, NULL); zbx_audit_update_json_append_uint64(itemid, AUDIT_ITEM_ID, AUDIT_DETAILS_ACTION_ADD, audit_key_sortorder, index, NULL, NULL); } } if (NULL != element_old) element_old = strtok_r(NULL, "\r\n", &val_old_tmp); if (NULL != element_new) element_new = strtok_r(NULL, "\r\n", &val_new_tmp); if (NULL == element_old && NULL == element_new) break; } while(1); out: zbx_free(val_old_mut); zbx_free(val_new_mut); } void zbx_audit_entry_update_json_add_headers(zbx_audit_entry_t* audit_entry, const char *val) { #define KEY(s) zbx_audit_item_headers(index, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override" char *val_tmp, *val_mut, *element = NULL, key[AUDIT_DETAILS_KEY_LEN]; int index = 0; if (NULL == audit_entry) return; if (SUCCEED == audit_field_value_matches_db_default("items", "headers", val, 0)) return; val_mut = zbx_strdup(NULL, val); if (NULL == (element = strtok_r(val_mut, "\r\n", &val_tmp))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 ", array is empty", audit_entry->id); goto out; } do { index++; char *val_tmp2, *name, *value; if (NULL == (name = strtok_r(element, ":", &val_tmp2))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse headers for itemid: " ZBX_FS_UI64 " for element %s", audit_entry->id, element); goto out; } value = strtok_r(NULL, ":", &val_tmp2); zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY(NULL), "Added"); zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY("name"), name); zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY("value"), ZBX_NULL2EMPTY_STRTOK_R_VALUE(value)); zbx_audit_entry_add_int(audit_entry, NULL, NULL, KEY("sortorder"), index); } while (NULL != (element = strtok_r(NULL, "\r\n", &val_tmp))); out: zbx_free(val_mut); #undef AUDIT_TABLE_NAME #undef KEY } #undef ZBX_NULL2EMPTY_STRTOK_R_VALUE /****************************************************************************** * * * Purpose: get audit entry for an item * * * * Parameters: audit_context_mode - [IN] audit context mode * * itemid - [IN] host identifier * * * * Return value: pointer to the audit entry or NULL if audit is disabled * * * ******************************************************************************/ zbx_audit_entry_t *zbx_audit_item_get_entry(int audit_context_mode, zbx_uint64_t itemid) { int audit_enabled = 0; zbx_audit_get_status(audit_context_mode, &audit_enabled); if (0 == audit_enabled) return NULL; return audit_get_entry(itemid, NULL, AUDIT_ITEM_ID); } /****************************************************************************** * * * Purpose: get or create audit entry for a host * * * * Parameters: audit_context_mode - [IN] audit context mode * * audit_action - [IN] audit action * * hostid - [IN] host identifier * * name - [IN] host name * * flags - [IN] host flags * * * * Return value: pointer to the audit entry or NULL if audit is disabled * * * ******************************************************************************/ zbx_audit_entry_t *zbx_audit_item_get_or_create_entry(int audit_context_mode, int audit_action, zbx_uint64_t itemid, const char *name, int flags) { int audit_enabled = 0; zbx_audit_get_status(audit_context_mode, &audit_enabled); if (0 == audit_enabled) return NULL; zbx_audit_entry_t audit_entry_local, *paudit_entry_local = &audit_entry_local, **audit_entry; audit_entry_local.id = itemid; audit_entry_local.cuid = NULL; audit_entry_local.id_table = AUDIT_ITEM_ID; if (NULL == (audit_entry = (zbx_audit_entry_t **)zbx_hashset_search(zbx_get_audit_hashset(), &paudit_entry_local))) { int resource_type = zbx_audit_item_flag_to_resource_type(flags); paudit_entry_local = zbx_audit_entry_init(itemid, AUDIT_ITEM_ID, name, audit_action, resource_type); audit_entry = (zbx_audit_entry_t **)zbx_hashset_insert(zbx_get_audit_hashset(), &paudit_entry_local, sizeof(paudit_entry_local)); } return *audit_entry; } const char *zbx_audit_lldrule_macro_path(zbx_uint64_t lld_macro_pathid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "lld_macro_paths[" ZBX_FS_UI64 "]", lld_macro_pathid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_filter_condition(zbx_uint64_t filterid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "filter.conditions[" ZBX_FS_UI64 "]", filterid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override(zbx_uint64_t overrideid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "overrides[" ZBX_FS_UI64 "]", overrideid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override_filter(zbx_uint64_t overrideid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "overrides[" ZBX_FS_UI64 "].filter", overrideid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override_filter_condition(zbx_uint64_t overrideid, zbx_uint64_t filterid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "overrides[" ZBX_FS_UI64 "].filter.conditions[" ZBX_FS_UI64 "]", overrideid, filterid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override_operation(zbx_uint64_t overrideid, zbx_uint64_t operationid, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "overrides[" ZBX_FS_UI64 "].operations[" ZBX_FS_UI64 "]", overrideid, operationid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override_operation_optag(zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optagid, const char *field, char *key, size_t key_size) { size_t offset; zbx_audit_lldrule_override_operation(overrideid, operationid, NULL, key, key_size); offset = strlen(key); offset += zbx_snprintf(key + offset, key_size - offset, ".optags[" ZBX_FS_UI64 "]", optagid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_lldrule_override_operation_optemplate(zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optemplateid, const char *field, char *key, size_t key_size) { size_t offset; zbx_audit_lldrule_override_operation(overrideid, operationid, NULL, key, key_size); offset = strlen(key); offset += zbx_snprintf(key + offset, key_size - offset, ".optemplates[" ZBX_FS_UI64 "]", optemplateid); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_item_query_fields(int index, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "query_fields[%d]", index); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } const char *zbx_audit_item_headers(int index, const char *field, char *key, size_t key_size) { size_t offset = zbx_snprintf(key, key_size, "headers[%d]", index); if (NULL != field) zbx_snprintf(key + offset, key_size - offset, ".%s", field); return key; } void zbx_audit_audit_entry_update_json_delete_lld_macro_path(zbx_audit_entry_t *audit_entry, zbx_uint64_t lld_macro_pathid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_macro_path(lld_macro_pathid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_add_lld_macro_path(zbx_audit_entry_t *audit_entry, zbx_uint64_t lld_macro_pathid, const char *lld_macro, const char *path) { #define KEY(s) zbx_audit_lldrule_macro_path(lld_macro_pathid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_macro_path" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "lld_macro", KEY("lld_macro"), lld_macro); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "path", KEY("path"), path); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_delete_filter_conditions(zbx_audit_entry_t *audit_entry, zbx_uint64_t rule_conditionid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_filter_condition(rule_conditionid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_add_filter_conditions(zbx_audit_entry_t *audit_entry, zbx_uint64_t rule_conditionid, zbx_uint64_t op, const char *macro, const char *value) { #define KEY(s) zbx_audit_lldrule_filter_condition(rule_conditionid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "item_condition" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add_string(audit_entry, NULL, NULL, "filter", "Added"); zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, NULL, NULL, KEY("item_conditionid"), rule_conditionid); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "operator", KEY("operator"), op); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "macro", KEY("macro"), macro); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "value", KEY("value"), value); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_delete_lld_override_filter(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t conditionid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_override_filter_condition(overrideid, conditionid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_delete_lld_override_operation(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t operationid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_override_operation(overrideid, operationid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_delete_lld_override_operation_optag(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optagid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_override_operation_optag(overrideid, operationid, optagid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_delete_lld_override_operation_optemplate(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t optemplateid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_override_operation_optemplate(overrideid, operationid, optemplateid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_add_lld_override_condition(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t override_conditionid, int condition_operator, const char *macro, const char *value) { #define KEY(s) zbx_audit_lldrule_override_filter_condition(overrideid, override_conditionid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override_condition" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, AUDIT_TABLE_NAME, "lld_override_conditionid", KEY("lld_override_conditionid"), override_conditionid); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "operator", KEY("operator"), condition_operator); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "macro", KEY("macro"), macro); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "value", KEY("value"), value); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_add_lld_override_operation(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t override_operationid, int operationobject, int condition_operator, const char *value) { #define KEY(s) zbx_audit_lldrule_override_operation(overrideid, override_operationid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override_operation" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, AUDIT_TABLE_NAME, "lld_override_operationid", KEY("lld_override_operationid"), override_operationid); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "operationobject", KEY("operationobject"), operationobject); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "operator", KEY("operator"), condition_operator); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "value", KEY("value"), value); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_add_lld_override_optag(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t override_operationid, zbx_uint64_t lld_override_optagid, const char *tag, const char *value) { #define KEY(s) zbx_audit_lldrule_override_operation_optag(overrideid, override_operationid, lld_override_optagid, s, \ key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override_optag" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, AUDIT_TABLE_NAME, "lld_override_optagid", KEY("lld_override_optagid"), lld_override_optagid); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "tag", KEY("tag"), tag); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "value", KEY("value"), value); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_add_lld_override_optemplate(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, zbx_uint64_t operationid, zbx_uint64_t lld_override_optemplateid, zbx_uint64_t templateid) { #define KEY(s) zbx_audit_lldrule_override_operation_optemplate(overrideid, operationid, lld_override_optemplateid, s, \ key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override_optemplate" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, AUDIT_TABLE_NAME, "templateid", KEY("templateid"), templateid); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_delete_lld_override(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid) { if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_lldrule_override(overrideid, NULL, key, sizeof(key)); zbx_audit_entry_delete(audit_entry, key); } void zbx_audit_entry_update_json_add_lld_override(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, const char *name, int step, int stop) { #define KEY(s) zbx_audit_lldrule_override(overrideid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_uint64(audit_entry, NULL, NULL, KEY("lld_overrideid"), overrideid); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "name", KEY("name"), name); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "step", KEY("step"), step); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "stop", KEY("stop"), stop); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_add_lld_override_filter(zbx_audit_entry_t *audit_entry, zbx_uint64_t overrideid, int evaltype, const char *formula) { #define KEY(s) zbx_audit_lldrule_override_filter(overrideid, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override" if (NULL == audit_entry) return; char key[AUDIT_DETAILS_KEY_LEN]; zbx_audit_entry_add(audit_entry, KEY(NULL)); zbx_audit_entry_add_int(audit_entry, AUDIT_TABLE_NAME, "evaltype", KEY("evaltype"), evaltype); zbx_audit_entry_add_string(audit_entry, AUDIT_TABLE_NAME, "formula", KEY("formula"), formula); #undef AUDIT_TABLE_NAME #undef KEY } void zbx_audit_entry_update_json_add_query_fields_json(zbx_audit_entry_t *audit_entry, const char *val) { #define KEY(s) zbx_audit_item_query_fields(index, s, key, sizeof(key)) #define AUDIT_TABLE_NAME "lld_override" struct zbx_json_parse jp_array, jp_object; const char *element = NULL; char key[AUDIT_DETAILS_KEY_LEN]; int index = 0; if (NULL == audit_entry) return; if (SUCCEED == audit_field_value_matches_db_default("items", "query_fields", val, 0)) return; if (SUCCEED != zbx_json_open(val, &jp_array)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", error: %s", audit_entry->id, zbx_json_strerror()); return; } if (NULL == (element = zbx_json_next(&jp_array, element))) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", array is empty", audit_entry->id); return; } do { char name[MAX_STRING_LEN], value[MAX_STRING_LEN]; const char *member; index++; if (SUCCEED != zbx_json_brackets_open(element, &jp_object) || NULL == (member = zbx_json_pair_next(&jp_object, NULL, name, sizeof(name))) || NULL == zbx_json_decodevalue(member, value, sizeof(value), NULL)) { zabbix_log(LOG_LEVEL_ERR, "cannot parse query fields for itemid: " ZBX_FS_UI64 ", %s", audit_entry->id, zbx_json_strerror()); return; } zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY(NULL), "Added"); zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY("name"), name); zbx_audit_entry_add_string(audit_entry, NULL, NULL, KEY("value"), value); zbx_audit_entry_add_int(audit_entry, NULL, NULL, KEY("sortorder"), index); } while (NULL != (element = zbx_json_next(&jp_array, element))); #undef AUDIT_TABLE_NAME #undef KEY }