aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-01-10 12:10:39 +0100
committerDan Engelbrecht <[email protected]>2025-01-10 12:10:39 +0100
commit997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e (patch)
tree4c0ae961fe10bbd7701ffe49724de627701a6297 /src
parentuse local service account for zen service (diff)
downloadzen-997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e.tar.xz
zen-997c23cd9b6a7c21a4cfc1744ec338e9ee55b36e.zip
make windows elevation optional
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/service_cmd.cpp200
-rw-r--r--src/zen/cmds/service_cmd.h2
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{