2using System.DirectoryServices.AccountManagement;
3using System.Runtime.Versioning;
4using System.Security.Principal;
6using System.Threading.Tasks;
8using Microsoft.Extensions.Logging;
9using Microsoft.Win32.SafeHandles;
20 [SupportedOSPlatform(
"windows")]
26 readonly ILogger<WindowsSystemIdentityFactory>
logger;
36 var splits = input.Split(
'\\');
37 username = splits.Length > 1 ? splits[1] : splits[0];
38 domainName = splits.Length > 1 ? splits[0] :
null;
47 this.logger =
logger ??
throw new ArgumentNullException(nameof(
logger));
57 ArgumentNullException.ThrowIfNull(user);
59 if (user.SystemIdentifier ==
null)
60 throw new InvalidOperationException(
"User's SystemIdentifier must not be null!");
62 PrincipalContext pc =
null;
63 UserPrincipal principal =
null;
67 bool TryGetPrincipalFromContextType(ContextType contextType)
71 pc = domainName !=
null
72 ?
new PrincipalContext(contextType, domainName)
73 :
new PrincipalContext(contextType);
74 cancellationToken.ThrowIfCancellationRequested();
75 principal = UserPrincipal.FindByIdentity(pc, user.SystemIdentifier);
77 catch (OperationCanceledException)
85 "Error loading user for context type {contextType} and principal \"{domainName}\"!",
91 if (principal ==
null)
94 cancellationToken.ThrowIfCancellationRequested();
98 return principal !=
null;
101 if (!TryGetPrincipalFromContextType(ContextType.Machine) && !TryGetPrincipalFromContextType(ContextType.Domain))
107 TaskScheduler.Current);
110 public Task<ISystemIdentity>
CreateSystemIdentity(
string username,
string password, CancellationToken cancellationToken) => Task.Factory.StartNew(
113 ArgumentNullException.ThrowIfNull(username);
114 ArgumentNullException.ThrowIfNull(password);
116 var originalUsername = username;
122 logger.LogTrace(
"Invalid system identity/password combo for username {0}!", originalUsername);
126 logger.LogTrace(
"Authenticated username {0} using system identity!", originalUsername);
129 using var handle =
new SafeAccessTokenHandle(token);
131 new WindowsIdentity(handle.DangerousGetHandle()));
135 TaskScheduler.Current);
IIOManager that resolves paths to Environment.CurrentDirectory.
const TaskCreationOptions BlockingTaskCreationOptions
The TaskCreationOptions used to spawn Tasks for potentially long running, blocking operations.
ISystemIdentityFactory for windows systems. Uses long running tasks due to potential networked domain...
static void GetUserAndDomainName(string input, out string username, out string domainName)
Extract the username and domain name from a string in the format "username\\domainname".
readonly ILogger< WindowsSystemIdentityFactory > logger
The ILogger for the WindowsSystemIdentityFactory.
WindowsSystemIdentityFactory(ILogger< WindowsSystemIdentityFactory > logger)
Initializes a new instance of the WindowsSystemIdentityFactory class.
Task< ISystemIdentity > CreateSystemIdentity(string username, string password, CancellationToken cancellationToken)
Create a ISystemIdentity for a given username and password. A new ISystemIdentity.
ISystemIdentity GetCurrent()
Retrieves a ISystemIdentity representing the user executing tgstation-server. A ISystemIdentity repre...
Task< ISystemIdentity > CreateSystemIdentity(User user, CancellationToken cancellationToken)
Create a ISystemIdentity for a given user . A new ISystemIdentity or null if the user has no ISystem...
ISystemIdentity for windows systems.
Native Windows methods used by the code.
static bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken)
See https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx.
Factory for ISystemIdentitys.
Represents a user on the current global::System.Runtime.InteropServices.OSPlatform.