Roddles
Roddles

Reputation: 307

Does a Non UI thread which is running under impersonated user automatically imersonate the UI thread?

I have been searching for several hours now and have so far had no luck with this one - so thought I would post.

I have a WPF Application written in vb.net running on DotNet 4.0 which launches worker threads to perform specific functions such as hashing files and other processor / time intensive routines.

Some of the threads that are launched need to impersonate a different user in order to access network resources which the logged on user ordinarily cannot access directly (they are allowed controlled access to network resources through the application but not, for example, through windows explorer). To do this, the worker thread impersonates a pre-determined user account which has access which then allows the application access to the network resources.

While this worked thread running under the impersonated user account is working - it occasionaly needs to update a local sql 3.5 compact database sitting in the Users directory. This database is accessible only to the logged on user - not the impersonated user.

To allow this update, from the impersonated worker thread I have access to the UI Dispatcher object (its passed through when the thread is created) in which i invoke a subroutine to update the SQL compact database.

Here is an interesting issue which I cannot explain but read on as someone may be able to explain this.

The application when it called the UI Dispatcher from the worker thread would drop back to the logged on users credentials to upadte the sql database in the UI thread - and then when the UIthread.dispatcher.invoke call returned to the worker thread - it would be back at the impersonated worker thread account.

Today - and I have no reason why - when I call the UI dispatcher thread to update the SQL Compact database, the thread context is remaining at the impersonated user - not the logged on user on the UI Thread. Its like the impersonated user is now imposed across all threads - including the UI thread.

What I am trying to understand is what is the correct result - should the UIThread.Dispatcher.Invoke execute whatever code is invoked under the user context of the UI thread (not impersonated) OR does the impersomated user context come into effect for the invoke call back on the UI thread becuase it was initiated from the worker thread?

I am puzzled because yesterday - when I had a break point in the UIThread.Dispatcher.Invoked routine, I could see that the thread was executing under the logged on users account and the updates to the SQL compact database worked. Today however, the same code is executing under the impersonated account and I am getting access denied exceptions while trying to update the database.

I checked the ManagedThreadId of the UI thread before launching worker threads, and am able to confirm that the ManagedThreadId when the UIThread.Dispatcher.Invoke is executed returns to the ManagedThreadId of the UI thread - then when the invoke ends and execution returns to the worker thread the ManagedThreadId returns to the correct worker ManagedThreadId. What is not changing this time round is the User for that thread. It seems to now remain on the impersonated user all the time unless I explicity end the impersonation of the thread.

Can someone please shed some light on this - and suggest if I am going about this all wrong and should be trying to do this another way. WhatI really want to understand is why it has been working - and why now it doesnt - and no - no code changes to this code between yesterday and today.

Sorry for the long post

Cheers

Rod.

Upvotes: 4

Views: 937

Answers (1)

Jason
Jason

Reputation: 5027

You might want to look at the thread's Execution Context.

http://msdn.microsoft.com/en-us/library/system.threading.executioncontext.aspx

From CLR via C#, 3d ed pg 721:

In the System.Threading namespace, there is an ExecutionContext class that allows you to control how a thread's execution context flows from one thread to another.

...

If the initiating thread's execution context does not flow to a helper thread, the helper thread will use whatever execution context it last associated with it. Therefore, the helper thread really shouldn't execute any code that relies on the execution context state (such as a user's Windows identity).

Also, I had to so some impersonation in an ASP.NET application recently, and the LogonUser win32 api offered some really fine grained control when I wanted to impersonate, how I wanted to impersonate (i.e., network, interactive, service, etc), and then quickly revert within a single thread.

http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_impersonatingusinglogonuser

Upvotes: 3

Related Questions