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