mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-25 05:56:58 +01:00
Merge pull request #196 from Cyberboss/ConfigACLImpersonation
Config editing now impersonates the calling windows user. Moves MoveServer() to ITGAdministration
This commit is contained in:
@@ -9,14 +9,39 @@ namespace TGCommandLine
|
||||
public AdminCommand()
|
||||
{
|
||||
Keyword = "admin";
|
||||
Children = new Command[] { new AdminViewGroupCommand(), new AdminSetGroupCommand(), new AdminClearGroupCommand(), new AdminViewPortCommand(), new AdminSetPortCommand() };
|
||||
Children = new Command[] { new AdminViewGroupCommand(), new AdminSetGroupCommand(), new AdminClearGroupCommand(), new AdminViewPortCommand(), new AdminSetPortCommand(), new AdminMoveServerCommand() };
|
||||
}
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Manage server service authentication";
|
||||
}
|
||||
}
|
||||
|
||||
class AdminMoveServerCommand : Command
|
||||
{
|
||||
public AdminMoveServerCommand()
|
||||
{
|
||||
Keyword = "move-server";
|
||||
RequiredParameters = 1;
|
||||
}
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Server.GetComponent<ITGAdministration>().MoveServer(parameters[0]);
|
||||
OutputProc(res ?? "Success");
|
||||
return res == null ? ExitCode.Normal : ExitCode.ServerError;
|
||||
}
|
||||
|
||||
public override string GetArgumentString()
|
||||
{
|
||||
return "<new path>";
|
||||
}
|
||||
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Move the server installation (BYOND, Repo, Game) to a new location. Nothing else may be running for this task to complete";
|
||||
}
|
||||
}
|
||||
|
||||
class AdminSetPortCommand : Command
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace TGCommandLine
|
||||
public ConfigCommand()
|
||||
{
|
||||
Keyword = "config";
|
||||
Children = new Command[] { new ConfigMoveServerCommand(), new ConfigServerDirectoryCommand(), new ConfigDownloadCommand(), new ConfigUploadCommand() };
|
||||
Children = new Command[] { new ConfigServerDirectoryCommand(), new ConfigDownloadCommand(), new ConfigUploadCommand() };
|
||||
}
|
||||
public override string GetHelpText()
|
||||
{
|
||||
@@ -18,32 +18,6 @@ namespace TGCommandLine
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigMoveServerCommand : Command
|
||||
{
|
||||
public ConfigMoveServerCommand()
|
||||
{
|
||||
Keyword = "move-server";
|
||||
RequiredParameters = 1;
|
||||
}
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Server.GetComponent<ITGConfig>().MoveServer(parameters[0]);
|
||||
OutputProc(res ?? "Success");
|
||||
return res == null ? ExitCode.Normal : ExitCode.ServerError;
|
||||
}
|
||||
|
||||
public override string GetArgumentString()
|
||||
{
|
||||
return "<new path>";
|
||||
}
|
||||
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Move the server installation (BYOND, Repo, Game) to a new location. Nothing else may be running for this task to complete";
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigServerDirectoryCommand : Command
|
||||
{
|
||||
public ConfigServerDirectoryCommand()
|
||||
|
||||
@@ -88,13 +88,17 @@ namespace TGControlPanel
|
||||
|
||||
void UpdateServerPath()
|
||||
{
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
if (updatingFields || ServerPathTextbox.Text.Trim() == Config.ServerDirectory())
|
||||
if (!Server.AuthenticateAdmin())
|
||||
{
|
||||
MessageBox.Show("Only system administrators may move the server installation");
|
||||
return;
|
||||
}
|
||||
if (updatingFields || ServerPathTextbox.Text.Trim() == Server.GetComponent<ITGConfig>().ServerDirectory())
|
||||
return;
|
||||
var DialogResult = MessageBox.Show("This will move the entire server installation.", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult != DialogResult.Yes)
|
||||
return;
|
||||
MessageBox.Show(Config.MoveServer(ServerPathTextbox.Text) ?? "Success!");
|
||||
MessageBox.Show(Server.GetComponent<ITGAdministration>().MoveServer(ServerPathTextbox.Text) ?? "Success!");
|
||||
}
|
||||
|
||||
void LoadServerPage()
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.DirectoryServices.AccountManagement;
|
||||
using System.IO;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceModel;
|
||||
using System.Threading;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGServerService
|
||||
@@ -123,5 +125,119 @@ namespace TGServerService
|
||||
Config.Save();
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string MoveServer(string new_location)
|
||||
{
|
||||
var Config = Properties.Settings.Default;
|
||||
try
|
||||
{
|
||||
var di1 = new DirectoryInfo(Config.ServerDirectory);
|
||||
var di2 = new DirectoryInfo(new_location);
|
||||
|
||||
var copy = di1.Root.FullName != di2.Root.FullName;
|
||||
|
||||
if (copy && File.Exists(PrivateKeyPath))
|
||||
return String.Format("Unable to perform a cross drive server move with the {0}. Copy aborted!", PrivateKeyPath);
|
||||
|
||||
new_location = di2.FullName;
|
||||
|
||||
while (di2.Parent != null)
|
||||
if (di2.Parent.FullName == di1.FullName)
|
||||
return "Cannot move to child of current directory!";
|
||||
else
|
||||
di2 = di2.Parent;
|
||||
|
||||
if (!Monitor.TryEnter(RepoLock))
|
||||
return "Repo locked!";
|
||||
try
|
||||
{
|
||||
if (RepoBusy)
|
||||
return "Repo busy!";
|
||||
DisposeRepo();
|
||||
if (!Monitor.TryEnter(ByondLock))
|
||||
return "BYOND locked";
|
||||
try
|
||||
{
|
||||
if (updateStat != TGByondStatus.Idle)
|
||||
return "BYOND busy!";
|
||||
if (!Monitor.TryEnter(CompilerLock))
|
||||
return "Compiler locked!";
|
||||
|
||||
try
|
||||
{
|
||||
if (compilerCurrentStatus != TGCompilerStatus.Uninitialized && compilerCurrentStatus != TGCompilerStatus.Initialized)
|
||||
return "Compiler busy!";
|
||||
if (!Monitor.TryEnter(watchdogLock))
|
||||
return "Watchdog locked!";
|
||||
try
|
||||
{
|
||||
if (currentStatus != TGDreamDaemonStatus.Offline)
|
||||
return "Watchdog running!";
|
||||
lock (configLock)
|
||||
{
|
||||
CleanGameFolder();
|
||||
Program.DeleteDirectory(GameDir);
|
||||
string error = null;
|
||||
if (copy)
|
||||
{
|
||||
Program.CopyDirectory(Config.ServerDirectory, new_location);
|
||||
Directory.CreateDirectory(new_location);
|
||||
Environment.CurrentDirectory = new_location;
|
||||
try
|
||||
{
|
||||
Program.DeleteDirectory(Config.ServerDirectory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = "The move was successful, but the path " + Config.ServerDirectory + " was unable to be deleted fully!";
|
||||
TGServerService.WriteWarning(String.Format("Server move from {0} to {1} partial success: {2}", Config.ServerDirectory, new_location, e.ToString()), TGServerService.EventID.ServerMovePartial);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Environment.CurrentDirectory = di2.Root.FullName;
|
||||
Directory.Move(Config.ServerDirectory, new_location);
|
||||
Environment.CurrentDirectory = new_location;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Environment.CurrentDirectory = Config.ServerDirectory;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
TGServerService.WriteInfo(String.Format("Server moved from {0} to {1}", Config.ServerDirectory, new_location), TGServerService.EventID.ServerMoveComplete);
|
||||
Config.ServerDirectory = new_location;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(watchdogLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(CompilerLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(ByondLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(RepoLock);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TGServerService.WriteError(String.Format("Server move from {0} to {1} failed: {2}", Config.ServerDirectory, new_location, e.ToString()), TGServerService.EventID.ServerMoveFailed);
|
||||
return e.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-117
@@ -2,8 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TGServiceInterface;
|
||||
using System.ServiceModel;
|
||||
using System.Threading;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGServerService
|
||||
{
|
||||
@@ -11,121 +12,6 @@ namespace TGServerService
|
||||
partial class TGStationServer : ITGConfig
|
||||
{
|
||||
object configLock = new object(); //for atomic reads/writes
|
||||
|
||||
//public api
|
||||
public string MoveServer(string new_location)
|
||||
{
|
||||
var Config = Properties.Settings.Default;
|
||||
try
|
||||
{
|
||||
var di1 = new DirectoryInfo(Config.ServerDirectory);
|
||||
var di2 = new DirectoryInfo(new_location);
|
||||
|
||||
var copy = di1.Root.FullName != di2.Root.FullName;
|
||||
|
||||
if (copy && File.Exists(PrivateKeyPath))
|
||||
return String.Format("Unable to perform a cross drive server move with the {0}. Copy aborted!", PrivateKeyPath);
|
||||
|
||||
new_location = di2.FullName;
|
||||
|
||||
while (di2.Parent != null)
|
||||
if (di2.Parent.FullName == di1.FullName)
|
||||
return "Cannot move to child of current directory!";
|
||||
else
|
||||
di2 = di2.Parent;
|
||||
|
||||
if (!Monitor.TryEnter(RepoLock))
|
||||
return "Repo locked!";
|
||||
try
|
||||
{
|
||||
if (RepoBusy)
|
||||
return "Repo busy!";
|
||||
DisposeRepo();
|
||||
if (!Monitor.TryEnter(ByondLock))
|
||||
return "BYOND locked";
|
||||
try
|
||||
{
|
||||
if (updateStat != TGByondStatus.Idle)
|
||||
return "BYOND busy!";
|
||||
if (!Monitor.TryEnter(CompilerLock))
|
||||
return "Compiler locked!";
|
||||
|
||||
try
|
||||
{
|
||||
if (compilerCurrentStatus != TGCompilerStatus.Uninitialized && compilerCurrentStatus != TGCompilerStatus.Initialized)
|
||||
return "Compiler busy!";
|
||||
if (!Monitor.TryEnter(watchdogLock))
|
||||
return "Watchdog locked!";
|
||||
try
|
||||
{
|
||||
if (currentStatus != TGDreamDaemonStatus.Offline)
|
||||
return "Watchdog running!";
|
||||
lock (configLock)
|
||||
{
|
||||
CleanGameFolder();
|
||||
Program.DeleteDirectory(GameDir);
|
||||
string error = null;
|
||||
if (copy)
|
||||
{
|
||||
Program.CopyDirectory(Config.ServerDirectory, new_location);
|
||||
Directory.CreateDirectory(new_location);
|
||||
Environment.CurrentDirectory = new_location;
|
||||
try
|
||||
{
|
||||
Program.DeleteDirectory(Config.ServerDirectory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = "The move was successful, but the path " + Config.ServerDirectory + " was unable to be deleted fully!";
|
||||
TGServerService.WriteWarning(String.Format("Server move from {0} to {1} partial success: {2}", Config.ServerDirectory, new_location, e.ToString()), TGServerService.EventID.ServerMovePartial);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Environment.CurrentDirectory = di2.Root.FullName;
|
||||
Directory.Move(Config.ServerDirectory, new_location);
|
||||
Environment.CurrentDirectory = new_location;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Environment.CurrentDirectory = Config.ServerDirectory;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
TGServerService.WriteInfo(String.Format("Server moved from {0} to {1}", Config.ServerDirectory, new_location), TGServerService.EventID.ServerMoveComplete);
|
||||
Config.ServerDirectory = new_location;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(watchdogLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(CompilerLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(ByondLock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(RepoLock);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TGServerService.WriteError(String.Format("Server move from {0} to {1} failed: {2}", Config.ServerDirectory, new_location, e.ToString()), TGServerService.EventID.ServerMoveFailed);
|
||||
return e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
//public api
|
||||
public string ServerDirectory()
|
||||
{
|
||||
@@ -133,6 +19,7 @@ namespace TGServerService
|
||||
}
|
||||
|
||||
//public api
|
||||
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
|
||||
public string ReadText(string staticRelativePath, bool repo, out string error)
|
||||
{
|
||||
try
|
||||
@@ -197,7 +84,7 @@ namespace TGServerService
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
|
||||
public string WriteText(string staticRelativePath, string data)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -38,5 +38,13 @@ namespace TGServiceInterface
|
||||
/// <returns>The name of the windows group that is now authorized to use the service on success, null on failure, "ADMIN" on clearing</returns>
|
||||
[OperationContract]
|
||||
string SetAuthorizedGroup(string groupName);
|
||||
|
||||
/// <summary>
|
||||
/// Moves the entire server installation, requires no operations to be running
|
||||
/// </summary>
|
||||
/// <param name="new_location">The new path to place the server</param>
|
||||
/// <returns>null on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string MoveServer(string new_location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,6 @@ namespace TGServiceInterface
|
||||
[OperationContract]
|
||||
string ServerDirectory();
|
||||
|
||||
/// <summary>
|
||||
/// Moves the entire server installation, requires no operations to be running
|
||||
/// </summary>
|
||||
/// <param name="new_location">The new path to place the server</param>
|
||||
/// <returns>null on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string MoveServer(string new_location);
|
||||
|
||||
/// <summary>
|
||||
/// For when you really just need to see the raw data of the config
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user