int main(int argc, char **argv) { ZBX_TASK_EX t; #ifdef _WINDOWS int ret; /* Provide, so our process handles errors instead of the system itself. */ /* Attention!!! */ /* The system does not display the critical-error-handler message box. */ /* Instead, the system sends the error to the calling process.*/ SetErrorMode(SEM_FAILCRITICALERRORS); #endif #if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV) argv = setproctitle_save_env(argc, argv); #endif memset(&t, 0, sizeof(t)); t.task = ZBX_TASK_START; progname = get_program_name(argv[0]); parse_commandline(argc, argv, &t); import_symbols(); /* this is needed to set default hostname in zbx_load_config() */ init_metrics(); switch (t.task) { case ZBX_TASK_SHOW_USAGE: usage(); exit(EXIT_FAILURE); break; #ifdef _WINDOWS case ZBX_TASK_INSTALL_SERVICE: case ZBX_TASK_UNINSTALL_SERVICE: case ZBX_TASK_START_SERVICE: case ZBX_TASK_STOP_SERVICE: zbx_load_config(ZBX_CFG_FILE_REQUIRED); zbx_free_config(); if (t.flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS) { zbx_snprintf(ZABBIX_SERVICE_NAME, sizeof(ZABBIX_SERVICE_NAME), "%s [%s]", APPLICATION_NAME, CONFIG_HOSTNAME); zbx_snprintf(ZABBIX_EVENT_SOURCE, sizeof(ZABBIX_EVENT_SOURCE), "%s [%s]", APPLICATION_NAME, CONFIG_HOSTNAME); } ret = zbx_exec_service_task(argv[0], &t); free_metrics(); exit(ret); break; #endif case ZBX_TASK_TEST_METRIC: case ZBX_TASK_PRINT_SUPPORTED: zbx_load_config(ZBX_CFG_FILE_OPTIONAL); #ifdef _WINDOWS init_perf_collector(0); load_perf_counters(CONFIG_PERF_COUNTERS); #else zbx_set_common_signal_handlers(); #endif #ifndef _WINDOWS if (FAIL == load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 0)) { zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting..."); exit(EXIT_FAILURE); } #endif load_user_parameters(CONFIG_USER_PARAMETERS); load_aliases(CONFIG_ALIASES); zbx_free_config(); if (ZBX_TASK_TEST_METRIC == t.task) test_parameter(TEST_METRIC); else test_parameters(); #ifdef _WINDOWS free_perf_collector(); /* cpu_collector must be freed before perf_collector is freed */ #endif #ifndef _WINDOWS unload_modules(); #endif free_metrics(); alias_list_free(); exit(SUCCEED); break; default: zbx_load_config(ZBX_CFG_FILE_REQUIRED); break; } START_MAIN_ZABBIX_ENTRY(CONFIG_ALLOW_ROOT); exit(SUCCEED); }
/****************************************************************************** * * * Function: daemon_start * * * * Purpose: init process as daemon * * * * Parameters: allow_root - allow root permission for application * * user - user on the system to which to drop the * * privileges * * * * Author: Alexei Vladishev * * * * Comments: it doesn't allow running under 'root' if allow_root is zero * * * ******************************************************************************/ int daemon_start(int allow_root, const char *user) { pid_t pid; struct passwd *pwd; if (0 == allow_root && 0 == getuid()) /* running as root? */ { if (NULL == user) user = "******"; pwd = getpwnam(user); if (NULL == pwd) { zbx_error("user %s does not exist", user); zbx_error("cannot run as root!"); exit(EXIT_FAILURE); } if (0 == pwd->pw_uid) { zbx_error("User=%s contradicts AllowRoot=0", user); zbx_error("cannot run as root!"); exit(EXIT_FAILURE); } if (-1 == setgid(pwd->pw_gid)) { zbx_error("cannot setgid to %s: %s", user, zbx_strerror(errno)); exit(EXIT_FAILURE); } #ifdef HAVE_FUNCTION_INITGROUPS if (-1 == initgroups(user, pwd->pw_gid)) { zbx_error("cannot initgroups to %s: %s", user, zbx_strerror(errno)); exit(EXIT_FAILURE); } #endif if (-1 == setuid(pwd->pw_uid)) { zbx_error("cannot setuid to %s: %s", user, zbx_strerror(errno)); exit(EXIT_FAILURE); } #ifdef HAVE_FUNCTION_SETEUID if (-1 == setegid(pwd->pw_gid) || -1 == seteuid(pwd->pw_uid)) { zbx_error("cannot setegid or seteuid to %s: %s", user, zbx_strerror(errno)); exit(EXIT_FAILURE); } #endif } if (0 != (pid = zbx_fork())) exit(EXIT_SUCCESS); setsid(); signal(SIGHUP, SIG_IGN); if (0 != (pid = zbx_fork())) exit(EXIT_SUCCESS); if (-1 == chdir("/")) /* this is to eliminate warning: ignoring return value of chdir */ assert(0); umask(0002); redirect_std(CONFIG_LOG_FILE); if (FAIL == create_pid_file(CONFIG_PID_FILE)) exit(EXIT_FAILURE); atexit(daemon_stop); parent_pid = (int)getpid(); zbx_set_common_signal_handlers(); set_daemon_signal_handlers(); /* Set SIGCHLD now to avoid race conditions when a child process is created before */ /* sigaction() is called. To avoid problems when scripts exit in zbx_execute() and */ /* other cases, SIGCHLD is set to SIG_DFL in zbx_child_fork(). */ zbx_set_child_signal_handler(); return MAIN_ZABBIX_ENTRY(); }
int main(int argc, char **argv) { char ch; int task = ZBX_TASK_START; char *TEST_METRIC = NULL; zbx_sock_t s_in; zbx_sock_t s_out; int ret; char **value; AGENT_RESULT result; progname = get_program_name(argv[0]); /* parse the command-line */ while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, "c:hVpt:", longopts, NULL))) { switch (ch) { case 'c': CONFIG_FILE = strdup(zbx_optarg); break; case 'h': help(); exit(EXIT_SUCCESS); break; case 'V': version(); #ifdef _AIX tl_version(); #endif exit(EXIT_SUCCESS); break; case 'p': if (task == ZBX_TASK_START) task = ZBX_TASK_PRINT_SUPPORTED; break; case 't': if (task == ZBX_TASK_START) { task = ZBX_TASK_TEST_METRIC; TEST_METRIC = strdup(zbx_optarg); } break; default: usage(); exit(EXIT_FAILURE); break; } } if (NULL == CONFIG_FILE) CONFIG_FILE = DEFAULT_CONFIG_FILE; /* load configuration */ if (ZBX_TASK_PRINT_SUPPORTED == task || ZBX_TASK_TEST_METRIC == task) zbx_load_config(ZBX_CFG_FILE_OPTIONAL); else zbx_load_config(ZBX_CFG_FILE_REQUIRED); /* set defaults */ if (NULL == CONFIG_LOAD_MODULE_PATH) CONFIG_LOAD_MODULE_PATH = zbx_strdup(CONFIG_LOAD_MODULE_PATH, LIBDIR "/modules"); zbx_set_common_signal_handlers(); /* metrics should be initialized before loading user parameters */ init_metrics(); /* loadable modules */ if (FAIL == load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 0)) { zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting..."); exit(EXIT_FAILURE); } /* user parameters */ load_user_parameters(CONFIG_USER_PARAMETERS); /* aliases */ load_aliases(CONFIG_ALIASES); zbx_free_config(); /* do not create debug files */ zabbix_open_log(LOG_TYPE_SYSLOG, LOG_LEVEL_EMPTY, NULL); switch (task) { case ZBX_TASK_TEST_METRIC: case ZBX_TASK_PRINT_SUPPORTED: if (ZBX_TASK_TEST_METRIC == task) test_parameter(TEST_METRIC); else test_parameters(); zbx_on_exit(); break; default: /* do nothing */ break; } alarm(CONFIG_TIMEOUT); zbx_tcp_init(&s_in, (ZBX_SOCKET)fileno(stdin)); zbx_tcp_init(&s_out, (ZBX_SOCKET)fileno(stdout)); if (SUCCEED == (ret = zbx_tcp_check_security(&s_in, CONFIG_HOSTS_ALLOWED, 0))) { if (SUCCEED == (ret = zbx_tcp_recv(&s_in))) { zbx_rtrim(s_in.buffer, "\r\n"); zabbix_log(LOG_LEVEL_DEBUG, "requested [%s]", s_in.buffer); init_result(&result); process(s_in.buffer, 0, &result); if (NULL == (value = GET_TEXT_RESULT(&result))) value = GET_MSG_RESULT(&result); if (NULL != value) { zabbix_log(LOG_LEVEL_DEBUG, "sending back [%s]", *value); ret = zbx_tcp_send(&s_out, *value); } free_result(&result); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "processing error: %s", zbx_tcp_strerror()); } fflush(stdout); alarm(0); zbx_on_exit(); return SUCCEED; }