# include <sys/types.h>
# include <pwd.h>
# include <grp.h>
+#else
+# include <windows.h>
+# include <Lmcons.h>
+# include <Shellapi.h>
+# include <tchar.h>
#endif /* _WIN32 */
using namespace icinga;
return EXIT_FAILURE;
}
+#ifdef _WIN32
+ char username[UNLEN + 1];
+ DWORD usernameLen = UNLEN + 1;
+ GetUserName(username, &usernameLen);
+
+ std::ifstream userFile;
+ userFile.open(Application::GetSysconfDir() + "/icinga2/user");
+
+ if (userFile && command && !Application::IsProcessElevated()) {
+ std::string userLine;
+ if (std::getline(userFile, userLine)) {
+ userFile.close();
+
+ std::vector<std::string> strs;
+ boost::split(strs, userLine, boost::is_any_of("\\"));
+
+ if (username != strs[1] && command->GetImpersonationLevel() == ImpersonationLevel::ImpersonateIcinga
+ || command->GetImpersonationLevel() == ImpersonationLevel::ImpersonateRoot) {
+ TCHAR szPath[MAX_PATH];
+
+ if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
+ SHELLEXECUTEINFO sei = { sizeof(sei) };
+ sei.lpVerb = _T("runas");
+ sei.lpFile = "cmd.exe";
+ sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI;
+ sei.nShow = SW_SHOW;
+
+ std::stringstream parameters;
+
+ parameters << "/C " << "\"" << szPath << "\"" << " ";
+
+ for (int i = 1; i < argc; i++) {
+ if (i != 1)
+ parameters << " ";
+ parameters << argv[i];
+ }
+
+ parameters << " & SET exitcode=%errorlevel%";
+ parameters << " & pause";
+ parameters << " & EXIT /B %exitcode%";
+
+ std::string str = parameters.str();
+ LPCSTR cstr = str.c_str();
+
+ sei.lpParameters = cstr;
+
+ if (!ShellExecuteEx(&sei)) {
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_CANCELLED)
+ Application::Exit(0);
+ } else {
+ WaitForSingleObject(sei.hProcess, INFINITE);
+
+ DWORD exitCode;
+ GetExitCodeProcess(sei.hProcess, &exitCode);
+
+ CloseHandle(sei.hProcess);
+
+ Application::Exit(exitCode);
+ }
+ }
+ }
+ } else {
+ userFile.close();
+ }
+ }
+#endif /* _WIN32 */
+
#ifndef _WIN32
if (vm.count("color")) {
Console::SetType(std::cout, Console_VT100);
#include <sys/prctl.h>
#endif /* __linux__ */
+#ifdef _WIN32
+#include <windows.h>
+#endif /* _win32 */
+
using namespace icinga;
REGISTER_TYPE(Application);
SetConsoleCtrlHandler(NULL, FALSE);
return TRUE;
}
+
+bool Application::IsProcessElevated(void) {
+ BOOL fIsElevated = FALSE;
+ DWORD dwError = ERROR_SUCCESS;
+ HANDLE hToken = NULL;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ dwError = GetLastError();
+ else {
+ TOKEN_ELEVATION elevation;
+ DWORD dwSize;
+
+ if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize))
+ dwError = GetLastError();
+ else
+ fIsElevated = elevation.TokenIsElevated;
+ }
+
+ if (hToken) {
+ CloseHandle(hToken);
+ hToken = NULL;
+ }
+
+ if (ERROR_SUCCESS != dwError) {
+ LPSTR mBuf = NULL;
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), mBuf, 0, NULL))
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to format error message, last error was: " + dwError));
+ else
+ BOOST_THROW_EXCEPTION(std::runtime_error(mBuf));
+ }
+
+ return fIsElevated;
+}
#endif /* _WIN32 */
/**
static String GetRunAsGroup(void);
static void DeclareRunAsGroup(const String& group);
+#ifdef _WIN32
+ static bool IsProcessElevated(void);
+#endif /* _WIN32 */
+
static int GetRLimitFiles(void);
static int GetDefaultRLimitFiles(void);
static void DeclareRLimitFiles(int limit);
if (!configs.empty()) {
for (const String& configPath : configs) {
- Expression *expression = ConfigCompiler::CompileFile(configPath, String(), "_etc");
- success = ExecuteExpression(expression);
- delete expression;
- if (!success)
- return false;
+ try {
+ Expression *expression = ConfigCompiler::CompileFile(configPath, String(), "_etc");
+ success = ExecuteExpression(expression);
+ delete expression;
+ if (!success)
+ return false;
+ } catch (const std::exception& ex) {
+ Log(LogCritical, "cli", "Could not compile config files: " + DiagnosticInformation(ex, false));
+ Application::Exit(1);
+ }
}
}
}
ConfigCompilerContext::GetInstance()->FinishObjectsFile();
- ScriptGlobal::WriteToFile(varsfile);
+
+ try {
+ ScriptGlobal::WriteToFile(varsfile);
+ } catch (const std::exception& ex) {
+ Log(LogCritical, "cli", "Could not write vars file: " + DiagnosticInformation(ex, false));
+ Application::Exit(1);
+ }
return true;
}
#include "base/json.hpp"
#include "base/netstring.hpp"
#include "base/exception.hpp"
+#include "base/application.hpp"
using namespace icinga;
m_ObjectsPath = filename;
std::fstream *fp = new std::fstream();
- m_ObjectsTempFile = Utility::CreateTempFile(filename + ".XXXXXX", 0600, *fp);
+ try {
+ m_ObjectsTempFile = Utility::CreateTempFile(filename + ".XXXXXX", 0600, *fp);
+ } catch (const std::exception& ex) {
+ Log(LogCritical, "cli", "Could not create temporary objects file: " + DiagnosticInformation(ex, false));
+ Application::Exit(1);
+ }
if (!*fp)
BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + m_ObjectsTempFile + "' file"));