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