I can't seem to start a process as another user when using impersonation under .Net Core.
I'm running this script in Linqpad running as User1 and trying to launch a program as User2.
At first, the impersonation seems to work (the Console.Writeline()
s on the current user change correctly from User1 to User2 in the RunImpersonated()
Method). However, the process always runs as User1.
This is one of many tests I'm doing to validate that RunImpersonated()
works (this originally stems from issues in an ASP.Net Core App trying to impersonate the current user). This is the simplest reproducible example I could find.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);
void Main()
{
string domainName = "myDomain";
string userName = "User2";
string passWord = "User2Password";
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
SafeAccessTokenHandle safeAccessTokenHandle;
bool returnValue = LogonUser(userName, domainName, passWord,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new System.ComponentModel.Win32Exception(ret);
}
Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
// Check the identity.
Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
// Note: if you want to run as unimpersonated, pass
// 'SafeAccessTokenHandle.InvalidHandle' instead of variable 'safeAccessTokenHandle'
WindowsIdentity.RunImpersonated(
safeAccessTokenHandle,
// User action
() =>
{
// Check the identity.
Console.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);
Directory.GetFiles(@"C:\TMP\").Dump();
var pi = new ProcessStartInfo
{
WorkingDirectory = @"C:\TMP\",
FileName = @"C:\TMP\TestUser.exe"
};
var proc = Process.Start(pi);
proc.WaitForExit();
}
);
// Check the identity again.
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
}