/*
** Zabbix
** Copyright (C) 2001-2020 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 <stddef.h>
#include "common.h"
#include "log.h"
#include "threads.h"
#include "dbcache.h"
#include "ipc.h"
#include "mutexs.h"
#include "memalloc.h"
#include "zbxserver.h"
#include "zbxalgo.h"
#include "zbxregexp.h"
#include "cfg.h"
#include "zbxtasks.h"
#include "../zbxcrypto/tls_tcp_active.h"
#define ZBX_DBCONFIG_IMPL
#include "dbconfig.h"
#include "dbsync.h"
#include "actions.h"
int sync_in_progress = 0;
#define START_SYNC WRLOCK_CACHE; sync_in_progress = 1
#define FINISH_SYNC sync_in_progress = 0; UNLOCK_CACHE
#define ZBX_LOC_NOWHERE 0
#define ZBX_LOC_QUEUE 1
#define ZBX_LOC_POLLER 2
#define ZBX_SNMP_OID_TYPE_NORMAL 0
#define ZBX_SNMP_OID_TYPE_DYNAMIC 1
#define ZBX_SNMP_OID_TYPE_MACRO 2
/* trigger is functional unless its expression contains disabled or not monitored items */
#define TRIGGER_FUNCTIONAL_TRUE 0
#define TRIGGER_FUNCTIONAL_FALSE 1
/* trigger contains time functions and is also scheduled by timer queue */
#define ZBX_TRIGGER_TIMER_UNKNOWN 0
#define ZBX_TRIGGER_TIMER_QUEUE 1
/* item priority in poller queue */
#define ZBX_QUEUE_PRIORITY_HIGH 0
#define ZBX_QUEUE_PRIORITY_NORMAL 1
#define ZBX_QUEUE_PRIORITY_LOW 2
/* shorthand macro for calling in_maintenance_without_data_collection() */
#define DCin_maintenance_without_data_collection(dc_host, dc_item) \
in_maintenance_without_data_collection(dc_host->maintenance_status, \
dc_host->maintenance_type, dc_item->type)
/******************************************************************************
* *
* Function: zbx_value_validator_func_t *
* *
* Purpose: validate macro value when expanding user macros *
* *
* Parameters: macro - [IN] the user macro *
* value - [IN] the macro value *
* error - [OUT] the error message *
* *
* Return value: SUCCEED - the value is valid *
* FAIL - otherwise *
* *
******************************************************************************/
typedef int (*zbx_value_validator_func_t)(const char *macro, const char *value, char **error);
ZBX_DC_CONFIG *config = NULL;
zbx_rwlock_t config_lock = ZBX_RWLOCK_NULL;
static zbx_mem_info_t *config_mem;
extern unsigned char program_type;
extern int CONFIG_TIMER_FORKS;
ZBX_MEM_FUNC_IMPL(__config, config_mem)
static void dc_maintenance_precache_nested_groups(void);
/******************************************************************************
* *
* Function: dc_strdup *
* *
* Purpose: copies string into configuration cache shared memory *
* *
******************************************************************************/
static char *dc_strdup(const char *source)
{
char *dst;
size_t len;
len = strlen(source) + 1;
dst = (char *)__config_mem_malloc_func(NULL, len);
memcpy(dst, source, len);
return dst;
}
/******************************************************************************
* *
* Function: is_item_processed_by_server *
* *
* Parameters: type - [IN] item type [ITEM_TYPE_* flag] *
* key - [IN] item key *
* *
* Return value: SUCCEED when an item should be processed by server *
* FAIL otherwise *
* *
* Comments: list of the items, always processed by server *
* ,------------------+--------------------------------------, *
* | type | key | *
* +------------------+--------------------------------------+ *
* | Zabbix internal | zabbix[host,,items] | *
* | Zabbix internal | zabbix[host,,items_unsupported] | *
* | Zabbix internal | zabbix[host,discovery,interfaces] | *
* | Zabbix internal | zabbix[host,,maintenance] | *
* | Zabbix internal | zabbix[proxy,<proxyname>,lastaccess] | *
* | Zabbix aggregate | * | *
* | Calculated | * | *
* '------------------+--------------------------------------' *
* *
******************************************************************************/
int is_item_processed_by_server(unsigned char type, const char *key)
{
int ret = FAIL;
switch (type)
{
case ITEM_TYPE_AGGREGATE:
case ITEM_TYPE_CALCULATED:
ret = SUCCEED;
break;
case ITEM_TYPE_INTERNAL:
if (0 == strncmp(key, "zabbix[", 7))
{
AGENT_REQUEST request;
char *arg1, *arg2, *arg3;
init_request(&request);
if (SUCCEED != parse_item_key(key, &request) || 3 != request.nparam)
goto clean;
arg1 = get_rparam(&request, 0);
arg2 = get_rparam(&request, 1);
arg3 = get_rparam(&request, 2);
if (0 == strcmp(arg1, "host"))
{
if ('\0' == *arg2)
{
if (0 == strcmp(arg3, "maintenance") || 0 == strcmp(arg3, "items") ||
0 == strcmp(arg3, "items_unsupported"))
{
ret = SUCCEED;
}
}
else if (0 == strcmp(arg2, "discovery") && 0 == strcmp(arg3, "interfaces"))
ret = SUCCEED;
}
else if (0 == strcmp(arg1, "proxy") && 0 == strcmp(arg3, "lastaccess"))
ret = SUCCEED;
clean:
free_request(&request);
}
break;
}
return ret;
}
static unsigned char poller_by_item(unsigned char type, const char *key)
{
switch (type)
{
case ITEM_TYPE_SIMPLE:
if (SUCCEED == cmp_key_id(key, SERVER_ICMPPING_KEY) ||
SUCCEED == cmp_key_id(key, SERVER_ICMPPINGSEC_KEY) ||
SUCCEED == cmp_key_id(key, SERVER_ICMPPINGLOSS_KEY))
{
if (0 == CONFIG_PINGER_FORKS)
break;
return ZBX_POLLER_TYPE_PINGER;
}
ZBX_FALLTHROUGH;
case ITEM_TYPE_ZABBIX:
case ITEM_TYPE_SNMPv1:
case ITEM_TYPE_SNMPv2c:
case ITEM_TYPE_SNMPv3:
case ITEM_TYPE_INTERNAL:
case ITEM_TYPE_AGGR