mirror of https://github.com/Icinga/icinga2.git
Merge pull request #5850 from Icinga/fix/prepare-dirs-5793
init script security fixes
This commit is contained in:
commit
aea43ddeb9
|
@ -21,7 +21,7 @@
|
|||
#define ICINGA_INCLUDECONFDIR "${CMAKE_INSTALL_FULL_DATADIR}/icinga2/include"
|
||||
#define ICINGA_USER "${ICINGA2_USER}"
|
||||
#define ICINGA_GROUP "${ICINGA2_GROUP}"
|
||||
|
||||
#define ICINGA_SYSCONFIGFILE "${ICINGA2_SYSCONFIGFILE}"
|
||||
#define ICINGA_BUILD_HOST_NAME "${ICINGA2_BUILD_HOST_NAME}"
|
||||
#define ICINGA_BUILD_COMPILER_NAME "${ICINGA2_BUILD_COMPILER_NAME}"
|
||||
#define ICINGA_BUILD_COMPILER_VERSION "${ICINGA2_BUILD_COMPILER_VERSION}"
|
||||
|
|
|
@ -389,8 +389,8 @@ ObjectsPath |**Read-write.** Contains the path of the Icinga 2 objects f
|
|||
PidPath |**Read-write.** Contains the path of the Icinga 2 PID file. Defaults to RunDir + "/icinga2/icinga2.pid".
|
||||
Vars |**Read-write.** Contains a dictionary with global custom attributes. Not set by default.
|
||||
NodeName |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
|
||||
RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Used in the `init.conf` configuration file.
|
||||
RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Used in the `init.conf` configuration file.
|
||||
RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
||||
RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
||||
PlatformName |**Read-only.** The name of the operating system, e.g. "Ubuntu".
|
||||
PlatformVersion |**Read-only.** The version of the operating system, e.g. "14.04.3 LTS".
|
||||
PlatformKernel |**Read-only.** The name of the operating system kernel, e.g. "Linux".
|
||||
|
@ -407,9 +407,9 @@ Variable |Description
|
|||
--------------------|-------------------
|
||||
EventEngine |**Read-write.** The name of the socket event engine, can be `poll` or `epoll`. The epoll interface is only supported on Linux.
|
||||
AttachDebugger |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to `false`.
|
||||
RLimitFiles |**Read-write.** Defines the resource limit for RLIMIT_NOFILE that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Used in the `init.conf` configuration file.
|
||||
RLimitProcesses |**Read-write.** Defines the resource limit for RLIMIT_NPROC that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Used in the `init.conf` configuration file.
|
||||
RLimitStack |**Read-write.** Defines the resource limit for RLIMIT_STACK that should be set at start-up. Value cannot be set lower than the default `256 * 1024`. 0 disables the setting. Used in the `init.conf` configuration file.
|
||||
RLimitFiles |**Read-write.** Defines the resource limit for RLIMIT_NOFILE that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
|
||||
RLimitProcesses |**Read-write.** Defines the resource limit for RLIMIT_NPROC that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
|
||||
RLimitStack |**Read-write.** Defines the resource limit for RLIMIT_STACK that should be set at start-up. Value cannot be set lower than the default `256 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
|
||||
|
||||
## Apply <a id="apply"></a>
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
# along with this program; if not, write to the Free Software Foundation
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
configure_file(icinga2/init.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2/init.conf @ONLY)
|
||||
|
||||
if(NOT WIN32)
|
||||
configure_file(icinga2/constants.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf @ONLY)
|
||||
endif()
|
||||
|
@ -25,8 +23,6 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
|||
configure_file(logrotate.d/icinga2.cmake ${CMAKE_CURRENT_BINARY_DIR}/logrotate.d/icinga2 @ONLY)
|
||||
endif()
|
||||
|
||||
install_if_not_exists(${CMAKE_CURRENT_BINARY_DIR}/icinga2/init.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||
|
||||
if(NOT WIN32)
|
||||
install_if_not_exists(${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||
install_if_not_exists(icinga2/icinga2.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
* This file is read by Icinga 2 before the main
|
||||
* configuration file (icinga2.conf) is processed.
|
||||
*/
|
||||
|
||||
const RunAsUser = "@ICINGA2_USER@"
|
||||
const RunAsGroup = "@ICINGA2_GROUP@"
|
|
@ -31,16 +31,14 @@ if [ ! -e $ICINGA2_CONFIG_FILE ]; then
|
|||
exit 6
|
||||
fi
|
||||
|
||||
ICINGA2_USER=`$DAEMON variable get --current RunAsUser`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not fetch RunAsUser variable. Error '$ICINGA2_USER'. Exiting."
|
||||
exit 6
|
||||
if [ ! $ICINGA2_USER ]; then
|
||||
echo "Could not fetch \$ICINGA2_USER. Exiting."
|
||||
exit 6
|
||||
fi
|
||||
|
||||
ICINGA2_GROUP=`$DAEMON variable get --current RunAsGroup`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not fetch RunAsGroup variable. Error '$ICINGA2_GROUP'. Exiting."
|
||||
exit 6
|
||||
if [ ! $ICINGA2_GROUP ]; then
|
||||
echo "Could not fetch \$ICINGA2_GROUP. Exiting."
|
||||
exit 6
|
||||
fi
|
||||
|
||||
getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6)
|
||||
|
@ -49,14 +47,14 @@ getent group $ICINGA2_COMMAND_GROUP >/dev/null 2>&1 || (echo "Icinga command gro
|
|||
|
||||
# Get function from functions library
|
||||
if [ -f /etc/rc.d/init.d/functions ]; then
|
||||
. /etc/rc.d/init.d/functions
|
||||
. /etc/rc.d/init.d/functions
|
||||
elif [ -f /etc/init.d/functions ]; then
|
||||
. /etc/init.d/functions
|
||||
. /etc/init.d/functions
|
||||
fi
|
||||
|
||||
# Load extra environment variables
|
||||
if [ -f /etc/default/icinga2 ]; then
|
||||
. /etc/default/icinga2
|
||||
. /etc/default/icinga2
|
||||
fi
|
||||
|
||||
# Start Icinga 2
|
||||
|
@ -74,34 +72,33 @@ start() {
|
|||
|
||||
# Restart Icinga 2
|
||||
stop() {
|
||||
printf "Stopping Icinga 2: "
|
||||
printf "Stopping Icinga 2: "
|
||||
|
||||
if [ ! -e $ICINGA2_PID_FILE ]; then
|
||||
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
|
||||
if [ "x$1" = "xnofail" ]; then
|
||||
if [ ! -e $ICINGA2_PID_FILE ]; then
|
||||
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
|
||||
if [ "x$1" = "xnofail" ]; then
|
||||
return
|
||||
else
|
||||
exit 7
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
pid=`cat $ICINGA2_PID_FILE`
|
||||
|
||||
if kill -INT $pid >/dev/null 2>&1; then
|
||||
if icinga2 internal signal -s SIGINT -p $pid >/dev/null 2>&1; then
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
if ! kill -CHLD $pid >/dev/null 2>&1; then
|
||||
if ! icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
|
||||
printf '.'
|
||||
|
||||
sleep 3
|
||||
done
|
||||
fi
|
||||
|
||||
if kill -CHLD $pid >/dev/null 2>&1; then
|
||||
kill -KILL $pid
|
||||
fi
|
||||
if icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
|
||||
icinga2 internal signal -s SIGKILL -p $pid >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
echo "Done"
|
||||
}
|
||||
|
@ -116,21 +113,21 @@ checkconfig() {
|
|||
printf "Checking configuration: "
|
||||
|
||||
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -C > $ICINGA2_STARTUP_LOG 2>&1; then
|
||||
if [ "x$1" = "x" ]; then
|
||||
if [ "x$1" = "x" ]; then
|
||||
cat $ICINGA2_STARTUP_LOG
|
||||
echo "Icinga 2 detected configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
|
||||
exit 1
|
||||
else
|
||||
exit 1
|
||||
else
|
||||
echo "Not "$1"ing Icinga 2 due to configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
|
||||
if [ "x$2" = "xfail" ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "x$2" = "xfail" ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Done"
|
||||
# no arguments requires full output
|
||||
if [ "x$1" = "x" ]; then
|
||||
if [ "x$1" = "x" ]; then
|
||||
cat $ICINGA2_STARTUP_LOG
|
||||
fi
|
||||
}
|
||||
|
@ -145,7 +142,7 @@ status() {
|
|||
fi
|
||||
|
||||
pid=`cat $ICINGA2_PID_FILE`
|
||||
if kill -CHLD $pid >/dev/null 2>&1; then
|
||||
if icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
|
||||
echo "Running"
|
||||
else
|
||||
echo "Not running"
|
||||
|
@ -157,33 +154,34 @@ status() {
|
|||
case "$1" in
|
||||
start)
|
||||
checkconfig start fail
|
||||
start
|
||||
;;
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
stop
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
status
|
||||
;;
|
||||
restart)
|
||||
checkconfig restart fail
|
||||
stop nofail
|
||||
start
|
||||
;;
|
||||
stop nofail
|
||||
start
|
||||
;;
|
||||
condrestart)
|
||||
status > /dev/null 2>&1 || exit 0
|
||||
checkconfig restart fail
|
||||
stop nofail
|
||||
start
|
||||
;;
|
||||
status > /dev/null 2>&1 || exit 0
|
||||
checkconfig restart fail
|
||||
stop nofail
|
||||
start
|
||||
;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
;;
|
||||
checkconfig)
|
||||
checkconfig
|
||||
;;
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|reload|checkconfig|status}"
|
||||
exit 3
|
||||
echo "Usage: $0 {start|stop|restart|reload|checkconfig|status}"
|
||||
exit 3
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -3,9 +3,10 @@ ICINGA2_CONFIG_FILE=@CMAKE_INSTALL_FULL_SYSCONFDIR@/icinga2/icinga2.conf
|
|||
ICINGA2_RUN_DIR=@ICINGA2_RUNDIR@
|
||||
ICINGA2_STATE_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@
|
||||
ICINGA2_PID_FILE=$ICINGA2_RUN_DIR/icinga2/icinga2.pid
|
||||
ICINGA2_ERROR_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/error.log
|
||||
ICINGA2_STARTUP_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/startup.log
|
||||
ICINGA2_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/icinga2.log
|
||||
ICINGA2_LOG_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2
|
||||
ICINGA2_ERROR_LOG=$ICINGA2_LOG_DIR/error.log
|
||||
ICINGA2_STARTUP_LOG=$ICINGA2_LOG_DIR/startup.log
|
||||
ICINGA2_LOG=$ICINGA2_LOG_DIR/icinga2.log
|
||||
ICINGA2_CACHE_DIR=$ICINGA2_STATE_DIR/cache/icinga2
|
||||
ICINGA2_USER=@ICINGA2_USER@
|
||||
ICINGA2_GROUP=@ICINGA2_GROUP@
|
||||
|
|
|
@ -13,49 +13,42 @@ else
|
|||
fi
|
||||
|
||||
|
||||
ICINGA2_USER=`$DAEMON variable get --current RunAsUser`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not fetch RunAsUser variable. Error '$ICINGA2_USER'. Exiting."
|
||||
exit 6
|
||||
if [ ! $ICINGA2_USER ]; then
|
||||
echo "Could not fetch \$ICINGA2_USER. Exiting."
|
||||
exit 6
|
||||
fi
|
||||
|
||||
ICINGA2_GROUP=`$DAEMON variable get --current RunAsGroup`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not fetch RunAsGroup variable. Error '$ICINGA2_GROUP'. Exiting."
|
||||
exit 6
|
||||
if [ ! $ICINGA2_GROUP ]; then
|
||||
echo "Could not fetch \$ICINGA2_GROUP. Exiting."
|
||||
exit 6
|
||||
fi
|
||||
|
||||
getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6)
|
||||
getent group $ICINGA2_GROUP >/dev/null 2>&1 || (echo "Icinga group '$ICINGA2_GROUP' does not exist. Exiting." && exit 6)
|
||||
getent group $ICINGA2_COMMAND_GROUP >/dev/null 2>&1 || (echo "Icinga command group '$ICINGA2_COMMAND_GROUP' does not exist. Exiting." && exit 6)
|
||||
|
||||
mkdir -p $(dirname -- $ICINGA2_PID_FILE)
|
||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $(dirname -- $ICINGA2_PID_FILE)
|
||||
if [ -f $ICINGA2_PID_FILE ]; then
|
||||
chown $ICINGA2_USER:$ICINGA2_GROUP $ICINGA2_PID_FILE
|
||||
if [ ! -e "$ICINGA2_RUN_DIR"/icinga2 ]; then
|
||||
mkdir "$ICINGA2_RUN_DIR"/icinga2
|
||||
mkdir "$ICINGA2_RUN_DIR"/icinga2/cmd
|
||||
chmod 755 "$ICINGA2_RUN_DIR"/icinga2
|
||||
chmod 2750 "$ICINGA2_RUN_DIR"/icinga2/cmd
|
||||
chown -R $ICINGA2_USER:$ICINGA2_COMMAND_GROUP "$ICINGA2_RUN_DIR"/icinga2
|
||||
fi
|
||||
|
||||
mkdir -p $(dirname -- $ICINGA2_ERROR_LOG)
|
||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $(dirname -- $ICINGA2_ERROR_LOG)
|
||||
chmod 750 $(dirname -- $ICINGA2_ERROR_LOG)
|
||||
if [ -f $ICINGA2_ERROR_LOG ]; then
|
||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_ERROR_LOG
|
||||
fi
|
||||
if [ -f $ICINGA2_LOG ]; then
|
||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_LOG
|
||||
# Could be undefined in installations where sysconf is not overridden on upgrade
|
||||
if [ -z "$ICINGA2_LOG_DIR" ]; then
|
||||
$ICINGA2_LOG_DIR=$(dirname -- "$ICINGA2_LOG")
|
||||
fi
|
||||
|
||||
mkdir -p $ICINGA2_RUN_DIR/icinga2/cmd
|
||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_RUN_DIR/icinga2/cmd
|
||||
test -e "$ICINGA2_LOG_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_LOG_DIR"
|
||||
|
||||
if type restorecon >/dev/null 2>&1; then
|
||||
restorecon -R $ICINGA2_RUN_DIR/icinga2/
|
||||
restorecon -R "$ICINGA2_RUN_DIR"/icinga2/
|
||||
fi
|
||||
chmod 2750 $ICINGA2_RUN_DIR/icinga2/cmd
|
||||
|
||||
# Add a fallback if the user did not specify this directory in the sysconfig file
|
||||
if [ -z "$ICINGA2_CACHE_DIR" ]; then
|
||||
ICINGA2_CACHE_DIR=$ICINGA2_STATE_DIR/cache/icinga2
|
||||
ICINGA2_CACHE_DIR="$ICINGA2_STATE_DIR"/cache/icinga2
|
||||
fi
|
||||
mkdir -p $ICINGA2_CACHE_DIR
|
||||
chown $ICINGA2_USER:$ICINGA2_GROUP $ICINGA2_CACHE_DIR
|
||||
chmod 750 $ICINGA2_CACHE_DIR
|
||||
|
||||
test -e "$ICINGA2_CACHE_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_CACHE_DIR"
|
||||
|
|
|
@ -143,6 +143,7 @@ static int Main()
|
|||
|
||||
#endif /* _WIN32 */
|
||||
Application::DeclarePrefixDir(ICINGA_PREFIX);
|
||||
Application::DeclareSysconfigFile(ICINGA_SYSCONFIGFILE);
|
||||
Application::DeclareSysconfDir(ICINGA_SYSCONFDIR);
|
||||
Application::DeclareRunDir(ICINGA_RUNDIR);
|
||||
Application::DeclareLocalStateDir(ICINGA_LOCALSTATEDIR);
|
||||
|
@ -153,13 +154,63 @@ static int Main()
|
|||
#endif /* _WIN32 */
|
||||
|
||||
Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d");
|
||||
Application::DeclareRunAsUser(ICINGA_USER);
|
||||
Application::DeclareRunAsGroup(ICINGA_GROUP);
|
||||
#ifdef __linux__
|
||||
Application::DeclareRLimitFiles(Application::GetDefaultRLimitFiles());
|
||||
Application::DeclareRLimitProcesses(Application::GetDefaultRLimitProcesses());
|
||||
Application::DeclareRLimitStack(Application::GetDefaultRLimitStack());
|
||||
#endif /* __linux__ */
|
||||
|
||||
String icingaUser = Utility::GetFromSysconfig("ICINGA2_USER");
|
||||
if (icingaUser.IsEmpty())
|
||||
icingaUser = ICINGA_USER;
|
||||
|
||||
String icingaGroup = Utility::GetFromSysconfig("ICINGA2_GROUP");
|
||||
if (icingaGroup.IsEmpty())
|
||||
icingaGroup = ICINGA_GROUP;
|
||||
|
||||
Application::DeclareRunAsUser(icingaUser);
|
||||
Application::DeclareRunAsGroup(icingaGroup);
|
||||
|
||||
#ifdef RLIMIT_NOFILE
|
||||
String rLimitFiles = Utility::GetFromSysconfig("ICINGA2_RLIMIT_FILES");
|
||||
if (rLimitFiles.IsEmpty())
|
||||
Application::DeclareRLimitFiles(Application::GetDefaultRLimitFiles());
|
||||
else {
|
||||
try {
|
||||
Application::DeclareRLimitFiles(Convert::ToLong(rLimitFiles));
|
||||
} catch (const std::invalid_argument& ex) {
|
||||
std::cout
|
||||
<< "Error while parsing \"ICINGA2_RLIMIT_FILES\" from sysconfig: " << ex.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* RLIMIT_NOFILE */
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
String rLimitProcesses = Utility::GetFromSysconfig("ICINGA2_RLIMIT_PROCESSES");
|
||||
if (rLimitProcesses.IsEmpty())
|
||||
Application::DeclareRLimitProcesses(Application::GetDefaultRLimitProcesses());
|
||||
else {
|
||||
try {
|
||||
Application::DeclareRLimitProcesses(Convert::ToLong(rLimitProcesses));
|
||||
} catch (const std::invalid_argument& ex) {
|
||||
std::cout
|
||||
<< "Error while parsing \"ICINGA2_RLIMIT_PROCESSES\" from sysconfig: " << ex.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* RLIMIT_NPROC */
|
||||
|
||||
#ifdef RLIMIT_STACK
|
||||
String rLimitStack = Utility::GetFromSysconfig("ICINGA2_RLIMIT_STACK");
|
||||
if (rLimitStack.IsEmpty())
|
||||
Application::DeclareRLimitStack(Application::GetDefaultRLimitStack());
|
||||
else {
|
||||
try {
|
||||
Application::DeclareRLimitStack(Convert::ToLong(rLimitStack));
|
||||
} catch (const std::invalid_argument& ex) {
|
||||
std::cout
|
||||
<< "Error while parsing \"ICINGA2_RLIMIT_STACK\" from sysconfig: " << ex.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* RLIMIT_STACK */
|
||||
|
||||
Application::DeclareConcurrency(std::thread::hardware_concurrency());
|
||||
Application::DeclareMaxConcurrentChecks(Application::GetDefaultMaxConcurrentChecks());
|
||||
|
||||
|
@ -175,21 +226,6 @@ static int Main()
|
|||
ScriptGlobal::Set("BuildCompilerName", ICINGA_BUILD_COMPILER_NAME);
|
||||
ScriptGlobal::Set("BuildCompilerVersion", ICINGA_BUILD_COMPILER_VERSION);
|
||||
|
||||
String initconfig = Application::GetSysconfDir() + "/icinga2/init.conf";
|
||||
|
||||
if (Utility::PathExists(initconfig)) {
|
||||
std::unique_ptr<Expression> expression;
|
||||
try {
|
||||
expression = ConfigCompiler::CompileFile(initconfig);
|
||||
|
||||
ScriptFrame frame(true);
|
||||
expression->Evaluate(frame);
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!autocomplete)
|
||||
Application::SetResourceLimits();
|
||||
|
||||
|
|
|
@ -1326,6 +1326,27 @@ void Application::DeclareStatePath(const String& path)
|
|||
ScriptGlobal::Set("StatePath", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrives the path of the sysconfig file.
|
||||
*
|
||||
* @returns The path.
|
||||
*/
|
||||
String Application::GetSysconfigFile(void)
|
||||
{
|
||||
return ScriptGlobal::Get("SysconfigFile");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path of the sysconfig file.
|
||||
*
|
||||
* @param path The new path.
|
||||
*/
|
||||
void Application::DeclareSysconfigFile(const String& path)
|
||||
{
|
||||
if (!ScriptGlobal::Exists("SysconfigFile"))
|
||||
ScriptGlobal::Set("SysconfigFile", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path for the modified attributes file.
|
||||
*
|
||||
|
|
|
@ -106,7 +106,10 @@ public:
|
|||
static String GetIncludeConfDir();
|
||||
static void DeclareIncludeConfDir(const String& path);
|
||||
|
||||
static String GetStatePath();
|
||||
static String GetSysconfigFile(void);
|
||||
static void DeclareSysconfigFile(const String& path);
|
||||
|
||||
static String GetStatePath(void);
|
||||
static void DeclareStatePath(const String& path);
|
||||
|
||||
static String GetModAttrPath();
|
||||
|
|
|
@ -1935,3 +1935,35 @@ String Utility::GetIcingaDataPath()
|
|||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
String Utility::GetFromSysconfig(const String& env)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
String sysconf = Application::GetSysconfigFile();
|
||||
if (sysconf.IsEmpty())
|
||||
return "";
|
||||
|
||||
String cmdInner = ". " + EscapeShellArg(sysconf) + " 2>&1 >/dev/null;echo \"$" + env + "\"";
|
||||
String cmd = "sh -c " + EscapeShellArg(cmdInner);
|
||||
|
||||
FILE *fp = popen(cmd.CStr(), "r");
|
||||
|
||||
if (!fp)
|
||||
return "";
|
||||
|
||||
char line[1024];
|
||||
String out;
|
||||
|
||||
if (fgets(line, sizeof(line), fp))
|
||||
out = line;
|
||||
else
|
||||
return "";
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return out.Trim();
|
||||
#else
|
||||
//TODO: Figure out how to do this on windows
|
||||
return "";
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
|
|
@ -147,6 +147,8 @@ public:
|
|||
static String GetIcingaDataPath();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
static String GetFromSysconfig(const String& env);
|
||||
|
||||
#ifdef I2_DEBUG
|
||||
static void SetTime(double);
|
||||
static void IncrementTime(double);
|
||||
|
|
|
@ -30,6 +30,7 @@ set(cli_SOURCES
|
|||
featureenablecommand.cpp featureenablecommand.hpp
|
||||
featurelistcommand.cpp featurelistcommand.hpp
|
||||
featureutility.cpp featureutility.hpp
|
||||
internalsignalcommand.cpp internalsignalcommand.hpp
|
||||
nodesetupcommand.cpp nodesetupcommand.hpp
|
||||
nodeutility.cpp nodeutility.hpp
|
||||
nodewizardcommand.cpp nodewizardcommand.hpp
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "cli/internalsignalcommand.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include <signal.h>
|
||||
|
||||
using namespace icinga;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
REGISTER_CLICOMMAND("internal/signal", InternalSignalCommand);
|
||||
|
||||
String InternalSignalCommand::GetDescription() const
|
||||
{
|
||||
return "Send signal as Icinga user";
|
||||
}
|
||||
|
||||
String InternalSignalCommand::GetShortDescription() const
|
||||
{
|
||||
return "Send signal as Icinga user";
|
||||
}
|
||||
|
||||
ImpersonationLevel InternalSignalCommand::GetImpersonationLevel() const
|
||||
{
|
||||
return ImpersonateIcinga;
|
||||
}
|
||||
|
||||
bool InternalSignalCommand::IsHidden() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void InternalSignalCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
{
|
||||
visibleDesc.add_options()
|
||||
("pid,p", po::value<int>(), "Target PID")
|
||||
("sig,s", po::value<String>(), "Signal (POSIX string) to send")
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* The entry point for the "internal signal" CLI command.
|
||||
*
|
||||
* @returns An exit status.
|
||||
*/
|
||||
int InternalSignalCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
String signal = vm["sig"].as<String>();
|
||||
|
||||
/* Thank POSIX */
|
||||
if (signal == "SIGKILL")
|
||||
return kill(vm["pid"].as<int>(), SIGKILL);
|
||||
if (signal == "SIGINT")
|
||||
return kill(vm["pid"].as<int>(), SIGINT);
|
||||
if (signal == "SIGCHLD")
|
||||
return kill(vm["pid"].as<int>(), SIGCHLD);
|
||||
if (signal == "SIGHUP")
|
||||
return kill(vm["pid"].as<int>(), SIGHUP);
|
||||
|
||||
Log(LogCritical, "cli") << "Unsupported signal \"" << signal << "\"";
|
||||
#else
|
||||
Log(LogCritical, "cli", "Unsupported action on Windows.");
|
||||
#endif /* _Win32 */
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef INTERNALSIGNALCOMMAND_H
|
||||
#define INTERNALSIGNALCOMMAND_H
|
||||
|
||||
#include "cli/clicommand.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* The "internal signal" command.
|
||||
*
|
||||
* @ingroup cli
|
||||
*/
|
||||
class InternalSignalCommand final : public CLICommand
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(InternalSignalCommand);
|
||||
|
||||
String GetDescription() const override;
|
||||
String GetShortDescription() const override;
|
||||
ImpersonationLevel GetImpersonationLevel() const override;
|
||||
bool IsHidden() const override;
|
||||
void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const override;
|
||||
int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* INTERNALSIGNALCOMMAND_H */
|
Loading…
Reference in New Issue