diff options
| author | Dan Engelbrecht <[email protected]> | 2025-01-10 12:10:39 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2025-01-10 12:10:39 +0100 |
| commit | 997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e (patch) | |
| tree | 4c0ae961fe10bbd7701ffe49724de627701a6297 /src | |
| parent | use local service account for zen service (diff) | |
| download | zen-997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e.tar.xz zen-997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e.zip | |
make windows elevation optional
Diffstat (limited to 'src')
| -rw-r--r-- | src/zen/cmds/service_cmd.cpp | 200 | ||||
| -rw-r--r-- | src/zen/cmds/service_cmd.h | 2 |
2 files changed, 132 insertions, 70 deletions
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp index 294ed6bf8..0d538ffda 100644 --- a/src/zen/cmds/service_cmd.cpp +++ b/src/zen/cmds/service_cmd.cpp @@ -13,6 +13,10 @@ # include <shellapi.h> #endif +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC +# include <unistd.h> +#endif + ZEN_THIRD_PARTY_INCLUDES_START #include <gsl/gsl-lite.hpp> ZEN_THIRD_PARTY_INCLUDES_END @@ -22,76 +26,104 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { ////////////////////////////////////////////////////////////////////////// + +namespace { + #if ZEN_PLATFORM_WINDOWS -BOOL -WinIsElevated() -{ - BOOL fRet = FALSE; - HANDLE hToken = NULL; - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + BOOL IsElevated() { - TOKEN_ELEVATION Elevation; - DWORD cbSize = sizeof(TOKEN_ELEVATION); - if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) + BOOL fRet = FALSE; + HANDLE hToken = NULL; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - fRet = Elevation.TokenIsElevated; + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) + { + fRet = Elevation.TokenIsElevated; + } } + if (hToken) + { + CloseHandle(hToken); + } + return fRet; } - if (hToken) - { - CloseHandle(hToken); - } - return fRet; -} -int -WinRelaunchElevated() -{ - TCHAR CurrentDir[4096]; - GetCurrentDirectory(4096, CurrentDir); - - ExtendableWideStringBuilder<256> Parameters; - std::filesystem::path ExecutablePath = GetRunningExecutablePath(); - std::wstring CommandLine(GetCommandLine()); - std::string::size_type ExtraLength = CommandLine[0] == '\"' ? 2 : 0; - std::wstring CommandArguments = CommandLine.substr(ExecutablePath.string().length() + ExtraLength + 1); - - ZEN_CONSOLE("Attempting to run '{} {}' elevated...", ExecutablePath, WideToUtf8(CommandArguments)); - - SHELLEXECUTEINFO shExInfo = {0}; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE; - shExInfo.hwnd = 0; - shExInfo.lpVerb = TEXT("runas"); // Operation to perform - shExInfo.lpFile = ExecutablePath.c_str(); // Application to start - shExInfo.lpParameters = CommandArguments.c_str(); // Additional parameters - shExInfo.lpDirectory = CurrentDir; - shExInfo.nShow = SW_SHOW; - shExInfo.hInstApp = 0; - - DWORD ReturnCode = 1; - if (ShellExecuteEx(&shExInfo)) + int WinRelaunchElevated() { - WaitForSingleObject(shExInfo.hProcess, INFINITE); - GetExitCodeProcess(shExInfo.hProcess, &ReturnCode); - CloseHandle(shExInfo.hProcess); - if (ReturnCode == 0) + TCHAR CurrentDir[4096]; + GetCurrentDirectory(4096, CurrentDir); + + ExtendableWideStringBuilder<256> Parameters; + std::filesystem::path ExecutablePath = GetRunningExecutablePath(); + std::wstring CommandLine(GetCommandLine()); + std::string::size_type ExtraLength = CommandLine[0] == '\"' ? 2 : 0; + std::wstring CommandArguments = CommandLine.substr(ExecutablePath.string().length() + ExtraLength + 1); + + ZEN_CONSOLE("Attempting to run '{} {}' elevated...", ExecutablePath, WideToUtf8(CommandArguments)); + + SHELLEXECUTEINFO shExInfo = {0}; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE; + shExInfo.hwnd = 0; + shExInfo.lpVerb = TEXT("runas"); // Operation to perform + shExInfo.lpFile = ExecutablePath.c_str(); // Application to start + shExInfo.lpParameters = CommandArguments.c_str(); // Additional parameters + shExInfo.lpDirectory = CurrentDir; + shExInfo.nShow = SW_SHOW; + shExInfo.hInstApp = 0; + + DWORD ReturnCode = 1; + if (ShellExecuteEx(&shExInfo)) { - ZEN_CONSOLE("Elevated execution completed successfully."); + WaitForSingleObject(shExInfo.hProcess, INFINITE); + GetExitCodeProcess(shExInfo.hProcess, &ReturnCode); + CloseHandle(shExInfo.hProcess); + if (ReturnCode == 0) + { + ZEN_CONSOLE("Elevated execution completed successfully."); + } + else + { + ZEN_CONSOLE("Elevated execution completed unsuccessfully, return code: '{}'.", ReturnCode); + } } else { - ZEN_CONSOLE("Elevated execution completed unsuccessfully, return code: '{}'.", ReturnCode); + ZEN_CONSOLE("Failed to run elevated, operation did not complete."); } + return (int)ReturnCode; } - else + +#else // ZEN_PLATFORM_WINDOWS + + bool IsElevated() { return geteuid() == 0; } + +#endif // ZEN_PLATFORM_WINDOWS + + int RunElevated(bool AllowElevation) { - ZEN_CONSOLE("Failed to run elevated, operation did not complete."); +#if ZEN_PLATFORM_WINDOWS + if (AllowElevation) + { + return WinRelaunchElevated(); + } + else + { + ZEN_CONSOLE( + "This command requires elevated priviliges. Run command with elevated priviliges or add '--allow-elevation' command line " + "option."); + return 1; + } +#endif // ZEN_PLATFORM_WINDOWS +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + ZEN_CONSOLE("This command requires elevated priviliges. Run the command with `sudo`"); + return 1; +#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC } - return (int)ReturnCode; -} -#endif +} // namespace ServiceCommand::ServiceCommand() { @@ -141,6 +173,14 @@ ServiceCommand::ServiceCommand() "<description>"); m_InstallOptions.parse_positional({"executable", "name", "display-name"}); m_InstallOptions.positional_help("executable name display-name"); +#if ZEN_PLATFORM_WINDOWS + m_InstallOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS m_UninstallOptions.add_options()("h,help", "Print help"); m_UninstallOptions.add_option("", @@ -151,6 +191,14 @@ ServiceCommand::ServiceCommand() "<name>"); m_UninstallOptions.parse_positional({"name"}); m_UninstallOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_UninstallOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS m_StartOptions.add_options()("h,help", "Print help"); m_StartOptions.add_option("", @@ -161,6 +209,14 @@ ServiceCommand::ServiceCommand() "<name>"); m_StartOptions.parse_positional({"name"}); m_StartOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_StartOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS m_StopOptions.add_options()("h,help", "Print help"); m_StopOptions.add_option("", @@ -171,6 +227,14 @@ ServiceCommand::ServiceCommand() "<name>"); m_StopOptions.parse_positional({"name"}); m_StopOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_StopOptions.add_option("", + mak "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS } ServiceCommand::~ServiceCommand() = default; @@ -254,12 +318,11 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) return 1; } -#if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!IsElevated()) { - return WinRelaunchElevated(); + return RunElevated(m_AllowElevation); } -#endif // ZEN_PLATFORM_WINDOWS + if (m_ServerExecutable.empty()) { std::filesystem::path ExePath = zen::GetRunningExecutablePath(); @@ -300,12 +363,11 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) return 0; } -#if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!IsElevated()) { - return WinRelaunchElevated(); + return RunElevated(m_AllowElevation); } -#endif // ZEN_PLATFORM_WINDOWS + Ec = UninstallService(m_ServiceName); if (Ec) { @@ -335,12 +397,11 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) return 1; } -#if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!IsElevated()) { - return WinRelaunchElevated(); + return RunElevated(m_AllowElevation); } -#endif // ZEN_PLATFORM_WINDOWS + Ec = StartService(m_ServiceName); if (Ec) { @@ -370,12 +431,11 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) return 1; } -#if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!IsElevated()) { - return WinRelaunchElevated(); + return RunElevated(m_AllowElevation); } -#endif // ZEN_PLATFORM_WINDOWS + Ec = StopService(m_ServiceName); if (Ec) { diff --git a/src/zen/cmds/service_cmd.h b/src/zen/cmds/service_cmd.h index 15273e952..b247a63ce 100644 --- a/src/zen/cmds/service_cmd.h +++ b/src/zen/cmds/service_cmd.h @@ -27,6 +27,8 @@ private: std::string m_ServiceName = "ZenServer"; + bool m_AllowElevation = false; + cxxopts::Options m_StatusOptions{"status", "Show information about an installed zenserver service"}; cxxopts::Options m_InstallOptions{ |