Merge pull request #196 from Cyberboss/ConfigACLImpersonation

Config editing now impersonates the calling windows user. Moves MoveServer() to ITGAdministration
This commit is contained in:
Jordan Brown
2017-09-21 11:32:44 -04:00
committed by GitHub
7 changed files with 162 additions and 156 deletions
+26 -1
View File
@@ -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
{
+1 -27
View File
@@ -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()
+7 -3
View File
@@ -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()
+116
View File
@@ -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
View File
@@ -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
+8
View File
@@ -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);
}
}
-8
View File
@@ -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>