Inside and Out…

An attempt to understand technology better…

Managed code impersonation: CLR ThreadPool and more…

Posted by Gaurav Khanna on February 9, 2005

Under managed code, once you impersonate your application’s thread using LogonUser and WindowsIdentity class’s Impersonate method, you can go ahead and perform tasks using the impersonated thread as you require. However, there are couple of catches to this:

1) If you launch a process using Process.Start method, the launched process will not execute under the impersonation context of your application. If you want to make that happen, you will have to launch the process using CreateProcessWithLogonW as I have discussed here.

2) If, from the impersonated thread, you schedule some task to execute using QueueUserWorkItem of ThreadPool class, even the ThreadPool threads do not get the impersonated context, as shown below:

However, once the ThreadPool thread is impersonated, results are as expected:

Below is the snippet to accomplish this:

private staticIntPtr LogUser(stringstrUsername, stringstrDomain, stringstrPassword)
{
IntPtr tokenHandle = newIntPtr(0);
IntPtr dupeTokenHandle = newIntPtr(0);

stringUserName, MachineName,passWord;
const intLOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const intLOGON32_LOGON_INTERACTIVE = 2;
const intSecurityImpersonation = 2;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
boolreturnValue = LogonUser(strUsername, strDomain, strPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
reftokenHandle);

if(false== returnValue)
{
intret = Marshal.GetLastWin32Error();
returnIntPtr.Zero;
}

WindowsIdentity mWI1 = WindowsIdentity.GetCurrent();
IntPtr token2 = newIntPtr(tokenHandle.ToInt32());

returntoken2;
}

///
///The main entry point for the application.
///
[STAThread]
static voidMain(string[] args)
{
// show current principal..
IIdentity curI = null;
curI = WindowsIdentity.GetCurrent();
Console.WriteLine(“Your current identity is {0}”,curI.Name);

// Impersonate
IntPtr token = LogUser(“username”,”domain”,”password!”);
WindowsIdentity mWI2 = newWindowsIdentity(token);
WindowsPrincipal winPrin = newWindowsPrincipal(mWI2);
System.Threading.Thread.CurrentPrincipal = winPrin;
WindowsImpersonationContext impersonatedUser = mWI2.Impersonate();

curI = WindowsIdentity.GetCurrent();
Console.WriteLine(“After impersonation in the main thread, you are {0}”,curI.Name);

ThreadPool.QueueUserWorkItem(newWaitCallback(callback));
Console.ReadLine();
}

static voidcallback(Object stateInfo)
{
// No state object was passed to QueueUserWorkItem, so
// stateInfo is null.
Console.WriteLine(“Hello from the thread pool.”);

IIdentity curI = null;
curI = WindowsIdentity.GetCurrent();
Console.WriteLine(“In ThreadPool Thread, you are {0}”,curI.Name);

IntPtr token = LogUser(“username”,”domain”,”password!”);
WindowsIdentity mWI2 = newWindowsIdentity(token);

WindowsPrincipal winPrin = newWindowsPrincipal(mWI2);
System.Threading.Thread.CurrentPrincipal = winPrin;
WindowsImpersonationContext impersonatedUser = mWI2.Impersonate();

curI = WindowsIdentity.GetCurrent();
Console.WriteLine(“After impersonation, in ThreadPool Thread, you are {0}”,curI.Name);
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: