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