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 
22 #include "comms.h"
23 #include "log.h"
24 #include "zbxjson.h"
25 #include "zbxserver.h"
26 #include "dbcache.h"
27 #include "proxy.h"
28 #include "zbxself.h"
29 
30 #include "trapper.h"
31 #include "active.h"
32 #include "nodecommand.h"
33 #include "proxyconfig.h"
34 #include "proxydata.h"
35 #include "../alerter/alerter_protocol.h"
36 #include "trapper_preproc.h"
37 #include "trapper_expressions_evaluate.h"
38 
39 #include "daemon.h"
40 #include "zbxcrypto.h"
41 #include "../../libs/zbxserver/zabbix_stats.h"
42 #include "zbxipcservice.h"
43 #include "trapper_item_test.h"
44 #include "../poller/checks_snmp.h"
45 
46 #define ZBX_MAX_SECTION_ENTRIES		4
47 #define ZBX_MAX_ENTRY_ATTRIBUTES	3
48 
49 extern unsigned char	process_type, program_type;
50 extern int		server_num, process_num;
51 extern size_t		(*find_psk_in_cache)(const unsigned char *, unsigned char *, unsigned int *);
52 
53 extern int	CONFIG_CONFSYNCER_FORKS;
54 
55 #ifdef HAVE_NETSNMP
56 static volatile sig_atomic_t	snmp_cache_reload_requested;
57 #endif
58 
59 typedef struct
60 {
61 	zbx_counter_value_t	online;
62 	zbx_counter_value_t	offline;
63 }
64 zbx_user_stats_t;
65 
66 typedef union
67 {
68 	zbx_counter_value_t	counter;	/* single global counter */
69 	zbx_vector_ptr_t	counters;	/* array of per proxy counters */
70 }
71 zbx_entry_info_t;
72 
73 typedef struct
74 {
75 	const char	*name;
76 	zbx_uint64_t	value;
77 }
78 zbx_entry_attribute_t;
79 
80 typedef struct
81 {
82 	zbx_entry_info_t	*info;
83 	zbx_counter_type_t	counter_type;
84 	zbx_entry_attribute_t	attributes[ZBX_MAX_ENTRY_ATTRIBUTES];
85 }
86 zbx_section_entry_t;
87 
88 typedef enum
89 {
90 	ZBX_SECTION_ENTRY_THE_ONLY,
91 	ZBX_SECTION_ENTRY_PER_PROXY
92 }
93 zbx_entry_type_t;
94 
95 typedef struct
96 {
97 	const char		*name;
98 	zbx_entry_type_t	entry_type;
99 	zbx_user_type_t		access_level;
100 	int			*res;
101 	zbx_section_entry_t	entries[ZBX_MAX_SECTION_ENTRIES];
102 }
103 zbx_status_section_t;
104 
105 /******************************************************************************
106  *                                                                            *
107  * Function: recv_agenthistory                                                *
108  *                                                                            *
109  * Purpose: processes the received values from active agents                  *
110  *                                                                            *
111  ******************************************************************************/
recv_agenthistory(zbx_socket_t * sock,struct zbx_json_parse * jp,zbx_timespec_t * ts)112 static void	recv_agenthistory(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts)
113 {
114 	char	*info = NULL;
115 	int	ret;
116 
117 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
118 
119 	if (SUCCEED != (ret = process_agent_history_data(sock, jp, ts, &info)))
120 	{
121 		zabbix_log(LOG_LEVEL_WARNING, "received invalid agent history data from \"%s\": %s", sock->peer, info);
122 	}
123 	else if (!ZBX_IS_RUNNING())
124 	{
125 		info = zbx_strdup(info, "Zabbix server shutdown in progress");
126 		zabbix_log(LOG_LEVEL_WARNING, "cannot receive agent history data from \"%s\": %s", sock->peer, info);
127 		ret = FAIL;
128 	}
129 
130 	zbx_send_response_same(sock, ret, info, CONFIG_TIMEOUT);
131 
132 	zbx_free(info);
133 
134 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
135 }
136 
137 /******************************************************************************
138  *                                                                            *
139  * Function: recv_senderhistory                                               *
140  *                                                                            *
141  * Purpose: processes the received values from senders                        *
142  *                                                                            *
143  ******************************************************************************/
recv_senderhistory(zbx_socket_t * sock,struct zbx_json_parse * jp,zbx_timespec_t * ts)144 static void	recv_senderhistory(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts)
145 {
146 	char	*info = NULL;
147 	int	ret;
148 
149 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
150 
151 	if (SUCCEED != (ret = process_sender_history_data(sock, jp, ts, &info)))
152 	{
153 		zabbix_log(LOG_LEVEL_WARNING, "received invalid sender data from \"%s\": %s", sock->peer, info);
154 	}
155 	else if (!ZBX_IS_RUNNING())
156 	{
157 		info = zbx_strdup(info, "Zabbix server shutdown in progress");
158 		zabbix_log(LOG_LEVEL_WARNING, "cannot process sender data from \"%s\": %s", sock->peer, info);
159 		ret = FAIL;
160 	}
161 
162 	zbx_send_response_same(sock, ret, info, CONFIG_TIMEOUT);
163 
164 	zbx_free(info);
165 
166 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
167 }
168 
169 /******************************************************************************
170  *                                                                            *
171  * Function: recv_proxy_heartbeat                                             *
172  *                                                                            *
173  * Purpose: process heartbeat sent by proxy servers                           *
174  *                                                                            *
175  * Return value:  SUCCEED - processed successfully                            *
176  *                FAIL - an error occurred                                    *
177  *                                                                            *
178  * Author: Alexander Vladishev                                                *
179  *                                                                            *
180  ******************************************************************************/
recv_proxy_heartbeat(zbx_socket_t * sock,struct zbx_json_parse * jp)181 static void	recv_proxy_heartbeat(zbx_socket_t *sock, struct zbx_json_parse *jp)
182 {
183 	char		*error = NULL;
184 	int		ret, flags = ZBX_TCP_PROTOCOL;
185 	DC_PROXY	proxy;
186 
187 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
188 
189 	if (SUCCEED != (ret = get_active_proxy_from_request(jp, &proxy, &error)))
190 	{
191 		zabbix_log(LOG_LEVEL_WARNING, "cannot parse heartbeat from active proxy at \"%s\": %s",
192 				sock->peer, error);
193 		goto out;
194 	}
195 
196 	if (SUCCEED != (ret = zbx_proxy_check_permissions(&proxy, sock, &error)))
197 	{
198 		zabbix_log(LOG_LEVEL_WARNING, "cannot accept connection from proxy \"%s\" at \"%s\", allowed address:"
199 				" \"%s\": %s", proxy.host, sock->peer, proxy.proxy_address, error);
200 		goto out;
201 	}
202 
203 	zbx_update_proxy_data(&proxy, zbx_get_proxy_protocol_version(jp), time(NULL),
204 			(0 != (sock->protocol & ZBX_TCP_COMPRESS) ? 1 : 0), ZBX_FLAGS_PROXY_DIFF_UPDATE_HEARTBEAT);
205 
206 	if (0 != proxy.auto_compress)
207 		flags |= ZBX_TCP_COMPRESS;
208 out:
209 	if (FAIL == ret && 0 != (sock->protocol & ZBX_TCP_COMPRESS))
210 		flags |= ZBX_TCP_COMPRESS;
211 
212 	zbx_send_response_ext(sock, ret, error, NULL, flags, CONFIG_TIMEOUT);
213 
214 	zbx_free(error);
215 
216 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
217 }
218 
219 #define ZBX_GET_QUEUE_UNKNOWN		-1
220 #define ZBX_GET_QUEUE_OVERVIEW		0
221 #define ZBX_GET_QUEUE_PROXY		1
222 #define ZBX_GET_QUEUE_DETAILS		2
223 
224 /* queue stats split by delay times */
225 typedef struct
226 {
227 	zbx_uint64_t	id;
228 	int		delay5;
229 	int		delay10;
230 	int		delay30;
231 	int		delay60;
232 	int		delay300;
233 	int		delay600;
234 }
235 zbx_queue_stats_t;
236 
237 /******************************************************************************
238  *                                                                            *
239  * Function: queue_stats_update                                               *
240  *                                                                            *
241  * Purpose: update queue stats with a new item delay                          *
242  *                                                                            *
243  * Parameters: stats   - [IN] the queue stats                                 *
244  *             delay   - [IN] the delay time of an delayed item               *
245  *                                                                            *
246  ******************************************************************************/
queue_stats_update(zbx_queue_stats_t * stats,int delay)247 static void	queue_stats_update(zbx_queue_stats_t *stats, int delay)
248 {
249 	if (10 >= delay)
250 		stats->delay5++;
251 	else if (30 >= delay)
252 		stats->delay10++;
253 	else if (60 >= delay)
254 		stats->delay30++;
255 	else if (300 >= delay)
256 		stats->delay60++;
257 	else if (600 >= delay)
258 		stats->delay300++;
259 	else
260 		stats->delay600++;
261 }
262 
263 /******************************************************************************
264  *                                                                            *
265  * Function: queue_stats_export                                               *
266  *                                                                            *
267  * Purpose: export queue stats to JSON format                                 *
268  *                                                                            *
269  * Parameters: queue_stats - [IN] a hashset containing item stats             *
270  *             id_name     - [IN] the name of stats id field                  *
271  *             json        - [OUT] the output JSON                            *
272  *                                                                            *
273  ******************************************************************************/
queue_stats_export(zbx_hashset_t * queue_stats,const char * id_name,struct zbx_json * json)274 static void	queue_stats_export(zbx_hashset_t *queue_stats, const char *id_name, struct zbx_json *json)
275 {
276 	zbx_hashset_iter_t	iter;
277 	zbx_queue_stats_t	*stats;
278 
279 	zbx_json_addarray(json, ZBX_PROTO_TAG_DATA);
280 
281 	zbx_hashset_iter_reset(queue_stats, &iter);
282 
283 	while (NULL != (stats = (zbx_queue_stats_t *)zbx_hashset_iter_next(&iter)))
284 	{
285 		zbx_json_addobject(json, NULL);
286 		zbx_json_adduint64(json, id_name, stats->id);
287 		zbx_json_adduint64(json, "delay5", stats->delay5);
288 		zbx_json_adduint64(json, "delay10", stats->delay10);
289 		zbx_json_adduint64(json, "delay30", stats->delay30);
290 		zbx_json_adduint64(json, "delay60", stats->delay60);
291 		zbx_json_adduint64(json, "delay300", stats->delay300);
292 		zbx_json_adduint64(json, "delay600", stats->delay600);
293 		zbx_json_close(json);
294 	}
295 
296 	zbx_json_close(json);
297 }
298 
299 /* queue item comparison function used to sort queue by nextcheck */
queue_compare_by_nextcheck_asc(zbx_queue_item_t ** d1,zbx_queue_item_t ** d2)300 static int	queue_compare_by_nextcheck_asc(zbx_queue_item_t **d1, zbx_queue_item_t **d2)
301 {
302 	zbx_queue_item_t	*i1 = *d1, *i2 = *d2;
303 
304 	return i1->nextcheck - i2->nextcheck;
305 }
306 
307 /******************************************************************************
308  *                                                                            *
309  * Function: recv_getqueue                                                    *
310  *                                                                            *
311  * Purpose: process queue request                                             *
312  *                                                                            *
313  * Parameters:  sock  - [IN] the request socket                               *
314  *              jp    - [IN] the request data                                 *
315  *                                                                            *
316  * Return value:  SUCCEED - processed successfully                            *
317  *                FAIL - an error occurred                                    *
318  *                                                                            *
319  ******************************************************************************/
recv_getqueue(zbx_socket_t * sock,struct zbx_json_parse * jp)320 static int	recv_getqueue(zbx_socket_t *sock, struct zbx_json_parse *jp)
321 {
322 	int			ret = FAIL, request_type = ZBX_GET_QUEUE_UNKNOWN, now, i, limit;
323 	char			type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN], limit_str[MAX_STRING_LEN];
324 	zbx_user_t		user;
325 	zbx_vector_ptr_t	queue;
326 	struct zbx_json		json;
327 	zbx_hashset_t		queue_stats;
328 	zbx_queue_stats_t	*stats;
329 
330 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
331 
332 	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid), NULL) ||
333 			SUCCEED != DBget_user_by_active_session(sessionid, &user) || USER_TYPE_SUPER_ADMIN > user.type)
334 	{
335 		zbx_send_response(sock, ret, "Permission denied.", CONFIG_TIMEOUT);
336 		goto out;
337 	}
338 
339 	if (FAIL != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type), NULL))
340 	{
341 		if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_OVERVIEW))
342 		{
343 			request_type = ZBX_GET_QUEUE_OVERVIEW;
344 		}
345 		else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_PROXY))
346 		{
347 			request_type = ZBX_GET_QUEUE_PROXY;
348 		}
349 		else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_DETAILS))
350 		{
351 			request_type = ZBX_GET_QUEUE_DETAILS;
352 
353 			if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_LIMIT, limit_str, sizeof(limit_str), NULL) ||
354 					FAIL == is_uint31(limit_str, &limit))
355 			{
356 				zbx_send_response(sock, ret, "Unsupported limit value.", CONFIG_TIMEOUT);
357 				goto out;
358 			}
359 		}
360 	}
361 
362 	if (ZBX_GET_QUEUE_UNKNOWN == request_type)
363 	{
364 		zbx_send_response(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT);
365 		goto out;
366 	}
367 
368 	now = time(NULL);
369 	zbx_vector_ptr_create(&queue);
370 	DCget_item_queue(&queue, ZBX_QUEUE_FROM_DEFAULT, ZBX_QUEUE_TO_INFINITY);
371 
372 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
373 
374 	switch (request_type)
375 	{
376 		case ZBX_GET_QUEUE_OVERVIEW:
377 			zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC,
378 					ZBX_DEFAULT_UINT64_COMPARE_FUNC);
379 
380 			/* gather queue stats by item type */
381 			for (i = 0; i < queue.values_num; i++)
382 			{
383 				zbx_queue_item_t	*item = (zbx_queue_item_t *)queue.values[i];
384 				zbx_uint64_t		id = item->type;
385 
386 				if (NULL == (stats = (zbx_queue_stats_t *)zbx_hashset_search(&queue_stats, &id)))
387 				{
388 					zbx_queue_stats_t	data = {.id = id};
389 
390 					stats = (zbx_queue_stats_t *)zbx_hashset_insert(&queue_stats, &data, sizeof(data));
391 				}
392 				queue_stats_update(stats, now - item->nextcheck);
393 			}
394 
395 			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
396 					ZBX_JSON_TYPE_STRING);
397 			queue_stats_export(&queue_stats, "itemtype", &json);
398 			zbx_hashset_destroy(&queue_stats);
399 
400 			break;
401 		case ZBX_GET_QUEUE_PROXY:
402 			zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC,
403 					ZBX_DEFAULT_UINT64_COMPARE_FUNC);
404 
405 			/* gather queue stats by proxy hostid */
406 			for (i = 0; i < queue.values_num; i++)
407 			{
408 				zbx_queue_item_t	*item = (zbx_queue_item_t *)queue.values[i];
409 				zbx_uint64_t		id = item->proxy_hostid;
410 
411 				if (NULL == (stats = (zbx_queue_stats_t *)zbx_hashset_search(&queue_stats, &id)))
412 				{
413 					zbx_queue_stats_t	data = {.id = id};
414 
415 					stats = (zbx_queue_stats_t *)zbx_hashset_insert(&queue_stats, &data, sizeof(data));
416 				}
417 				queue_stats_update(stats, now - item->nextcheck);
418 			}
419 
420 			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
421 					ZBX_JSON_TYPE_STRING);
422 			queue_stats_export(&queue_stats, "proxyid", &json);
423 			zbx_hashset_destroy(&queue_stats);
424 
425 			break;
426 		case ZBX_GET_QUEUE_DETAILS:
427 			zbx_vector_ptr_sort(&queue, (zbx_compare_func_t)queue_compare_by_nextcheck_asc);
428 			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
429 					ZBX_JSON_TYPE_STRING);
430 			zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA);
431 
432 			for (i = 0; i < queue.values_num && i < limit; i++)
433 			{
434 				zbx_queue_item_t	*item = (zbx_queue_item_t *)queue.values[i];
435 
436 				zbx_json_addobject(&json, NULL);
437 				zbx_json_adduint64(&json, "itemid", item->itemid);
438 				zbx_json_adduint64(&json, "nextcheck", item->nextcheck);
439 				zbx_json_close(&json);
440 			}
441 
442 			zbx_json_close(&json);
443 			zbx_json_adduint64(&json, "total", queue.values_num);
444 
445 			break;
446 	}
447 
448 	zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __func__, json.buffer);
449 
450 	(void)zbx_tcp_send(sock, json.buffer);
451 
452 	DCfree_item_queue(&queue);
453 	zbx_vector_ptr_destroy(&queue);
454 
455 	zbx_json_free(&json);
456 
457 	ret = SUCCEED;
458 out:
459 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
460 
461 	return ret;
462 }
463 
464 /******************************************************************************
465  *                                                                            *
466  * Function: recv_alert_send                                                  *
467  *                                                                            *
468  * Purpose: process alert send request that is used to test media types       *
469  *                                                                            *
470  * Parameters:  sock  - [IN] the request socket                               *
471  *              jp    - [IN] the request data                                 *
472  *                                                                            *
473  * Return value:  SUCCEED - processed successfully                            *
474  *                FAIL - an error occurred                                    *
475  *                                                                            *
476  ******************************************************************************/
recv_alert_send(zbx_socket_t * sock,const struct zbx_json_parse * jp)477 static void	recv_alert_send(zbx_socket_t *sock, const struct zbx_json_parse *jp)
478 {
479 	DB_RESULT		result;
480 	DB_ROW			row;
481 	int			ret = FAIL, errcode;
482 	char			tmp[ZBX_MAX_UINT64_LEN + 1], sessionid[MAX_STRING_LEN], *sendto = NULL, *subject = NULL,
483 				*message = NULL, *error = NULL, *params = NULL, *value = NULL, *debug = NULL;
484 	zbx_uint64_t		mediatypeid;
485 	size_t			string_alloc;
486 	struct zbx_json		json;
487 	struct zbx_json_parse	jp_data, jp_params;
488 	unsigned char		*data = NULL,smtp_security, smtp_verify_peer, smtp_verify_host,
489 				smtp_authentication, content_type, *response = NULL;
490 	zbx_uint32_t		size;
491 	zbx_user_t		user;
492 	unsigned short		smtp_port;
493 
494 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
495 
496 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
497 
498 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid), NULL) ||
499 			SUCCEED != DBget_user_by_active_session(sessionid, &user) || USER_TYPE_SUPER_ADMIN > user.type)
500 	{
501 		error = zbx_strdup(NULL, "Permission denied.");
502 		goto fail;
503 	}
504 
505 	if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data))
506 	{
507 		error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_DATA);
508 		goto fail;
509 	}
510 
511 	if (SUCCEED != zbx_json_value_by_name(&jp_data, ZBX_PROTO_TAG_MEDIATYPEID, tmp, sizeof(tmp), NULL) ||
512 			SUCCEED != is_uint64(tmp, &mediatypeid))
513 	{
514 		error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_MEDIATYPEID);
515 		goto fail;
516 	}
517 
518 	string_alloc = 0;
519 	if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SENDTO, &sendto, &string_alloc, NULL))
520 		string_alloc = 0;
521 	if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SUBJECT, &subject, &string_alloc, NULL))
522 		string_alloc = 0;
523 	if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_MESSAGE, &message, &string_alloc, NULL))
524 		string_alloc = 0;
525 
526 	if (SUCCEED == zbx_json_brackets_by_name(&jp_data, ZBX_PROTO_TAG_PARAMETERS, &jp_params))
527 	{
528 		size_t	string_offset = 0;
529 
530 		zbx_strncpy_alloc(&params, &string_alloc, &string_offset, jp_params.start,
531 				jp_params.end - jp_params.start + 1);
532 	}
533 
534 	result = DBselect("select type,smtp_server,smtp_helo,smtp_email,exec_path,gsm_modem,username,"
535 				"passwd,smtp_port,smtp_security,smtp_verify_peer,smtp_verify_host,smtp_authentication,"
536 				"exec_params,maxsessions,maxattempts,attempt_interval,content_type,script,timeout"
537 			" from media_type"
538 			" where mediatypeid=" ZBX_FS_UI64, mediatypeid);
539 
540 	if (NULL == (row = DBfetch(result)))
541 	{
542 		DBfree_result(result);
543 		error = zbx_dsprintf(NULL, "Cannot find the specified media type.");
544 		goto fail;
545 	}
546 
547 	if (FAIL == is_ushort(row[8], &smtp_port))
548 	{
549 		DBfree_result(result);
550 		error = zbx_dsprintf(NULL, "Invalid port value.");
551 		goto fail;
552 	}
553 
554 	ZBX_STR2UCHAR(smtp_security, row[9]);
555 	ZBX_STR2UCHAR(smtp_verify_peer, row[10]);
556 	ZBX_STR2UCHAR(smtp_verify_host, row[11]);
557 	ZBX_STR2UCHAR(smtp_authentication, row[12]);
558 	ZBX_STR2UCHAR(content_type, row[17]);
559 
560 	size = zbx_alerter_serialize_alert_send(&data, mediatypeid, atoi(row[0]), row[1], row[2], row[3], row[4],
561 			row[5], row[6], row[7], smtp_port, smtp_security, smtp_verify_peer, smtp_verify_host,
562 			smtp_authentication, row[13], atoi(row[14]), atoi(row[15]), row[16], content_type, row[18],
563 			row[19], sendto, subject, message, params);
564 
565 	DBfree_result(result);
566 
567 	if (SUCCEED != zbx_ipc_async_exchange(ZBX_IPC_SERVICE_ALERTER, ZBX_IPC_ALERTER_ALERT, SEC_PER_MIN, data, size,
568 			&response, &error))
569 	{
570 		goto fail;
571 	}
572 
573 	zbx_alerter_deserialize_result(response, &value, &errcode, &error, &debug);
574 	zbx_free(response);
575 
576 	if (SUCCEED == errcode)
577 		ret = SUCCEED;
578 fail:
579 	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, SUCCEED == ret ? ZBX_PROTO_VALUE_SUCCESS :
580 				ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING);
581 
582 	if (SUCCEED == ret)
583 	{
584 		if (NULL != value)
585 			zbx_json_addstring(&json, ZBX_PROTO_TAG_DATA, value, ZBX_JSON_TYPE_STRING);
586 	}
587 	else
588 	{
589 		if (NULL != error && '\0' != *error)
590 			zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING);
591 	}
592 
593 	if (NULL != debug)
594 		zbx_json_addraw(&json, "debug", debug);
595 
596 	(void)zbx_tcp_send(sock, json.buffer);
597 
598 	zbx_free(params);
599 	zbx_free(message);
600 	zbx_free(subject);
601 	zbx_free(sendto);
602 	zbx_free(data);
603 	zbx_free(value);
604 	zbx_free(error);
605 	zbx_free(debug);
606 	zbx_json_free(&json);
607 
608 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
609 }
610 
DBget_template_count(zbx_uint64_t * count)611 static int	DBget_template_count(zbx_uint64_t *count)
612 {
613 	DB_RESULT	result;
614 	DB_ROW		row;
615 	int		ret = FAIL;
616 
617 	if (NULL == (result = DBselect("select count(*) from hosts where status=%d", HOST_STATUS_TEMPLATE)))
618 		goto out;
619 
620 	if (NULL == (row = DBfetch(result)) || SUCCEED != is_uint64(row[0], count))
621 		goto out;
622 
623 	ret = SUCCEED;
624 out:
625 	DBfree_result(result);
626 
627 	return ret;
628 }
629 
DBget_user_count(zbx_uint64_t * count_online,zbx_uint64_t * count_offline)630 static int	DBget_user_count(zbx_uint64_t *count_online, zbx_uint64_t *count_offline)
631 {
632 	DB_RESULT	result;
633 	DB_ROW		row;
634 	zbx_uint64_t	users_offline, users_online = 0;
635 	int		now, ret = FAIL;
636 
637 	if (NULL == (result = DBselect("select count(*) from users")))
638 		goto out;
639 
640 	if (NULL == (row = DBfetch(result)) || SUCCEED != is_uint64(row[0], &users_offline))
641 		goto out;
642 
643 	DBfree_result(result);
644 	now = time(NULL);
645 
646 	if (NULL == (result = DBselect("select max(lastaccess) from sessions where status=%d group by userid,status",
647 			ZBX_SESSION_ACTIVE)))
648 	{
649 		goto out;
650 	}
651 
652 	while (NULL != (row = DBfetch(result)))
653 	{
654 		if (atoi(row[0]) + ZBX_USER_ONLINE_TIME < now)
655 			continue;
656 
657 		users_online++;
658 
659 		if (0 == users_offline)	/* new user can be created and log in between two selects */
660 			continue;
661 
662 		users_offline--;
663 	}
664 
665 	*count_online = users_online;
666 	*count_offline = users_offline;
667 	ret = SUCCEED;
668 out:
669 	DBfree_result(result);
670 
671 	return ret;
672 }
673 
674 /* auxiliary variables for status_stats_export() */
675 
676 static zbx_entry_info_t	templates, hosts_monitored, hosts_not_monitored, items_active_normal, items_active_notsupported,
677 			items_disabled, triggers_enabled_ok, triggers_enabled_problem, triggers_disabled, users_online,
678 			users_offline, required_performance;
679 static int		templates_res, users_res;
680 
zbx_status_counters_init(void)681 static void	zbx_status_counters_init(void)
682 {
683 	zbx_vector_ptr_create(&hosts_monitored.counters);
684 	zbx_vector_ptr_create(&hosts_not_monitored.counters);
685 	zbx_vector_ptr_create(&items_active_normal.counters);
686 	zbx_vector_ptr_create(&items_active_notsupported.counters);
687 	zbx_vector_ptr_create(&items_disabled.counters);
688 	zbx_vector_ptr_create(&required_performance.counters);
689 }
690 
zbx_status_counters_free(void)691 static void	zbx_status_counters_free(void)
692 {
693 	zbx_vector_ptr_clear_ext(&hosts_monitored.counters, zbx_default_mem_free_func);
694 	zbx_vector_ptr_clear_ext(&hosts_not_monitored.counters, zbx_default_mem_free_func);
695 	zbx_vector_ptr_clear_ext(&items_active_normal.counters, zbx_default_mem_free_func);
696 	zbx_vector_ptr_clear_ext(&items_active_notsupported.counters, zbx_default_mem_free_func);
697 	zbx_vector_ptr_clear_ext(&items_disabled.counters, zbx_default_mem_free_func);
698 	zbx_vector_ptr_clear_ext(&required_performance.counters, zbx_default_mem_free_func);
699 
700 	zbx_vector_ptr_destroy(&hosts_monitored.counters);
701 	zbx_vector_ptr_destroy(&hosts_not_monitored.counters);
702 	zbx_vector_ptr_destroy(&items_active_normal.counters);
703 	zbx_vector_ptr_destroy(&items_active_notsupported.counters);
704 	zbx_vector_ptr_destroy(&items_disabled.counters);
705 	zbx_vector_ptr_destroy(&required_performance.counters);
706 }
707 
708 const zbx_status_section_t	status_sections[] = {
709 /*	{SECTION NAME,			NUMBER OF SECTION ENTRIES	SECTION ACCESS LEVEL	SECTION READYNESS, */
710 /*		{                                                                                                  */
711 /*			{ENTRY INFORMATION,		COUNTER TYPE,                                              */
712 /*				{                                                                                  */
713 /*					{ATTR. NAME,	ATTRIBUTE VALUE},                                          */
714 /*					... (up to ZBX_MAX_ENTRY_ATTRIBUTES)                                       */
715 /*				}                                                                                  */
716 /*			},                                                                                         */
717 /*			... (up to ZBX_MAX_SECTION_ENTRIES)                                                        */
718 /*		}                                                                                                  */
719 /*	},                                                                                                         */
720 /*	...                                                                                                        */
721 	{"template stats",		ZBX_SECTION_ENTRY_THE_ONLY,	USER_TYPE_ZABBIX_USER,	&templates_res,
722 		{
723 			{&templates,			ZBX_COUNTER_TYPE_UI64,
724 				{
725 					{NULL}
726 				}
727 			},
728 			{NULL}
729 		}
730 	},
731 	{"host stats",			ZBX_SECTION_ENTRY_PER_PROXY,	USER_TYPE_ZABBIX_USER,	NULL,
732 		{
733 			{&hosts_monitored,		ZBX_COUNTER_TYPE_UI64,
734 				{
735 					{"status",	HOST_STATUS_MONITORED},
736 					{NULL}
737 				}
738 			},
739 			{&hosts_not_monitored,		ZBX_COUNTER_TYPE_UI64,
740 				{
741 					{"status",	HOST_STATUS_NOT_MONITORED},
742 					{NULL}
743 				}
744 			},
745 			{NULL}
746 		}
747 	},
748 	{"item stats",			ZBX_SECTION_ENTRY_PER_PROXY,	USER_TYPE_ZABBIX_USER,	NULL,
749 		{
750 			{&items_active_normal,		ZBX_COUNTER_TYPE_UI64,
751 				{
752 					{"status",	ITEM_STATUS_ACTIVE},
753 					{"state",	ITEM_STATE_NORMAL},
754 					{NULL}
755 				}
756 			},
757 			{&items_active_notsupported,	ZBX_COUNTER_TYPE_UI64,
758 				{
759 					{"status",	ITEM_STATUS_ACTIVE},
760 					{"state",	ITEM_STATE_NOTSUPPORTED},
761 					{NULL}
762 				}
763 			},
764 			{&items_disabled,		ZBX_COUNTER_TYPE_UI64,
765 				{
766 					{"status",	ITEM_STATUS_DISABLED},
767 					{NULL}
768 				}
769 			},
770 			{NULL}
771 		}
772 	},
773 	{"trigger stats",		ZBX_SECTION_ENTRY_THE_ONLY,	USER_TYPE_ZABBIX_USER,	NULL,
774 		{
775 			{&triggers_enabled_ok,		ZBX_COUNTER_TYPE_UI64,
776 				{
777 					{"status",	TRIGGER_STATUS_ENABLED},
778 					{"value",	TRIGGER_VALUE_OK},
779 					{NULL}
780 				}
781 			},
782 			{&triggers_enabled_problem,	ZBX_COUNTER_TYPE_UI64,
783 				{
784 					{"status",	TRIGGER_STATUS_ENABLED},
785 					{"value",	TRIGGER_VALUE_PROBLEM},
786 					{NULL}
787 				}
788 			},
789 			{&triggers_disabled,		ZBX_COUNTER_TYPE_UI64,
790 				{
791 					{"status",	TRIGGER_STATUS_DISABLED},
792 					{NULL}
793 				}
794 			},
795 			{NULL}
796 		}
797 	},
798 	{"user stats",			ZBX_SECTION_ENTRY_THE_ONLY,	USER_TYPE_ZABBIX_USER,	&users_res,
799 		{
800 			{&users_online,			ZBX_COUNTER_TYPE_UI64,
801 				{
802 					{"status",	ZBX_SESSION_ACTIVE},
803 					{NULL}
804 				}
805 			},
806 			{&users_offline,		ZBX_COUNTER_TYPE_UI64,
807 				{
808 					{"status",	ZBX_SESSION_PASSIVE},
809 					{NULL}
810 				}
811 			},
812 			{NULL}
813 		}
814 	},
815 	{"required performance",	ZBX_SECTION_ENTRY_PER_PROXY,	USER_TYPE_SUPER_ADMIN,	NULL,
816 		{
817 			{&required_performance,		ZBX_COUNTER_TYPE_DBL,
818 				{
819 					{NULL}
820 				}
821 			},
822 			{NULL}
823 		}
824 	},
825 	{NULL}
826 };
827 
status_entry_export(struct zbx_json * json,const zbx_section_entry_t * entry,zbx_counter_value_t counter_value,const zbx_uint64_t * proxyid)828 static void	status_entry_export(struct zbx_json *json, const zbx_section_entry_t *entry,
829 		zbx_counter_value_t counter_value, const zbx_uint64_t *proxyid)
830 {
831 	const zbx_entry_attribute_t	*attribute;
832 	char				*tmp = NULL;
833 
834 	zbx_json_addobject(json, NULL);
835 
836 	if (NULL != entry->attributes[0].name || NULL != proxyid)
837 	{
838 		zbx_json_addobject(json, "attributes");
839 
840 		if (NULL != proxyid)
841 			zbx_json_adduint64(json, "proxyid", *proxyid);
842 
843 		for (attribute = entry->attributes; NULL != attribute->name; attribute++)
844 			zbx_json_adduint64(json, attribute->name, attribute->value);
845 
846 		zbx_json_close(json);
847 	}
848 
849 	switch (entry->counter_type)
850 	{
851 		case ZBX_COUNTER_TYPE_UI64:
852 			zbx_json_adduint64(json, "count", counter_value.ui64);
853 			break;
854 		case ZBX_COUNTER_TYPE_DBL:
855 			tmp = zbx_dsprintf(tmp, ZBX_FS_DBL64, counter_value.dbl);
856 			zbx_json_addstring(json, "count", tmp, ZBX_JSON_TYPE_STRING);
857 			break;
858 		default:
859 			THIS_SHOULD_NEVER_HAPPEN;
860 	}
861 
862 	zbx_json_close(json);
863 
864 	zbx_free(tmp);
865 }
866 
status_stats_export(struct zbx_json * json,zbx_user_type_t access_level)867 static void	status_stats_export(struct zbx_json *json, zbx_user_type_t access_level)
868 {
869 	const zbx_status_section_t	*section;
870 	const zbx_section_entry_t	*entry;
871 	int				i;
872 
873 	zbx_status_counters_init();
874 
875 	/* get status information */
876 
877 	templates_res = DBget_template_count(&templates.counter.ui64);
878 	users_res = DBget_user_count(&users_online.counter.ui64, &users_offline.counter.ui64);
879 	DCget_status(&hosts_monitored.counters, &hosts_not_monitored.counters, &items_active_normal.counters,
880 			&items_active_notsupported.counters, &items_disabled.counters,
881 			&triggers_enabled_ok.counter.ui64, &triggers_enabled_problem.counter.ui64,
882 			&triggers_disabled.counter.ui64, &required_performance.counters);
883 
884 	/* add status information to JSON */
885 	for (section = status_sections; NULL != section->name; section++)
886 	{
887 		if (access_level < section->access_level)	/* skip sections user has no rights to access */
888 			continue;
889 
890 		if (NULL != section->res && SUCCEED != *section->res)	/* skip section we have no information for */
891 			continue;
892 
893 		zbx_json_addarray(json, section->name);
894 
895 		for (entry = section->entries; NULL != entry->info; entry++)
896 		{
897 			switch (section->entry_type)
898 			{
899 				case ZBX_SECTION_ENTRY_THE_ONLY:
900 					status_entry_export(json, entry, entry->info->counter, NULL);
901 					break;
902 				case ZBX_SECTION_ENTRY_PER_PROXY:
903 					for (i = 0; i < entry->info->counters.values_num; i++)
904 					{
905 						const zbx_proxy_counter_t	*proxy_counter;
906 
907 						proxy_counter = (zbx_proxy_counter_t *)entry->info->counters.values[i];
908 						status_entry_export(json, entry, proxy_counter->counter_value,
909 								&proxy_counter->proxyid);
910 					}
911 					break;
912 				default:
913 					THIS_SHOULD_NEVER_HAPPEN;
914 			}
915 		}
916 
917 		zbx_json_close(json);
918 	}
919 
920 	zbx_status_counters_free();
921 }
922 
923 /******************************************************************************
924  *                                                                            *
925  * Function: recv_getstatus                                                   *
926  *                                                                            *
927  * Purpose: process status request                                            *
928  *                                                                            *
929  * Parameters:  sock  - [IN] the request socket                               *
930  *              jp    - [IN] the request data                                 *
931  *                                                                            *
932  * Return value:  SUCCEED - processed successfully                            *
933  *                FAIL - an error occurred                                    *
934  *                                                                            *
935  ******************************************************************************/
recv_getstatus(zbx_socket_t * sock,struct zbx_json_parse * jp)936 static int	recv_getstatus(zbx_socket_t *sock, struct zbx_json_parse *jp)
937 {
938 #define ZBX_GET_STATUS_UNKNOWN	-1
939 #define ZBX_GET_STATUS_PING	0
940 #define ZBX_GET_STATUS_FULL	1
941 
942 	zbx_user_t	user;
943 	int		ret = FAIL, request_type = ZBX_GET_STATUS_UNKNOWN;
944 	char		type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN];
945 	struct zbx_json	json;
946 
947 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
948 
949 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid), NULL) ||
950 			SUCCEED != DBget_user_by_active_session(sessionid, &user))
951 	{
952 		zbx_send_response(sock, ret, "Permission denied.", CONFIG_TIMEOUT);
953 		goto out;
954 	}
955 
956 	if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type), NULL))
957 	{
958 		if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_STATUS_PING))
959 		{
960 			request_type = ZBX_GET_STATUS_PING;
961 		}
962 		else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_STATUS_FULL))
963 		{
964 			request_type = ZBX_GET_STATUS_FULL;
965 		}
966 	}
967 
968 	if (ZBX_GET_STATUS_UNKNOWN == request_type)
969 	{
970 		zbx_send_response(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT);
971 		goto out;
972 	}
973 
974 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
975 
976 	switch (request_type)
977 	{
978 		case ZBX_GET_STATUS_PING:
979 			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
980 			zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
981 			zbx_json_close(&json);
982 			break;
983 		case ZBX_GET_STATUS_FULL:
984 			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
985 			zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
986 			status_stats_export(&json, user.type);
987 			zbx_json_close(&json);
988 			break;
989 		default:
990 			THIS_SHOULD_NEVER_HAPPEN;
991 	}
992 
993 	zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __func__, json.buffer);
994 
995 	(void)zbx_tcp_send(sock, json.buffer);
996 
997 	zbx_json_free(&json);
998 
999 	ret = SUCCEED;
1000 out:
1001 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
1002 
1003 	return ret;
1004 
1005 #undef ZBX_GET_STATUS_UNKNOWN
1006 #undef ZBX_GET_STATUS_PING
1007 #undef ZBX_GET_STATUS_FULL
1008 }
1009 
1010 /******************************************************************************
1011  *                                                                            *
1012  * Function: send_internal_stats_json                                         *
1013  *                                                                            *
1014  * Purpose: process Zabbix stats request                                      *
1015  *                                                                            *
1016  * Parameters: sock  - [IN] the request socket                                *
1017  *             jp    - [IN] the request data                                  *
1018  *                                                                            *
1019  * Return value:  SUCCEED - processed successfully                            *
1020  *                FAIL - an error occurred                                    *
1021  *                                                                            *
1022  ******************************************************************************/
send_internal_stats_json(zbx_socket_t * sock,const struct zbx_json_parse * jp)1023 static int	send_internal_stats_json(zbx_socket_t *sock, const struct zbx_json_parse *jp)
1024 {
1025 	struct zbx_json	json;
1026 	char		type[MAX_STRING_LEN], error[MAX_STRING_LEN];
1027 	int		ret = FAIL;
1028 
1029 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
1030 
1031 	if (NULL == CONFIG_STATS_ALLOWED_IP ||
1032 			SUCCEED != zbx_tcp_check_allowed_peers(sock, CONFIG_STATS_ALLOWED_IP))
1033 	{
1034 		zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming stats request: %s",
1035 				NULL == CONFIG_STATS_ALLOWED_IP ? "StatsAllowedIP not set" : zbx_socket_strerror());
1036 		strscpy(error, "Permission denied.");
1037 		goto out;
1038 	}
1039 
1040 	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
1041 
1042 	if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type), NULL) &&
1043 			0 == strcmp(type, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE))
1044 	{
1045 		char			from_str[ZBX_MAX_UINT64_LEN + 1], to_str[ZBX_MAX_UINT64_LEN + 1];
1046 		int			from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY;
1047 		struct zbx_json_parse	jp_data;
1048 
1049 		if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_PARAMS, &jp_data))
1050 		{
1051 			zbx_snprintf(error, sizeof(error), "cannot find tag: %s", ZBX_PROTO_TAG_PARAMS);
1052 			goto param_error;
1053 		}
1054 
1055 		if (SUCCEED == zbx_json_value_by_name(&jp_data, ZBX_PROTO_TAG_FROM, from_str, sizeof(from_str), NULL)
1056 				&& FAIL == is_time_suffix(from_str, &from, ZBX_LENGTH_UNLIMITED))
1057 		{
1058 			strscpy(error, "invalid 'from' parameter");
1059 			goto param_error;
1060 		}
1061 
1062 		if (SUCCEED == zbx_json_value_by_name(&jp_data, ZBX_PROTO_TAG_TO, to_str, sizeof(to_str), NULL) &&
1063 				FAIL == is_time_suffix(to_str, &to, ZBX_LENGTH_UNLIMITED))
1064 		{
1065 			strscpy(error, "invalid 'to' parameter");
1066 			goto param_error;
1067 		}
1068 
1069 		if (ZBX_QUEUE_TO_INFINITY != to && from > to)
1070 		{
1071 			strscpy(error, "parameters represent an invalid interval");
1072 			goto param_error;
1073 		}
1074 
1075 		zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
1076 		zbx_json_adduint64(&json, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE, DCget_item_queue(NULL, from, to));
1077 	}
1078 	else
1079 	{
1080 		zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
1081 		zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
1082 
1083 		zbx_get_zabbix_stats(&json);
1084 
1085 		zbx_json_close(&json);
1086 	}
1087 
1088 	(void)zbx_tcp_send(sock, json.buffer);
1089 	ret = SUCCEED;
1090 param_error:
1091 	zbx_json_free(&json);
1092 out:
1093 	if (SUCCEED != ret)
1094 		zbx_send_response(sock, ret, error, CONFIG_TIMEOUT);
1095 
1096 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
1097 
1098 	return ret;
1099 }
1100 
active_passive_misconfig(zbx_socket_t * sock)1101 static void	active_passive_misconfig(zbx_socket_t *sock)
1102 {
1103 	char	*msg = NULL;
1104 
1105 	msg = zbx_dsprintf(msg, "misconfiguration error: the proxy is running in the active mode but server at \"%s\""
1106 			" sends requests to it as to proxy in passive mode", sock->peer);
1107 
1108 	zabbix_log(LOG_LEVEL_WARNING, "%s", msg);
1109 	zbx_send_proxy_response(sock, FAIL, msg, CONFIG_TIMEOUT);
1110 	zbx_free(msg);
1111 }
1112 
process_trap(zbx_socket_t * sock,char * s,ssize_t bytes_received,zbx_timespec_t * ts)1113 static int	process_trap(zbx_socket_t *sock, char *s, ssize_t bytes_received, zbx_timespec_t *ts)
1114 {
1115 	int	ret = SUCCEED;
1116 
1117 	zbx_rtrim(s, " \r\n");
1118 
1119 	zabbix_log(LOG_LEVEL_DEBUG, "trapper got '%s'", s);
1120 
1121 	if ('{' == *s)	/* JSON protocol */
1122 	{
1123 		struct zbx_json_parse	jp;
1124 		char			value[MAX_STRING_LEN];
1125 
1126 		if (SUCCEED != zbx_json_open(s, &jp))
1127 		{
1128 			zbx_send_response(sock, FAIL, zbx_json_strerror(), CONFIG_TIMEOUT);
1129 			zabbix_log(LOG_LEVEL_WARNING, "received invalid JSON object from %s: %s",
1130 					sock->peer, zbx_json_strerror());
1131 			return FAIL;
1132 		}
1133 
1134 		if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value), NULL))
1135 			return FAIL;
1136 
1137 		if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
1138 		{
1139 			if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1140 			{
1141 				send_proxyconfig(sock, &jp);
1142 			}
1143 			else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
1144 			{
1145 				zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server"
1146 						" at \"%s\", datalen " ZBX_FS_SIZE_T,
1147 						sock->peer, (zbx_fs_size_t)(jp.end - jp.start + 1));
1148 				recv_proxyconfig(sock, &jp);
1149 			}
1150 			else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
1151 			{
1152 				/* This is a misconfiguration: the proxy is configured in active mode */
1153 				/* but server sends requests to it as to a proxy in passive mode. To  */
1154 				/* prevent logging of this problem for every request we report it     */
1155 				/* only when the server sends configuration to the proxy and ignore   */
1156 				/* it for other requests.                                             */
1157 				active_passive_misconfig(sock);
1158 			}
1159 		}
1160 		else
1161 		{
1162 			if (ZBX_GIBIBYTE < bytes_received)
1163 			{
1164 				zabbix_log(LOG_LEVEL_WARNING, "message size " ZBX_FS_I64 " exceeds the maximum size "
1165 						ZBX_FS_UI64 " for request \"%s\" received from \"%s\"", bytes_received,
1166 						(zbx_uint64_t)ZBX_GIBIBYTE, value, sock->peer);
1167 				return FAIL;
1168 			}
1169 
1170 			if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA))
1171 			{
1172 				recv_agenthistory(sock, &jp, ts);
1173 			}
1174 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
1175 			{
1176 				recv_senderhistory(sock, &jp, ts);
1177 			}
1178 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_TASKS))
1179 			{
1180 				if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
1181 					zbx_send_task_data(sock, ts);
1182 			}
1183 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_DATA))
1184 			{
1185 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1186 					zbx_recv_proxy_data(sock, &jp, ts);
1187 				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
1188 					zbx_send_proxy_data(sock, ts);
1189 			}
1190 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
1191 			{
1192 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1193 					recv_proxy_heartbeat(sock, &jp);
1194 			}
1195 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
1196 			{
1197 				ret = send_list_of_active_checks_json(sock, &jp);
1198 			}
1199 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
1200 			{
1201 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1202 					ret = node_process_command(sock, s, &jp);
1203 			}
1204 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE))
1205 			{
1206 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1207 					ret = recv_getqueue(sock, &jp);
1208 			}
1209 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_STATUS))
1210 			{
1211 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1212 					ret = recv_getstatus(sock, &jp);
1213 			}
1214 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_STATS))
1215 			{
1216 				ret = send_internal_stats_json(sock, &jp);
1217 			}
1218 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_ALERT_SEND))
1219 			{
1220 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1221 					recv_alert_send(sock, &jp);
1222 			}
1223 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PREPROCESSING_TEST))
1224 			{
1225 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1226 					ret = zbx_trapper_preproc_test(sock, &jp);
1227 			}
1228 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_EXPRESSIONS_EVALUATE))
1229 			{
1230 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1231 					ret = zbx_trapper_expressions_evaluate(sock, &jp);
1232 			}
1233 			else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_ITEM_TEST))
1234 			{
1235 				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
1236 					zbx_trapper_item_test(sock, &jp);
1237 			}
1238 			else
1239 			{
1240 				zabbix_log(LOG_LEVEL_WARNING, "unknown request received from \"%s\": [%s]", sock->peer,
1241 						value);
1242 			}
1243 		}
1244 	}
1245 	else if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21))	/* request for list of active checks */
1246 	{
1247 		ret = send_list_of_active_checks(sock, s);
1248 	}
1249 	else
1250 	{
1251 		char			value_dec[MAX_BUFFER_LEN], lastlogsize[ZBX_MAX_UINT64_LEN], timestamp[11],
1252 					source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11],
1253 					host[HOST_HOST_LEN * ZBX_MAX_BYTES_IN_UTF8_CHAR + 1],
1254 					key[ITEM_KEY_LEN * ZBX_MAX_BYTES_IN_UTF8_CHAR + 1];
1255 		zbx_agent_value_t	av;
1256 		zbx_host_key_t		hk = {host, key};
1257 		DC_ITEM			item;
1258 		int			errcode;
1259 
1260 		if (ZBX_GIBIBYTE < bytes_received)
1261 		{
1262 			zabbix_log(LOG_LEVEL_WARNING, "message size " ZBX_FS_I64 " exceeds the maximum size "
1263 					ZBX_FS_UI64 " for XML protocol received from \"%s\"", bytes_received,
1264 					(zbx_uint64_t)ZBX_GIBIBYTE, sock->peer);
1265 			return FAIL;
1266 		}
1267 
1268 		memset(&av, 0, sizeof(zbx_agent_value_t));
1269 
1270 		if ('<' == *s)	/* XML protocol */
1271 		{
1272 			comms_parse_response(s, host, sizeof(host), key, sizeof(key), value_dec,
1273 					sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp,
1274 					sizeof(timestamp), source, sizeof(source), severity, sizeof(severity));
1275 
1276 			av.value = value_dec;
1277 			if (SUCCEED != is_uint64(lastlogsize, &av.lastlogsize))
1278 				av.lastlogsize = 0;
1279 			av.timestamp = atoi(timestamp);
1280 			av.source = source;
1281 			av.severity = atoi(severity);
1282 		}
1283 		else
1284 		{
1285 			char	*pl, *pr;
1286 
1287 			pl = s;
1288 			if (NULL == (pr = strchr(pl, ':')))
1289 				return FAIL;
1290 
1291 			*pr = '\0';
1292 			zbx_strlcpy(host, pl, sizeof(host));
1293 			*pr = ':';
1294 
1295 			pl = pr + 1;
1296 			if (NULL == (pr = strchr(pl, ':')))
1297 				return FAIL;
1298 
1299 			*pr = '\0';
1300 			zbx_strlcpy(key, pl, sizeof(key));
1301 			*pr = ':';
1302 
1303 			av.value = pr + 1;
1304 			av.severity = 0;
1305 		}
1306 
1307 		zbx_timespec(&av.ts);
1308 
1309 		if (0 == strcmp(av.value, ZBX_NOTSUPPORTED))
1310 			av.state = ITEM_STATE_NOTSUPPORTED;
1311 
1312 		DCconfig_get_items_by_keys(&item, &hk, &errcode, 1);
1313 		process_history_data(&item, &av, &errcode, 1, NULL);
1314 		DCconfig_clean_items(&item, &errcode, 1);
1315 
1316 		zbx_alarm_on(CONFIG_TIMEOUT);
1317 		if (SUCCEED != zbx_tcp_send_raw(sock, "OK"))
1318 			zabbix_log(LOG_LEVEL_WARNING, "Error sending result back");
1319 		zbx_alarm_off();
1320 	}
1321 
1322 	return ret;
1323 }
1324 
process_trapper_child(zbx_socket_t * sock,zbx_timespec_t * ts)1325 static void	process_trapper_child(zbx_socket_t *sock, zbx_timespec_t *ts)
1326 {
1327 	ssize_t	bytes_received;
1328 
1329 	if (FAIL == (bytes_received = zbx_tcp_recv_ext(sock, CONFIG_TRAPPER_TIMEOUT, ZBX_TCP_LARGE)))
1330 		return;
1331 
1332 	process_trap(sock, sock->buffer, bytes_received, ts);
1333 }
1334 
zbx_trapper_sigusr_handler(int flags)1335 static void	zbx_trapper_sigusr_handler(int flags)
1336 {
1337 #ifdef HAVE_NETSNMP
1338 	if (ZBX_RTC_SNMP_CACHE_RELOAD == ZBX_RTC_GET_MSG(flags))
1339 		snmp_cache_reload_requested = 1;
1340 #else
1341 	ZBX_UNUSED(flags);
1342 #endif
1343 }
1344 
ZBX_THREAD_ENTRY(trapper_thread,args)1345 ZBX_THREAD_ENTRY(trapper_thread, args)
1346 {
1347 	double		sec = 0.0;
1348 	zbx_socket_t	s;
1349 	int		ret;
1350 
1351 	process_type = ((zbx_thread_args_t *)args)->process_type;
1352 	server_num = ((zbx_thread_args_t *)args)->server_num;
1353 	process_num = ((zbx_thread_args_t *)args)->process_num;
1354 
1355 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
1356 			server_num, get_process_type_string(process_type), process_num);
1357 
1358 	update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
1359 
1360 	memcpy(&s, (zbx_socket_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_socket_t));
1361 
1362 #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
1363 	zbx_tls_init_child();
1364 	find_psk_in_cache = DCget_psk_by_identity;
1365 #endif
1366 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
1367 
1368 	DBconnect(ZBX_DB_CONNECT_NORMAL);
1369 
1370 	zbx_set_sigusr_handler(zbx_trapper_sigusr_handler);
1371 
1372 	while (ZBX_IS_RUNNING())
1373 	{
1374 #ifdef HAVE_NETSNMP
1375 		if (1 == snmp_cache_reload_requested)
1376 		{
1377 			zbx_clear_cache_snmp(process_type, process_num);
1378 			snmp_cache_reload_requested = 0;
1379 		}
1380 #endif
1381 		zbx_setproctitle("%s #%d [processed data in " ZBX_FS_DBL " sec, waiting for connection]",
1382 				get_process_type_string(process_type), process_num, sec);
1383 
1384 		update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
1385 
1386 		/* Trapper has to accept all types of connections it can accept with the specified configuration. */
1387 		/* Only after receiving data it is known who has sent them and one can decide to accept or discard */
1388 		/* the data. */
1389 		ret = zbx_tcp_accept(&s, ZBX_TCP_SEC_TLS_CERT | ZBX_TCP_SEC_TLS_PSK | ZBX_TCP_SEC_UNENCRYPTED);
1390 		zbx_update_env(zbx_time());
1391 
1392 		if (SUCCEED == ret)
1393 		{
1394 			zbx_timespec_t	ts;
1395 
1396 			/* get connection timestamp */
1397 			zbx_timespec(&ts);
1398 
1399 			update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
1400 
1401 			zbx_setproctitle("%s #%d [processing data]", get_process_type_string(process_type),
1402 					process_num);
1403 
1404 			sec = zbx_time();
1405 			process_trapper_child(&s, &ts);
1406 			sec = zbx_time() - sec;
1407 
1408 			zbx_tcp_unaccept(&s);
1409 		}
1410 		else if (EINTR != zbx_socket_last_error())
1411 		{
1412 			zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming connection: %s",
1413 					zbx_socket_strerror());
1414 		}
1415 	}
1416 
1417 	zbx_setproctitle("%s #%d [terminated]", get_process_type_string(process_type), process_num);
1418 
1419 	while (1)
1420 		zbx_sleep(SEC_PER_MIN);
1421 }
1422