
I forgot, this is the exact code that handles the impersonation. I can't find
the original article which had this....
using System;
using System.Web;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
namespace EnterpriseUtilities
{
/// <summary>
/// used for connecting to other Logon Providers
/// </summary>
public enum LogonProvider
{
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT50 = 3
}
/// <summary>
/// Used to change the level of impersonation on remote systems
/// </summary>
public enum ImpersonationLevel
{
SecurityAnonymous = 0,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
public enum LogonTypes
{
//logon types
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
// Windows2000
LOGON32_LOGON_NETWORK_CLEARPASSWORD = 8,
LOGON32_LOGON_NEW_CREDENTIALS = 9
}
/// <summary>
/// Impersonate a specific user in the domain.
/// Note that the user account on the calling process must have
/// the SE_TCB_NAME priviledge when running on W2k.
/// This can be given using Local Policy MMC and adding account to
/// "Act as Part of the Operationg System". For ASP.NET applications the
calling
/// user context is usually ASPNET user.
/// </summary>
public class Impersonate
{
#region Dll Imports
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public extern static bool DuplicateToken(IntPtr hToken, int
impersonationLevel, ref IntPtr hNewToken);
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern int ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("advapi32.dll", SetLastError=true)]
static extern int RevertToSelf();
#endregion
#region MEMBER VARIABLES
private IntPtr token = IntPtr.Zero;
private IntPtr dupToken = IntPtr.Zero;
private LogonProvider _logonProvider;
private ImpersonationLevel _impersonationLevel;
private string _originalUser = Thread.CurrentPrincipal.Identity.Name;
private LogonTypes _logonType;
private bool impersonated = false;
#endregion
#region CONTRUCTORS
public Impersonate(LogonProvider logonProvider, ImpersonationLevel level,
LogonTypes logonType)
{
this._logonProvider = logonProvider;
this._impersonationLevel = level;
this._logonType = logonType;
}
public Impersonate(LogonProvider logonProvider, ImpersonationLevel level)
public Impersonate(LogonProvider logonProvider) : this (logonProvider,
ImpersonationLevel.SecurityImpersonation, LogonTypes.LOGON32_LOGON_NETWORK) {}
public Impersonate() : this(LogonProvider.LOGON32_PROVIDER_DEFAULT,
ImpersonationLevel.SecurityImpersonation, LogonTypes.LOGON32_LOGON_NETWORK) {}
#endregion
#region PUBLIC PROPERTIES
public ImpersonationLevel Level
{
get { return this._impersonationLevel; }
set { this._impersonationLevel = value; }
}
public LogonTypes LogonType
{
get { return this._logonType; }
set { this._logonType = value; }
}
public string CurrentIdentity
{
get
{
return Thread.CurrentPrincipal.Identity.Name;
}
}
/// <summary>
/// Property returns whether or not an impersonation is occurring
/// </summary>
public bool Impersonating
{
get
{
return this.CurrentIdentity != this._originalUser;
}
}
#endregion
#region PUBLIC METHODS
/// <summary>
/// Impersonates a specific user in the domain. This changes the process
/// identity to the impersonated user's security context.
/// </summary>
/// Domain name
/// Login ID
/// Password
public void ImpersonateUser(string domain, string username, string password)
{
ImpersonateUser(domain, username, password, false);
}
/// <summary>
/// Impersonates a specific user in the domain. This changes the process
/// identity to the impersonated user's security context.
/// </summary>
/// Domain name
/// Login ID
/// Password
/// Do not process impersonisation.
public void ImpersonateUser(string domain, string username, string
password, bool justLogon)
{
if (Impersonating) throw new System.Security.SecurityException("You are
already impersonating " + CurrentIdentity);
impersonated = LogonUser(username,
domain,
password,
(int)_logonType,
(int)_logonProvider,
ref token);
//check the error
if(!impersonated) throw new Win32Exception(Marshal.GetLastWin32Error());
if (!justLogon) ImpersonateLoggedOnUser(token);
}
/// <summary>
/// Reverts back to the original process identity.
/// </summary>
public void UndoImpersonation()
{
if (impersonated) RevertToSelf();
if (token != IntPtr.Zero) CloseHandle(token);
if (dupToken != IntPtr.Zero) CloseHandle(dupToken);
}
#endregion
}
}