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