diff --git a/TGServerService/Administration.cs b/TGServerService/Administration.cs
index bc9f171782..1040501497 100644
--- a/TGServerService/Administration.cs
+++ b/TGServerService/Administration.cs
@@ -6,132 +6,153 @@ using TGServiceInterface;
namespace TGServerService
{
- //note this only works with MACHINE LOCAL groups and admins for now
- //if someone wants AD shit, code it yourself
- partial class TGStationServer : ServiceAuthorizationManager, ITGAdministration
- {
- SecurityIdentifier TheDroidsWereLookingFor;
- object authLock = new object();
- string LastSeenUser = null;
+ //note this only works with MACHINE LOCAL groups and admins for now
+ //if someone wants AD shit, code it yourself
+ partial class TGStationServer : ServiceAuthorizationManager, ITGAdministration
+ {
+ SecurityIdentifier TheDroidsWereLookingFor;
+ object authLock = new object();
+ string LastSeenUser = null;
- ///
- public string GetCurrentAuthorizedGroup()
- {
- try
- {
- if (TheDroidsWereLookingFor == null)
- return "ADMIN";
+ readonly SecurityIdentifier ServiceSID = UserPrincipal.Current.Sid;
- var pc = new PrincipalContext(ContextType.Machine);
- return GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value).Name;
- }
- catch
- {
- return null;
- }
- }
+ ///
+ public string GetCurrentAuthorizedGroup()
+ {
+ try
+ {
+ if (TheDroidsWereLookingFor == null)
+ return "ADMIN";
- ///
- public string SetAuthorizedGroup(string groupName)
- {
- if(groupName == null)
- {
- TheDroidsWereLookingFor = null;
- var config = Properties.Settings.Default;
- config.AuthorizedGroupSID = null;
- config.Save();
- return "ADMIN";
- }
- return FindTheDroidsWereLookingFor(groupName);
- }
+ var pc = new PrincipalContext(ContextType.Machine);
+ return GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value).Name;
+ }
+ catch
+ {
+ return null;
+ }
+ }
- string FindTheDroidsWereLookingFor(string search = null)
- {
- //find the group that is authorized to use the tools
- var pc = new PrincipalContext(ContextType.Machine);
- var config = Properties.Settings.Default;
- var groupName = search ?? config.AuthorizedGroupSID;
- if (String.IsNullOrWhiteSpace(groupName))
- return null;
- var gp = GroupPrincipal.FindByIdentity(pc, search != null ? IdentityType.Name : IdentityType.Sid, groupName);
- if (gp == null)
- {
- if (search != null)
- //try again with all types
- gp = GroupPrincipal.FindByIdentity(pc, search);
- if (gp == null)
- return null;
- }
- TheDroidsWereLookingFor = gp.Sid;
- if (search != null)
- {
- config.AuthorizedGroupSID = TheDroidsWereLookingFor.Value;
- config.Save();
- }
- return gp.Name;
- }
+ ///
+ public string SetAuthorizedGroup(string groupName)
+ {
+ if (groupName == null)
+ {
+ TheDroidsWereLookingFor = null;
+ var config = Properties.Settings.Default;
+ config.AuthorizedGroupSID = null;
+ config.Save();
+ return "ADMIN";
+ }
+ return FindTheDroidsWereLookingFor(groupName);
+ }
- //This function checks for authorization whenever an API call is made
- //This does NOT validate the windows account, that is done when the user connects internally
- protected override bool CheckAccessCore(OperationContext operationContext)
- {
- if (operationContext.EndpointDispatcher.ContractName == typeof(ITGConnectivity).Name) //always allow connectivity checks
- return true;
+ string FindTheDroidsWereLookingFor(string search = null)
+ {
+ //find the group that is authorized to use the tools
+ var pc = new PrincipalContext(ContextType.Machine);
+ var config = Properties.Settings.Default;
+ var groupName = search ?? config.AuthorizedGroupSID;
+ if (String.IsNullOrWhiteSpace(groupName))
+ return null;
+ var gp = GroupPrincipal.FindByIdentity(pc, search != null ? IdentityType.Name : IdentityType.Sid, groupName);
+ if (gp == null)
+ {
+ if (search != null)
+ //try again with all types
+ gp = GroupPrincipal.FindByIdentity(pc, search);
+ if (gp == null)
+ return null;
+ }
+ TheDroidsWereLookingFor = gp.Sid;
+ if (search != null)
+ {
+ config.AuthorizedGroupSID = TheDroidsWereLookingFor.Value;
+ config.Save();
+ }
+ return gp.Name;
+ }
- var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity;
- var wp = new WindowsPrincipal(windowsIdent);
- //first allow admins
- var authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator);
+ static UserPrincipal WindowsIdentityToUserPrincipal(WindowsIdentity windowsIdent, out PrincipalContext pc)
+ {
+ pc = new PrincipalContext(ContextType.Machine);
+ var up = UserPrincipal.FindByIdentity(pc, IdentityType.Sid, windowsIdent.User.Value);
+ //tiny bit of ad support here just cause i was debugging at work
+ //if up is null check it on a domain
+ if (up == null)
+ try
+ {
+ up = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), IdentityType.Sid, windowsIdent.User.Value);
+ }
+ catch { }
+ return up;
+ }
- //if we're not an admin, check that we aren't trying to access the admin interface
- if (!authSuccess && operationContext.EndpointDispatcher.ContractName != typeof(ITGAdministration).Name && TheDroidsWereLookingFor != null)
- {
- var pc = new PrincipalContext(ContextType.Machine);
- var up = UserPrincipal.FindByIdentity(pc, IdentityType.Sid, windowsIdent.User.Value);
- //tiny bit of ad support here just cause i was debugging at work
- //if up is null check it on a domain
- if (up == null)
- try
- {
- up = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), IdentityType.Sid, windowsIdent.User.Value);
- }
- catch { }
- if (up != null)
- {
- var gp = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value);
- if (gp != null)
- {
- //and allow those in the authorized group
- authSuccess = up.IsMemberOf(gp);
- }
- }
- }
- lock (authLock)
- {
- var user = operationContext.ServiceSecurityContext.WindowsIdentity.Name;
- if (LastSeenUser != user) {
- LastSeenUser = user;
- TGServerService.WriteAccess(user, authSuccess);
- }
- }
- return authSuccess;
- }
+ //This function checks for authorization whenever an API call is made
+ //This does NOT validate the windows account, that is done when the user connects internally
+ protected override bool CheckAccessCore(OperationContext operationContext)
+ {
+ if (operationContext.EndpointDispatcher.ContractName == typeof(ITGConnectivity).Name) //always allow connectivity checks
+ return true;
- ///
- public ushort RemoteAccessPort()
- {
- return Properties.Settings.Default.RemoteAccessPort;
- }
+ var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity;
+ var wp = new WindowsPrincipal(windowsIdent);
- ///
- public string SetRemoteAccessPort(ushort port)
- {
- if (port == 0)
- return "Cannot bind to port 0";
- var Config = Properties.Settings.Default;
- Config.RemoteAccessPort = port;
- Config.Save();
- return null;
- }
- }
+ bool authSuccess;
+ var isInterop = operationContext.EndpointDispatcher.ContractName == typeof(ITGInterop).Name;
+ if (isInterop)
+ {
+ //only DD is allowed to use Interop
+ //make sure it's from the same windows account
+ var up = WindowsIdentityToUserPrincipal(windowsIdent, out PrincipalContext pc);
+ authSuccess = up.Sid != ServiceSID;
+ }
+ else
+ //first allow admins
+ authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator);
+
+ //if we're not an admin, check that we aren't trying to access the admin interface
+ if (!authSuccess && operationContext.EndpointDispatcher.ContractName != typeof(ITGAdministration).Name && TheDroidsWereLookingFor != null)
+ {
+ var up = WindowsIdentityToUserPrincipal(windowsIdent, out PrincipalContext pc);
+ if (up != null)
+ {
+ var gp = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value);
+ if (gp != null)
+ {
+ //and allow those in the authorized group
+ authSuccess = up.IsMemberOf(gp);
+ }
+ }
+ }
+ if (!isInterop)
+ lock (authLock)
+ {
+ var user = operationContext.ServiceSecurityContext.WindowsIdentity.Name;
+ if (LastSeenUser != user)
+ {
+ LastSeenUser = user;
+ TGServerService.WriteAccess(user, authSuccess);
+ }
+ }
+ return authSuccess;
+ }
+
+ ///
+ public ushort RemoteAccessPort()
+ {
+ return Properties.Settings.Default.RemoteAccessPort;
+ }
+
+ ///
+ public string SetRemoteAccessPort(ushort port)
+ {
+ if (port == 0)
+ return "Cannot bind to port 0";
+ var Config = Properties.Settings.Default;
+ Config.RemoteAccessPort = port;
+ Config.Save();
+ return null;
+ }
+ }
}