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 "sysinfo.h"
22 
23 #include "cfg.h"
24 #include "log.h"
25 #include "zbxconf.h"
26 #include "zbxgetopt.h"
27 #include "comms.h"
28 
29 char	*CONFIG_HOSTS_ALLOWED		= NULL;
30 char	*CONFIG_HOSTNAME		= NULL;
31 char	*CONFIG_HOSTNAME_ITEM		= NULL;
32 char	*CONFIG_HOST_METADATA		= NULL;
33 char	*CONFIG_HOST_METADATA_ITEM	= NULL;
34 
35 int	CONFIG_ENABLE_REMOTE_COMMANDS	= 0;
36 int	CONFIG_LOG_REMOTE_COMMANDS	= 0;
37 int	CONFIG_UNSAFE_USER_PARAMETERS	= 0;
38 int	CONFIG_LISTEN_PORT		= ZBX_DEFAULT_AGENT_PORT;
39 int	CONFIG_REFRESH_ACTIVE_CHECKS	= 120;
40 char	*CONFIG_LISTEN_IP		= NULL;
41 char	*CONFIG_SOURCE_IP		= NULL;
42 int	CONFIG_LOG_LEVEL		= LOG_LEVEL_WARNING;
43 
44 int	CONFIG_BUFFER_SIZE		= 100;
45 int	CONFIG_BUFFER_SEND		= 5;
46 
47 int	CONFIG_MAX_LINES_PER_SECOND	= 20;
48 
49 char	*CONFIG_LOAD_MODULE_PATH	= NULL;
50 
51 char	**CONFIG_ALIASES		= NULL;
52 char	**CONFIG_LOAD_MODULE		= NULL;
53 char	**CONFIG_USER_PARAMETERS	= NULL;
54 #if defined(_WINDOWS)
55 char	**CONFIG_PERF_COUNTERS		= NULL;
56 char	**CONFIG_PERF_COUNTERS_EN	= NULL;
57 #endif
58 
59 char	*CONFIG_USER			= NULL;
60 
61 /* SSL parameters */
62 char	*CONFIG_SSL_CA_LOCATION;
63 char	*CONFIG_SSL_CERT_LOCATION;
64 char	*CONFIG_SSL_KEY_LOCATION;
65 
66 /* TLS parameters */
67 unsigned int	configured_tls_connect_mode = ZBX_TCP_SEC_UNENCRYPTED;
68 unsigned int	configured_tls_accept_modes = ZBX_TCP_SEC_UNENCRYPTED;
69 
70 char	*CONFIG_TLS_CONNECT		= NULL;
71 char	*CONFIG_TLS_ACCEPT		= NULL;
72 char	*CONFIG_TLS_CA_FILE		= NULL;
73 char	*CONFIG_TLS_CRL_FILE		= NULL;
74 char	*CONFIG_TLS_SERVER_CERT_ISSUER	= NULL;
75 char	*CONFIG_TLS_SERVER_CERT_SUBJECT	= NULL;
76 char	*CONFIG_TLS_CERT_FILE		= NULL;
77 char	*CONFIG_TLS_KEY_FILE		= NULL;
78 char	*CONFIG_TLS_PSK_IDENTITY	= NULL;
79 char	*CONFIG_TLS_PSK_FILE		= NULL;
80 char	*CONFIG_TLS_CIPHER_CERT13	= NULL;
81 char	*CONFIG_TLS_CIPHER_CERT		= NULL;
82 char	*CONFIG_TLS_CIPHER_PSK13	= NULL;
83 char	*CONFIG_TLS_CIPHER_PSK		= NULL;
84 char	*CONFIG_TLS_CIPHER_ALL13	= NULL;
85 char	*CONFIG_TLS_CIPHER_ALL		= NULL;
86 char	*CONFIG_TLS_CIPHER_CMD13	= NULL;	/* not used in agent, defined for linking with tls.c */
87 char	*CONFIG_TLS_CIPHER_CMD		= NULL;	/* not used in agent, defined for linking with tls.c */
88 
89 #ifndef _WINDOWS
90 #	include "../libs/zbxnix/control.h"
91 #	include "zbxmodules.h"
92 #endif
93 
94 #include "comms.h"
95 #include "alias.h"
96 
97 #include "stats.h"
98 #ifdef _WINDOWS
99 #	include "perfstat.h"
100 #else
101 #	include "zbxnix.h"
102 #	include "sighandler.h"
103 #endif
104 #include "active.h"
105 #include "listener.h"
106 
107 #include "symbols.h"
108 
109 #if defined(ZABBIX_SERVICE)
110 #	include "service.h"
111 #elif defined(ZABBIX_DAEMON)
112 #	include "daemon.h"
113 #endif
114 
115 #include "setproctitle.h"
116 #include "../libs/zbxcrypto/tls.h"
117 
118 const char	*progname = NULL;
119 
120 /* application TITLE */
121 const char	title_message[] = "zabbix_agentd"
122 #if defined(_WIN64)
123 				" Win64"
124 #elif defined(_WIN32)
125 				" Win32"
126 #endif
127 #if defined(ZABBIX_SERVICE)
128 				" (service)"
129 #elif defined(ZABBIX_DAEMON)
130 				" (daemon)"
131 #endif
132 	;
133 /* end of application TITLE */
134 
135 const char	syslog_app_name[] = "zabbix_agentd";
136 
137 /* application USAGE message */
138 const char	*usage_message[] = {
139 	"[-c config-file]", NULL,
140 	"[-c config-file]", "-p", NULL,
141 	"[-c config-file]", "-t item-key", NULL,
142 #ifdef _WINDOWS
143 	"[-c config-file]", "-i", "[-m]", NULL,
144 	"[-c config-file]", "-d", "[-m]", NULL,
145 	"[-c config-file]", "-s", "[-m]", NULL,
146 	"[-c config-file]", "-x", "[-m]", NULL,
147 #else
148 	"[-c config-file]", "-R runtime-option", NULL,
149 #endif
150 	"-h", NULL,
151 	"-V", NULL,
152 	NULL	/* end of text */
153 };
154 /* end of application USAGE message */
155 
156 /* application HELP message */
157 const char	*help_message[] = {
158 	"A Zabbix daemon for monitoring of various server parameters.",
159 	"",
160 	"Options:",
161 	"  -c --config config-file        Path to the configuration file",
162 	"                                 (default: \"" DEFAULT_CONFIG_FILE "\")",
163 	"  -f --foreground                Run Zabbix agent in foreground",
164 	"  -p --print                     Print known items and exit",
165 	"  -t --test item-key             Test specified item and exit",
166 #ifdef _WINDOWS
167 	"  -m --multiple-agents           For -i -d -s -x functions service name will",
168 	"                                 include Hostname parameter specified in",
169 	"                                 configuration file",
170 	"Functions:",
171 	"",
172 	"  -i --install                   Install Zabbix agent as service",
173 	"  -d --uninstall                 Uninstall Zabbix agent from service",
174 
175 	"  -s --start                     Start Zabbix agent service",
176 	"  -x --stop                      Stop Zabbix agent service",
177 #else
178 	"  -R --runtime-control runtime-option   Perform administrative functions",
179 	"",
180 	"    Runtime control options:",
181 	"      " ZBX_LOG_LEVEL_INCREASE "=target  Increase log level, affects all processes if",
182 	"                                 target is not specified",
183 	"      " ZBX_LOG_LEVEL_DECREASE "=target  Decrease log level, affects all processes if",
184 	"                                 target is not specified",
185 	"",
186 	"      Log level control targets:",
187 	"        process-type             All processes of specified type (active checks,",
188 	"                                 collector, listener)",
189 	"        process-type,N           Process type and number (e.g., listener,3)",
190 	"        pid                      Process identifier, up to 65535. For larger",
191 	"                                 values specify target as \"process-type,N\"",
192 #endif
193 	"",
194 	"  -h --help                      Display this help message",
195 	"  -V --version                   Display version number",
196 	"",
197 #ifndef _WINDOWS
198 	"Default loadable module location:",
199 	"  LoadModulePath                 \"" DEFAULT_LOAD_MODULE_PATH "\"",
200 	"",
201 #endif
202 #ifdef _WINDOWS
203 	"Example: zabbix_agentd -c C:\\zabbix\\zabbix_agentd.conf",
204 #else
205 	"Example: zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf",
206 #endif
207 	NULL	/* end of text */
208 };
209 /* end of application HELP message */
210 
211 /* COMMAND LINE OPTIONS */
212 static struct zbx_option	longopts[] =
213 {
214 	{"config",		1,	NULL,	'c'},
215 	{"foreground",		0,	NULL,	'f'},
216 	{"help",		0,	NULL,	'h'},
217 	{"version",		0,	NULL,	'V'},
218 	{"print",		0,	NULL,	'p'},
219 	{"test",		1,	NULL,	't'},
220 #ifndef _WINDOWS
221 	{"runtime-control",	1,	NULL,	'R'},
222 #else
223 	{"install",		0,	NULL,	'i'},
224 	{"uninstall",		0,	NULL,	'd'},
225 
226 	{"start",		0,	NULL,	's'},
227 	{"stop",		0,	NULL,	'x'},
228 
229 	{"multiple-agents",	0,	NULL,	'm'},
230 #endif
231 	{NULL}
232 };
233 
234 static char	shortopts[] =
235 	"c:hVpt:f"
236 #ifndef _WINDOWS
237 	"R:"
238 #else
239 	"idsxm"
240 #endif
241 	;
242 /* end of COMMAND LINE OPTIONS */
243 
244 static char		*TEST_METRIC = NULL;
245 int			threads_num = 0;
246 ZBX_THREAD_HANDLE	*threads = NULL;
247 static int		*threads_flags;
248 
249 unsigned char	program_type = ZBX_PROGRAM_TYPE_AGENTD;
250 
251 ZBX_THREAD_LOCAL unsigned char	process_type	= 255;	/* ZBX_PROCESS_TYPE_UNKNOWN */
252 ZBX_THREAD_LOCAL int		process_num;
253 ZBX_THREAD_LOCAL int		server_num	= 0;
254 
255 static ZBX_THREAD_ACTIVECHK_ARGS	*CONFIG_ACTIVE_ARGS = NULL;
256 
257 int	CONFIG_ALERTER_FORKS		= 0;
258 int	CONFIG_DISCOVERER_FORKS		= 0;
259 int	CONFIG_HOUSEKEEPER_FORKS	= 0;
260 int	CONFIG_PINGER_FORKS		= 0;
261 int	CONFIG_POLLER_FORKS		= 0;
262 int	CONFIG_UNREACHABLE_POLLER_FORKS	= 0;
263 int	CONFIG_HTTPPOLLER_FORKS		= 0;
264 int	CONFIG_IPMIPOLLER_FORKS		= 0;
265 int	CONFIG_TIMER_FORKS		= 0;
266 int	CONFIG_TRAPPER_FORKS		= 0;
267 int	CONFIG_SNMPTRAPPER_FORKS	= 0;
268 int	CONFIG_JAVAPOLLER_FORKS		= 0;
269 int	CONFIG_ESCALATOR_FORKS		= 0;
270 int	CONFIG_SELFMON_FORKS		= 0;
271 int	CONFIG_DATASENDER_FORKS		= 0;
272 int	CONFIG_HEARTBEAT_FORKS		= 0;
273 int	CONFIG_PROXYPOLLER_FORKS	= 0;
274 int	CONFIG_HISTSYNCER_FORKS		= 0;
275 int	CONFIG_CONFSYNCER_FORKS		= 0;
276 int	CONFIG_VMWARE_FORKS		= 0;
277 int	CONFIG_COLLECTOR_FORKS		= 1;
278 int	CONFIG_PASSIVE_FORKS		= 3;	/* number of listeners for processing passive checks */
279 int	CONFIG_ACTIVE_FORKS		= 0;
280 int	CONFIG_TASKMANAGER_FORKS	= 0;
281 int	CONFIG_IPMIMANAGER_FORKS	= 0;
282 int	CONFIG_ALERTMANAGER_FORKS	= 0;
283 int	CONFIG_PREPROCMAN_FORKS		= 0;
284 int	CONFIG_PREPROCESSOR_FORKS	= 0;
285 
286 char	*opt = NULL;
287 
288 #ifdef _WINDOWS
289 void	zbx_co_uninitialize();
290 #endif
291 
292 int	get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num);
293 void	zbx_free_service_resources(int ret);
294 
get_process_info_by_thread(int local_server_num,unsigned char * local_process_type,int * local_process_num)295 int	get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num)
296 {
297 	int	server_count = 0;
298 
299 	if (0 == local_server_num)
300 	{
301 		/* fail if the main process is queried */
302 		return FAIL;
303 	}
304 	else if (local_server_num <= (server_count += CONFIG_COLLECTOR_FORKS))
305 	{
306 		*local_process_type = ZBX_PROCESS_TYPE_COLLECTOR;
307 		*local_process_num = local_server_num - server_count + CONFIG_COLLECTOR_FORKS;
308 	}
309 	else if (local_server_num <= (server_count += CONFIG_PASSIVE_FORKS))
310 	{
311 		*local_process_type = ZBX_PROCESS_TYPE_LISTENER;
312 		*local_process_num = local_server_num - server_count + CONFIG_PASSIVE_FORKS;
313 
314 	}
315 	else if (local_server_num <= (server_count += CONFIG_ACTIVE_FORKS))
316 	{
317 		*local_process_type = ZBX_PROCESS_TYPE_ACTIVE_CHECKS;
318 		*local_process_num = local_server_num - server_count + CONFIG_ACTIVE_FORKS;
319 	}
320 	else
321 		return FAIL;
322 
323 	return SUCCEED;
324 }
325 
parse_commandline(int argc,char ** argv,ZBX_TASK_EX * t)326 static int	parse_commandline(int argc, char **argv, ZBX_TASK_EX *t)
327 {
328 	int		i, ret = SUCCEED;
329 	char		ch;
330 #ifdef _WINDOWS
331 	unsigned int	opt_mask = 0;
332 #endif
333 	unsigned short	opt_count[256] = {0};
334 
335 	t->task = ZBX_TASK_START;
336 
337 	/* parse the command-line */
338 	while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, shortopts, longopts, NULL)))
339 	{
340 		opt_count[(unsigned char)ch]++;
341 
342 		switch (ch)
343 		{
344 			case 'c':
345 				if (NULL == CONFIG_FILE)
346 					CONFIG_FILE = strdup(zbx_optarg);
347 				break;
348 #ifndef _WINDOWS
349 			case 'R':
350 				if (SUCCEED != parse_rtc_options(zbx_optarg, program_type, &t->data))
351 					exit(EXIT_FAILURE);
352 
353 				t->task = ZBX_TASK_RUNTIME_CONTROL;
354 				break;
355 #endif
356 			case 'h':
357 				t->task = ZBX_TASK_SHOW_HELP;
358 				goto out;
359 			case 'V':
360 				t->task = ZBX_TASK_SHOW_VERSION;
361 				goto out;
362 			case 'p':
363 				if (ZBX_TASK_START == t->task)
364 					t->task = ZBX_TASK_PRINT_SUPPORTED;
365 				break;
366 			case 't':
367 				if (ZBX_TASK_START == t->task)
368 				{
369 					t->task = ZBX_TASK_TEST_METRIC;
370 					TEST_METRIC = strdup(zbx_optarg);
371 				}
372 				break;
373 			case 'f':
374 				t->flags |= ZBX_TASK_FLAG_FOREGROUND;
375 				break;
376 #ifdef _WINDOWS
377 			case 'i':
378 				t->task = ZBX_TASK_INSTALL_SERVICE;
379 				break;
380 			case 'd':
381 				t->task = ZBX_TASK_UNINSTALL_SERVICE;
382 				break;
383 			case 's':
384 				t->task = ZBX_TASK_START_SERVICE;
385 				break;
386 			case 'x':
387 				t->task = ZBX_TASK_STOP_SERVICE;
388 				break;
389 			case 'm':
390 				t->flags |= ZBX_TASK_FLAG_MULTIPLE_AGENTS;
391 				break;
392 #endif
393 			default:
394 				t->task = ZBX_TASK_SHOW_USAGE;
395 				goto out;
396 		}
397 	}
398 
399 #ifdef _WINDOWS
400 	switch (t->task)
401 	{
402 		case ZBX_TASK_START:
403 			break;
404 		case ZBX_TASK_INSTALL_SERVICE:
405 		case ZBX_TASK_UNINSTALL_SERVICE:
406 		case ZBX_TASK_START_SERVICE:
407 		case ZBX_TASK_STOP_SERVICE:
408 			if (0 != (t->flags & ZBX_TASK_FLAG_FOREGROUND))
409 			{
410 				zbx_error("foreground option cannot be used with Zabbix agent services");
411 				ret = FAIL;
412 				goto out;
413 			}
414 			break;
415 		default:
416 			if (0 != (t->flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS))
417 			{
418 				zbx_error("multiple agents option can be used only with Zabbix agent services");
419 				ret = FAIL;
420 				goto out;
421 			}
422 	}
423 #endif
424 
425 	/* every option may be specified only once */
426 
427 	for (i = 0; NULL != longopts[i].name; i++)
428 	{
429 		ch = (char)longopts[i].val;
430 
431 		if ('h' == ch || 'V' == ch)
432 			continue;
433 
434 		if (1 < opt_count[(unsigned char)ch])
435 		{
436 			if (NULL == strchr(shortopts, ch))
437 				zbx_error("option \"--%s\" specified multiple times", longopts[i].name);
438 			else
439 				zbx_error("option \"-%c\" or \"--%s\" specified multiple times", ch, longopts[i].name);
440 
441 			ret = FAIL;
442 		}
443 	}
444 
445 	if (FAIL == ret)
446 		goto out;
447 
448 #ifdef _WINDOWS
449 	/* check for mutually exclusive options */
450 	/* Allowed option combinations.		*/
451 	/* Option 'c' is always optional.	*/
452 	/*   p  t  i  d  s  x  m    opt_mask	*/
453 	/* ---------------------    --------	*/
454 	/*   -  -  -  -  -  -  - 	0x00	*/
455 	/*   p  -  -  -  -  -  -	0x40	*/
456 	/*   -  t  -  -  -  -  -	0x20	*/
457 	/*   -  -  i  -  -  -  -	0x10	*/
458 	/*   -  -  -  d  -  -  -	0x08	*/
459 	/*   -  -  -  -  s  -  -	0x04	*/
460 	/*   -  -  -  -  -  x  -	0x02	*/
461 	/*   -  -  i  -  -  -  m	0x11	*/
462 	/*   -  -  -  d  -  -  m	0x09	*/
463 	/*   -  -  -  -  s  -  m	0x05	*/
464 	/*   -  -  -  -  -  x  m	0x03	*/
465 	/*   -  -  -  -  -  -  m	0x01 special case required for starting as a service with '-m' option */
466 
467 	if (0 < opt_count['p'])
468 		opt_mask |= 0x40;
469 	if (0 < opt_count['t'])
470 		opt_mask |= 0x20;
471 	if (0 < opt_count['i'])
472 		opt_mask |= 0x10;
473 	if (0 < opt_count['d'])
474 		opt_mask |= 0x08;
475 	if (0 < opt_count['s'])
476 		opt_mask |= 0x04;
477 	if (0 < opt_count['x'])
478 		opt_mask |= 0x02;
479 	if (0 < opt_count['m'])
480 		opt_mask |= 0x01;
481 
482 	switch (opt_mask)
483 	{
484 		case 0x00:
485 		case 0x01:
486 		case 0x02:
487 		case 0x03:
488 		case 0x04:
489 		case 0x05:
490 		case 0x08:
491 		case 0x09:
492 		case 0x10:
493 		case 0x11:
494 		case 0x20:
495 		case 0x40:
496 			break;
497 		default:
498 			zbx_error("mutually exclusive options used");
499 			usage();
500 			ret = FAIL;
501 			goto out;
502 	}
503 #else
504 	/* check for mutually exclusive options */
505 	if (1 < opt_count['p'] + opt_count['t'] + opt_count['R'])
506 	{
507 		zbx_error("only one of options \"-p\" or \"--print\", \"-t\" or \"--test\","
508 				" \"-R\" or \"--runtime-control\" can be used");
509 		ret = FAIL;
510 		goto out;
511 	}
512 #endif
513 	/* Parameters which are not option values are invalid. The check relies on zbx_getopt_internal() which */
514 	/* always permutes command line arguments regardless of POSIXLY_CORRECT environment variable. */
515 	if (argc > zbx_optind)
516 	{
517 		for (i = zbx_optind; i < argc; i++)
518 			zbx_error("invalid parameter \"%s\"", argv[i]);
519 
520 		ret = FAIL;
521 		goto out;
522 	}
523 
524 	if (NULL == CONFIG_FILE)
525 		CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
526 out:
527 	if (FAIL == ret)
528 	{
529 		zbx_free(TEST_METRIC);
530 		zbx_free(CONFIG_FILE);
531 	}
532 
533 	return ret;
534 }
535 
536 /******************************************************************************
537  *                                                                            *
538  * Function: set_defaults                                                     *
539  *                                                                            *
540  * Purpose: set configuration defaults                                        *
541  *                                                                            *
542  * Author: Vladimir Levijev, Rudolfs Kreicbergs                               *
543  *                                                                            *
544  ******************************************************************************/
set_defaults(void)545 static void	set_defaults(void)
546 {
547 	AGENT_RESULT	result;
548 	char		**value = NULL;
549 
550 	if (NULL == CONFIG_HOSTNAME)
551 	{
552 		if (NULL == CONFIG_HOSTNAME_ITEM)
553 			CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");
554 
555 		init_result(&result);
556 
557 		if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, PROCESS_LOCAL_COMMAND | PROCESS_WITH_ALIAS, &result) &&
558 				NULL != (value = GET_STR_RESULT(&result)))
559 		{
560 			assert(*value);
561 
562 			if (MAX_ZBX_HOSTNAME_LEN < strlen(*value))
563 			{
564 				(*value)[MAX_ZBX_HOSTNAME_LEN] = '\0';
565 				zabbix_log(LOG_LEVEL_WARNING, "hostname truncated to [%s])", *value);
566 			}
567 
568 			CONFIG_HOSTNAME = zbx_strdup(CONFIG_HOSTNAME, *value);
569 		}
570 		else
571 			zabbix_log(LOG_LEVEL_WARNING, "failed to get system hostname from [%s])", CONFIG_HOSTNAME_ITEM);
572 
573 		free_result(&result);
574 	}
575 	else if (NULL != CONFIG_HOSTNAME_ITEM)
576 		zabbix_log(LOG_LEVEL_WARNING, "both Hostname and HostnameItem defined, using [%s]", CONFIG_HOSTNAME);
577 
578 	if (NULL != CONFIG_HOST_METADATA && NULL != CONFIG_HOST_METADATA_ITEM)
579 	{
580 		zabbix_log(LOG_LEVEL_WARNING, "both HostMetadata and HostMetadataItem defined, using [%s]",
581 				CONFIG_HOST_METADATA);
582 	}
583 
584 #ifndef _WINDOWS
585 	if (NULL == CONFIG_LOAD_MODULE_PATH)
586 		CONFIG_LOAD_MODULE_PATH = zbx_strdup(CONFIG_LOAD_MODULE_PATH, DEFAULT_LOAD_MODULE_PATH);
587 
588 	if (NULL == CONFIG_PID_FILE)
589 		CONFIG_PID_FILE = (char *)"/tmp/zabbix_agentd.pid";
590 #endif
591 	if (NULL == CONFIG_LOG_TYPE_STR)
592 		CONFIG_LOG_TYPE_STR = zbx_strdup(CONFIG_LOG_TYPE_STR, ZBX_OPTION_LOGTYPE_FILE);
593 }
594 
595 /******************************************************************************
596  *                                                                            *
597  * Function: zbx_validate_config                                              *
598  *                                                                            *
599  * Purpose: validate configuration parameters                                 *
600  *                                                                            *
601  * Author: Vladimir Levijev                                                   *
602  *                                                                            *
603  ******************************************************************************/
zbx_validate_config(ZBX_TASK_EX * task)604 static void	zbx_validate_config(ZBX_TASK_EX *task)
605 {
606 	char	*ch_error;
607 	int	err = 0;
608 
609 	if (0 != CONFIG_PASSIVE_FORKS)
610 	{
611 		if (NULL == CONFIG_HOSTS_ALLOWED)
612 		{
613 			zabbix_log(LOG_LEVEL_CRIT, "StartAgents is not 0, parameter \"Server\" must be defined");
614 			err = 1;
615 		}
616 		else if (SUCCEED != zbx_validate_peer_list(CONFIG_HOSTS_ALLOWED, &ch_error))
617 		{
618 			zabbix_log(LOG_LEVEL_CRIT, "invalid entry in \"Server\" configuration parameter: %s", ch_error);
619 			zbx_free(ch_error);
620 			err = 1;
621 		}
622 	}
623 	if (NULL == CONFIG_HOSTNAME)
624 	{
625 		zabbix_log(LOG_LEVEL_CRIT, "\"Hostname\" configuration parameter is not defined");
626 		err = 1;
627 	}
628 	else if (FAIL == zbx_check_hostname(CONFIG_HOSTNAME, &ch_error))
629 	{
630 		zabbix_log(LOG_LEVEL_CRIT, "invalid \"Hostname\" configuration parameter: '%s': %s", CONFIG_HOSTNAME,
631 				ch_error);
632 		zbx_free(ch_error);
633 		err = 1;
634 	}
635 
636 	if (NULL != CONFIG_HOST_METADATA && HOST_METADATA_LEN < zbx_strlen_utf8(CONFIG_HOST_METADATA))
637 	{
638 		zabbix_log(LOG_LEVEL_CRIT, "the value of \"HostMetadata\" configuration parameter cannot be longer than"
639 				" %d characters", HOST_METADATA_LEN);
640 		err = 1;
641 	}
642 
643 	/* make sure active or passive check is enabled */
644 	if (0 == CONFIG_ACTIVE_FORKS && 0 == CONFIG_PASSIVE_FORKS)
645 	{
646 		zabbix_log(LOG_LEVEL_CRIT, "either active or passive checks must be enabled");
647 		err = 1;
648 	}
649 
650 	if (NULL != CONFIG_SOURCE_IP && SUCCEED != is_supported_ip(CONFIG_SOURCE_IP))
651 	{
652 		zabbix_log(LOG_LEVEL_CRIT, "invalid \"SourceIP\" configuration parameter: '%s'", CONFIG_SOURCE_IP);
653 		err = 1;
654 	}
655 
656 	if (SUCCEED != zbx_validate_log_parameters(task))
657 		err = 1;
658 
659 #if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
660 	err |= (FAIL == check_cfg_feature_str("TLSConnect", CONFIG_TLS_CONNECT, "TLS support"));
661 	err |= (FAIL == check_cfg_feature_str("TLSAccept", CONFIG_TLS_ACCEPT, "TLS support"));
662 	err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
663 	err |= (FAIL == check_cfg_feature_str("TLSCRLFile", CONFIG_TLS_CRL_FILE, "TLS support"));
664 	err |= (FAIL == check_cfg_feature_str("TLSServerCertIssuer", CONFIG_TLS_SERVER_CERT_ISSUER, "TLS support"));
665 	err |= (FAIL == check_cfg_feature_str("TLSServerCertSubject", CONFIG_TLS_SERVER_CERT_SUBJECT, "TLS support"));
666 	err |= (FAIL == check_cfg_feature_str("TLSCertFile", CONFIG_TLS_CERT_FILE, "TLS support"));
667 	err |= (FAIL == check_cfg_feature_str("TLSKeyFile", CONFIG_TLS_KEY_FILE, "TLS support"));
668 	err |= (FAIL == check_cfg_feature_str("TLSPSKIdentity", CONFIG_TLS_PSK_IDENTITY, "TLS support"));
669 	err |= (FAIL == check_cfg_feature_str("TLSPSKFile", CONFIG_TLS_PSK_FILE, "TLS support"));
670 #endif
671 #if !(defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
672 	err |= (FAIL == check_cfg_feature_str("TLSCipherCert", CONFIG_TLS_CIPHER_CERT, "GnuTLS or OpenSSL"));
673 	err |= (FAIL == check_cfg_feature_str("TLSCipherPSK", CONFIG_TLS_CIPHER_PSK, "GnuTLS or OpenSSL"));
674 	err |= (FAIL == check_cfg_feature_str("TLSCipherAll", CONFIG_TLS_CIPHER_ALL, "GnuTLS or OpenSSL"));
675 #endif
676 #if !defined(HAVE_OPENSSL)
677 	err |= (FAIL == check_cfg_feature_str("TLSCipherCert13", CONFIG_TLS_CIPHER_CERT13, "OpenSSL 1.1.1 or newer"));
678 	err |= (FAIL == check_cfg_feature_str("TLSCipherPSK13", CONFIG_TLS_CIPHER_PSK13, "OpenSSL 1.1.1 or newer"));
679 	err |= (FAIL == check_cfg_feature_str("TLSCipherAll13", CONFIG_TLS_CIPHER_ALL13, "OpenSSL 1.1.1 or newer"));
680 #endif
681 
682 	if (0 != err)
683 		exit(EXIT_FAILURE);
684 }
685 
add_activechk_host(const char * host,unsigned short port)686 static int	add_activechk_host(const char *host, unsigned short port)
687 {
688 	int	i;
689 
690 	for (i = 0; i < CONFIG_ACTIVE_FORKS; i++)
691 	{
692 		if (0 == strcmp(CONFIG_ACTIVE_ARGS[i].host, host) && CONFIG_ACTIVE_ARGS[i].port == port)
693 			return FAIL;
694 	}
695 
696 	CONFIG_ACTIVE_FORKS++;
697 	CONFIG_ACTIVE_ARGS = (ZBX_THREAD_ACTIVECHK_ARGS *)zbx_realloc(CONFIG_ACTIVE_ARGS, sizeof(ZBX_THREAD_ACTIVECHK_ARGS) * CONFIG_ACTIVE_FORKS);
698 	CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].host = zbx_strdup(NULL, host);
699 	CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].port = port;
700 
701 	return SUCCEED;
702 }
703 
704 /******************************************************************************
705  *                                                                            *
706  * Function: get_serveractive_hosts                                           *
707  *                                                                            *
708  * Purpose: parse string like IP<:port>,[IPv6]<:port>                         *
709  *                                                                            *
710  ******************************************************************************/
get_serveractive_hosts(char * active_hosts)711 static void	get_serveractive_hosts(char *active_hosts)
712 {
713 	char	*l = active_hosts, *r;
714 	int	rc = SUCCEED;
715 
716 	do
717 	{
718 		char		*host = NULL;
719 		unsigned short	port;
720 
721 		if (NULL != (r = strchr(l, ',')))
722 			*r = '\0';
723 
724 		if (SUCCEED != parse_serveractive_element(l, &host, &port, (unsigned short)ZBX_DEFAULT_SERVER_PORT))
725 			goto fail;
726 
727 		rc = add_activechk_host(host, port);
728 
729 		zbx_free(host);
730 
731 		if (SUCCEED != rc)
732 			goto fail;
733 
734 		if (NULL != r)
735 		{
736 			*r = ',';
737 			l = r + 1;
738 		}
739 	}
740 	while (NULL != r);
741 
742 	return;
743 fail:
744 	if (SUCCEED != rc)
745 		zbx_error("error parsing a \"ServerActive\" option: address \"%s\" specified more than once", l);
746 	else
747 		zbx_error("error parsing a \"ServerActive\" option: address \"%s\" is invalid", l);
748 
749 	if (NULL != r)
750 		*r = ',';
751 
752 	exit(EXIT_FAILURE);
753 }
754 
755 /******************************************************************************
756  *                                                                            *
757  * Function: zbx_load_config                                                  *
758  *                                                                            *
759  * Purpose: load configuration from config file                               *
760  *                                                                            *
761  * Parameters: requirement - produce error if config file missing or not      *
762  *                                                                            *
763  ******************************************************************************/
zbx_load_config(int requirement,ZBX_TASK_EX * task)764 static void	zbx_load_config(int requirement, ZBX_TASK_EX *task)
765 {
766 	static char	*active_hosts;
767 
768 	struct cfg_line	cfg[] =
769 	{
770 		/* PARAMETER,			VAR,					TYPE,
771 			MANDATORY,	MIN,			MAX */
772 		{"Server",			&CONFIG_HOSTS_ALLOWED,			TYPE_STRING_LIST,
773 			PARM_OPT,	0,			0},
774 		{"ServerActive",		&active_hosts,				TYPE_STRING_LIST,
775 			PARM_OPT,	0,			0},
776 		{"Hostname",			&CONFIG_HOSTNAME,			TYPE_STRING,
777 			PARM_OPT,	0,			0},
778 		{"HostnameItem",		&CONFIG_HOSTNAME_ITEM,			TYPE_STRING,
779 			PARM_OPT,	0,			0},
780 		{"HostMetadata",		&CONFIG_HOST_METADATA,			TYPE_STRING,
781 			PARM_OPT,	0,			0},
782 		{"HostMetadataItem",		&CONFIG_HOST_METADATA_ITEM,		TYPE_STRING,
783 			PARM_OPT,	0,			0},
784 		{"BufferSize",			&CONFIG_BUFFER_SIZE,			TYPE_INT,
785 			PARM_OPT,	2,			65535},
786 		{"BufferSend",			&CONFIG_BUFFER_SEND,			TYPE_INT,
787 			PARM_OPT,	1,			SEC_PER_HOUR},
788 #ifndef _WINDOWS
789 		{"PidFile",			&CONFIG_PID_FILE,			TYPE_STRING,
790 			PARM_OPT,	0,			0},
791 #endif
792 		{"LogType",			&CONFIG_LOG_TYPE_STR,			TYPE_STRING,
793 			PARM_OPT,	0,			0},
794 		{"LogFile",			&CONFIG_LOG_FILE,			TYPE_STRING,
795 			PARM_OPT,	0,			0},
796 		{"LogFileSize",			&CONFIG_LOG_FILE_SIZE,			TYPE_INT,
797 			PARM_OPT,	0,			1024},
798 		{"Timeout",			&CONFIG_TIMEOUT,			TYPE_INT,
799 			PARM_OPT,	1,			30},
800 		{"ListenPort",			&CONFIG_LISTEN_PORT,			TYPE_INT,
801 			PARM_OPT,	1024,			32767},
802 		{"ListenIP",			&CONFIG_LISTEN_IP,			TYPE_STRING_LIST,
803 			PARM_OPT,	0,			0},
804 		{"SourceIP",			&CONFIG_SOURCE_IP,			TYPE_STRING,
805 			PARM_OPT,	0,			0},
806 		{"DebugLevel",			&CONFIG_LOG_LEVEL,			TYPE_INT,
807 			PARM_OPT,	0,			5},
808 		{"StartAgents",			&CONFIG_PASSIVE_FORKS,			TYPE_INT,
809 			PARM_OPT,	0,			100},
810 		{"RefreshActiveChecks",		&CONFIG_REFRESH_ACTIVE_CHECKS,		TYPE_INT,
811 			PARM_OPT,	SEC_PER_MIN,		SEC_PER_HOUR},
812 		{"MaxLinesPerSecond",		&CONFIG_MAX_LINES_PER_SECOND,		TYPE_INT,
813 			PARM_OPT,	1,			1000},
814 		{"EnableRemoteCommands",	&CONFIG_ENABLE_REMOTE_COMMANDS,		TYPE_INT,
815 			PARM_OPT,	0,			1},
816 		{"LogRemoteCommands",		&CONFIG_LOG_REMOTE_COMMANDS,		TYPE_INT,
817 			PARM_OPT,	0,			1},
818 		{"UnsafeUserParameters",	&CONFIG_UNSAFE_USER_PARAMETERS,		TYPE_INT,
819 			PARM_OPT,	0,			1},
820 		{"Alias",			&CONFIG_ALIASES,			TYPE_MULTISTRING,
821 			PARM_OPT,	0,			0},
822 		{"UserParameter",		&CONFIG_USER_PARAMETERS,		TYPE_MULTISTRING,
823 			PARM_OPT,	0,			0},
824 #ifndef _WINDOWS
825 		{"LoadModulePath",		&CONFIG_LOAD_MODULE_PATH,		TYPE_STRING,
826 			PARM_OPT,	0,			0},
827 		{"LoadModule",			&CONFIG_LOAD_MODULE,			TYPE_MULTISTRING,
828 			PARM_OPT,	0,			0},
829 		{"AllowRoot",			&CONFIG_ALLOW_ROOT,			TYPE_INT,
830 			PARM_OPT,	0,			1},
831 		{"User",			&CONFIG_USER,				TYPE_STRING,
832 			PARM_OPT,	0,			0},
833 #endif
834 #ifdef _WINDOWS
835 		{"PerfCounter",			&CONFIG_PERF_COUNTERS,			TYPE_MULTISTRING,
836 			PARM_OPT,	0,			0},
837 		{"PerfCounterEn",		&CONFIG_PERF_COUNTERS_EN,		TYPE_MULTISTRING,
838 			PARM_OPT,	0,			0},
839 #endif
840 		{"TLSConnect",			&CONFIG_TLS_CONNECT,			TYPE_STRING,
841 			PARM_OPT,	0,			0},
842 		{"TLSAccept",			&CONFIG_TLS_ACCEPT,			TYPE_STRING_LIST,
843 			PARM_OPT,	0,			0},
844 		{"TLSCAFile",			&CONFIG_TLS_CA_FILE,			TYPE_STRING,
845 			PARM_OPT,	0,			0},
846 		{"TLSCRLFile",			&CONFIG_TLS_CRL_FILE,			TYPE_STRING,
847 			PARM_OPT,	0,			0},
848 		{"TLSServerCertIssuer",		&CONFIG_TLS_SERVER_CERT_ISSUER,		TYPE_STRING,
849 			PARM_OPT,	0,			0},
850 		{"TLSServerCertSubject",	&CONFIG_TLS_SERVER_CERT_SUBJECT,	TYPE_STRING,
851 			PARM_OPT,	0,			0},
852 		{"TLSCertFile",			&CONFIG_TLS_CERT_FILE,			TYPE_STRING,
853 			PARM_OPT,	0,			0},
854 		{"TLSKeyFile",			&CONFIG_TLS_KEY_FILE,			TYPE_STRING,
855 			PARM_OPT,	0,			0},
856 		{"TLSPSKIdentity",		&CONFIG_TLS_PSK_IDENTITY,		TYPE_STRING,
857 			PARM_OPT,	0,			0},
858 		{"TLSPSKFile",			&CONFIG_TLS_PSK_FILE,			TYPE_STRING,
859 			PARM_OPT,	0,			0},
860 		{"TLSCipherCert13",		&CONFIG_TLS_CIPHER_CERT13,		TYPE_STRING,
861 			PARM_OPT,	0,			0},
862 		{"TLSCipherCert",		&CONFIG_TLS_CIPHER_CERT,		TYPE_STRING,
863 			PARM_OPT,	0,			0},
864 		{"TLSCipherPSK13",		&CONFIG_TLS_CIPHER_PSK13,		TYPE_STRING,
865 			PARM_OPT,	0,			0},
866 		{"TLSCipherPSK",		&CONFIG_TLS_CIPHER_PSK,			TYPE_STRING,
867 			PARM_OPT,	0,			0},
868 		{"TLSCipherAll13",		&CONFIG_TLS_CIPHER_ALL13,		TYPE_STRING,
869 			PARM_OPT,	0,			0},
870 		{"TLSCipherAll",		&CONFIG_TLS_CIPHER_ALL,			TYPE_STRING,
871 			PARM_OPT,	0,			0},
872 		{NULL}
873 	};
874 
875 	/* initialize multistrings */
876 	zbx_strarr_init(&CONFIG_ALIASES);
877 	zbx_strarr_init(&CONFIG_USER_PARAMETERS);
878 #ifndef _WINDOWS
879 	zbx_strarr_init(&CONFIG_LOAD_MODULE);
880 #endif
881 #ifdef _WINDOWS
882 	zbx_strarr_init(&CONFIG_PERF_COUNTERS);
883 	zbx_strarr_init(&CONFIG_PERF_COUNTERS_EN);
884 #endif
885 	parse_cfg_file(CONFIG_FILE, cfg, requirement, ZBX_CFG_STRICT);
886 
887 	set_defaults();
888 
889 	CONFIG_LOG_TYPE = zbx_get_log_type(CONFIG_LOG_TYPE_STR);
890 
891 	if (NULL != active_hosts && '\0' != *active_hosts)
892 		get_serveractive_hosts(active_hosts);
893 
894 	zbx_free(active_hosts);
895 
896 	if (ZBX_CFG_FILE_REQUIRED == requirement)
897 	{
898 		zbx_validate_config(task);
899 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
900 		zbx_tls_validate_config();
901 #endif
902 	}
903 }
904 
905 /******************************************************************************
906  *                                                                            *
907  * Function: zbx_free_config                                                  *
908  *                                                                            *
909  * Purpose: free configuration memory                                         *
910  *                                                                            *
911  * Author: Vladimir Levijev                                                   *
912  *                                                                            *
913  ******************************************************************************/
zbx_free_config(void)914 static void	zbx_free_config(void)
915 {
916 	zbx_strarr_free(CONFIG_ALIASES);
917 	zbx_strarr_free(CONFIG_USER_PARAMETERS);
918 #ifndef _WINDOWS
919 	zbx_strarr_free(CONFIG_LOAD_MODULE);
920 #endif
921 #ifdef _WINDOWS
922 	zbx_strarr_free(CONFIG_PERF_COUNTERS);
923 	zbx_strarr_free(CONFIG_PERF_COUNTERS_EN);
924 #endif
925 }
926 
927 #ifdef _WINDOWS
zbx_exec_service_task(const char * name,const ZBX_TASK_EX * t)928 static int	zbx_exec_service_task(const char *name, const ZBX_TASK_EX *t)
929 {
930 	int	ret;
931 
932 	switch (t->task)
933 	{
934 		case ZBX_TASK_INSTALL_SERVICE:
935 			ret = ZabbixCreateService(name, t->flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS);
936 			break;
937 		case ZBX_TASK_UNINSTALL_SERVICE:
938 			ret = ZabbixRemoveService();
939 			break;
940 		case ZBX_TASK_START_SERVICE:
941 			ret = ZabbixStartService();
942 			break;
943 		case ZBX_TASK_STOP_SERVICE:
944 			ret = ZabbixStopService();
945 			break;
946 		default:
947 			/* there can not be other choice */
948 			assert(0);
949 	}
950 
951 	return ret;
952 }
953 #endif	/* _WINDOWS */
954 
MAIN_ZABBIX_ENTRY(int flags)955 int	MAIN_ZABBIX_ENTRY(int flags)
956 {
957 	zbx_socket_t	listen_sock;
958 	char		*error = NULL;
959 	int		i, j = 0;
960 #ifdef _WINDOWS
961 	DWORD		res;
962 #endif
963 
964 	if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
965 	{
966 		printf("Starting Zabbix Agent [%s]. Zabbix %s (revision %s).\nPress Ctrl+C to exit.\n\n",
967 				CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
968 	}
969 #ifndef _WINDOWS
970 	if (SUCCEED != zbx_locks_create(&error))
971 	{
972 		zbx_error("cannot create locks: %s", error);
973 		zbx_free(error);
974 		exit(EXIT_FAILURE);
975 	}
976 #endif
977 	if (SUCCEED != zabbix_open_log(CONFIG_LOG_TYPE, CONFIG_LOG_LEVEL, CONFIG_LOG_FILE, &error))
978 	{
979 		zbx_error("cannot open log: %s", error);
980 		zbx_free(error);
981 		exit(EXIT_FAILURE);
982 	}
983 
984 #ifdef HAVE_IPV6
985 #	define IPV6_FEATURE_STATUS	"YES"
986 #else
987 #	define IPV6_FEATURE_STATUS	" NO"
988 #endif
989 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
990 #	define TLS_FEATURE_STATUS	"YES"
991 #else
992 #	define TLS_FEATURE_STATUS	" NO"
993 #endif
994 
995 	zabbix_log(LOG_LEVEL_INFORMATION, "Starting Zabbix Agent [%s]. Zabbix %s (revision %s).",
996 			CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
997 
998 	zabbix_log(LOG_LEVEL_INFORMATION, "**** Enabled features ****");
999 	zabbix_log(LOG_LEVEL_INFORMATION, "IPv6 support:          " IPV6_FEATURE_STATUS);
1000 	zabbix_log(LOG_LEVEL_INFORMATION, "TLS support:           " TLS_FEATURE_STATUS);
1001 	zabbix_log(LOG_LEVEL_INFORMATION, "**************************");
1002 
1003 	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
1004 
1005 #if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
1006 	if (SUCCEED != zbx_coredump_disable())
1007 	{
1008 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
1009 		zbx_free_service_resources(FAIL);
1010 		exit(EXIT_FAILURE);
1011 	}
1012 #endif
1013 #ifndef _WINDOWS
1014 	if (FAIL == zbx_load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 1))
1015 	{
1016 		zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
1017 		zbx_free_service_resources(FAIL);
1018 		exit(EXIT_FAILURE);
1019 	}
1020 #endif
1021 	if (0 != CONFIG_PASSIVE_FORKS)
1022 	{
1023 		if (FAIL == zbx_tcp_listen(&listen_sock, CONFIG_LISTEN_IP, (unsigned short)CONFIG_LISTEN_PORT))
1024 		{
1025 			zabbix_log(LOG_LEVEL_CRIT, "listener failed: %s", zbx_socket_strerror());
1026 			zbx_free_service_resources(FAIL);
1027 			exit(EXIT_FAILURE);
1028 		}
1029 	}
1030 
1031 	if (SUCCEED != init_collector_data(&error))
1032 	{
1033 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize collector: %s", error);
1034 		zbx_free(error);
1035 		zbx_free_service_resources(FAIL);
1036 		exit(EXIT_FAILURE);
1037 	}
1038 
1039 #ifdef _WINDOWS
1040 	if (SUCCEED != init_perf_collector(ZBX_MULTI_THREADED, &error))
1041 	{
1042 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize performance counter collector: %s", error);
1043 		zbx_free(error);
1044 		zbx_free_service_resources(FAIL);
1045 		exit(EXIT_FAILURE);
1046 	}
1047 
1048 	load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN);
1049 #endif
1050 	zbx_free_config();
1051 
1052 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
1053 	zbx_tls_init_parent();
1054 #endif
1055 	/* --- START THREADS ---*/
1056 
1057 	/* allocate memory for a collector, all listeners and active checks */
1058 	threads_num = CONFIG_COLLECTOR_FORKS + CONFIG_PASSIVE_FORKS + CONFIG_ACTIVE_FORKS;
1059 
1060 #ifdef _WINDOWS
1061 	if (MAXIMUM_WAIT_OBJECTS < threads_num)
1062 	{
1063 		zabbix_log(LOG_LEVEL_CRIT, "Too many agent threads. Please reduce the StartAgents configuration"
1064 				" parameter or the number of active servers in ServerActive configuration parameter.");
1065 		zbx_free_service_resources(FAIL);
1066 		exit(EXIT_FAILURE);
1067 	}
1068 #endif
1069 	threads = (ZBX_THREAD_HANDLE *)zbx_calloc(threads, threads_num, sizeof(ZBX_THREAD_HANDLE));
1070 	threads_flags = (int *)zbx_calloc(threads_flags, threads_num, sizeof(int));
1071 
1072 	zabbix_log(LOG_LEVEL_INFORMATION, "agent #0 started [main process]");
1073 
1074 	for (i = 0; i < threads_num; i++)
1075 	{
1076 		zbx_thread_args_t	*thread_args;
1077 
1078 		thread_args = (zbx_thread_args_t *)zbx_malloc(NULL, sizeof(zbx_thread_args_t));
1079 
1080 		if (FAIL == get_process_info_by_thread(i + 1, &thread_args->process_type, &thread_args->process_num))
1081 		{
1082 			THIS_SHOULD_NEVER_HAPPEN;
1083 			exit(EXIT_FAILURE);
1084 		}
1085 
1086 		thread_args->server_num = i + 1;
1087 		thread_args->args = NULL;
1088 
1089 		switch (thread_args->process_type)
1090 		{
1091 			case ZBX_PROCESS_TYPE_COLLECTOR:
1092 				zbx_thread_start(collector_thread, thread_args, &threads[i]);
1093 				break;
1094 			case ZBX_PROCESS_TYPE_LISTENER:
1095 				thread_args->args = &listen_sock;
1096 				zbx_thread_start(listener_thread, thread_args, &threads[i]);
1097 				break;
1098 			case ZBX_PROCESS_TYPE_ACTIVE_CHECKS:
1099 				thread_args->args = &CONFIG_ACTIVE_ARGS[j++];
1100 				zbx_thread_start(active_checks_thread, thread_args, &threads[i]);
1101 				break;
1102 		}
1103 #ifndef _WINDOWS
1104 		zbx_free(thread_args);
1105 #endif
1106 	}
1107 
1108 #ifdef _WINDOWS
1109 	set_parent_signal_handler();	/* must be called after all threads are created */
1110 
1111 	/* wait for an exiting thread */
1112 	res = WaitForMultipleObjectsEx(threads_num, threads, FALSE, INFINITE, FALSE);
1113 
1114 	if (ZBX_IS_RUNNING())
1115 	{
1116 		/* Zabbix agent service should either be stopped by the user in ServiceCtrlHandler() or */
1117 		/* crash. If some thread has terminated normally, it means something is terribly wrong. */
1118 
1119 		zabbix_log(LOG_LEVEL_CRIT, "One thread has terminated unexpectedly (code:%lu). Exiting ...", res);
1120 		THIS_SHOULD_NEVER_HAPPEN;
1121 
1122 		/* notify other threads and allow them to terminate */
1123 		ZBX_DO_EXIT();
1124 		zbx_sleep(1);
1125 	}
1126 	else
1127 	{
1128 		zbx_tcp_close(&listen_sock);
1129 
1130 		/* Wait for the service worker thread to terminate us. Listener threads may not exit up to */
1131 		/* CONFIG_TIMEOUT seconds if they're waiting for external processes to finish / timeout */
1132 		zbx_sleep(CONFIG_TIMEOUT);
1133 
1134 		THIS_SHOULD_NEVER_HAPPEN;
1135 	}
1136 #else
1137 	while (-1 == wait(&i))	/* wait for any child to exit */
1138 	{
1139 		if (EINTR != errno)
1140 		{
1141 			zabbix_log(LOG_LEVEL_ERR, "failed to wait on child processes: %s", zbx_strerror(errno));
1142 			break;
1143 		}
1144 	}
1145 
1146 	/* all exiting child processes should be caught by signal handlers */
1147 	THIS_SHOULD_NEVER_HAPPEN;
1148 #endif
1149 	zbx_on_exit(SUCCEED);
1150 
1151 	return SUCCEED;
1152 }
1153 
1154 /******************************************************************************
1155  *                                                                            *
1156  * Function: zbx_free_service_resources                                       *
1157  *                                                                            *
1158  * Purpose: free service resources allocated by main thread                   *
1159  *                                                                            *
1160  ******************************************************************************/
zbx_free_service_resources(int ret)1161 void	zbx_free_service_resources(int ret)
1162 {
1163 	if (NULL != threads)
1164 	{
1165 		zbx_threads_wait(threads, threads_flags, threads_num, ret);	/* wait for all child processes to exit */
1166 		zbx_free(threads);
1167 		zbx_free(threads_flags);
1168 	}
1169 #ifdef HAVE_PTHREAD_PROCESS_SHARED
1170 	zbx_locks_disable();
1171 #endif
1172 	free_metrics();
1173 	alias_list_free();
1174 	free_collector_data();
1175 #ifdef _WINDOWS
1176 	free_perf_collector();
1177 	zbx_co_uninitialize();
1178 #endif
1179 #ifndef _WINDOWS
1180 	zbx_unload_modules();
1181 #endif
1182 	zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent stopped. Zabbix %s (revision %s).",
1183 			ZABBIX_VERSION, ZABBIX_REVISION);
1184 
1185 	zabbix_close_log();
1186 }
1187 
zbx_on_exit(int ret)1188 void	zbx_on_exit(int ret)
1189 {
1190 	zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called");
1191 
1192 	zbx_free_service_resources(ret);
1193 
1194 #if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
1195 	zbx_tls_free();
1196 	zbx_tls_library_deinit();	/* deinitialize crypto library from parent thread */
1197 #endif
1198 #if defined(PS_OVERWRITE_ARGV)
1199 	setproctitle_free_env();
1200 #endif
1201 #ifdef _WINDOWS
1202 	while (0 == WSACleanup())
1203 		;
1204 #endif
1205 
1206 	exit(EXIT_SUCCESS);
1207 }
1208 
main(int argc,char ** argv)1209 int	main(int argc, char **argv)
1210 {
1211 	ZBX_TASK_EX	t = {ZBX_TASK_START};
1212 #ifdef _WINDOWS
1213 	int		ret;
1214 	char		*error;
1215 
1216 	/* Provide, so our process handles errors instead of the system itself. */
1217 	/* Attention!!! */
1218 	/* The system does not display the critical-error-handler message box. */
1219 	/* Instead, the system sends the error to the calling process.*/
1220 	SetErrorMode(SEM_FAILCRITICALERRORS);
1221 #endif
1222 #if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV)
1223 	argv = setproctitle_save_env(argc, argv);
1224 #endif
1225 	progname = get_program_name(argv[0]);
1226 
1227 	if (SUCCEED != parse_commandline(argc, argv, &t))
1228 		exit(EXIT_FAILURE);
1229 
1230 	import_symbols();
1231 
1232 #ifdef _WINDOWS
1233 	if (ZBX_TASK_SHOW_USAGE != t.task && ZBX_TASK_SHOW_VERSION != t.task && ZBX_TASK_SHOW_HELP != t.task &&
1234 			SUCCEED != zbx_socket_start(&error))
1235 	{
1236 		zbx_error(error);
1237 		zbx_free(error);
1238 		exit(EXIT_FAILURE);
1239 	}
1240 #endif
1241 
1242 	/* this is needed to set default hostname in zbx_load_config() */
1243 	init_metrics();
1244 
1245 	switch (t.task)
1246 	{
1247 		case ZBX_TASK_SHOW_USAGE:
1248 			usage();
1249 			exit(EXIT_FAILURE);
1250 			break;
1251 #ifndef _WINDOWS
1252 		case ZBX_TASK_RUNTIME_CONTROL:
1253 			zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1254 			exit(SUCCEED == zbx_sigusr_send(t.data) ? EXIT_SUCCESS : EXIT_FAILURE);
1255 			break;
1256 #else
1257 		case ZBX_TASK_INSTALL_SERVICE:
1258 		case ZBX_TASK_UNINSTALL_SERVICE:
1259 		case ZBX_TASK_START_SERVICE:
1260 		case ZBX_TASK_STOP_SERVICE:
1261 			if (t.flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS)
1262 			{
1263 				zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1264 
1265 				zbx_snprintf(ZABBIX_SERVICE_NAME, sizeof(ZABBIX_SERVICE_NAME), "%s [%s]",
1266 						APPLICATION_NAME, CONFIG_HOSTNAME);
1267 				zbx_snprintf(ZABBIX_EVENT_SOURCE, sizeof(ZABBIX_EVENT_SOURCE), "%s [%s]",
1268 						APPLICATION_NAME, CONFIG_HOSTNAME);
1269 			}
1270 			else
1271 				zbx_load_config(ZBX_CFG_FILE_OPTIONAL, &t);
1272 
1273 			zbx_free_config();
1274 
1275 			ret = zbx_exec_service_task(argv[0], &t);
1276 
1277 			while (0 == WSACleanup())
1278 				;
1279 
1280 			free_metrics();
1281 			exit(SUCCEED == ret ? EXIT_SUCCESS : EXIT_FAILURE);
1282 			break;
1283 #endif
1284 		case ZBX_TASK_TEST_METRIC:
1285 		case ZBX_TASK_PRINT_SUPPORTED:
1286 			zbx_load_config(ZBX_CFG_FILE_OPTIONAL, &t);
1287 #ifdef _WINDOWS
1288 			if (SUCCEED != init_perf_collector(ZBX_SINGLE_THREADED, &error))
1289 			{
1290 				zbx_error("cannot initialize performance counter collector: %s", error);
1291 				zbx_free(error);
1292 				exit(EXIT_FAILURE);
1293 			}
1294 
1295 			load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN);
1296 #else
1297 			zbx_set_common_signal_handlers();
1298 #endif
1299 #ifndef _WINDOWS
1300 			if (FAIL == zbx_load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 0))
1301 			{
1302 				zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
1303 				exit(EXIT_FAILURE);
1304 			}
1305 #endif
1306 			load_user_parameters(CONFIG_USER_PARAMETERS);
1307 			load_aliases(CONFIG_ALIASES);
1308 			zbx_free_config();
1309 			if (ZBX_TASK_TEST_METRIC == t.task)
1310 				test_parameter(TEST_METRIC);
1311 			else
1312 				test_parameters();
1313 #ifdef _WINDOWS
1314 			free_perf_collector();	/* cpu_collector must be freed before perf_collector is freed */
1315 
1316 			while (0 == WSACleanup())
1317 				;
1318 #endif
1319 #ifndef _WINDOWS
1320 			zbx_unload_modules();
1321 #endif
1322 			free_metrics();
1323 			alias_list_free();
1324 			exit(EXIT_SUCCESS);
1325 			break;
1326 		case ZBX_TASK_SHOW_VERSION:
1327 			version();
1328 #ifdef _AIX
1329 			printf("\n");
1330 			tl_version();
1331 #endif
1332 			exit(EXIT_SUCCESS);
1333 			break;
1334 		case ZBX_TASK_SHOW_HELP:
1335 			help();
1336 			exit(EXIT_SUCCESS);
1337 			break;
1338 		default:
1339 			zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1340 			load_user_parameters(CONFIG_USER_PARAMETERS);
1341 			load_aliases(CONFIG_ALIASES);
1342 			break;
1343 	}
1344 
1345 	START_MAIN_ZABBIX_ENTRY(CONFIG_ALLOW_ROOT, CONFIG_USER, t.flags);
1346 
1347 	exit(EXIT_SUCCESS);
1348 }
1349