Skip to content

Instantly share code, notes, and snippets.

@mxmissile
Created May 15, 2014 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mxmissile/8f2ef5ed3f5687e9053f to your computer and use it in GitHub Desktop.
Save mxmissile/8f2ef5ed3f5687e9053f to your computer and use it in GitHub Desktop.
public class Impersonation : IDisposable
{
public Impersonation(string username, string password, string domain)
{
try
{
IntPtr tokenHandle; // = IntPtr.Zero;
Int32 ret;
if (
!LogonUser(username, domain, password, LogonType.Interactive, LogonProvider.Default, out tokenHandle))
{
ret = Marshal.GetLastWin32Error();
if (ret != 0)
throw new Exception("LogonUser; GetLastError Return Code: " + ret);
}
if (!ImpersonateLoggedOnUser(tokenHandle))
{
ret = Marshal.GetLastWin32Error();
if (ret != 0)
throw new Exception("ImpersonateLoggedOnUser; GetLastError Return Code: " + ret);
}
}
catch (Exception ex)
{
throw new Exception("Problem Beginning Impersonation", ex);
}
}
#region LogonUser-Related Enum Values
/// <summary>Used for the impersonation API calls.</summary>
private enum LogonType
{
/// <summary>Interactive logon type</summary>
Interactive = 2,
/// <summary>Network logon type</summary>
Network,
/// <summary>Batch logon type</summary>
Batch,
/// <summary>Service logon type</summary>
Service
}
/// <summary>Used for the impersonation API calls.</summary>
private enum LogonProvider
{
/// <summary>Default logon provider</summary>
Default,
/// <summary>NT 3.5 logon provider</summary>
WinNT35
}
#endregion
#region Win32 DLL Imports
/// <summary>Internal windows function used for loging in as a user</summary>
/// <param name="lpszUsername">The user name of the user to log in as</param>
/// <param name="lpszDomain">The domain the user is in</param>
/// <param name="lpszPassword">The users password</param>
/// <param name="dwLogonType">Method of logging in. <see cref="LogonType"/></param>
/// <param name="dwLogonProvider">Which provider to log in with. <see cref="LogonProvider"/></param>
/// <param name="phToken">Token returned that points to the user. Needed for impersonation</param>
/// <returns>False for success True for error</returns>
[DllImport("advapi32.dll")]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
LogonType dwLogonType, LogonProvider dwLogonProvider, out IntPtr phToken);
/// <summary>Internal windows function used for assuming the identity of a user</summary>
/// <param name="hToken">Token returned from LogonUser</param>
/// <returns>False for sucess True for error</returns>
/// <seealso cref="LogonUser"/>
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
/// <summary>Internal windows function used to stop impersonating</summary>
/// <returns>False for sucess True for error</returns>
/// <seealso cref="ImpersonateLoggedOnUser"/>
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool RevertToSelf();
#endregion
public void Dispose()
{
try
{
if (!RevertToSelf())
{
Int32 ret = Marshal.GetLastWin32Error();
if (ret != 0)
throw new Exception("RevertToSelf; GetLastError Return Code: " + ret);
}
}
catch (Exception ex)
{
throw new Exception("Problem Ending Impersonation", ex);
}
}
}
using(new Impersonation("username","domain","password"))
{
//code to run under impersonated user
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment