Impersonation - Access is denied
- by krisg
I am having trouble using impersonation to delete a PerformanceCounterCategory from an MVC website. I have a static class and when the application starts it checks whether or not a PerformanceCounterCategory exists, and if it contains the correct counters. If not, it deletes the category and creates it again with the required counters.
It works fine when running under the built in webserver Cassini, but when i try run it through IIS7 (Vista) i get the following error:
Access is denied
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.ComponentModel.Win32Exception: Access is denied
The code used is from an MS article, from memory...
var username = "user";
var password = "password";
var domain = "tempuri.org";
WindowsImpersonationContext impersonationContext;
// if impersonation fails - return
if (!ImpersonateValidUser(username, password, domain, out impersonationContext))
{
throw new AuthenticationException("Impersonation failed");
}
PerformanceCounterCategory.Delete(PerfCategory);
UndoImpersonation(impersonationContext);
...
private static bool ImpersonateValidUser(string username, string password,
string domain, out WindowsImpersonationContext impersonationContext)
{
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsIdentity tempWindowsIdentity;
var token = IntPtr.Zero;
var tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(username, domain, password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
impersonationContext = null;
return false;
}
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName, String lpszDomain,
String lpszPassword, int dwLogonType, int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
The error is thrown when processing tries to execute the PerformanceCounterCategory.Delete command.
Suggestions?