I'm trying to impersonate a user account in a .NET console application and when it reaches the point where I call the Impersonate() method, the application seems to exit instantly. The method call is in a try-catch block, but it never even reaches the 'catch' block so I can't see what the error was!
Here's the relevant code:
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
And then at the start of my application:
bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref m_tokenHandle);
if (!returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
// Impersonate
WindowsIdentity _identity = new WindowsIdentity(m_tokenHandle);
EmailHelper.SendErrorMessage("Windows Identity Created!", string.Format("Created at: {0}", DateTime.Now.ToLongTimeString()));
try
{
m_impersonatedUser = _identity.Impersonate();
EmailHelper.SendErrorMessage("Impersonation Complete...", string.Format("Impersonation at: {0}", DateTime.Now.ToLongTimeString()));
}
catch
{
int ret = Marshal.GetLastWin32Error();
EmailHelper.SendErrorMessage("Error impersonating user!", string.Format("Error: {0}", ret));
}
finally
{
EmailHelper.SendErrorMessage("Finally block executed?!", "What is going on?");
}
I'm getting the initial "Windows identity created" email but not any of the others! Does anyone know how I can find out what my underlying error is and why my impersonation isn't working?
Thanks!
EDIT:
I tried the code from this MSDN article: http://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.110).aspx with the only modification being trying to create a file when impersonating.
The modification was changing this code:
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
// Check the identity.
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
}
To:
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
// Check the identity.
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
System.IO.File.CreateText(@"Test.txt");
}
The output I am getting when running the exe as a "standard" user says that LogonUser succeeded, WindowsIdentity.GetCurrent().Name returns the impersonated user name but creating the file fails with error code 1346, which, according to MSDN, is:
ERROR_BAD_IMPERSONATION_LEVEL 1346 (0x542) Either a required impersonation level was not provided, or the provided impersonation level is invalid.
What does that mean? Google hasn't been able to shed any light on it yet...
EDIT 2:
I can impersonate another standard user account using this code, but when I try to impersonate my admin account it fails. Is it possible to change the code somehow to allow a standard user running this exe to impersonate an admin account?