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