1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 #include "db.h"
22 #include "dbcache.h"
23 #include "log.h"
24 #include "zbxserver.h"
25 #include "zbxregexp.h"
26 #include "zbxcompress.h"
27 
28 #include "../../libs/zbxcrypto/tls_tcp_active.h"
29 
30 #include "active.h"
31 
32 extern unsigned char	program_type;
33 
34 /******************************************************************************
35  *                                                                            *
36  * Function: db_register_host                                                 *
37  *                                                                            *
38  * Purpose: perform active agent auto registration                            *
39  *                                                                            *
40  * Parameters: host          - [IN] name of the host to be added or updated   *
41  *             ip            - [IN] IP address of the host                    *
42  *             port          - [IN] port of the host                          *
43  *             connection_type - [IN] ZBX_TCP_SEC_UNENCRYPTED,                *
44  *                             ZBX_TCP_SEC_TLS_PSK or ZBX_TCP_SEC_TLS_CERT    *
45  *             host_metadata - [IN] host metadata                             *
46  *             flag          - [IN] flag describing interface type            *
47  *             interface     - [IN] interface value if flag is not default    *
48  *                                                                            *
49  * Comments: helper function for get_hostid_by_host                           *
50  *                                                                            *
51  ******************************************************************************/
db_register_host(const char * host,const char * ip,unsigned short port,unsigned int connection_type,const char * host_metadata,zbx_conn_flags_t flag,const char * interface)52 static void	db_register_host(const char *host, const char *ip, unsigned short port, unsigned int connection_type,
53 		const char *host_metadata, zbx_conn_flags_t flag, const char *interface)
54 {
55 	char		dns[INTERFACE_DNS_LEN_MAX];
56 	char		ip_addr[INTERFACE_IP_LEN_MAX];
57 	const char	*p;
58 	const char	*p_ip, *p_dns;
59 
60 	p_ip = ip;
61 	p_dns = dns;
62 
63 	if (ZBX_CONN_DEFAULT == flag)
64 		p = ip;
65 	else if (ZBX_CONN_IP  == flag)
66 		p_ip = p = interface;
67 
68 	zbx_alarm_on(CONFIG_TIMEOUT);
69 	if (ZBX_CONN_DEFAULT == flag || ZBX_CONN_IP == flag)
70 	{
71 		if (0 == strncmp("::ffff:", p, 7) && SUCCEED == is_ip4(p + 7))
72 			p += 7;
73 
74 		zbx_gethost_by_ip(p, dns, sizeof(dns));
75 	}
76 	else if (ZBX_CONN_DNS == flag)
77 	{
78 		zbx_getip_by_host(interface, ip_addr, sizeof(ip_addr));
79 		p_ip = ip_addr;
80 		p_dns = interface;
81 	}
82 	zbx_alarm_off();
83 
84 	DBbegin();
85 
86 	if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
87 	{
88 		DBregister_host(0, host, p_ip, p_dns, port, connection_type, host_metadata, (unsigned short)flag,
89 				(int)time(NULL));
90 	}
91 	else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY))
92 		DBproxy_register_host(host, p_ip, p_dns, port, connection_type, host_metadata, (unsigned short)flag);
93 
94 	DBcommit();
95 }
96 
zbx_autoreg_check_permissions(const char * host,const char * ip,unsigned short port,const zbx_socket_t * sock)97 static int	zbx_autoreg_check_permissions(const char *host, const char *ip, unsigned short port,
98 		const zbx_socket_t *sock)
99 {
100 	zbx_config_t	cfg;
101 	int		ret = FAIL;
102 
103 	zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_AUTOREG_TLS_ACCEPT);
104 
105 	if (0 == (cfg.autoreg_tls_accept & sock->connection_type))
106 	{
107 		zabbix_log(LOG_LEVEL_WARNING, "autoregistration from \"%s\" denied (host:\"%s\" ip:\"%s\""
108 				" port:%hu): connection type \"%s\" is not allowed for autoregistration",
109 				sock->peer, host, ip, port, zbx_tcp_connection_type_name(sock->connection_type));
110 		goto out;
111 	}
112 
113 #if defined(HAVE_GNUTLS) || (defined(HAVE_OPENSSL) && defined(HAVE_OPENSSL_WITH_PSK))
114 	if (ZBX_TCP_SEC_TLS_PSK == sock->connection_type)
115 	{
116 		if (0 == (ZBX_PSK_FOR_AUTOREG & zbx_tls_get_psk_usage()))
117 		{
118 			zabbix_log(LOG_LEVEL_WARNING, "autoregistration from \"%s\" denied (host:\"%s\" ip:\"%s\""
119 					" port:%hu): connection used PSK which is not configured for autoregistration",
120 					sock->peer, host, ip, port);
121 			goto out;
122 		}
123 
124 		ret = SUCCEED;
125 	}
126 	else if (ZBX_TCP_SEC_UNENCRYPTED == sock->connection_type)
127 	{
128 		ret = SUCCEED;
129 	}
130 	else
131 		THIS_SHOULD_NEVER_HAPPEN;
132 #else
133 	ret = SUCCEED;
134 #endif
135 out:
136 	zbx_config_clean(&cfg);
137 
138 	return ret;
139 }
140 
141 /******************************************************************************
142  *                                                                            *
143  * Function: get_hostid_by_host                                               *
144  *                                                                            *
145  * Purpose: check for host name and return hostid                             *
146  *                                                                            *
147  * Parameters: sock          - [IN] open socket of server-agent connection    *
148  *             host          - [IN] host name                                 *
149  *             ip            - [IN] IP address of the host                    *
150  *             port          - [IN] port of the host                          *
151  *             host_metadata - [IN] host metadata                             *
152  *             flag          - [IN] flag describing interface type            *
153  *             interface     - [IN] interface value if flag is not default    *
154  *             hostid        - [OUT] host ID                                  *
155  *             error         - [OUT] error message                            *
156  *                                                                            *
157  * Return value:  SUCCEED - host is found                                     *
158  *                FAIL - an error occurred or host not found                  *
159  *                                                                            *
160  * Author: Alexander Vladishev                                                *
161  *                                                                            *
162  * Comments: NB! adds host to the database if it does not exist or if it      *
163  *           exists but metadata, interface, interface type or port has       *
164  *           changed                                                          *
165  *                                                                            *
166  ******************************************************************************/
get_hostid_by_host(const zbx_socket_t * sock,const char * host,const char * ip,unsigned short port,const char * host_metadata,zbx_conn_flags_t flag,const char * interface,zbx_uint64_t * hostid,char * error)167 static int	get_hostid_by_host(const zbx_socket_t *sock, const char *host, const char *ip, unsigned short port,
168 		const char *host_metadata, zbx_conn_flags_t flag, const char *interface, zbx_uint64_t *hostid,
169 		char *error)
170 {
171 	char			*host_esc, *ch_error, *old_metadata, *old_ip, *old_dns, *old_flag, *old_port;
172 	DB_RESULT		result;
173 	DB_ROW			row;
174 	unsigned short		old_port_v;
175 	int			tls_offset = 0, ret = FAIL;
176 	zbx_conn_flags_t	old_flag_v;
177 
178 	zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' metadata:'%s'", __func__, host, host_metadata);
179 
180 	if (FAIL == zbx_check_hostname(host, &ch_error))
181 	{
182 		zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]: %s", host, ch_error);
183 		zbx_free(ch_error);
184 		goto out;
185 	}
186 
187 	host_esc = DBdyn_escape_string(host);
188 
189 	result =
190 #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
191 		DBselect(
192 			"select h.hostid,h.status,h.tls_accept,h.tls_issuer,h.tls_subject,h.tls_psk_identity,"
193 			"a.host_metadata,a.listen_ip,a.listen_dns,a.listen_port,a.flags"
194 			" from hosts h"
195 				" left join autoreg_host a"
196 					" on a.proxy_hostid is null and a.host=h.host"
197 			" where h.host='%s'"
198 				" and h.status in (%d,%d)"
199 				" and h.flags<>%d"
200 				" and h.proxy_hostid is null",
201 			host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE);
202 #else
203 		DBselect(
204 			"select h.hostid,h.status,h.tls_accept,a.host_metadata,a.listen_ip,a.listen_dns,a.listen_port,"
205 			"a.flags"
206 			" from hosts h"
207 				" left join autoreg_host a"
208 					" on a.proxy_hostid is null and a.host=h.host"
209 			" where h.host='%s'"
210 				" and h.status in (%d,%d)"
211 				" and h.flags<>%d"
212 				" and h.proxy_hostid is null",
213 			host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE);
214 #endif
215 	if (NULL != (row = DBfetch(result)))
216 	{
217 		if (0 == ((unsigned int)atoi(row[2]) & sock->connection_type))
218 		{
219 			zbx_snprintf(error, MAX_STRING_LEN, "connection of type \"%s\" is not allowed for host"
220 					" \"%s\"", zbx_tcp_connection_type_name(sock->connection_type), host);
221 			goto done;
222 		}
223 
224 #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
225 		if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
226 		{
227 			zbx_tls_conn_attr_t	attr;
228 
229 			if (SUCCEED != zbx_tls_get_attr_cert(sock, &attr))
230 			{
231 				THIS_SHOULD_NEVER_HAPPEN;
232 
233 				zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host"
234 						" \"%s\"", host);
235 				goto done;
236 			}
237 
238 			/* simplified match, not compliant with RFC 4517, 4518 */
239 			if ('\0' != *row[3] && 0 != strcmp(row[3], attr.issuer))
240 			{
241 				zbx_snprintf(error, MAX_STRING_LEN, "certificate issuer does not match for"
242 						" host \"%s\"", host);
243 				goto done;
244 			}
245 
246 			/* simplified match, not compliant with RFC 4517, 4518 */
247 			if ('\0' != *row[4] && 0 != strcmp(row[4], attr.subject))
248 			{
249 				zbx_snprintf(error, MAX_STRING_LEN, "certificate subject does not match for"
250 						" host \"%s\"", host);
251 				goto done;
252 			}
253 		}
254 #if defined(HAVE_GNUTLS) || (defined(HAVE_OPENSSL) && defined(HAVE_OPENSSL_WITH_PSK))
255 		else if (ZBX_TCP_SEC_TLS_PSK == sock->connection_type)
256 		{
257 			zbx_tls_conn_attr_t	attr;
258 
259 			if (SUCCEED != zbx_tls_get_attr_psk(sock, &attr))
260 			{
261 				THIS_SHOULD_NEVER_HAPPEN;
262 
263 				zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host"
264 						" \"%s\"", host);
265 				goto done;
266 			}
267 
268 			if (strlen(row[5]) != attr.psk_identity_len ||
269 					0 != memcmp(row[5], attr.psk_identity, attr.psk_identity_len))
270 			{
271 				zbx_snprintf(error, MAX_STRING_LEN, "false PSK identity for host \"%s\"", host);
272 				goto done;
273 			}
274 		}
275 #endif
276 		tls_offset = 3;
277 #endif
278 		old_metadata = row[3 + tls_offset];
279 		old_ip = row[4 + tls_offset];
280 		old_dns = row[5 + tls_offset];
281 		old_port = row[6 + tls_offset];
282 		old_flag = row[7 + tls_offset];
283 		old_port_v = (unsigned short)(SUCCEED == DBis_null(old_port)) ? 0 : atoi(old_port);
284 		old_flag_v = (zbx_conn_flags_t)(SUCCEED == DBis_null(old_flag)) ? ZBX_CONN_DEFAULT : atoi(old_flag);
285 		/* metadata is available only on Zabbix server */
286 		if (SUCCEED == DBis_null(old_flag) || 0 != strcmp(old_metadata, host_metadata) ||
287 				(ZBX_CONN_IP  == flag && ( 0 != strcmp(old_ip, interface)  || old_port_v != port)) ||
288 				(ZBX_CONN_DNS == flag && ( 0 != strcmp(old_dns, interface) || old_port_v != port)) ||
289 				(old_flag_v != flag))
290 		{
291 			db_register_host(host, ip, port, sock->connection_type, host_metadata, flag, interface);
292 		}
293 
294 		if (HOST_STATUS_MONITORED != atoi(row[1]))
295 		{
296 			zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host);
297 			goto done;
298 		}
299 
300 		ZBX_STR2UINT64(*hostid, row[0]);
301 		ret = SUCCEED;
302 	}
303 	else
304 	{
305 		zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host);
306 
307 		if (SUCCEED == zbx_autoreg_check_permissions(host, ip, port, sock))
308 			db_register_host(host, ip, port, sock->connection_type, host_metadata, flag, interface);
309 	}
310 done:
311 	DBfree_result(result);
312 
313 	zbx_free(host_esc);
314 out:
315 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
316 
317 	return ret;
318 }
319 
get_list_of_active_checks(zbx_uint64_t hostid,zbx_vector_uint64_t * itemids)320 static void	get_list_of_active_checks(zbx_uint64_t hostid, zbx_vector_uint64_t *itemids)
321 {
322 	DB_RESULT	result;
323 	DB_ROW		row;
324 	zbx_uint64_t	itemid;
325 
326 	result = DBselect(
327 			"select itemid"
328 			" from items"
329 			" where type=%d"
330 				" and flags<>%d"
331 				" and hostid=" ZBX_FS_UI64,
332 			ITEM_TYPE_ZABBIX_ACTIVE, ZBX_FLAG_DISCOVERY_PROTOTYPE, hostid);
333 
334 	while (NULL != (row = DBfetch(result)))
335 	{
336 		ZBX_STR2UINT64(itemid, row[0]);
337 		zbx_vector_uint64_append(itemids, itemid);
338 	}
339 	DBfree_result(result);
340 }
341 
342 /******************************************************************************
343  *                                                                            *
344  * Function: send_list_of_active_checks                                       *
345  *                                                                            *
346  * Purpose: send list of active checks to the host (older version agent)      *
347  *                                                                            *
348  * Parameters: sock - open socket of server-agent connection                  *
349  *             request - request buffer                                       *
350  *                                                                            *
351  * Return value:  SUCCEED - list of active checks sent successfully           *
352  *                FAIL - an error occurred                                    *
353  *                                                                            *
354  * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n      *
355  *           format of the list: key:delay:last_log_size                      *
356  *                                                                            *
357  ******************************************************************************/
send_list_of_active_checks(zbx_socket_t * sock,char * request)358 int	send_list_of_active_checks(zbx_socket_t *sock, char *request)
359 {
360 	char			*host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN];
361 	size_t			buffer_alloc = 8 * ZBX_KIBIBYTE, buffer_offset = 0;
362 	int			ret = FAIL, i;
363 	zbx_uint64_t		hostid;
364 	zbx_vector_uint64_t	itemids;
365 
366 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
367 
368 	if (NULL != (host = strchr(request, '\n')))
369 	{
370 		host++;
371 		if (NULL != (p = strchr(host, '\n')))
372 			*p = '\0';
373 	}
374 	else
375 	{
376 		zbx_snprintf(error, sizeof(error), "host is null");
377 		goto out;
378 	}
379 
380 	/* no host metadata in older versions of agent */
381 	if (FAIL == get_hostid_by_host(sock, host, sock->peer, ZBX_DEFAULT_AGENT_PORT, "", 0, "",  &hostid, error))
382 		goto out;
383 
384 	zbx_vector_uint64_create(&itemids);
385 
386 	get_list_of_active_checks(hostid, &itemids);
387 
388 	buffer = (char *)zbx_malloc(buffer, buffer_alloc);
389 
390 	if (0 != itemids.values_num)
391 	{
392 		DC_ITEM		*dc_items;
393 		int		*errcodes;
394 
395 		dc_items = (DC_ITEM *)zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num);
396 		errcodes = (int *)zbx_malloc(NULL, sizeof(int) * itemids.values_num);
397 
398 		DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num);
399 
400 		for (i = 0; i < itemids.values_num; i++)
401 		{
402 			int	delay;
403 
404 			if (SUCCEED != errcodes[i])
405 			{
406 				zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the"
407 						" server cache. Not sending now.", __func__, itemids.values[i]);
408 				continue;
409 			}
410 
411 			if (ITEM_STATUS_ACTIVE != dc_items[i].status)
412 				continue;
413 
414 			if (HOST_STATUS_MONITORED != dc_items[i].host.status)
415 				continue;
416 
417 			if (SUCCEED != zbx_interval_preproc(dc_items[i].delay, &delay, NULL, NULL))
418 				continue;
419 
420 			zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%d:" ZBX_FS_UI64 "\n",
421 					dc_items[i].key_orig, delay, dc_items[i].lastlogsize);
422 		}
423 
424 		DCconfig_clean_items(dc_items, errcodes, itemids.values_num);
425 
426 		zbx_free(errcodes);
427 		zbx_free(dc_items);
428 	}
429 
430 	zbx_vector_uint64_destroy(&itemids);
431 
432 	zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n");
433 
434 	zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __func__, buffer);
435 
436 	zbx_alarm_on(CONFIG_TIMEOUT);
437 	if (SUCCEED != zbx_tcp_send_raw(sock, buffer))
438 		zbx_strlcpy(error, zbx_socket_strerror(), MAX_STRING_LEN);
439 	else
440 		ret = SUCCEED;
441 	zbx_alarm_off();
442 
443 	zbx_free(buffer);
444 out:
445 	if (FAIL == ret)
446 		zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error);
447 
448 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
449 
450 	return ret;
451 }
452 
453 /******************************************************************************
454  *                                                                            *
455  * Function: zbx_vector_str_append_uniq                                       *
456  *                                                                            *
457  * Purpose: append non duplicate string to the string vector                  *
458  *                                                                            *
459  * Parameters: vector - [IN/OUT] the string vector                            *
460  *             str    - [IN] the string to append                             *
461  *                                                                            *
462  ******************************************************************************/
zbx_vector_str_append_uniq(zbx_vector_str_t * vector,const char * str)463 static void	zbx_vector_str_append_uniq(zbx_vector_str_t *vector, const char *str)
464 {
465 	if (FAIL == zbx_vector_str_search(vector, str, ZBX_DEFAULT_STR_COMPARE_FUNC))
466 		zbx_vector_str_append(vector, zbx_strdup(NULL, str));
467 }
468 
469 /******************************************************************************
470  *                                                                            *
471  * Function: zbx_itemkey_extract_global_regexps                               *
472  *                                                                            *
473  * Purpose: extract global regular expression names from item key             *
474  *                                                                            *
475  * Parameters: key     - [IN] the item key to parse                           *
476  *             regexps - [OUT] the extracted regular expression names         *
477  *                                                                            *
478  ******************************************************************************/
zbx_itemkey_extract_global_regexps(const char * key,zbx_vector_str_t * regexps)479 static void	zbx_itemkey_extract_global_regexps(const char *key, zbx_vector_str_t *regexps)
480 {
481 #define ZBX_KEY_LOG		1
482 #define ZBX_KEY_EVENTLOG	2
483 
484 	AGENT_REQUEST	request;
485 	int		item_key;
486 	const char	*param;
487 
488 	if (0 == strncmp(key, "log[", 4) || 0 == strncmp(key, "logrt[", 6) || 0 == strncmp(key, "log.count[", 10) ||
489 			0 == strncmp(key, "logrt.count[", 12))
490 		item_key = ZBX_KEY_LOG;
491 	else if (0 == strncmp(key, "eventlog[", 9))
492 		item_key = ZBX_KEY_EVENTLOG;
493 	else
494 		return;
495 
496 	init_request(&request);
497 
498 	if(SUCCEED != parse_item_key(key, &request))
499 		goto out;
500 
501 	/* "params" parameter */
502 	if (NULL != (param = get_rparam(&request, 1)) && '@' == *param)
503 		zbx_vector_str_append_uniq(regexps, param + 1);
504 
505 	if (ZBX_KEY_EVENTLOG == item_key)
506 	{
507 		/* "severity" parameter */
508 		if (NULL != (param = get_rparam(&request, 2)) && '@' == *param)
509 			zbx_vector_str_append_uniq(regexps, param + 1);
510 
511 		/* "source" parameter */
512 		if (NULL != (param = get_rparam(&request, 3)) && '@' == *param)
513 			zbx_vector_str_append_uniq(regexps, param + 1);
514 
515 		/* "logeventid" parameter */
516 		if (NULL != (param = get_rparam(&request, 4)) && '@' == *param)
517 			zbx_vector_str_append_uniq(regexps, param + 1);
518 	}
519 out:
520 	free_request(&request);
521 }
522 
523 /******************************************************************************
524  *                                                                            *
525  * Function: send_list_of_active_checks_json                                  *
526  *                                                                            *
527  * Purpose: send list of active checks to the host                            *
528  *                                                                            *
529  * Parameters: sock - open socket of server-agent connection                  *
530  *             jp   - request buffer                                          *
531  *                                                                            *
532  * Return value:  SUCCEED - list of active checks sent successfully           *
533  *                FAIL - an error occurred                                    *
534  *                                                                            *
535  * Author: Alexander Vladishev                                                *
536  *                                                                            *
537  ******************************************************************************/
send_list_of_active_checks_json(zbx_socket_t * sock,struct zbx_json_parse * jp)538 int	send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *jp)
539 {
540 	char			host[HOST_HOST_LEN_MAX], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX],
541 				error[MAX_STRING_LEN], *host_metadata = NULL, *interface = NULL, *buffer = NULL;
542 	struct zbx_json		json;
543 	int			ret = FAIL, i, version;
544 	zbx_uint64_t		hostid;
545 	size_t			host_metadata_alloc = 1;	/* for at least NUL-termination char */
546 	size_t			interface_alloc = 1;		/* for at least NUL-termination char */
547 	size_t			buffer_size, reserved = 0;
548 	unsigned short		port;
549 	zbx_vector_uint64_t	itemids;
550 	zbx_conn_flags_t	flag = ZBX_CONN_DEFAULT;
551 
552 	zbx_vector_ptr_t	regexps;
553 	zbx_vector_str_t	names;
554 
555 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
556 
557 	zbx_vector_ptr_create(&regexps);
558 	zbx_vector_str_create(&names);
559 
560 	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host), NULL))
561 	{
562 		zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror());
563 		goto error;
564 	}
565 
566 	host_metadata = (char *)zbx_malloc(host_metadata, host_metadata_alloc);
567 
568 	if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA,
569 			&host_metadata, &host_metadata_alloc, NULL))
570 	{
571 		*host_metadata = '\0';
572 	}
573 
574 	interface = (char *)zbx_malloc(interface, interface_alloc);
575 
576 	if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_INTERFACE, &interface, &interface_alloc, NULL))
577 	{
578 		*interface = '\0';
579 	}
580 	else if (SUCCEED == is_ip(interface))
581 	{
582 		flag = ZBX_CONN_IP;
583 	}
584 	else if (SUCCEED == zbx_validate_hostname(interface))
585 	{
586 		flag = ZBX_CONN_DNS;
587 	}
588 	else
589 	{
590 		zbx_snprintf(error, MAX_STRING_LEN, "\"%s\" is not a valid IP or DNS", interface);
591 		goto error;
592 	}
593 
594 	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip), NULL))
595 		strscpy(ip, sock->peer);
596 
597 	if (FAIL == is_ip(ip))	/* check even if 'ip' came from get_ip_by_socket() - it can return not a valid IP */
598 	{
599 		zbx_snprintf(error, MAX_STRING_LEN, "\"%s\" is not a valid IP address", ip);
600 		goto error;
601 	}
602 
603 	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp), NULL))
604 	{
605 		port = ZBX_DEFAULT_AGENT_PORT;
606 	}
607 	else if (FAIL == is_ushort(tmp, &port))
608 	{
609 		zbx_snprintf(error, MAX_STRING_LEN, "\"%s\" is not a valid port", tmp);
610 		goto error;
611 	}
612 
613 	if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, flag, interface, &hostid, error))
614 		goto error;
615 
616 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_VERSION, tmp, sizeof(tmp), NULL) ||
617 			FAIL == (version = zbx_get_component_version(tmp)))
618 	{
619 		version = ZBX_COMPONENT_VERSION(4, 2);
620 	}
621 
622 	zbx_vector_uint64_create(&itemids);
623 
624 	get_list_of_active_checks(hostid, &itemids);
625 
626 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
627 	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
628 	zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA);
629 
630 	if (0 != itemids.values_num)
631 	{
632 		DC_ITEM		*dc_items;
633 		int		*errcodes, delay;
634 
635 		dc_items = (DC_ITEM *)zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num);
636 		errcodes = (int *)zbx_malloc(NULL, sizeof(int) * itemids.values_num);
637 
638 		DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num);
639 
640 		for (i = 0; i < itemids.values_num; i++)
641 		{
642 			if (SUCCEED != errcodes[i])
643 			{
644 				zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the"
645 						" server cache. Not sending now.", __func__, itemids.values[i]);
646 				continue;
647 			}
648 
649 			if (ITEM_STATUS_ACTIVE != dc_items[i].status)
650 				continue;
651 
652 			if (HOST_STATUS_MONITORED != dc_items[i].host.status)
653 				continue;
654 
655 			if (SUCCEED != zbx_interval_preproc(dc_items[i].delay, &delay, NULL, NULL))
656 				continue;
657 
658 
659 			dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig);
660 			substitute_key_macros_unmasked(&dc_items[i].key, NULL, &dc_items[i], NULL, NULL,
661 					MACRO_TYPE_ITEM_KEY, NULL, 0);
662 
663 			zbx_json_addobject(&json, NULL);
664 			zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING);
665 
666 			if (ZBX_COMPONENT_VERSION(4,4) > version)
667 			{
668 				if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig))
669 				{
670 					zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG,
671 							dc_items[i].key_orig, ZBX_JSON_TYPE_STRING);
672 				}
673 
674 				zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, delay);
675 			}
676 			else
677 			{
678 				zbx_json_adduint64(&json, ZBX_PROTO_TAG_ITEMID, dc_items[i].itemid);
679 				zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay, ZBX_JSON_TYPE_STRING);
680 			}
681 
682 			/* The agent expects ALWAYS to have lastlogsize and mtime tags. */
683 			/* Removing those would cause older agents to fail. */
684 			zbx_json_adduint64(&json, ZBX_PROTO_TAG_LASTLOGSIZE, dc_items[i].lastlogsize);
685 			zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime);
686 			zbx_json_close(&json);
687 
688 			zbx_itemkey_extract_global_regexps(dc_items[i].key, &names);
689 
690 			zbx_free(dc_items[i].key);
691 		}
692 
693 		DCconfig_clean_items(dc_items, errcodes, itemids.values_num);
694 
695 		zbx_free(errcodes);
696 		zbx_free(dc_items);
697 	}
698 
699 	zbx_json_close(&json);
700 
701 	if (ZBX_COMPONENT_VERSION(4,4) == version || ZBX_COMPONENT_VERSION(5,0) == version)
702 		zbx_json_adduint64(&json, ZBX_PROTO_TAG_REFRESH_UNSUPPORTED, 600);
703 
704 	zbx_vector_uint64_destroy(&itemids);
705 
706 	DCget_expressions_by_names(&regexps, (const char * const *)names.values, names.values_num);
707 
708 	if (0 < regexps.values_num)
709 	{
710 		char	str[32];
711 
712 		zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP);
713 
714 		for (i = 0; i < regexps.values_num; i++)
715 		{
716 			zbx_expression_t	*regexp = (zbx_expression_t *)regexps.values[i];
717 
718 			zbx_json_addobject(&json, NULL);
719 			zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING);
720 			zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING);
721 
722 			zbx_snprintf(str, sizeof(str), "%d", regexp->expression_type);
723 			zbx_json_addstring(&json, "expression_type", str, ZBX_JSON_TYPE_INT);
724 
725 			zbx_snprintf(str, sizeof(str), "%c", regexp->exp_delimiter);
726 			zbx_json_addstring(&json, "exp_delimiter", str, ZBX_JSON_TYPE_STRING);
727 
728 			zbx_snprintf(str, sizeof(str), "%d", regexp->case_sensitive);
729 			zbx_json_addstring(&json, "case_sensitive", str, ZBX_JSON_TYPE_INT);
730 
731 			zbx_json_close(&json);
732 		}
733 
734 		zbx_json_close(&json);
735 	}
736 
737 	zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __func__, json.buffer);
738 
739 	if (0 != (ZBX_TCP_COMPRESS & sock->protocol))
740 	{
741 		if (SUCCEED != zbx_compress(json.buffer, json.buffer_size, &buffer, &buffer_size))
742 		{
743 			zbx_snprintf(error, MAX_STRING_LEN, "cannot compress data: %s", zbx_compress_strerror());
744 			goto error;
745 		}
746 
747 		reserved = json.buffer_size;
748 		zbx_json_free(&json);	/* json buffer can be large, free as fast as possible */
749 
750 		if (SUCCEED != (ret = zbx_tcp_send_ext(sock, buffer, buffer_size, reserved, sock->protocol,
751 				CONFIG_TIMEOUT)))
752 		{
753 			strscpy(error, zbx_socket_strerror());
754 		}
755 	}
756 	else
757 	{
758 		if (SUCCEED != (ret = zbx_tcp_send_ext(sock, json.buffer, json.buffer_size, 0, sock->protocol,
759 				CONFIG_TIMEOUT)))
760 		{
761 			strscpy(error, zbx_socket_strerror());
762 		}
763 	}
764 
765 	zbx_json_free(&json);
766 
767 	goto out;
768 error:
769 	zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error);
770 
771 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
772 	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING);
773 	zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING);
774 
775 	zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __func__, json.buffer);
776 
777 	ret = zbx_tcp_send(sock, json.buffer);
778 
779 	zbx_json_free(&json);
780 out:
781 	for (i = 0; i < names.values_num; i++)
782 		zbx_free(names.values[i]);
783 
784 	zbx_vector_str_destroy(&names);
785 
786 	zbx_regexp_clean_expressions(&regexps);
787 	zbx_vector_ptr_destroy(&regexps);
788 
789 	zbx_free(host_metadata);
790 	zbx_free(interface);
791 	zbx_free(buffer);
792 
793 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
794 
795 	return ret;
796 }
797