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 
22 #include "cfg.h"
23 #include "pid.h"
24 #include "db.h"
25 #include "dbcache.h"
26 #include "zbxdbupgrade.h"
27 #include "log.h"
28 #include "zbxgetopt.h"
29 #include "mutexs.h"
30 #include "proxy.h"
31 
32 #include "sysinfo.h"
33 #include "zbxmodules.h"
34 #include "zbxserver.h"
35 
36 #include "zbxnix.h"
37 #include "daemon.h"
38 #include "zbxself.h"
39 #include "../libs/zbxnix/control.h"
40 
41 #include "../zabbix_server/dbsyncer/dbsyncer.h"
42 #include "../zabbix_server/discoverer/discoverer.h"
43 #include "../zabbix_server/httppoller/httppoller.h"
44 #include "housekeeper/housekeeper.h"
45 #include "../zabbix_server/pinger/pinger.h"
46 #include "../zabbix_server/poller/poller.h"
47 #include "../zabbix_server/trapper/trapper.h"
48 #include "../zabbix_server/trapper/proxydata.h"
49 #include "../zabbix_server/snmptrapper/snmptrapper.h"
50 #include "proxyconfig/proxyconfig.h"
51 #include "datasender/datasender.h"
52 #include "heart/heart.h"
53 #include "taskmanager/taskmanager.h"
54 #include "../zabbix_server/selfmon/selfmon.h"
55 #include "../zabbix_server/vmware/vmware.h"
56 #include "setproctitle.h"
57 #include "../libs/zbxcrypto/tls.h"
58 #include "zbxipcservice.h"
59 
60 #ifdef HAVE_OPENIPMI
61 #include "../zabbix_server/ipmi/ipmi_manager.h"
62 #include "../zabbix_server/ipmi/ipmi_poller.h"
63 #endif
64 
65 const char	*progname = NULL;
66 const char	title_message[] = "zabbix_proxy";
67 const char	syslog_app_name[] = "zabbix_proxy";
68 const char	*usage_message[] = {
69 	"[-c config-file]", NULL,
70 	"[-c config-file]", "-R runtime-option", NULL,
71 	"-h", NULL,
72 	"-V", NULL,
73 	NULL	/* end of text */
74 };
75 
76 const char	*help_message[] = {
77 	"A Zabbix daemon that collects monitoring data from devices and sends it to",
78 	"Zabbix server.",
79 	"",
80 	"Options:",
81 	"  -c --config config-file        Path to the configuration file",
82 	"                                 (default: \"" DEFAULT_CONFIG_FILE "\")",
83 	"  -f --foreground                Run Zabbix proxy in foreground",
84 	"  -R --runtime-control runtime-option   Perform administrative functions",
85 	"",
86 	"    Runtime control options:",
87 	"      " ZBX_CONFIG_CACHE_RELOAD "        Reload configuration cache",
88 	"      " ZBX_HOUSEKEEPER_EXECUTE "        Execute the housekeeper",
89 	"      " ZBX_LOG_LEVEL_INCREASE "=target  Increase log level, affects all processes if",
90 	"                                 target is not specified",
91 	"      " ZBX_LOG_LEVEL_DECREASE "=target  Decrease log level, affects all processes if",
92 	"                                 target is not specified",
93 	"",
94 	"      Log level control targets:",
95 	"        process-type             All processes of specified type",
96 	"                                 (configuration syncer, data sender, discoverer,",
97 	"                                 heartbeat sender, history syncer, housekeeper,",
98 	"                                 http poller, icmp pinger, ipmi manager,",
99 	"                                 ipmi poller, java poller, poller,",
100 	"                                 self-monitoring, snmp trapper, task manager,",
101 	"                                 trapper, unreachable poller, vmware collector)",
102 	"        process-type,N           Process type and number (e.g., poller,3)",
103 	"        pid                      Process identifier, up to 65535. For larger",
104 	"                                 values specify target as \"process-type,N\"",
105 	"",
106 	"  -h --help                      Display this help message",
107 	"  -V --version                   Display version number",
108 	"",
109 	"Some configuration parameter default locations:",
110 	"  ExternalScripts                \"" DEFAULT_EXTERNAL_SCRIPTS_PATH "\"",
111 #ifdef HAVE_LIBCURL
112 	"  SSLCertLocation                \"" DEFAULT_SSL_CERT_LOCATION "\"",
113 	"  SSLKeyLocation                 \"" DEFAULT_SSL_KEY_LOCATION "\"",
114 #endif
115 	"  LoadModulePath                 \"" DEFAULT_LOAD_MODULE_PATH "\"",
116 	NULL	/* end of text */
117 };
118 
119 /* COMMAND LINE OPTIONS */
120 
121 /* long options */
122 static struct zbx_option	longopts[] =
123 {
124 	{"config",		1,	NULL,	'c'},
125 	{"foreground",		0,	NULL,	'f'},
126 	{"runtime-control",	1,	NULL,	'R'},
127 	{"help",		0,	NULL,	'h'},
128 	{"version",		0,	NULL,	'V'},
129 	{NULL}
130 };
131 
132 /* short options */
133 static char	shortopts[] = "c:hVR:f";
134 
135 /* end of COMMAND LINE OPTIONS */
136 
137 int		threads_num = 0;
138 pid_t		*threads = NULL;
139 static int	*threads_flags;
140 
141 unsigned char	program_type		= ZBX_PROGRAM_TYPE_PROXY_ACTIVE;
142 
143 unsigned char	process_type		= ZBX_PROCESS_TYPE_UNKNOWN;
144 int		process_num		= 0;
145 int		server_num		= 0;
146 
147 static int	CONFIG_PROXYMODE	= ZBX_PROXYMODE_ACTIVE;
148 int	CONFIG_DATASENDER_FORKS		= 1;
149 int	CONFIG_DISCOVERER_FORKS		= 1;
150 int	CONFIG_HOUSEKEEPER_FORKS	= 1;
151 int	CONFIG_PINGER_FORKS		= 1;
152 int	CONFIG_POLLER_FORKS		= 5;
153 int	CONFIG_UNREACHABLE_POLLER_FORKS	= 1;
154 int	CONFIG_HTTPPOLLER_FORKS		= 1;
155 int	CONFIG_IPMIPOLLER_FORKS		= 0;
156 int	CONFIG_TRAPPER_FORKS		= 5;
157 int	CONFIG_SNMPTRAPPER_FORKS	= 0;
158 int	CONFIG_JAVAPOLLER_FORKS		= 0;
159 int	CONFIG_SELFMON_FORKS		= 1;
160 int	CONFIG_PROXYPOLLER_FORKS	= 0;
161 int	CONFIG_ESCALATOR_FORKS		= 0;
162 int	CONFIG_ALERTER_FORKS		= 0;
163 int	CONFIG_TIMER_FORKS		= 0;
164 int	CONFIG_HEARTBEAT_FORKS		= 1;
165 int	CONFIG_COLLECTOR_FORKS		= 0;
166 int	CONFIG_PASSIVE_FORKS		= 0;
167 int	CONFIG_ACTIVE_FORKS		= 0;
168 int	CONFIG_TASKMANAGER_FORKS	= 1;
169 int	CONFIG_IPMIMANAGER_FORKS	= 0;
170 int	CONFIG_ALERTMANAGER_FORKS	= 0;
171 int	CONFIG_PREPROCMAN_FORKS		= 0;
172 int	CONFIG_PREPROCESSOR_FORKS	= 0;
173 
174 int	CONFIG_LISTEN_PORT		= ZBX_DEFAULT_SERVER_PORT;
175 char	*CONFIG_LISTEN_IP		= NULL;
176 char	*CONFIG_SOURCE_IP		= NULL;
177 int	CONFIG_TRAPPER_TIMEOUT		= 300;
178 
179 int	CONFIG_HOUSEKEEPING_FREQUENCY	= 1;
180 int	CONFIG_PROXY_LOCAL_BUFFER	= 0;
181 int	CONFIG_PROXY_OFFLINE_BUFFER	= 1;
182 
183 int	CONFIG_HEARTBEAT_FREQUENCY	= 60;
184 
185 int	CONFIG_PROXYCONFIG_FREQUENCY	= SEC_PER_HOUR;
186 int	CONFIG_PROXYDATA_FREQUENCY	= 1;
187 
188 int	CONFIG_HISTSYNCER_FORKS		= 4;
189 int	CONFIG_HISTSYNCER_FREQUENCY	= 1;
190 int	CONFIG_CONFSYNCER_FORKS		= 1;
191 
192 int	CONFIG_VMWARE_FORKS		= 0;
193 int	CONFIG_VMWARE_FREQUENCY		= 60;
194 int	CONFIG_VMWARE_PERF_FREQUENCY	= 60;
195 int	CONFIG_VMWARE_TIMEOUT		= 10;
196 
197 zbx_uint64_t	CONFIG_CONF_CACHE_SIZE		= 8 * ZBX_MEBIBYTE;
198 zbx_uint64_t	CONFIG_HISTORY_CACHE_SIZE	= 16 * ZBX_MEBIBYTE;
199 zbx_uint64_t	CONFIG_HISTORY_INDEX_CACHE_SIZE	= 4 * ZBX_MEBIBYTE;
200 zbx_uint64_t	CONFIG_TRENDS_CACHE_SIZE	= 0;
201 zbx_uint64_t	CONFIG_VALUE_CACHE_SIZE		= 0;
202 zbx_uint64_t	CONFIG_VMWARE_CACHE_SIZE	= 8 * ZBX_MEBIBYTE;
203 zbx_uint64_t	CONFIG_EXPORT_FILE_SIZE;
204 
205 int	CONFIG_UNREACHABLE_PERIOD	= 45;
206 int	CONFIG_UNREACHABLE_DELAY	= 15;
207 int	CONFIG_UNAVAILABLE_DELAY	= 60;
208 int	CONFIG_LOG_LEVEL		= LOG_LEVEL_WARNING;
209 char	*CONFIG_ALERT_SCRIPTS_PATH	= NULL;
210 char	*CONFIG_EXTERNALSCRIPTS		= NULL;
211 char	*CONFIG_TMPDIR			= NULL;
212 char	*CONFIG_FPING_LOCATION		= NULL;
213 char	*CONFIG_FPING6_LOCATION		= NULL;
214 char	*CONFIG_DBHOST			= NULL;
215 char	*CONFIG_DBNAME			= NULL;
216 char	*CONFIG_DBSCHEMA		= NULL;
217 char	*CONFIG_DBUSER			= NULL;
218 char	*CONFIG_DBPASSWORD		= NULL;
219 char	*CONFIG_DBSOCKET		= NULL;
220 char	*CONFIG_EXPORT_DIR		= NULL;
221 int	CONFIG_DBPORT			= 0;
222 int	CONFIG_ENABLE_REMOTE_COMMANDS	= 0;
223 int	CONFIG_LOG_REMOTE_COMMANDS	= 0;
224 int	CONFIG_UNSAFE_USER_PARAMETERS	= 0;
225 
226 char	*CONFIG_SERVER			= NULL;
227 int	CONFIG_SERVER_PORT		= ZBX_DEFAULT_SERVER_PORT;
228 char	*CONFIG_HOSTNAME		= NULL;
229 char	*CONFIG_HOSTNAME_ITEM		= NULL;
230 
231 char	*CONFIG_SNMPTRAP_FILE		= NULL;
232 
233 char	*CONFIG_JAVA_GATEWAY		= NULL;
234 int	CONFIG_JAVA_GATEWAY_PORT	= ZBX_DEFAULT_GATEWAY_PORT;
235 
236 char	*CONFIG_SSH_KEY_LOCATION	= NULL;
237 
238 int	CONFIG_LOG_SLOW_QUERIES		= 0;	/* ms; 0 - disable */
239 
240 /* zabbix server startup time */
241 int	CONFIG_SERVER_STARTUP_TIME	= 0;
242 
243 char	*CONFIG_LOAD_MODULE_PATH	= NULL;
244 char	**CONFIG_LOAD_MODULE		= NULL;
245 
246 char	*CONFIG_USER			= NULL;
247 
248 /* web monitoring */
249 char	*CONFIG_SSL_CA_LOCATION		= NULL;
250 char	*CONFIG_SSL_CERT_LOCATION	= NULL;
251 char	*CONFIG_SSL_KEY_LOCATION	= NULL;
252 
253 /* TLS parameters */
254 unsigned int	configured_tls_connect_mode = ZBX_TCP_SEC_UNENCRYPTED;
255 unsigned int	configured_tls_accept_modes = ZBX_TCP_SEC_UNENCRYPTED;
256 
257 char	*CONFIG_TLS_CONNECT		= NULL;
258 char	*CONFIG_TLS_ACCEPT		= NULL;
259 char	*CONFIG_TLS_CA_FILE		= NULL;
260 char	*CONFIG_TLS_CRL_FILE		= NULL;
261 char	*CONFIG_TLS_SERVER_CERT_ISSUER	= NULL;
262 char	*CONFIG_TLS_SERVER_CERT_SUBJECT	= NULL;
263 char	*CONFIG_TLS_CERT_FILE		= NULL;
264 char	*CONFIG_TLS_KEY_FILE		= NULL;
265 char	*CONFIG_TLS_PSK_IDENTITY	= NULL;
266 char	*CONFIG_TLS_PSK_FILE		= NULL;
267 char	*CONFIG_TLS_CIPHER_CERT13	= NULL;
268 char	*CONFIG_TLS_CIPHER_CERT		= NULL;
269 char	*CONFIG_TLS_CIPHER_PSK13	= NULL;
270 char	*CONFIG_TLS_CIPHER_PSK		= NULL;
271 char	*CONFIG_TLS_CIPHER_ALL13	= NULL;
272 char	*CONFIG_TLS_CIPHER_ALL		= NULL;
273 char	*CONFIG_TLS_CIPHER_CMD13	= NULL;	/* not used in proxy, defined for linking with tls.c */
274 char	*CONFIG_TLS_CIPHER_CMD		= NULL;	/* not used in proxy, defined for linking with tls.c */
275 
276 static char	*CONFIG_SOCKET_PATH	= NULL;
277 
278 char	*CONFIG_HISTORY_STORAGE_URL		= NULL;
279 char	*CONFIG_HISTORY_STORAGE_OPTS		= NULL;
280 int	CONFIG_HISTORY_STORAGE_PIPELINES	= 0;
281 
282 char	*CONFIG_STATS_ALLOWED_IP	= NULL;
283 
284 int	get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num);
285 
get_process_info_by_thread(int local_server_num,unsigned char * local_process_type,int * local_process_num)286 int	get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num)
287 {
288 	int	server_count = 0;
289 
290 	if (0 == local_server_num)
291 	{
292 		/* fail if the main process is queried */
293 		return FAIL;
294 	}
295 	else if (local_server_num <= (server_count += CONFIG_CONFSYNCER_FORKS))
296 	{
297 		/* make initial configuration sync before worker processes are forked on active Zabbix proxy */
298 		*local_process_type = ZBX_PROCESS_TYPE_CONFSYNCER;
299 		*local_process_num = local_server_num - server_count + CONFIG_CONFSYNCER_FORKS;
300 	}
301 	else if (local_server_num <= (server_count += CONFIG_TRAPPER_FORKS))
302 	{
303 		/* make initial configuration sync before worker processes are forked on passive Zabbix proxy */
304 		*local_process_type = ZBX_PROCESS_TYPE_TRAPPER;
305 		*local_process_num = local_server_num - server_count + CONFIG_TRAPPER_FORKS;
306 	}
307 	else if (local_server_num <= (server_count += CONFIG_HEARTBEAT_FORKS))
308 	{
309 		*local_process_type = ZBX_PROCESS_TYPE_HEARTBEAT;
310 		*local_process_num = local_server_num - server_count + CONFIG_HEARTBEAT_FORKS;
311 	}
312 	else if (local_server_num <= (server_count += CONFIG_DATASENDER_FORKS))
313 	{
314 		*local_process_type = ZBX_PROCESS_TYPE_DATASENDER;
315 		*local_process_num = local_server_num - server_count + CONFIG_DATASENDER_FORKS;
316 	}
317 	else if (local_server_num <= (server_count += CONFIG_IPMIMANAGER_FORKS))
318 	{
319 		*local_process_type = ZBX_PROCESS_TYPE_IPMIMANAGER;
320 		*local_process_num = local_server_num - server_count + CONFIG_TASKMANAGER_FORKS;
321 	}
322 	else if (local_server_num <= (server_count += CONFIG_HOUSEKEEPER_FORKS))
323 	{
324 		*local_process_type = ZBX_PROCESS_TYPE_HOUSEKEEPER;
325 		*local_process_num = local_server_num - server_count + CONFIG_HOUSEKEEPER_FORKS;
326 	}
327 	else if (local_server_num <= (server_count += CONFIG_HTTPPOLLER_FORKS))
328 	{
329 		*local_process_type = ZBX_PROCESS_TYPE_HTTPPOLLER;
330 		*local_process_num = local_server_num - server_count + CONFIG_HTTPPOLLER_FORKS;
331 	}
332 	else if (local_server_num <= (server_count += CONFIG_DISCOVERER_FORKS))
333 	{
334 		*local_process_type = ZBX_PROCESS_TYPE_DISCOVERER;
335 		*local_process_num = local_server_num - server_count + CONFIG_DISCOVERER_FORKS;
336 	}
337 	else if (local_server_num <= (server_count += CONFIG_HISTSYNCER_FORKS))
338 	{
339 		*local_process_type = ZBX_PROCESS_TYPE_HISTSYNCER;
340 		*local_process_num = local_server_num - server_count + CONFIG_HISTSYNCER_FORKS;
341 	}
342 	else if (local_server_num <= (server_count += CONFIG_IPMIPOLLER_FORKS))
343 	{
344 		*local_process_type = ZBX_PROCESS_TYPE_IPMIPOLLER;
345 		*local_process_num = local_server_num - server_count + CONFIG_IPMIPOLLER_FORKS;
346 	}
347 	else if (local_server_num <= (server_count += CONFIG_JAVAPOLLER_FORKS))
348 	{
349 		*local_process_type = ZBX_PROCESS_TYPE_JAVAPOLLER;
350 		*local_process_num = local_server_num - server_count + CONFIG_JAVAPOLLER_FORKS;
351 	}
352 	else if (local_server_num <= (server_count += CONFIG_SNMPTRAPPER_FORKS))
353 	{
354 		*local_process_type = ZBX_PROCESS_TYPE_SNMPTRAPPER;
355 		*local_process_num = local_server_num - server_count + CONFIG_SNMPTRAPPER_FORKS;
356 	}
357 	else if (local_server_num <= (server_count += CONFIG_SELFMON_FORKS))
358 	{
359 		*local_process_type = ZBX_PROCESS_TYPE_SELFMON;
360 		*local_process_num = local_server_num - server_count + CONFIG_SELFMON_FORKS;
361 	}
362 	else if (local_server_num <= (server_count += CONFIG_VMWARE_FORKS))
363 	{
364 		*local_process_type = ZBX_PROCESS_TYPE_VMWARE;
365 		*local_process_num = local_server_num - server_count + CONFIG_VMWARE_FORKS;
366 	}
367 	else if (local_server_num <= (server_count += CONFIG_TASKMANAGER_FORKS))
368 	{
369 		*local_process_type = ZBX_PROCESS_TYPE_TASKMANAGER;
370 		*local_process_num = local_server_num - server_count + CONFIG_TASKMANAGER_FORKS;
371 	}
372 	else if (local_server_num <= (server_count += CONFIG_POLLER_FORKS))
373 	{
374 		*local_process_type = ZBX_PROCESS_TYPE_POLLER;
375 		*local_process_num = local_server_num - server_count + CONFIG_POLLER_FORKS;
376 	}
377 	else if (local_server_num <= (server_count += CONFIG_UNREACHABLE_POLLER_FORKS))
378 	{
379 		*local_process_type = ZBX_PROCESS_TYPE_UNREACHABLE;
380 		*local_process_num = local_server_num - server_count + CONFIG_UNREACHABLE_POLLER_FORKS;
381 	}
382 	else if (local_server_num <= (server_count += CONFIG_PINGER_FORKS))
383 	{
384 		*local_process_type = ZBX_PROCESS_TYPE_PINGER;
385 		*local_process_num = local_server_num - server_count + CONFIG_PINGER_FORKS;
386 	}
387 	else
388 		return FAIL;
389 
390 	return SUCCEED;
391 }
392 
393 /******************************************************************************
394  *                                                                            *
395  * Function: zbx_set_defaults                                                 *
396  *                                                                            *
397  * Purpose: set configuration defaults                                        *
398  *                                                                            *
399  * Author: Rudolfs Kreicbergs                                                 *
400  *                                                                            *
401  ******************************************************************************/
zbx_set_defaults(void)402 static void	zbx_set_defaults(void)
403 {
404 	AGENT_RESULT	result;
405 	char		**value = NULL;
406 
407 	CONFIG_SERVER_STARTUP_TIME = time(NULL);
408 
409 	if (NULL == CONFIG_HOSTNAME)
410 	{
411 		if (NULL == CONFIG_HOSTNAME_ITEM)
412 			CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");
413 
414 		init_result(&result);
415 
416 		if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, PROCESS_LOCAL_COMMAND, &result) &&
417 				NULL != (value = GET_STR_RESULT(&result)))
418 		{
419 			assert(*value);
420 
421 			if (MAX_ZBX_HOSTNAME_LEN < strlen(*value))
422 			{
423 				(*value)[MAX_ZBX_HOSTNAME_LEN] = '\0';
424 				zabbix_log(LOG_LEVEL_WARNING, "proxy name truncated to [%s])", *value);
425 			}
426 
427 			CONFIG_HOSTNAME = zbx_strdup(CONFIG_HOSTNAME, *value);
428 		}
429 		else
430 			zabbix_log(LOG_LEVEL_WARNING, "failed to get proxy name from [%s])", CONFIG_HOSTNAME_ITEM);
431 
432 		free_result(&result);
433 	}
434 	else if (NULL != CONFIG_HOSTNAME_ITEM)
435 	{
436 		zabbix_log(LOG_LEVEL_WARNING, "both Hostname and HostnameItem defined, using [%s]", CONFIG_HOSTNAME);
437 	}
438 
439 	if (NULL == CONFIG_DBHOST)
440 		CONFIG_DBHOST = zbx_strdup(CONFIG_DBHOST, "localhost");
441 
442 	if (NULL == CONFIG_SNMPTRAP_FILE)
443 		CONFIG_SNMPTRAP_FILE = zbx_strdup(CONFIG_SNMPTRAP_FILE, "/tmp/zabbix_traps.tmp");
444 
445 	if (NULL == CONFIG_PID_FILE)
446 		CONFIG_PID_FILE = zbx_strdup(CONFIG_PID_FILE, "/tmp/zabbix_proxy.pid");
447 
448 	if (NULL == CONFIG_TMPDIR)
449 		CONFIG_TMPDIR = zbx_strdup(CONFIG_TMPDIR, "/tmp");
450 
451 	if (NULL == CONFIG_FPING_LOCATION)
452 		CONFIG_FPING_LOCATION = zbx_strdup(CONFIG_FPING_LOCATION, "/usr/local/sbin/fping");
453 #ifdef HAVE_IPV6
454 	if (NULL == CONFIG_FPING6_LOCATION)
455 		CONFIG_FPING6_LOCATION = zbx_strdup(CONFIG_FPING6_LOCATION, "/usr/local/sbin/fping6");
456 #endif
457 	if (NULL == CONFIG_EXTERNALSCRIPTS)
458 		CONFIG_EXTERNALSCRIPTS = zbx_strdup(CONFIG_EXTERNALSCRIPTS, DEFAULT_EXTERNAL_SCRIPTS_PATH);
459 
460 	if (NULL == CONFIG_LOAD_MODULE_PATH)
461 		CONFIG_LOAD_MODULE_PATH = zbx_strdup(CONFIG_LOAD_MODULE_PATH, DEFAULT_LOAD_MODULE_PATH);
462 #ifdef HAVE_LIBCURL
463 	if (NULL == CONFIG_SSL_CERT_LOCATION)
464 		CONFIG_SSL_CERT_LOCATION = zbx_strdup(CONFIG_SSL_CERT_LOCATION, DEFAULT_SSL_CERT_LOCATION);
465 
466 	if (NULL == CONFIG_SSL_KEY_LOCATION)
467 		CONFIG_SSL_KEY_LOCATION = zbx_strdup(CONFIG_SSL_KEY_LOCATION, DEFAULT_SSL_KEY_LOCATION);
468 #endif
469 	if (ZBX_PROXYMODE_ACTIVE != CONFIG_PROXYMODE || 0 == CONFIG_HEARTBEAT_FREQUENCY)
470 		CONFIG_HEARTBEAT_FORKS = 0;
471 
472 	if (ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE)
473 	{
474 		CONFIG_CONFSYNCER_FORKS = CONFIG_DATASENDER_FORKS = 0;
475 		program_type = ZBX_PROGRAM_TYPE_PROXY_PASSIVE;
476 	}
477 
478 	if (NULL == CONFIG_LOG_TYPE_STR)
479 		CONFIG_LOG_TYPE_STR = zbx_strdup(CONFIG_LOG_TYPE_STR, ZBX_OPTION_LOGTYPE_FILE);
480 
481 	if (NULL == CONFIG_SOCKET_PATH)
482 		CONFIG_SOCKET_PATH = zbx_strdup(CONFIG_SOCKET_PATH, "/tmp");
483 
484 	if (0 != CONFIG_IPMIPOLLER_FORKS)
485 		CONFIG_IPMIMANAGER_FORKS = 1;
486 }
487 
488 /******************************************************************************
489  *                                                                            *
490  * Function: zbx_validate_config                                              *
491  *                                                                            *
492  * Purpose: validate configuration parameters                                 *
493  *                                                                            *
494  * Author: Alexei Vladishev, Rudolfs Kreicbergs                               *
495  *                                                                            *
496  ******************************************************************************/
zbx_validate_config(ZBX_TASK_EX * task)497 static void	zbx_validate_config(ZBX_TASK_EX *task)
498 {
499 	char	*ch_error;
500 	int	err = 0;
501 
502 	if (NULL == CONFIG_HOSTNAME)
503 	{
504 		zabbix_log(LOG_LEVEL_CRIT, "\"Hostname\" configuration parameter is not defined");
505 		err = 1;
506 	}
507 	else if (FAIL == zbx_check_hostname(CONFIG_HOSTNAME, &ch_error))
508 	{
509 		zabbix_log(LOG_LEVEL_CRIT, "invalid \"Hostname\" configuration parameter '%s': %s", CONFIG_HOSTNAME,
510 				ch_error);
511 		zbx_free(ch_error);
512 		err = 1;
513 	}
514 
515 	if (0 == CONFIG_UNREACHABLE_POLLER_FORKS && 0 != CONFIG_POLLER_FORKS + CONFIG_JAVAPOLLER_FORKS)
516 	{
517 		zabbix_log(LOG_LEVEL_CRIT, "\"StartPollersUnreachable\" configuration parameter must not be 0"
518 				" if regular or Java pollers are started");
519 		err = 1;
520 	}
521 
522 	if ((NULL == CONFIG_JAVA_GATEWAY || '\0' == *CONFIG_JAVA_GATEWAY) && 0 < CONFIG_JAVAPOLLER_FORKS)
523 	{
524 		zabbix_log(LOG_LEVEL_CRIT, "\"JavaGateway\" configuration parameter is not specified or empty");
525 		err = 1;
526 	}
527 
528 	if (ZBX_PROXYMODE_ACTIVE == CONFIG_PROXYMODE && FAIL == is_supported_ip(CONFIG_SERVER) &&
529 			FAIL == zbx_validate_hostname(CONFIG_SERVER))
530 	{
531 		zabbix_log(LOG_LEVEL_CRIT, "invalid \"Server\" configuration parameter: '%s'", CONFIG_SERVER);
532 		err = 1;
533 	}
534 	else if (ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE && FAIL == zbx_validate_peer_list(CONFIG_SERVER, &ch_error))
535 	{
536 		zabbix_log(LOG_LEVEL_CRIT, "invalid entry in \"Server\" configuration parameter: %s", ch_error);
537 		zbx_free(ch_error);
538 		err = 1;
539 	}
540 
541 	if (NULL != CONFIG_SOURCE_IP && SUCCEED != is_supported_ip(CONFIG_SOURCE_IP))
542 	{
543 		zabbix_log(LOG_LEVEL_CRIT, "invalid \"SourceIP\" configuration parameter: '%s'", CONFIG_SOURCE_IP);
544 		err = 1;
545 	}
546 
547 	if (NULL != CONFIG_STATS_ALLOWED_IP && FAIL == zbx_validate_peer_list(CONFIG_STATS_ALLOWED_IP, &ch_error))
548 	{
549 		zabbix_log(LOG_LEVEL_CRIT, "invalid entry in \"StatsAllowedIP\" configuration parameter: %s", ch_error);
550 		zbx_free(ch_error);
551 		err = 1;
552 	}
553 #if !defined(HAVE_IPV6)
554 	err |= (FAIL == check_cfg_feature_str("Fping6Location", CONFIG_FPING6_LOCATION, "IPv6 support"));
555 #endif
556 #if !defined(HAVE_LIBCURL)
557 	err |= (FAIL == check_cfg_feature_str("SSLCALocation", CONFIG_SSL_CA_LOCATION, "cURL library"));
558 	err |= (FAIL == check_cfg_feature_str("SSLCertLocation", CONFIG_SSL_CERT_LOCATION, "cURL library"));
559 	err |= (FAIL == check_cfg_feature_str("SSLKeyLocation", CONFIG_SSL_KEY_LOCATION, "cURL library"));
560 #endif
561 #if !defined(HAVE_LIBXML2) || !defined(HAVE_LIBCURL)
562 	err |= (FAIL == check_cfg_feature_int("StartVMwareCollectors", CONFIG_VMWARE_FORKS, "VMware support"));
563 
564 	/* parameters VMwareFrequency, VMwarePerfFrequency, VMwareCacheSize, VMwareTimeout are not checked here */
565 	/* because they have non-zero default values */
566 #endif
567 
568 	if (SUCCEED != zbx_validate_log_parameters(task))
569 		err = 1;
570 
571 #if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
572 	err |= (FAIL == check_cfg_feature_str("TLSConnect", CONFIG_TLS_CONNECT, "TLS support"));
573 	err |= (FAIL == check_cfg_feature_str("TLSAccept", CONFIG_TLS_ACCEPT, "TLS support"));
574 	err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
575 	err |= (FAIL == check_cfg_feature_str("TLSCRLFile", CONFIG_TLS_CRL_FILE, "TLS support"));
576 	err |= (FAIL == check_cfg_feature_str("TLSServerCertIssuer", CONFIG_TLS_SERVER_CERT_ISSUER, "TLS support"));
577 	err |= (FAIL == check_cfg_feature_str("TLSServerCertSubject", CONFIG_TLS_SERVER_CERT_SUBJECT, "TLS support"));
578 	err |= (FAIL == check_cfg_feature_str("TLSCertFile", CONFIG_TLS_CERT_FILE, "TLS support"));
579 	err |= (FAIL == check_cfg_feature_str("TLSKeyFile", CONFIG_TLS_KEY_FILE, "TLS support"));
580 	err |= (FAIL == check_cfg_feature_str("TLSPSKIdentity", CONFIG_TLS_PSK_IDENTITY, "TLS support"));
581 	err |= (FAIL == check_cfg_feature_str("TLSPSKFile", CONFIG_TLS_PSK_FILE, "TLS support"));
582 #endif
583 #if !(defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
584 	err |= (FAIL == check_cfg_feature_str("TLSCipherCert", CONFIG_TLS_CIPHER_CERT, "GnuTLS or OpenSSL"));
585 	err |= (FAIL == check_cfg_feature_str("TLSCipherPSK", CONFIG_TLS_CIPHER_PSK, "GnuTLS or OpenSSL"));
586 	err |= (FAIL == check_cfg_feature_str("TLSCipherAll", CONFIG_TLS_CIPHER_ALL, "GnuTLS or OpenSSL"));
587 #endif
588 #if !defined(HAVE_OPENSSL)
589 	err |= (FAIL == check_cfg_feature_str("TLSCipherCert13", CONFIG_TLS_CIPHER_CERT13, "OpenSSL 1.1.1 or newer"));
590 	err |= (FAIL == check_cfg_feature_str("TLSCipherPSK13", CONFIG_TLS_CIPHER_PSK13, "OpenSSL 1.1.1 or newer"));
591 	err |= (FAIL == check_cfg_feature_str("TLSCipherAll13", CONFIG_TLS_CIPHER_ALL13, "OpenSSL 1.1.1 or newer"));
592 #endif
593 
594 #if !defined(HAVE_OPENIPMI)
595 	err |= (FAIL == check_cfg_feature_int("StartIPMIPollers", CONFIG_IPMIPOLLER_FORKS, "IPMI support"));
596 #endif
597 
598 	if (0 != err)
599 		exit(EXIT_FAILURE);
600 }
601 
602 /******************************************************************************
603  *                                                                            *
604  * Function: zbx_load_config                                                  *
605  *                                                                            *
606  * Purpose: parse config file and update configuration parameters             *
607  *                                                                            *
608  * Author: Alexei Vladishev                                                   *
609  *                                                                            *
610  * Comments: will terminate process if parsing fails                          *
611  *                                                                            *
612  ******************************************************************************/
zbx_load_config(ZBX_TASK_EX * task)613 static void	zbx_load_config(ZBX_TASK_EX *task)
614 {
615 	static struct cfg_line	cfg[] =
616 	{
617 		/* PARAMETER,			VAR,					TYPE,
618 			MANDATORY,	MIN,			MAX */
619 		{"ProxyMode",			&CONFIG_PROXYMODE,			TYPE_INT,
620 			PARM_OPT,	ZBX_PROXYMODE_ACTIVE,	ZBX_PROXYMODE_PASSIVE},
621 		{"Server",			&CONFIG_SERVER,				TYPE_STRING,
622 			PARM_MAND,	0,			0},
623 		{"ServerPort",			&CONFIG_SERVER_PORT,			TYPE_INT,
624 			PARM_OPT,	1024,			32767},
625 		{"Hostname",			&CONFIG_HOSTNAME,			TYPE_STRING,
626 			PARM_OPT,	0,			0},
627 		{"HostnameItem",		&CONFIG_HOSTNAME_ITEM,			TYPE_STRING,
628 			PARM_OPT,	0,			0},
629 		{"StartDBSyncers",		&CONFIG_HISTSYNCER_FORKS,		TYPE_INT,
630 			PARM_OPT,	1,			100},
631 		{"StartDiscoverers",		&CONFIG_DISCOVERER_FORKS,		TYPE_INT,
632 			PARM_OPT,	0,			250},
633 		{"StartHTTPPollers",		&CONFIG_HTTPPOLLER_FORKS,		TYPE_INT,
634 			PARM_OPT,	0,			1000},
635 		{"StartPingers",		&CONFIG_PINGER_FORKS,			TYPE_INT,
636 			PARM_OPT,	0,			1000},
637 		{"StartPollers",		&CONFIG_POLLER_FORKS,			TYPE_INT,
638 			PARM_OPT,	0,			1000},
639 		{"StartPollersUnreachable",	&CONFIG_UNREACHABLE_POLLER_FORKS,	TYPE_INT,
640 			PARM_OPT,	0,			1000},
641 		{"StartIPMIPollers",		&CONFIG_IPMIPOLLER_FORKS,		TYPE_INT,
642 			PARM_OPT,	0,			1000},
643 		{"StartTrappers",		&CONFIG_TRAPPER_FORKS,			TYPE_INT,
644 			PARM_OPT,	0,			1000},
645 		{"StartJavaPollers",		&CONFIG_JAVAPOLLER_FORKS,		TYPE_INT,
646 			PARM_OPT,	0,			1000},
647 		{"JavaGateway",			&CONFIG_JAVA_GATEWAY,			TYPE_STRING,
648 			PARM_OPT,	0,			0},
649 		{"JavaGatewayPort",		&CONFIG_JAVA_GATEWAY_PORT,		TYPE_INT,
650 			PARM_OPT,	1024,			32767},
651 		{"SNMPTrapperFile",		&CONFIG_SNMPTRAP_FILE,			TYPE_STRING,
652 			PARM_OPT,	0,			0},
653 		{"StartSNMPTrapper",		&CONFIG_SNMPTRAPPER_FORKS,		TYPE_INT,
654 			PARM_OPT,	0,			1},
655 		{"CacheSize",			&CONFIG_CONF_CACHE_SIZE,		TYPE_UINT64,
656 			PARM_OPT,	128 * ZBX_KIBIBYTE,	__UINT64_C(64) * ZBX_GIBIBYTE},
657 		{"HistoryCacheSize",		&CONFIG_HISTORY_CACHE_SIZE,		TYPE_UINT64,
658 			PARM_OPT,	128 * ZBX_KIBIBYTE,	__UINT64_C(2) * ZBX_GIBIBYTE},
659 		{"HistoryIndexCacheSize",	&CONFIG_HISTORY_INDEX_CACHE_SIZE,	TYPE_UINT64,
660 			PARM_OPT,	128 * ZBX_KIBIBYTE,	__UINT64_C(2) * ZBX_GIBIBYTE},
661 		{"HousekeepingFrequency",	&CONFIG_HOUSEKEEPING_FREQUENCY,		TYPE_INT,
662 			PARM_OPT,	0,			24},
663 		{"ProxyLocalBuffer",		&CONFIG_PROXY_LOCAL_BUFFER,		TYPE_INT,
664 			PARM_OPT,	0,			720},
665 		{"ProxyOfflineBuffer",		&CONFIG_PROXY_OFFLINE_BUFFER,		TYPE_INT,
666 			PARM_OPT,	1,			720},
667 		{"HeartbeatFrequency",		&CONFIG_HEARTBEAT_FREQUENCY,		TYPE_INT,
668 			PARM_OPT,	0,			ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX},
669 		{"ConfigFrequency",		&CONFIG_PROXYCONFIG_FREQUENCY,		TYPE_INT,
670 			PARM_OPT,	1,			SEC_PER_WEEK},
671 		{"DataSenderFrequency",		&CONFIG_PROXYDATA_FREQUENCY,		TYPE_INT,
672 			PARM_OPT,	1,			SEC_PER_HOUR},
673 		{"TmpDir",			&CONFIG_TMPDIR,				TYPE_STRING,
674 			PARM_OPT,	0,			0},
675 		{"FpingLocation",		&CONFIG_FPING_LOCATION,			TYPE_STRING,
676 			PARM_OPT,	0,			0},
677 		{"Fping6Location",		&CONFIG_FPING6_LOCATION,		TYPE_STRING,
678 			PARM_OPT,	0,			0},
679 		{"Timeout",			&CONFIG_TIMEOUT,			TYPE_INT,
680 			PARM_OPT,	1,			30},
681 		{"TrapperTimeout",		&CONFIG_TRAPPER_TIMEOUT,		TYPE_INT,
682 			PARM_OPT,	1,			300},
683 		{"UnreachablePeriod",		&CONFIG_UNREACHABLE_PERIOD,		TYPE_INT,
684 			PARM_OPT,	1,			SEC_PER_HOUR},
685 		{"UnreachableDelay",		&CONFIG_UNREACHABLE_DELAY,		TYPE_INT,
686 			PARM_OPT,	1,			SEC_PER_HOUR},
687 		{"UnavailableDelay",		&CONFIG_UNAVAILABLE_DELAY,		TYPE_INT,
688 			PARM_OPT,	1,			SEC_PER_HOUR},
689 		{"ListenIP",			&CONFIG_LISTEN_IP,			TYPE_STRING_LIST,
690 			PARM_OPT,	0,			0},
691 		{"ListenPort",			&CONFIG_LISTEN_PORT,			TYPE_INT,
692 			PARM_OPT,	1024,			32767},
693 		{"SourceIP",			&CONFIG_SOURCE_IP,			TYPE_STRING,
694 			PARM_OPT,	0,			0},
695 		{"DebugLevel",			&CONFIG_LOG_LEVEL,			TYPE_INT,
696 			PARM_OPT,	0,			5},
697 		{"PidFile",			&CONFIG_PID_FILE,			TYPE_STRING,
698 			PARM_OPT,	0,			0},
699 		{"LogType",			&CONFIG_LOG_TYPE_STR,			TYPE_STRING,
700 			PARM_OPT,	0,			0},
701 		{"LogFile",			&CONFIG_LOG_FILE,			TYPE_STRING,
702 			PARM_OPT,	0,			0},
703 		{"LogFileSize",			&CONFIG_LOG_FILE_SIZE,			TYPE_INT,
704 			PARM_OPT,	0,			1024},
705 		{"ExternalScripts",		&CONFIG_EXTERNALSCRIPTS,		TYPE_STRING,
706 			PARM_OPT,	0,			0},
707 		{"DBHost",			&CONFIG_DBHOST,				TYPE_STRING,
708 			PARM_OPT,	0,			0},
709 		{"DBName",			&CONFIG_DBNAME,				TYPE_STRING,
710 			PARM_MAND,	0,			0},
711 		{"DBSchema",			&CONFIG_DBSCHEMA,			TYPE_STRING,
712 			PARM_OPT,	0,			0},
713 		{"DBUser",			&CONFIG_DBUSER,				TYPE_STRING,
714 			PARM_OPT,	0,			0},
715 		{"DBPassword",			&CONFIG_DBPASSWORD,			TYPE_STRING,
716 			PARM_OPT,	0,			0},
717 		{"DBSocket",			&CONFIG_DBSOCKET,			TYPE_STRING,
718 			PARM_OPT,	0,			0},
719 		{"DBPort",			&CONFIG_DBPORT,				TYPE_INT,
720 			PARM_OPT,	1024,			65535},
721 		{"SSHKeyLocation",		&CONFIG_SSH_KEY_LOCATION,		TYPE_STRING,
722 			PARM_OPT,	0,			0},
723 		{"LogSlowQueries",		&CONFIG_LOG_SLOW_QUERIES,		TYPE_INT,
724 			PARM_OPT,	0,			3600000},
725 		{"LoadModulePath",		&CONFIG_LOAD_MODULE_PATH,		TYPE_STRING,
726 			PARM_OPT,	0,			0},
727 		{"LoadModule",			&CONFIG_LOAD_MODULE,			TYPE_MULTISTRING,
728 			PARM_OPT,	0,			0},
729 		{"StartVMwareCollectors",	&CONFIG_VMWARE_FORKS,			TYPE_INT,
730 			PARM_OPT,	0,			250},
731 		{"VMwareFrequency",		&CONFIG_VMWARE_FREQUENCY,		TYPE_INT,
732 			PARM_OPT,	10,			SEC_PER_DAY},
733 		{"VMwarePerfFrequency",		&CONFIG_VMWARE_PERF_FREQUENCY,		TYPE_INT,
734 			PARM_OPT,	10,			SEC_PER_DAY},
735 		{"VMwareCacheSize",		&CONFIG_VMWARE_CACHE_SIZE,		TYPE_UINT64,
736 			PARM_OPT,	256 * ZBX_KIBIBYTE,	__UINT64_C(2) * ZBX_GIBIBYTE},
737 		{"VMwareTimeout",		&CONFIG_VMWARE_TIMEOUT,			TYPE_INT,
738 			PARM_OPT,	1,			300},
739 		{"AllowRoot",			&CONFIG_ALLOW_ROOT,			TYPE_INT,
740 			PARM_OPT,	0,			1},
741 		{"User",			&CONFIG_USER,				TYPE_STRING,
742 			PARM_OPT,	0,			0},
743 		{"SSLCALocation",		&CONFIG_SSL_CA_LOCATION,		TYPE_STRING,
744 			PARM_OPT,	0,			0},
745 		{"SSLCertLocation",		&CONFIG_SSL_CERT_LOCATION,		TYPE_STRING,
746 			PARM_OPT,	0,			0},
747 		{"SSLKeyLocation",		&CONFIG_SSL_KEY_LOCATION,		TYPE_STRING,
748 			PARM_OPT,	0,			0},
749 		{"TLSConnect",			&CONFIG_TLS_CONNECT,			TYPE_STRING,
750 			PARM_OPT,	0,			0},
751 		{"TLSAccept",			&CONFIG_TLS_ACCEPT,			TYPE_STRING_LIST,
752 			PARM_OPT,	0,			0},
753 		{"TLSCAFile",			&CONFIG_TLS_CA_FILE,			TYPE_STRING,
754 			PARM_OPT,	0,			0},
755 		{"TLSCRLFile",			&CONFIG_TLS_CRL_FILE,			TYPE_STRING,
756 			PARM_OPT,	0,			0},
757 		{"TLSServerCertIssuer",		&CONFIG_TLS_SERVER_CERT_ISSUER,		TYPE_STRING,
758 			PARM_OPT,	0,			0},
759 		{"TLSServerCertSubject",	&CONFIG_TLS_SERVER_CERT_SUBJECT,	TYPE_STRING,
760 			PARM_OPT,	0,			0},
761 		{"TLSCertFile",			&CONFIG_TLS_CERT_FILE,			TYPE_STRING,
762 			PARM_OPT,	0,			0},
763 		{"TLSKeyFile",			&CONFIG_TLS_KEY_FILE,			TYPE_STRING,
764 			PARM_OPT,	0,			0},
765 		{"TLSPSKIdentity",		&CONFIG_TLS_PSK_IDENTITY,		TYPE_STRING,
766 			PARM_OPT,	0,			0},
767 		{"TLSPSKFile",			&CONFIG_TLS_PSK_FILE,			TYPE_STRING,
768 			PARM_OPT,	0,			0},
769 		{"TLSCipherCert13",		&CONFIG_TLS_CIPHER_CERT13,		TYPE_STRING,
770 			PARM_OPT,	0,			0},
771 		{"TLSCipherCert",		&CONFIG_TLS_CIPHER_CERT,		TYPE_STRING,
772 			PARM_OPT,	0,			0},
773 		{"TLSCipherPSK13",		&CONFIG_TLS_CIPHER_PSK13,		TYPE_STRING,
774 			PARM_OPT,	0,			0},
775 		{"TLSCipherPSK",		&CONFIG_TLS_CIPHER_PSK,			TYPE_STRING,
776 			PARM_OPT,	0,			0},
777 		{"TLSCipherAll13",		&CONFIG_TLS_CIPHER_ALL13,		TYPE_STRING,
778 			PARM_OPT,	0,			0},
779 		{"TLSCipherAll",		&CONFIG_TLS_CIPHER_ALL,			TYPE_STRING,
780 			PARM_OPT,	0,			0},
781 		{"SocketDir",			&CONFIG_SOCKET_PATH,			TYPE_STRING,
782 			PARM_OPT,	0,			0},
783 		{"EnableRemoteCommands",	&CONFIG_ENABLE_REMOTE_COMMANDS,		TYPE_INT,
784 			PARM_OPT,	0,			1},
785 		{"LogRemoteCommands",		&CONFIG_LOG_REMOTE_COMMANDS,		TYPE_INT,
786 			PARM_OPT,	0,			1},
787 		{"StatsAllowedIP",		&CONFIG_STATS_ALLOWED_IP,		TYPE_STRING_LIST,
788 			PARM_OPT,	0,			0},
789 		{NULL}
790 	};
791 
792 	/* initialize multistrings */
793 	zbx_strarr_init(&CONFIG_LOAD_MODULE);
794 
795 	parse_cfg_file(CONFIG_FILE, cfg, ZBX_CFG_FILE_REQUIRED, ZBX_CFG_STRICT);
796 
797 	zbx_set_defaults();
798 
799 	CONFIG_LOG_TYPE = zbx_get_log_type(CONFIG_LOG_TYPE_STR);
800 
801 	zbx_validate_config(task);
802 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
803 	zbx_tls_validate_config();
804 #endif
805 }
806 
807 /******************************************************************************
808  *                                                                            *
809  * Function: zbx_free_config                                                  *
810  *                                                                            *
811  * Purpose: free configuration memory                                         *
812  *                                                                            *
813  ******************************************************************************/
zbx_free_config(void)814 static void	zbx_free_config(void)
815 {
816 	zbx_strarr_free(CONFIG_LOAD_MODULE);
817 }
818 
819 /******************************************************************************
820  *                                                                            *
821  * Function: main                                                             *
822  *                                                                            *
823  * Purpose: executes proxy processes                                          *
824  *                                                                            *
825  * Author: Eugene Grigorjev                                                   *
826  *                                                                            *
827  ******************************************************************************/
main(int argc,char ** argv)828 int	main(int argc, char **argv)
829 {
830 	ZBX_TASK_EX	t = {ZBX_TASK_START};
831 	char		ch;
832 	int		opt_c = 0, opt_r = 0;
833 
834 #if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV)
835 	argv = setproctitle_save_env(argc, argv);
836 #endif
837 	progname = get_program_name(argv[0]);
838 
839 	/* parse the command-line */
840 	while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, shortopts, longopts, NULL)))
841 	{
842 		switch (ch)
843 		{
844 			case 'c':
845 				opt_c++;
846 				if (NULL == CONFIG_FILE)
847 					CONFIG_FILE = zbx_strdup(CONFIG_FILE, zbx_optarg);
848 				break;
849 			case 'R':
850 				opt_r++;
851 				if (SUCCEED != parse_rtc_options(zbx_optarg, program_type, &t.data))
852 					exit(EXIT_FAILURE);
853 
854 				t.task = ZBX_TASK_RUNTIME_CONTROL;
855 				break;
856 			case 'h':
857 				help();
858 				exit(EXIT_SUCCESS);
859 				break;
860 			case 'V':
861 				version();
862 				exit(EXIT_SUCCESS);
863 				break;
864 			case 'f':
865 				t.flags |= ZBX_TASK_FLAG_FOREGROUND;
866 				break;
867 			default:
868 				usage();
869 				exit(EXIT_FAILURE);
870 				break;
871 		}
872 	}
873 
874 	/* every option may be specified only once */
875 	if (1 < opt_c || 1 < opt_r)
876 	{
877 		if (1 < opt_c)
878 			zbx_error("option \"-c\" or \"--config\" specified multiple times");
879 		if (1 < opt_r)
880 			zbx_error("option \"-R\" or \"--runtime-control\" specified multiple times");
881 
882 		exit(EXIT_FAILURE);
883 	}
884 
885 	/* Parameters which are not option values are invalid. The check relies on zbx_getopt_internal() which */
886 	/* always permutes command line arguments regardless of POSIXLY_CORRECT environment variable. */
887 	if (argc > zbx_optind)
888 	{
889 		int	i;
890 
891 		for (i = zbx_optind; i < argc; i++)
892 			zbx_error("invalid parameter \"%s\"", argv[i]);
893 
894 		exit(EXIT_FAILURE);
895 	}
896 
897 	if (NULL == CONFIG_FILE)
898 		CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
899 
900 	/* required for simple checks */
901 	init_metrics();
902 
903 	zbx_load_config(&t);
904 
905 	if (ZBX_TASK_RUNTIME_CONTROL == t.task)
906 		exit(SUCCEED == zbx_sigusr_send(t.data) ? EXIT_SUCCESS : EXIT_FAILURE);
907 
908 #ifdef HAVE_OPENIPMI
909 	{
910 		char *error = NULL;
911 
912 		if (FAIL == zbx_ipc_service_init_env(CONFIG_SOCKET_PATH, &error))
913 		{
914 			zbx_error("Cannot initialize IPC services: %s", error);
915 			zbx_free(error);
916 			exit(EXIT_FAILURE);
917 		}
918 	}
919 #endif
920 	return daemon_start(CONFIG_ALLOW_ROOT, CONFIG_USER, t.flags);
921 }
922 
MAIN_ZABBIX_ENTRY(int flags)923 int	MAIN_ZABBIX_ENTRY(int flags)
924 {
925 	zbx_socket_t	listen_sock;
926 	char		*error = NULL;
927 	int		i, db_type;
928 
929 	if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
930 	{
931 		printf("Starting Zabbix Proxy (%s) [%s]. Zabbix %s (revision %s).\nPress Ctrl+C to exit.\n\n",
932 				ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE ? "passive" : "active",
933 				CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
934 	}
935 
936 	if (SUCCEED != zbx_locks_create(&error))
937 	{
938 		zbx_error("cannot create locks: %s", error);
939 		zbx_free(error);
940 		exit(EXIT_FAILURE);
941 	}
942 
943 	if (SUCCEED != zabbix_open_log(CONFIG_LOG_TYPE, CONFIG_LOG_LEVEL, CONFIG_LOG_FILE, &error))
944 	{
945 		zbx_error("cannot open log:%s", error);
946 		zbx_free(error);
947 		exit(EXIT_FAILURE);
948 	}
949 
950 #ifdef HAVE_NETSNMP
951 #	define SNMP_FEATURE_STATUS 	"YES"
952 #else
953 #	define SNMP_FEATURE_STATUS 	" NO"
954 #endif
955 #ifdef HAVE_OPENIPMI
956 #	define IPMI_FEATURE_STATUS 	"YES"
957 #else
958 #	define IPMI_FEATURE_STATUS 	" NO"
959 #endif
960 #ifdef HAVE_LIBCURL
961 #	define LIBCURL_FEATURE_STATUS	"YES"
962 #else
963 #	define LIBCURL_FEATURE_STATUS	" NO"
964 #endif
965 #if defined(HAVE_LIBCURL) && defined(HAVE_LIBXML2)
966 #	define VMWARE_FEATURE_STATUS	"YES"
967 #else
968 #	define VMWARE_FEATURE_STATUS	" NO"
969 #endif
970 #ifdef HAVE_UNIXODBC
971 #	define ODBC_FEATURE_STATUS 	"YES"
972 #else
973 #	define ODBC_FEATURE_STATUS 	" NO"
974 #endif
975 #if defined(HAVE_SSH2) || defined(HAVE_SSH)
976 #	define SSH_FEATURE_STATUS 	"YES"
977 #else
978 #	define SSH_FEATURE_STATUS 	" NO"
979 #endif
980 #ifdef HAVE_IPV6
981 #	define IPV6_FEATURE_STATUS 	"YES"
982 #else
983 #	define IPV6_FEATURE_STATUS 	" NO"
984 #endif
985 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
986 #	define TLS_FEATURE_STATUS	"YES"
987 #else
988 #	define TLS_FEATURE_STATUS	" NO"
989 #endif
990 
991 	zabbix_log(LOG_LEVEL_INFORMATION, "Starting Zabbix Proxy (%s) [%s]. Zabbix %s (revision %s).",
992 			ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE ? "passive" : "active",
993 			CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
994 
995 	zabbix_log(LOG_LEVEL_INFORMATION, "**** Enabled features ****");
996 	zabbix_log(LOG_LEVEL_INFORMATION, "SNMP monitoring:       " SNMP_FEATURE_STATUS);
997 	zabbix_log(LOG_LEVEL_INFORMATION, "IPMI monitoring:       " IPMI_FEATURE_STATUS);
998 	zabbix_log(LOG_LEVEL_INFORMATION, "Web monitoring:        " LIBCURL_FEATURE_STATUS);
999 	zabbix_log(LOG_LEVEL_INFORMATION, "VMware monitoring:     " VMWARE_FEATURE_STATUS);
1000 	zabbix_log(LOG_LEVEL_INFORMATION, "ODBC:                  " ODBC_FEATURE_STATUS);
1001 	zabbix_log(LOG_LEVEL_INFORMATION, "SSH support:           " SSH_FEATURE_STATUS);
1002 	zabbix_log(LOG_LEVEL_INFORMATION, "IPv6 support:          " IPV6_FEATURE_STATUS);
1003 	zabbix_log(LOG_LEVEL_INFORMATION, "TLS support:           " TLS_FEATURE_STATUS);
1004 	zabbix_log(LOG_LEVEL_INFORMATION, "**************************");
1005 
1006 	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
1007 
1008 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
1009 	if (SUCCEED != zbx_coredump_disable())
1010 	{
1011 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
1012 		exit(EXIT_FAILURE);
1013 	}
1014 #endif
1015 	if (FAIL == zbx_load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 1))
1016 	{
1017 		zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
1018 		exit(EXIT_FAILURE);
1019 	}
1020 
1021 	zbx_free_config();
1022 
1023 	if (SUCCEED != init_database_cache(&error))
1024 	{
1025 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize database cache: %s", error);
1026 		zbx_free(error);
1027 		exit(EXIT_FAILURE);
1028 	}
1029 
1030 	if (SUCCEED != init_proxy_history_lock(&error))
1031 	{
1032 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize lock for passive proxy history: %s", error);
1033 		zbx_free(error);
1034 		exit(EXIT_FAILURE);
1035 	}
1036 
1037 	if (SUCCEED != init_configuration_cache(&error))
1038 	{
1039 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize configuration cache: %s", error);
1040 		zbx_free(error);
1041 		exit(EXIT_FAILURE);
1042 	}
1043 
1044 	if (SUCCEED != init_selfmon_collector(&error))
1045 	{
1046 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize self-monitoring: %s", error);
1047 		zbx_free(error);
1048 		exit(EXIT_FAILURE);
1049 	}
1050 
1051 	if (0 != CONFIG_VMWARE_FORKS && SUCCEED != zbx_vmware_init(&error))
1052 	{
1053 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize VMware cache: %s", error);
1054 		zbx_free(error);
1055 		exit(EXIT_FAILURE);
1056 	}
1057 
1058 	if (SUCCEED != DBinit(&error))
1059 	{
1060 		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize database: %s", error);
1061 		zbx_free(error);
1062 		exit(EXIT_FAILURE);
1063 	}
1064 
1065 	DBinit_autoincrement_options();
1066 
1067 	if (ZBX_DB_UNKNOWN == (db_type = zbx_db_get_database_type()))
1068 	{
1069 		zabbix_log(LOG_LEVEL_CRIT, "cannot use database \"%s\": database is not a Zabbix database",
1070 				CONFIG_DBNAME);
1071 		exit(EXIT_FAILURE);
1072 	}
1073 	else if (ZBX_DB_PROXY != db_type)
1074 	{
1075 		zabbix_log(LOG_LEVEL_CRIT, "cannot use database \"%s\": Zabbix proxy cannot work with a"
1076 				" Zabbix server database", CONFIG_DBNAME);
1077 		exit(EXIT_FAILURE);
1078 	}
1079 
1080 	if (SUCCEED != DBcheck_version())
1081 		exit(EXIT_FAILURE);
1082 	DBcheck_character_set();
1083 
1084 	threads_num = CONFIG_CONFSYNCER_FORKS + CONFIG_HEARTBEAT_FORKS + CONFIG_DATASENDER_FORKS
1085 			+ CONFIG_POLLER_FORKS + CONFIG_UNREACHABLE_POLLER_FORKS + CONFIG_TRAPPER_FORKS
1086 			+ CONFIG_PINGER_FORKS + CONFIG_HOUSEKEEPER_FORKS + CONFIG_HTTPPOLLER_FORKS
1087 			+ CONFIG_DISCOVERER_FORKS + CONFIG_HISTSYNCER_FORKS + CONFIG_IPMIPOLLER_FORKS
1088 			+ CONFIG_JAVAPOLLER_FORKS + CONFIG_SNMPTRAPPER_FORKS + CONFIG_SELFMON_FORKS
1089 			+ CONFIG_VMWARE_FORKS + CONFIG_IPMIMANAGER_FORKS + CONFIG_TASKMANAGER_FORKS;
1090 
1091 	threads = (pid_t *)zbx_calloc(threads, threads_num, sizeof(pid_t));
1092 	threads_flags = (int *)zbx_calloc(threads_flags, threads_num, sizeof(int));
1093 
1094 	if (0 != CONFIG_TRAPPER_FORKS)
1095 	{
1096 		if (FAIL == zbx_tcp_listen(&listen_sock, CONFIG_LISTEN_IP, (unsigned short)CONFIG_LISTEN_PORT))
1097 		{
1098 			zabbix_log(LOG_LEVEL_CRIT, "listener failed: %s", zbx_socket_strerror());
1099 			exit(EXIT_FAILURE);
1100 		}
1101 	}
1102 
1103 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
1104 	zbx_tls_init_parent();
1105 #endif
1106 	zabbix_log(LOG_LEVEL_INFORMATION, "proxy #0 started [main process]");
1107 
1108 	for (i = 0; i < threads_num; i++)
1109 	{
1110 		zbx_thread_args_t	thread_args;
1111 		unsigned char		poller_type;
1112 
1113 		if (FAIL == get_process_info_by_thread(i + 1, &thread_args.process_type, &thread_args.process_num))
1114 		{
1115 			THIS_SHOULD_NEVER_HAPPEN;
1116 			exit(EXIT_FAILURE);
1117 		}
1118 
1119 		thread_args.server_num = i + 1;
1120 		thread_args.args = NULL;
1121 
1122 		switch (thread_args.process_type)
1123 		{
1124 			case ZBX_PROCESS_TYPE_CONFSYNCER:
1125 				zbx_thread_start(proxyconfig_thread, &thread_args, &threads[i]);
1126 				DCconfig_wait_sync();
1127 				break;
1128 			case ZBX_PROCESS_TYPE_TRAPPER:
1129 				thread_args.args = &listen_sock;
1130 				zbx_thread_start(trapper_thread, &thread_args, &threads[i]);
1131 				if (0 == CONFIG_CONFSYNCER_FORKS)
1132 					DCconfig_wait_sync();
1133 				break;
1134 			case ZBX_PROCESS_TYPE_HEARTBEAT:
1135 				zbx_thread_start(heart_thread, &thread_args, &threads[i]);
1136 				break;
1137 			case ZBX_PROCESS_TYPE_DATASENDER:
1138 				zbx_thread_start(datasender_thread, &thread_args, &threads[i]);
1139 				break;
1140 			case ZBX_PROCESS_TYPE_POLLER:
1141 				poller_type = ZBX_POLLER_TYPE_NORMAL;
1142 				thread_args.args = &poller_type;
1143 				zbx_thread_start(poller_thread, &thread_args, &threads[i]);
1144 				break;
1145 			case ZBX_PROCESS_TYPE_UNREACHABLE:
1146 				poller_type = ZBX_POLLER_TYPE_UNREACHABLE;
1147 				thread_args.args = &poller_type;
1148 				zbx_thread_start(poller_thread, &thread_args, &threads[i]);
1149 				break;
1150 			case ZBX_PROCESS_TYPE_PINGER:
1151 				zbx_thread_start(pinger_thread, &thread_args, &threads[i]);
1152 				break;
1153 			case ZBX_PROCESS_TYPE_HOUSEKEEPER:
1154 				zbx_thread_start(housekeeper_thread, &thread_args, &threads[i]);
1155 				break;
1156 			case ZBX_PROCESS_TYPE_HTTPPOLLER:
1157 				zbx_thread_start(httppoller_thread, &thread_args, &threads[i]);
1158 				break;
1159 			case ZBX_PROCESS_TYPE_DISCOVERER:
1160 				zbx_thread_start(discoverer_thread, &thread_args, &threads[i]);
1161 				break;
1162 			case ZBX_PROCESS_TYPE_HISTSYNCER:
1163 				threads_flags[i] = ZBX_THREAD_WAIT_EXIT;
1164 				zbx_thread_start(dbsyncer_thread, &thread_args, &threads[i]);
1165 				break;
1166 			case ZBX_PROCESS_TYPE_JAVAPOLLER:
1167 				poller_type = ZBX_POLLER_TYPE_JAVA;
1168 				thread_args.args = &poller_type;
1169 				zbx_thread_start(poller_thread, &thread_args, &threads[i]);
1170 				break;
1171 			case ZBX_PROCESS_TYPE_SNMPTRAPPER:
1172 				zbx_thread_start(snmptrapper_thread, &thread_args, &threads[i]);
1173 				break;
1174 			case ZBX_PROCESS_TYPE_SELFMON:
1175 				zbx_thread_start(selfmon_thread, &thread_args, &threads[i]);
1176 				break;
1177 			case ZBX_PROCESS_TYPE_VMWARE:
1178 				zbx_thread_start(vmware_thread, &thread_args, &threads[i]);
1179 				break;
1180 #ifdef HAVE_OPENIPMI
1181 			case ZBX_PROCESS_TYPE_IPMIMANAGER:
1182 				zbx_thread_start(ipmi_manager_thread, &thread_args, &threads[i]);
1183 				break;
1184 			case ZBX_PROCESS_TYPE_IPMIPOLLER:
1185 				zbx_thread_start(ipmi_poller_thread, &thread_args, &threads[i]);
1186 				break;
1187 #endif
1188 			case ZBX_PROCESS_TYPE_TASKMANAGER:
1189 				zbx_thread_start(taskmanager_thread, &thread_args, &threads[i]);
1190 				break;
1191 		}
1192 	}
1193 
1194 	while (-1 == wait(&i))	/* wait for any child to exit */
1195 	{
1196 		if (EINTR != errno)
1197 		{
1198 			zabbix_log(LOG_LEVEL_ERR, "failed to wait on child processes: %s", zbx_strerror(errno));
1199 			break;
1200 		}
1201 	}
1202 
1203 	/* all exiting child processes should be caught by signal handlers */
1204 	THIS_SHOULD_NEVER_HAPPEN;
1205 
1206 	zbx_on_exit(FAIL);
1207 
1208 	return SUCCEED;
1209 }
1210 
zbx_on_exit(int ret)1211 void	zbx_on_exit(int ret)
1212 {
1213 	zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called");
1214 
1215 	if (NULL != threads)
1216 	{
1217 		zbx_threads_wait(threads, threads_flags, threads_num, ret);	/* wait for all child processes to exit */
1218 		zbx_free(threads);
1219 		zbx_free(threads_flags);
1220 	}
1221 #ifdef HAVE_PTHREAD_PROCESS_SHARED
1222 	zbx_locks_disable();
1223 #endif
1224 	free_metrics();
1225 #ifdef HAVE_OPENIPMI
1226 	zbx_ipc_service_free_env();
1227 #endif
1228 
1229 	DBconnect(ZBX_DB_CONNECT_EXIT);
1230 	free_database_cache();
1231 	free_configuration_cache();
1232 	DBclose();
1233 
1234 	DBdeinit();
1235 
1236 	/* free vmware support */
1237 	if (0 != CONFIG_VMWARE_FORKS)
1238 		zbx_vmware_destroy();
1239 
1240 	free_selfmon_collector();
1241 	free_proxy_history_lock();
1242 
1243 	zbx_unload_modules();
1244 
1245 	zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Proxy stopped. Zabbix %s (revision %s).",
1246 			ZABBIX_VERSION, ZABBIX_REVISION);
1247 
1248 	zabbix_close_log();
1249 
1250 #if defined(PS_OVERWRITE_ARGV)
1251 	setproctitle_free_env();
1252 #endif
1253 
1254 	exit(EXIT_SUCCESS);
1255 }
1256