Geeks With Blogs

News
WinToolZone - Spelunking Microsoft Technologies
I work as a developer on the Common Language Runtime (CLR) team, specifically in the areas of exception handling and CLR hosting.
Disclaimer

The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Inside and Out... An attempt to understand technology better...
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 at http://geekswithblogs.net/khanna/archive/2005/02/09/22430.aspx.

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 static IntPtr LogUser(string strUsername, string strDomain, string strPassword)
		{
			IntPtr tokenHandle = new IntPtr(0);
			IntPtr dupeTokenHandle = new IntPtr(0);

			string UserName, MachineName,passWord;
			const int LOGON32_PROVIDER_DEFAULT = 0;
			//This parameter causes LogonUser to create a primary token.
			const int LOGON32_LOGON_INTERACTIVE = 2;
			const int SecurityImpersonation = 2;

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

			// Call LogonUser to obtain a handle to an access token.
			bool returnValue = LogonUser(strUsername, strDomain, strPassword, 
				LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
				ref tokenHandle);

				
			if (false == returnValue)
			{
				int ret = Marshal.GetLastWin32Error();
				return IntPtr.Zero;
			}

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

			return token2;
		}

		/// 
		/// The main entry point for the application.
		/// 
		[STAThread]
		static void Main(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 = new WindowsIdentity(token);
			WindowsPrincipal winPrin = new WindowsPrincipal(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(new WaitCallback(callback));
			Console.ReadLine();
		}

		static void callback(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 = new WindowsIdentity(token);
			
			WindowsPrincipal winPrin = new WindowsPrincipal(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);
		}
Posted on Wednesday, February 9, 2005 11:43 AM .NET Framework , .NET Framework V1.X , VS.NET 2002/2003 , VS 2005 , 32bit | Back to top


Comments on this post: Managed code impersonation: CLR ThreadPool and more...

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Gaurav Khanna | Powered by: GeeksWithBlogs.net