Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/zbxaudit/audit.c')
-rw-r--r--src/libs/zbxaudit/audit.c218
1 files changed, 162 insertions, 56 deletions
diff --git a/src/libs/zbxaudit/audit.c b/src/libs/zbxaudit/audit.c
index 061f53bd15c..0ae7b0907e9 100644
--- a/src/libs/zbxaudit/audit.c
+++ b/src/libs/zbxaudit/audit.c
@@ -40,22 +40,25 @@ zbx_hashset_t *zbx_get_audit_hashset(void)
return &zbx_audit;
}
-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(zbx_uint64_t id, const int id_table, 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 = id;
audit_entry->cuid = NULL;
+ audit_entry->id_table = id_table;
audit_entry->name = zbx_strdup(NULL, name);
audit_entry->audit_action = audit_action;
audit_entry->resource_type = resource_type;
+ zbx_new_cuid(audit_entry->audit_cuid);
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,
+zbx_audit_entry_t *zbx_audit_entry_init_cuid(const char *cuid, const int id_table, const char *name, int audit_action,
int resource_type)
{
zbx_audit_entry_t *audit_entry;
@@ -63,9 +66,11 @@ zbx_audit_entry_t *zbx_audit_entry_init_cuid(const char *cuid, const char *name,
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->id_table = id_table;
audit_entry->name = zbx_strdup(NULL, name);
audit_entry->audit_action = audit_action;
audit_entry->resource_type = resource_type;
+ zbx_new_cuid(audit_entry->audit_cuid);
zbx_json_init(&(audit_entry->details_json), ZBX_JSON_STAT_BUF_LEN);
return audit_entry;
@@ -168,10 +173,10 @@ int zbx_auditlog_global_script(unsigned char script_type, unsigned char script_e
zbx_uint64_t proxy_hostid, zbx_uint64_t userid, const char *username, const char *clientip,
const char *output, const char *error)
{
- int ret = SUCCEED;
- char auditid_cuid[CUID_LEN], execute_on_s[MAX_ID_LEN + 1], hostid_s[MAX_ID_LEN + 1],
- eventid_s[MAX_ID_LEN + 1], proxy_hostid_s[MAX_ID_LEN + 1];
-
+ int ret = SUCCEED;
+ char auditid_cuid[CUID_LEN], execute_on_s[MAX_ID_LEN + 1], hostid_s[MAX_ID_LEN + 1],
+ eventid_s[MAX_ID_LEN + 1], proxy_hostid_s[MAX_ID_LEN + 1];
+ char *details_esc;
struct zbx_json details_json;
zbx_config_t cfg;
@@ -209,27 +214,24 @@ int zbx_auditlog_global_script(unsigned char script_type, unsigned char script_e
append_str_json(&details_json, AUDIT_DETAILS_ACTION_ADD, "script.command", script_command_orig);
if (NULL != output)
- {
- char *output_esc;
-
- output_esc = zbx_strdup(NULL, output);
- zbx_json_escape(&output_esc);
- append_str_json(&details_json, AUDIT_DETAILS_ACTION_ADD, "script.output", output_esc);
- zbx_free(output_esc);
- }
+ append_str_json(&details_json, AUDIT_DETAILS_ACTION_ADD, "script.output", output);
if (NULL != error)
append_str_json(&details_json, AUDIT_DETAILS_ACTION_ADD, "script.error", error);
+ details_esc = DBdyn_escape_string(details_json.buffer);
+
if (ZBX_DB_OK > DBexecute("insert into auditlog (auditid,userid,username,clock,action,ip,resourceid,"
"resourcename,resourcetype,recordsetid,details) values ('%s'," ZBX_FS_UI64 ",'%s',%d,'%d','%s',"
ZBX_FS_UI64 ",'%s',%d,'%s','%s')", auditid_cuid, userid, username, (int)time(NULL),
AUDIT_ACTION_EXECUTE, clientip, hostid, hostname, AUDIT_RESOURCE_SCRIPT, auditid_cuid,
- details_json.buffer))
+ details_esc))
{
ret = FAIL;
}
+ zbx_free(details_esc);
+
zbx_json_free(&details_json);
out:
zabbix_log(LOG_LEVEL_TRACE, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -239,15 +241,15 @@ 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;
+ const zbx_audit_entry_t * const *audit_entry = (const zbx_audit_entry_t * const *)data;
hash = ZBX_DEFAULT_UINT64_HASH_FUNC(&(*audit_entry)->id);
if (NULL != (*audit_entry)->cuid)
hash = ZBX_DEFAULT_STRING_HASH_ALGO((*audit_entry)->cuid, strlen((*audit_entry)->cuid), hash);
- return hash;
+ return ZBX_DEFAULT_UINT64_HASH_ALGO(&((*audit_entry)->id_table), sizeof((*audit_entry)->id_table), hash);
}
static int zbx_audit_compare_func(const void *d1, const void *d2)
@@ -256,6 +258,7 @@ static int zbx_audit_compare_func(const void *d1, const void *d2)
const zbx_audit_entry_t * const *audit_entry_2 = (const zbx_audit_entry_t * const *)d2;
ZBX_RETURN_IF_NOT_EQUAL((*audit_entry_1)->id, (*audit_entry_2)->id);
+ ZBX_RETURN_IF_NOT_EQUAL((*audit_entry_1)->id_table, (*audit_entry_2)->id_table);
return zbx_strcmp_null((*audit_entry_1)->cuid, (*audit_entry_2)->cuid);
}
@@ -299,7 +302,7 @@ int zbx_audit_initialized(void)
void zbx_audit_flush(void)
{
- char audit_cuid[CUID_LEN], recsetid_cuid[CUID_LEN];
+ char recsetid_cuid[CUID_LEN];
zbx_hashset_iter_t iter;
zbx_audit_entry_t **audit_entry;
zbx_db_insert_t db_insert_audit;
@@ -314,15 +317,18 @@ void zbx_audit_flush(void)
while (NULL != (audit_entry = (zbx_audit_entry_t **)zbx_hashset_iter_next(&iter)))
{
- zbx_new_cuid(audit_cuid);
if (AUDIT_ACTION_DELETE == (*audit_entry)->audit_action ||
0 != strcmp((*audit_entry)->details_json.buffer, "{}"))
{
- 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);
+ char *details_esc;
+
+ details_esc = DBdyn_escape_string((*audit_entry)->details_json.buffer);
+
+ zbx_db_insert_add_values(&db_insert_audit, (*audit_entry)->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(details_esc, "{}") ? "" : details_esc);
+ zbx_free(details_esc);
}
}
@@ -334,7 +340,7 @@ void zbx_audit_flush(void)
int zbx_audit_flush_once(void)
{
- char audit_cuid[CUID_LEN], recsetid_cuid[CUID_LEN];
+ char recsetid_cuid[CUID_LEN];
int ret = ZBX_DB_OK;
zbx_hashset_iter_t iter;
zbx_audit_entry_t **audit_entry;
@@ -347,7 +353,7 @@ int zbx_audit_flush_once(void)
while (NULL != (audit_entry = (zbx_audit_entry_t **)zbx_hashset_iter_next(&iter)))
{
- char id[ZBX_MAX_UINT64_LEN + 1], *pfield, *pvalue, *name_esc;
+ char id[ZBX_MAX_UINT64_LEN + 1], *pfield, *pvalue, *name_esc, *details_esc;
if (AUDIT_ACTION_DELETE != (*audit_entry)->audit_action &&
0 == strcmp((*audit_entry)->details_json.buffer, "{}"))
@@ -355,8 +361,6 @@ int zbx_audit_flush_once(void)
continue;
}
- zbx_new_cuid(audit_cuid);
-
if (0 != (*audit_entry)->id)
{
zbx_snprintf(id, sizeof(id), ZBX_FS_UI64, (*audit_entry)->id);
@@ -370,15 +374,16 @@ int zbx_audit_flush_once(void)
}
name_esc = DBdyn_escape_string((*audit_entry)->name);
+ details_esc = DBdyn_escape_string((*audit_entry)->details_json.buffer);
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),
+ pfield, (*audit_entry)->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);
+ recsetid_cuid, 0 == strcmp(details_esc, "{}") ? "" : details_esc);
+ zbx_free(details_esc);
zbx_free(name_esc);
if (ZBX_DB_OK > ret)
@@ -390,15 +395,65 @@ int zbx_audit_flush_once(void)
return ret;
}
-void zbx_audit_update_json_append_string(const zbx_uint64_t id, const char *audit_op, const char *key,
- const char *value)
+static int audit_field_default(const char *table_name, const char *field_name, const char *value, uint64_t id)
+{
+ static ZBX_THREAD_LOCAL char cached_table_name[ZBX_TABLENAME_LEN_MAX];
+ static ZBX_THREAD_LOCAL const ZBX_TABLE *table = NULL;
+ const ZBX_FIELD *field;
+
+ if (NULL == table_name)
+ return FAIL;
+
+ /* Often 'table_name' stays the same and only 'field_name' changes in successive calls of this function. */
+ /* Here a simple caching of DBget_table() result is implemented. We rely on static array 'cached_table_name' */
+ /* initialization with zero bytes, i.e. with empty string. */
+
+ if ('\0' == cached_table_name[0] || 0 != strcmp(cached_table_name, table_name))
+ {
+ if (NULL == (table = DBget_table(table_name)))
+ {
+ zabbix_log(LOG_LEVEL_CRIT, "%s(): cannot find table '%s'", __func__, table_name);
+ THIS_SHOULD_NEVER_HAPPEN;
+ return FAIL;
+ }
+
+ zbx_strlcpy(cached_table_name, table_name, sizeof(cached_table_name));
+ }
+
+ if (NULL == (field = DBget_field(table, field_name)))
+ {
+ zabbix_log(LOG_LEVEL_CRIT, "%s(): table '%s', cannot find field '%s'", __func__, table_name,
+ field_name);
+ THIS_SHOULD_NEVER_HAPPEN;
+ return FAIL;
+ }
+
+ if (NULL != field->default_value)
+ {
+ if (NULL != value && (0 == strcmp(value, field->default_value) ||
+ (ZBX_TYPE_FLOAT == field->type && SUCCEED == zbx_double_compare(atof(value),
+ atof(field->default_value)))))
+ {
+ return SUCCEED;
+ }
+ }
+ else if (NULL == value || (ZBX_TYPE_ID == field->type && 0 == id))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+void zbx_audit_update_json_append_string(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key, const char *value, const char *table, const char *field)
{
zbx_audit_entry_t local_audit_entry, **found_audit_entry;
zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry;
- local_audit_entry.id = id;
- local_audit_entry.cuid = NULL;
+ if (SUCCEED == audit_field_default(table, field, value, 0))
+ return;
+ local_audit_entry.id = id;
+ local_audit_entry.id_table = id_table;
found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &(local_audit_entry_x));
if (NULL == found_audit_entry)
@@ -410,15 +465,41 @@ void zbx_audit_update_json_append_string(const zbx_uint64_t id, const char *audi
append_str_json(&((*found_audit_entry)->details_json), audit_op, key, value);
}
-void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const char *audit_op, const char *key,
- uint64_t value)
+void zbx_audit_update_json_append_string_secret(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key, const char *value, const char *table, const char *field)
{
zbx_audit_entry_t local_audit_entry, **found_audit_entry;
zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry;
+ if (SUCCEED == audit_field_default(table, field, value, 0))
+ return;
+
local_audit_entry.id = id;
- local_audit_entry.cuid = NULL;
+ local_audit_entry.id_table = id_table;
+ found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &(local_audit_entry_x));
+
+ if (NULL == found_audit_entry)
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ exit(EXIT_FAILURE);
+ }
+
+ append_str_json(&((*found_audit_entry)->details_json), audit_op, key, ZBX_MACRO_SECRET_MASK);
+}
+
+void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key, uint64_t value, const char *table, const char *field)
+{
+ char buffer[MAX_ID_LEN];
+ zbx_audit_entry_t local_audit_entry, **found_audit_entry;
+ zbx_audit_entry_t *local_audit_entry_x = &local_audit_entry;
+
+ zbx_snprintf(buffer, sizeof(buffer), ZBX_FS_UI64, value);
+ if (SUCCEED == audit_field_default(table, field, buffer, value))
+ return;
+ local_audit_entry.id = id;
+ local_audit_entry.id_table = id_table;
found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &(local_audit_entry_x));
if (NULL == found_audit_entry)
@@ -435,8 +516,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; \
- \
+ local_audit_entry.id_table = id_table; \
found_audit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, \
&(local_audit_entry_x)); \
if (NULL == found_audit_entry) \
@@ -445,64 +525,90 @@ void zbx_audit_update_json_append_uint64(const zbx_uint64_t id, const char *audi
exit(EXIT_FAILURE); \
} \
-void zbx_audit_update_json_append_no_value(const zbx_uint64_t id, const char *audit_op, const char *key)
+void zbx_audit_update_json_append_no_value(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key)
{
PREPARE_UPDATE_JSON_APPEND_OP();
append_json_no_value(&((*found_audit_entry)->details_json), audit_op, key);
}
-void zbx_audit_update_json_append_int(const zbx_uint64_t id, const char *audit_op, const char *key, int value)
+void zbx_audit_update_json_append_int(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key, int value, const char *table, const char *field)
{
- PREPARE_UPDATE_JSON_APPEND_OP();
- append_int_json(&((*found_audit_entry)->details_json), audit_op, key, value);
+ char buffer[MAX_ID_LEN];
+
+ zbx_snprintf(buffer, sizeof(buffer), "%d", value);
+
+ if (SUCCEED == audit_field_default(table, field, buffer, 0))
+ {
+ return;
+ }
+ else
+ {
+ PREPARE_UPDATE_JSON_APPEND_OP();
+ append_int_json(&((*found_audit_entry)->details_json), audit_op, key, value);
+ }
}
-void zbx_audit_update_json_append_double(const zbx_uint64_t id, const char *audit_op, const char *key, double value)
+void zbx_audit_update_json_append_double(const zbx_uint64_t id, const int id_table, const char *audit_op,
+ const char *key, double value, const char *table, const char *field)
{
- PREPARE_UPDATE_JSON_APPEND_OP();
- append_double_json(&((*found_audit_entry)->details_json), audit_op, key, value);
+ char buffer[MAX_ID_LEN];
+
+ zbx_snprintf(buffer, sizeof(buffer), ZBX_FS_DBL, value);
+
+ if (SUCCEED == audit_field_default(table, field, buffer, 0))
+ {
+ return;
+ }
+ else
+ {
+ PREPARE_UPDATE_JSON_APPEND_OP();
+ append_double_json(&((*found_audit_entry)->details_json), audit_op, key, value);
+ }
}
-void zbx_audit_update_json_update_string(const zbx_uint64_t id, const char *key, const char *value_old,
- const char *value_new)
+void zbx_audit_update_json_update_string(const zbx_uint64_t id, const int id_table, const char *key,
+ const char *value_old, const char *value_new)
{
PREPARE_UPDATE_JSON_APPEND_OP();
update_str_json(&((*found_audit_entry)->details_json), key, value_old, value_new);
}
-void zbx_audit_update_json_update_uint64(const zbx_uint64_t id, const char *key, uint64_t value_old,
- uint64_t value_new)
+void zbx_audit_update_json_update_uint64(const zbx_uint64_t id, const int id_table, const char *key,
+ uint64_t value_old, uint64_t value_new)
{
PREPARE_UPDATE_JSON_APPEND_OP();
update_uint64_json(&((*found_audit_entry)->details_json), key, value_old, value_new);
}
-void zbx_audit_update_json_update_int(const zbx_uint64_t id, const char *key, int value_old,
+void zbx_audit_update_json_update_int(const zbx_uint64_t id, const int id_table, const char *key, int value_old,
int value_new)
{
PREPARE_UPDATE_JSON_APPEND_OP();
update_int_json(&((*found_audit_entry)->details_json), key, value_old, 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_update_double(const zbx_uint64_t id, const int id_table, const char *key,
+ double value_old, double value_new)
{
PREPARE_UPDATE_JSON_APPEND_OP();
update_double_json(&((*found_audit_entry)->details_json), key, value_old, value_new);
}
-void zbx_audit_update_json_delete(const zbx_uint64_t id, const char *audit_op, const char *key)
+void zbx_audit_update_json_delete(const zbx_uint64_t id, const int id_table, const char *audit_op, const char *key)
{
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 *zbx_audit_get_entry(zbx_uint64_t id, const char *cuid, int id_table)
{
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;
+ local_audit_entry.id_table = id_table;
if (NULL == (paudit_entry = (zbx_audit_entry_t**)zbx_hashset_search(&zbx_audit, &plocal_audit_entry)))
{