views:

60

answers:

2

I have a c++ application in which threads could impersonate using LogonUser/ImpersonateLoggedOnUser, and then revert impersonation using RevertToSelf. I ran across the bug which caused thread to impersonate this way twice. I want to prevent this by testing if current thread is already impersonating and throw exception if it is. Is there a way to tell if current thread is impersonating already?

+1  A: 

I expect you could do this using a convoluted sequence of Win32 API calls similar to these checks for thread running as Administrator.

However, it is far simpler (and better design) to ensure that impersonating threads always revert. You could brute force this using the Win32 APIs, but I believe you could also do this by creating a wrapper class that impersonates on construction and reverts when it goes out of scope, similar to the common lock guard model for exception-safe mutex/critical section handling. Even if you have more than a few places where your code does this, aligning them all on a reliable construct seems advisable.

Flow would then be:

{
  MyImpersonationClass newContext(desiredUser);  
      // constructor calls Impersonate, saving required info

  // do the code that requires impersonation here
}

// newContext goes out of scope, destructor calls RevertToSelf
Steve Townsend
problem is that /*do the code that requires impersonation here*/ might be calling some code that attempts to impersonate and I want to block this behavior
galets
@galets - have your constructor save something in TLS (thread-local storage) to prevent recursive impersonation. Destructor should reset this, of course.
Steve Townsend
@Steve - doable...
galets
+4  A: 

You can use OpenThreadToken. If a thread has a token then it is impersonating; if it doesn't have a token then it is not impersonating.

Luke
+1 for the correct answer to the q as asked - personally, I would still prefer not to guess about this.
Steve Townsend
thanks, let me test that and then I'll mark it as correct if it works out.
galets