using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute
namespace Impersonate
{
// group type enum
public enum SECURITY_IMPERSONATION_LEVEL : int
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
// obtains user token
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// creates duplicate token handle
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblCurrentUser;
private System.Windows.Forms.TextBox textBoxUsername;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox textBoxPassword;
private System.Windows.Forms.Button buttonLogon;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox textBoxDomain;
private System.Security.Principal.WindowsImpersonationContext newUser;
private System.Windows.Forms.Button buttonRevert;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
// set logged on username
lblCurrentUser.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
// populate logon domain name
string sTempUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
if (sTempUser.IndexOf("\\") != -1)
{
string[] aryUser = new String[2];
char[] splitter = {'\\'};
aryUser = sTempUser.Split(splitter);
textBoxDomain.Text = aryUser[0];
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.lblCurrentUser = new System.Windows.Forms.Label();
this.textBoxUsername = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.textBoxPassword = new System.Windows.Forms.TextBox();
this.buttonLogon = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.textBoxDomain = new System.Windows.Forms.TextBox();
this.buttonRevert = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(88, 16);
this.label1.TabIndex = 0;
this.label1.Text = "Running As:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// lblCurrentUser
//
this.lblCurrentUser.Location = new System.Drawing.Point(112, 24);
this.lblCurrentUser.Name = "lblCurrentUser";
this.lblCurrentUser.Size = new System.Drawing.Size(200, 16);
this.lblCurrentUser.TabIndex = 1;
//
// textBoxUsername
//
this.textBoxUsername.Location = new System.Drawing.Point(112, 80);
this.textBoxUsername.Name = "textBoxUsername";
this.textBoxUsername.Size = new System.Drawing.Size(144, 20);
this.textBoxUsername.TabIndex = 2;
this.textBoxUsername.Text = "";
//
// label2
//
this.label2.Location = new System.Drawing.Point(16, 80);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(88, 16);
this.label2.TabIndex = 3;
this.label2.Text = "New Username:";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label3
//
this.label3.Location = new System.Drawing.Point(16, 104);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(88, 16);
this.label3.TabIndex = 5;
this.label3.Text = "New Password:";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// textBoxPassword
//
this.textBoxPassword.Location = new System.Drawing.Point(112, 104);
this.textBoxPassword.Name = "textBoxPassword";
this.textBoxPassword.PasswordChar = '*';
this.textBoxPassword.Size = new System.Drawing.Size(144, 20);
this.textBoxPassword.TabIndex = 4;
this.textBoxPassword.Text = "";
//
// buttonLogon
//
this.buttonLogon.Location = new System.Drawing.Point(181, 136);
this.buttonLogon.Name = "buttonLogon";
this.buttonLogon.TabIndex = 6;
this.buttonLogon.Text = "Logon";
this.buttonLogon.Click += new System.EventHandler(this.buttonLogon_Click);
//
// label4
//
this.label4.Location = new System.Drawing.Point(16, 56);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(88, 16);
this.label4.TabIndex = 8;
this.label4.Text = "Logon Domain:";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// textBoxDomain
//
this.textBoxDomain.Location = new System.Drawing.Point(112, 56);
this.textBoxDomain.Name = "textBoxDomain";
this.textBoxDomain.Size = new System.Drawing.Size(144, 20);
this.textBoxDomain.TabIndex = 7;
this.textBoxDomain.Text = "";
//
// buttonRevert
//
this.buttonRevert.Enabled = false;
this.buttonRevert.Location = new System.Drawing.Point(104, 136);
this.buttonRevert.Name = "buttonRevert";
this.buttonRevert.TabIndex = 9;
this.buttonRevert.Text = "Revert";
this.buttonRevert.Click += new System.EventHandler(this.buttonRevert_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(312, 189);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.buttonRevert,
this.label4,
this.textBoxDomain,
this.buttonLogon,
this.label3,
this.textBoxPassword,
this.label2,
this.textBoxUsername,
this.lblCurrentUser,
this.label1});
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "Impersonation Example";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void buttonLogon_Click(object sender, System.EventArgs e)
{
if (textBoxUsername.Text != "" && textBoxPassword.Text != "")
{
try
{
// attempt to impersonate specified user
newUser = this.ImpersonateUser(textBoxUsername.Text, textBoxDomain.Text, textBoxPassword.Text);
// update the running as name
lblCurrentUser.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
buttonRevert.Enabled = true;
buttonLogon.Enabled = false;
}
catch (Exception ex)
{
// why did it fail?
MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
MessageBox.Show(this, "Complete all the logon credentials", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
/// <summary>
/// Revert back to previous user
/// </summary>
private void buttonRevert_Click(object sender, System.EventArgs e)
{
// revert to previous user
newUser.Undo();
buttonRevert.Enabled = false;
buttonLogon.Enabled = true;
// update the running as name
lblCurrentUser.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
/// <summary>
/// Attempts to impersonate a user. If successful, returns
/// a WindowsImpersonationContext of the new users identity.
/// </summary>
/// <param name="sUsername">Username you want to impersonate</param>
/// <param name="sDomain">Logon domain</param>
/// <param name="sPassword">User's password to logon with</param></param>
/// <returns></returns>
public WindowsImpersonationContext ImpersonateUser(string sUsername, string sDomain, string sPassword)
{
// initialize tokens
IntPtr pExistingTokenHandle = new IntPtr(0);
IntPtr pDuplicateTokenHandle = new IntPtr(0);
pExistingTokenHandle = IntPtr.Zero;
pDuplicateTokenHandle = IntPtr.Zero;
// if domain name was blank, assume local machine
if (sDomain == "")
sDomain = System.Environment.MachineName;
try
{
string sResult = null;
const int LOGON32_PROVIDER_DEFAULT = 0;
// create token
const int LOGON32_LOGON_INTERACTIVE = 2;
//const int SecurityImpersonation = 2;
// get handle to token
bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
// did impersonation fail?
if (false == bImpersonated)
{
int nErrorCode = Marshal.GetLastWin32Error();
sResult = "LogonUser() failed with error code: " + nErrorCode + "\r\n";
// show the reason why LogonUser failed
MessageBox.Show(this, sResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Get identity before impersonation
sResult += "Before impersonation: " + WindowsIdentity.GetCurrent().Name + "\r\n";
bool bRetVal = DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle);
// did DuplicateToken fail?
if (false == bRetVal)
{
int nErrorCode = Marshal.GetLastWin32Error();
CloseHandle(pExistingTokenHandle); // close existing handle
sResult += "DuplicateToken() failed with error code: " + nErrorCode + "\r\n";
// show the reason why DuplicateToken failed
MessageBox.Show(this, sResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
else
{
// create new identity using new primary token
WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
// check the identity after impersonation
sResult += "After impersonation: " + WindowsIdentity.GetCurrent().Name + "\r\n";
MessageBox.Show(this, sResult, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
return impersonatedUser;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
// close handle(s)
if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}
}
}