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