OpenThreadToken() failed with access is denied RRS feed

  • Question

  • I have two users defined in my system.  One is UserA, and the other one is UserB.  Both of them are defined in the administrative group.  UserA is a local user, and UserB is a domain user.

    I have an application running as UserA, and a service running as UserB.  The application is calling a method defined in a COM object running in the service.  I run into a problem when trying to call OpenThreadToken() when the thread is impersonating with a copied impersonated token.  Here is the psuedo code:

    void SomeMethod()


        // Try to retrieve the access token of UserA


        HANDLE hTok, hCopyTok, hNewToken;

        ::OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hTok);

        ::DuplicateTokenEx(hTok, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersation, &hCopyTok);

        ::RpcRevertToSelf(); // Switch back to UserB

        // Try to impersonate with the token returned from the previous OpenThreadToken

        ::SetThreadToken(0, hTok);

        OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hNewTok);  // successful

        ::SetThreadToken(0, 0);


        // Try to impersonate with the token returned  from DuplicateTokenEx

        ::SetThreadToken(0, hCopyTok);

        // OpenThreadToken() will fail.  GetLastError() == 0x00000005 (Access is Denied)

        ::OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hNewTok);    

        ::SetThreadToken(0, 0);


    Does anybody know the problem with the last OpenThreadToken() call?  I suppose DuplicateTokenEx() will duplicate the token so that both have the same information.  I cannot figure out why the last OpenThreadToken() will fail when the thread is impersonating with the copied token.  I have even printed out the DACL of both tokens using GetTokenInformation(), and they look the same.



    Wednesday, November 15, 2006 4:49 PM

All replies

  • I suggest you make that last call with MAXIMUM_ALLOWED instead of TOKEN_ALL_ACCESS (which you probably don't need anyway).
    Does it succeed afterwards?

    Wednesday, November 15, 2006 8:14 PM
  • Thanks Eric.

    I changed the parameter to MAXIMUM_ALLOWED but it still does not work.  I went back to check my code and actually, I was passing TOKEN_QUERY instead of TOKEN_ALL_ACCESS.  And even if the accessMask was the problem, the first OpenThreadToken() should have failed aas well.

    One thing I notice is that, if the service is running as SYSTEM, both calls will pass without any problem.  I think this is because SYSTEM is always granted full access in the DACL of the access token.

    I am wondering whether RpcImpersonateClient() will give the impersonated token some special permission or privilege while the token received from DuplicateTokenEx() does not.


    Wednesday, November 15, 2006 8:35 PM
  • Since you printed out the DACLs, you may as well copy/paste them here...
    Wednesday, November 15, 2006 11:44 PM