diff options
author | Andris Zeila <andris.zeila@zabbix.com> | 2021-10-13 00:31:08 +0300 |
---|---|---|
committer | Andris Zeila <andris.zeila@zabbix.com> | 2021-10-13 00:31:54 +0300 |
commit | cb736d76972cb6266b3742cb32739fa106f08cfa (patch) | |
tree | 4bf1297075e7e733f8bac2ad58a06847efb0d88a /src/libs/zbxaudit | |
parent | 93b1a386e3229eeb43573760b9412e35f7001694 (diff) |
........S. [ZBXNEXT-6923] added audit logging to HA node operations
Diffstat (limited to 'src/libs/zbxaudit')
-rw-r--r-- | src/libs/zbxaudit/Makefile.am | 4 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit.c | 170 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit.h | 17 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_ha.c | 76 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_ha.h | 29 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_host.c | 2 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_httptest.c | 1 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_item.c | 2 | ||||
-rw-r--r-- | src/libs/zbxaudit/audit_trigger.c | 1 |
9 files changed, 290 insertions, 12 deletions
diff --git a/src/libs/zbxaudit/Makefile.am b/src/libs/zbxaudit/Makefile.am index 93d84ed6da1..1eba5ebb4af 100644 --- a/src/libs/zbxaudit/Makefile.am +++ b/src/libs/zbxaudit/Makefile.am @@ -14,4 +14,6 @@ libzbxaudit_a_SOURCES = \ audit_trigger.c \ audit_trigger.h \ audit_graph.c \ - audit_graph.h + audit_graph.h \ + audit_ha.c \ + audit_ha.h diff --git a/src/libs/zbxaudit/audit.c b/src/libs/zbxaudit/audit.c index 8a862bb5252..60fe27c295d 100644 --- a/src/libs/zbxaudit/audit.c +++ b/src/libs/zbxaudit/audit.c @@ -23,6 +23,10 @@ #include "audit.h" +#define AUDIT_USERID 0 +#define AUDIT_USERNAME "System" +#define AUDIT_IP "" + static int audit_mode; static zbx_hashset_t zbx_audit; @@ -42,6 +46,23 @@ zbx_audit_entry_t *zbx_audit_entry_init(zbx_uint64_t id, const char *name, int a audit_entry = (zbx_audit_entry_t*)zbx_malloc(NULL, sizeof(zbx_audit_entry_t)); audit_entry->id = id; + audit_entry->cuid = NULL; + audit_entry->name = zbx_strdup(NULL, name); + audit_entry->audit_action = audit_action; + audit_entry->resource_type = resource_type; + zbx_json_init(&(audit_entry->details_json), ZBX_JSON_STAT_BUF_LEN); + + return audit_entry; +} + +zbx_audit_entry_t *zbx_audit_entry_init_cuid(const char *cuid, const char *name, int audit_action, + int resource_type) +{ + zbx_audit_entry_t *audit_entry; + + audit_entry = (zbx_audit_entry_t*)zbx_malloc(NULL, sizeof(zbx_audit_entry_t)); + audit_entry->id = 0; + audit_entry->cuid = zbx_strdup(NULL, cuid); audit_entry->name = zbx_strdup(NULL, name); audit_entry->audit_action = audit_action; audit_entry->resource_type = resource_type; @@ -219,9 +240,14 @@ out: static unsigned zbx_audit_hash_func(const void *data) { const zbx_audit_entry_t * const *audit_entry = (const zbx_audit_entry_t * const *)data; + zbx_hash_t hash; + + hash = ZBX_DEFAULT_UINT64_HASH_FUNC(&(*audit_entry)->id); - return ZBX_DEFAULT_UINT64_HASH_ALGO(&((*audit_entry)->id), sizeof((*audit_entry)->id), - ZBX_DEFAULT_HASH_SEED); + if (NULL != (*audit_entry)->cuid) + hash = ZBX_DEFAULT_STRING_HASH_ALGO((*audit_entry)->cuid, strlen((*audit_entry)->cuid), hash); + + return hash; } static int zbx_audit_compare_func(const void *d1, const void *d2) @@ -231,10 +257,10 @@ static int zbx_audit_compare_func(const void *d1, const void *d2) ZBX_RETURN_IF_NOT_EQUAL((*audit_entry_1)->id, (*audit_entry_2)->id); - return 0; + return zbx_strcmp_null((*audit_entry_1)->cuid, (*audit_entry_2)->cuid); } -static void zbx_audit_clean(void) +void zbx_audit_clean(void) { zbx_hashset_iter_t iter; zbx_audit_entry_t **audit_entry; @@ -247,6 +273,7 @@ static void zbx_audit_clean(void) { zbx_json_free(&((*audit_entry)->details_json)); zbx_free((*audit_entry)->name); + zbx_free((*audit_entry)->cuid); zbx_free(*audit_entry); } @@ -262,6 +289,14 @@ void zbx_audit_init(int audit_mode_set) #undef AUDIT_HASHSET_DEF_SIZE } +int zbx_audit_initialized(void) +{ + if (ZBX_AUDITLOG_ENABLED != zbx_get_audit_mode()) + return SUCCEED; + + return 0 == zbx_audit.num_slots ? SUCCEED : FAIL; +} + void zbx_audit_flush(void) { char audit_cuid[CUID_LEN], recsetid_cuid[CUID_LEN]; @@ -283,17 +318,11 @@ void zbx_audit_flush(void) if (AUDIT_ACTION_DELETE == (*audit_entry)->audit_action || 0 != strcmp((*audit_entry)->details_json.buffer, "{}")) { -#define AUDIT_USERID 0 -#define AUDIT_USERNAME "System" -#define AUDIT_IP "" zbx_db_insert_add_values(&db_insert_audit, audit_cuid, AUDIT_USERID, AUDIT_USERNAME, (int)time(NULL), (*audit_entry)->audit_action, AUDIT_IP, (*audit_entry)->id, (*audit_entry)->name, (*audit_entry)->resource_type, recsetid_cuid, 0 == strcmp((*audit_entry)->details_json.buffer, "{}") ? "" : (*audit_entry)->details_json.buffer); -#undef AUDIT_USERID -#undef AUDIT_USERNAME -#undef AUDIT_IP } } @@ -303,6 +332,61 @@ void zbx_audit_flush(void) zbx_audit_clean(); } +void zbx_audit_flush_once(void) +{ + char audit_cuid[CUID_LEN], recsetid_cuid[CUID_LEN]; + int ret; + zbx_hashset_iter_t iter; + zbx_audit_entry_t **audit_entry; + + RETURN_IF_AUDIT_OFF(); + + zbx_new_cuid(recsetid_cuid); + zbx_hashset_iter_reset(&zbx_audit, &iter); + + while (NULL != (audit_entry = (zbx_audit_entry_t **)zbx_hashset_iter_next(&iter))) + { + char id[ZBX_MAX_UINT64_LEN + 1], *pfield, *pvalue, *name_esc; + + if (AUDIT_ACTION_DELETE != (*audit_entry)->audit_action && + 0 == strcmp((*audit_entry)->details_json.buffer, "{}")) + { + continue; + } + + zbx_new_cuid(audit_cuid); + + if (0 != (*audit_entry)->id) + { + zbx_snprintf(id, sizeof(id), ZBX_FS_UI64, (*audit_entry)->id); + pfield = "resourceid"; + pvalue = id; + } + else + { + pfield = "resource_cuid"; + pvalue = (*audit_entry)->cuid; + } + + name_esc = DBdyn_escape_string((*audit_entry)->name); + + ret = DBexecute_once("insert into auditlog (auditid,userid,username," + "clock,action,ip,%s,resourcename,resourcetype,recordsetid,details) values" + " ('%s',%d,'%s','%d','%d','%s','%s','%s',%d,'%s','%s')", + pfield, audit_cuid, AUDIT_USERID, AUDIT_USERNAME, (int)time(NULL), + (*audit_entry)->audit_action, AUDIT_IP, pvalue, name_esc, (*audit_entry)->resource_type, + recsetid_cuid, 0 == strcmp((*audit_entry)->details_json.buffer, "{}") ? "" : + (*audit_entry)->details_json.buffer); + + zbx_free(name_esc); + + if (ZBX_DB_OK > ret) + break; + } + + zbx_audit_clean(); +} + void zbx_audit_update_json_append_string(const zbx_uint64_t id, const char *audit_op, const char *key, const char *value) { @@ -310,6 +394,7 @@ void zbx_audit_update_json_append_string(const zbx_uint64_t id, const char *audi zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry; local_audit_entry.id = id; + local_audit_entry.cuid = NULL; found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &(local_audit_entry_x)); @@ -329,6 +414,7 @@ void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const char *audi zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry; local_audit_entry.id = id; + local_audit_entry.cuid = NULL; found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &(local_audit_entry_x)); @@ -346,6 +432,7 @@ void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const char *audi zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry; \ \ local_audit_entry.id = id; \ + local_audit_entry.cuid = NULL; \ \ found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, \ &(local_audit_entry_x)); \ @@ -406,3 +493,66 @@ void zbx_audit_update_json_delete(const zbx_uint64_t id, const char *audit_op, c PREPARE_UPDATE_JSON_APPEND_OP(); delete_json(&((*found_audit_entry)->details_json), audit_op, key); } + +zbx_audit_entry_t *zbx_audit_get_entry(zbx_uint64_t id, const char *cuid) +{ + zbx_audit_entry_t local_audit_entry, *plocal_audit_entry = &local_audit_entry, **paudit_entry; + + local_audit_entry.id = id; + local_audit_entry.cuid = (char *)cuid; + + if (NULL == (paudit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &plocal_audit_entry))) + { + THIS_SHOULD_NEVER_HAPPEN; + exit(EXIT_FAILURE); + } + + return *paudit_entry; +} + + +void zbx_audit_entry_append_int(zbx_audit_entry_t *entry, int audit_op, char *key, ...) +{ + va_list args; + int value1, value2; + + va_start(args, key); + value1 = va_arg(args, int); + + switch (audit_op) + { + case AUDIT_ACTION_ADD: + append_int_json(&entry->details_json, AUDIT_DETAILS_ACTION_ADD, key, value1); + break; + case AUDIT_ACTION_UPDATE: + value2 = va_arg(args, int); + update_int_json(&entry->details_json, key, value1, value2); + break; + } + + va_end(args); +} + +void zbx_audit_entry_append_string(zbx_audit_entry_t *entry, int audit_op, const char *key, ...) +{ + va_list args; + const char *value1, *value2; + + va_start(args, key); + value1 = va_arg(args, const char *); + + switch (audit_op) + { + case AUDIT_ACTION_ADD: + append_str_json(&entry->details_json, AUDIT_DETAILS_ACTION_ADD, key, value1); + break; + case AUDIT_ACTION_UPDATE: + value2 = va_arg(args, const char *); + update_str_json(&entry->details_json, key, value1, value2); + break; + } + + va_end(args); +} + + diff --git a/src/libs/zbxaudit/audit.h b/src/libs/zbxaudit/audit.h index e8d7be68ae6..98a8dbc50b7 100644 --- a/src/libs/zbxaudit/audit.h +++ b/src/libs/zbxaudit/audit.h @@ -49,6 +49,8 @@ #define AUDIT_RESOURCE_ITEM_PROTOTYPE 36 #define AUDIT_RESOURCE_HOST_PROTOTYPE 37 +#define AUDIT_RESOURCE_HA_NODE 47 + #define RETURN_IF_AUDIT_OFF() \ if (ZBX_AUDITLOG_ENABLED != zbx_get_audit_mode()) \ return \ @@ -59,13 +61,18 @@ zbx_hashset_t *zbx_get_audit_hashset(void); typedef struct zbx_audit_entry { zbx_uint64_t id; + char *cuid; char *name; struct zbx_json details_json; int audit_action; int resource_type; -} zbx_audit_entry_t; +} +zbx_audit_entry_t; zbx_audit_entry_t *zbx_audit_entry_init(zbx_uint64_t id, const char *name, int audit_action, int resource_type); +zbx_audit_entry_t *zbx_audit_entry_init_cuid(const char *cuid, const char *name, int audit_action, + int resource_type); + int zbx_auditlog_global_script(unsigned char script_type, unsigned char script_execute_on, const char *script_command_orig, zbx_uint64_t hostid, const char *hostname, zbx_uint64_t eventid, @@ -73,7 +80,10 @@ int zbx_auditlog_global_script(unsigned char script_type, unsigned char script_e const char *output, const char *error); void zbx_audit_init(int audit_mode_set); +void zbx_audit_clean(void); void zbx_audit_flush(void); +void zbx_audit_flush_once(void); +int zbx_audit_initialized(void); void zbx_audit_update_json_append_string(const zbx_uint64_t id, const char *audit_op, const char *key, const char *value); void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const char *audit_op, const char *key, @@ -88,4 +98,9 @@ void zbx_audit_update_json_update_uint64(const zbx_uint64_t id, const char *key, void zbx_audit_update_json_update_int(const zbx_uint64_t id, const char *key, int value_old, int value_new); void zbx_audit_update_json_update_double(const zbx_uint64_t id, const char *key, double value_old, double value_new); void zbx_audit_update_json_delete(const zbx_uint64_t id, const char *audit_op, const char *key); + +zbx_audit_entry_t *zbx_audit_get_entry(zbx_uint64_t id, const char *cuid); +void zbx_audit_entry_append_int(zbx_audit_entry_t *entry, int audit_op, char *key, ...); +void zbx_audit_entry_append_string(zbx_audit_entry_t *entry, int audit_op, const char *key, ...); + #endif /* ZABBIX_AUDIT_H */ diff --git a/src/libs/zbxaudit/audit_ha.c b/src/libs/zbxaudit/audit_ha.c new file mode 100644 index 00000000000..63e23fcbf72 --- /dev/null +++ b/src/libs/zbxaudit/audit_ha.c @@ -0,0 +1,76 @@ +/* +** Zabbix +** Copyright (C) 2001-2021 Zabbix SIA +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** 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 General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**/ + +#include "zbxalgo.h" +#include "zbxjson.h" +#include "audit.h" + +void zbx_audit_ha_create_entry(int audit_action, const char *nodeid, const char *name) +{ + zbx_audit_entry_t local_audit_entry, *plocal_audit_entry = &local_audit_entry; + + RETURN_IF_AUDIT_OFF(); + + local_audit_entry.id = 0; + local_audit_entry.cuid = (char *)nodeid; + + if (NULL == zbx_hashset_search(zbx_get_audit_hashset(), &plocal_audit_entry)) + { + zbx_audit_entry_t *new_entry; + + new_entry = zbx_audit_entry_init_cuid(nodeid, name, audit_action, AUDIT_RESOURCE_HA_NODE); + zbx_hashset_insert(zbx_get_audit_hashset(), &new_entry, sizeof(new_entry)); + } +} + +void zbx_audit_ha_add_create_fields(const char *nodeid, const char *name, int status) +{ + zbx_audit_entry_t *entry; + + RETURN_IF_AUDIT_OFF(); + + entry = zbx_audit_get_entry(0, nodeid); + + zbx_audit_entry_append_string(entry, AUDIT_ACTION_ADD, "ha_node.ha_nodeid", nodeid); + zbx_audit_entry_append_string(entry, AUDIT_ACTION_ADD, "ha_node.name", name); + zbx_audit_entry_append_int(entry, AUDIT_ACTION_ADD, "ha_node.status", status); +} + +void zbx_audit_ha_update_field_string(const char *nodeid, const char *key, const char *old_value, + const char *new_value) +{ + zbx_audit_entry_t *entry; + + RETURN_IF_AUDIT_OFF(); + + entry = zbx_audit_get_entry(0, nodeid); + zbx_audit_entry_append_string(entry, AUDIT_ACTION_UPDATE, key, old_value, new_value); +} + +void zbx_audit_ha_update_field_int(const char *nodeid, const char *key, int old_value, int new_value) +{ + zbx_audit_entry_t *entry; + + RETURN_IF_AUDIT_OFF(); + + entry = zbx_audit_get_entry(0, nodeid); + zbx_audit_entry_append_int(entry, AUDIT_ACTION_UPDATE, key, old_value, new_value); +} + + diff --git a/src/libs/zbxaudit/audit_ha.h b/src/libs/zbxaudit/audit_ha.h new file mode 100644 index 00000000000..16ac5149ec0 --- /dev/null +++ b/src/libs/zbxaudit/audit_ha.h @@ -0,0 +1,29 @@ +/* +** Zabbix +** Copyright (C) 2001-2021 Zabbix SIA +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** 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 General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**/ + +#ifndef ZABBIX_AUDIT_HA_H +#define ZABBIX_AUDIT_HA_H + +void zbx_audit_ha_create_entry(int audit_action, const char *nodeid, const char *name); +void zbx_audit_ha_add_create_fields(const char *nodeid, const char *name, int status); +void zbx_audit_ha_update_field_string(const char *nodeid, const char *key, const char *old_value, + const char *new_value); +void zbx_audit_ha_update_field_int(const char *nodeid, const char *key, int old_value, int new_value); + +#endif diff --git a/src/libs/zbxaudit/audit_host.c b/src/libs/zbxaudit/audit_host.c index 5184e55a53f..625c95aca18 100644 --- a/src/libs/zbxaudit/audit_host.c +++ b/src/libs/zbxaudit/audit_host.c @@ -189,6 +189,7 @@ void zbx_audit_##funcname##_create_entry(int audit_action, zbx_uint64_t hostid, RETURN_IF_AUDIT_OFF(); \ \ local_audit_host_entry.id = hostid; \ + local_audit_host_entry.cuid = NULL; \ \ found_audit_host_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), \ &(local_audit_host_entry_x)); \ @@ -803,6 +804,7 @@ void zbx_audit_host_group_create_entry(int audit_action, zbx_uint64_t groupid, c RETURN_IF_AUDIT_OFF(); local_audit_group_entry.id = groupid; + local_audit_group_entry.cuid = NULL; found_audit_group_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_group_entry_x)); diff --git a/src/libs/zbxaudit/audit_httptest.c b/src/libs/zbxaudit/audit_httptest.c index 2ea11f7bc61..877c8f52205 100644 --- a/src/libs/zbxaudit/audit_httptest.c +++ b/src/libs/zbxaudit/audit_httptest.c @@ -30,6 +30,7 @@ void zbx_audit_httptest_create_entry(int audit_action, zbx_uint64_t httptestid, RETURN_IF_AUDIT_OFF(); local_audit_httptest_entry.id = httptestid; + local_audit_httptest_entry.cuid = NULL; found_audit_httptest_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_httptest_entry_x)); diff --git a/src/libs/zbxaudit/audit_item.c b/src/libs/zbxaudit/audit_item.c index ca9fa16d104..30dff344caf 100644 --- a/src/libs/zbxaudit/audit_item.c +++ b/src/libs/zbxaudit/audit_item.c @@ -56,6 +56,7 @@ void zbx_audit_item_create_entry(int audit_action, zbx_uint64_t itemid, const ch resource_type = item_flag_to_resource_type(flags); local_audit_item_entry.id = itemid; + local_audit_item_entry.cuid = NULL; found_audit_item_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_item_entry_x)); @@ -361,6 +362,7 @@ void zbx_audit_item_create_entry_for_delete(zbx_uint64_t id, const char *name, i resource_type = item_flag_to_resource_type(flag); local_audit_item_entry.id = id; + local_audit_item_entry.cuid = NULL; found_audit_item_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_item_entry_x)); diff --git a/src/libs/zbxaudit/audit_trigger.c b/src/libs/zbxaudit/audit_trigger.c index d68d482303e..50008ca03a9 100644 --- a/src/libs/zbxaudit/audit_trigger.c +++ b/src/libs/zbxaudit/audit_trigger.c @@ -53,6 +53,7 @@ void zbx_audit_trigger_create_entry(int audit_action, zbx_uint64_t triggerid, co resource_type = trigger_flag_to_resource_type(flags); local_audit_trigger_entry.id = triggerid; + local_audit_trigger_entry.cuid = NULL; found_audit_trigger_entry = (zbx_audit_entry_t**)zbx_hashset_search(zbx_get_audit_hashset(), &(local_audit_trigger_entry_x)); |