Search code examples
c++comdcom

How can I get the SID of the user who invoked the method of COM server?


I already asked about how to get the user name. How can I get the user name who invoked the method of COM server? Now I need to get the SID too. How do I do this?

The OpenProcessToken approach doesn't work because this function fails with ERROR_BAD_IMPERSONATION_LEVEL error.


Solution

  • UPDATE In order to do this, the client should allow the server to get its information by configuring the proxy with CoSetProxyBlanket API as shown below:

    HRESULT hr;
    if(FAILED(hr = ::CoSetProxyBlanket(
                unk // An interface the client uses to access the com server
                , RPC_C_AUTHN_DEFAULT
                , RPC_C_AUTHZ_DEFAULT
                , NULL
                , RPC_C_AUTHN_LEVEL_DEFAULT
                , RPC_C_IMP_LEVEL_DELEGATE // This flag should be *_DELEGATE or *_IMPERSONATE or *_IDENTIFY
                , NULL
                , EOAC_DYNAMIC_CLOAKING)))
        throw com_exception(hr, "Failed to set proxy blanket");
    

    Then being impersonated (CoImpersonateClient) you may access the user's token with OpenThreadToken.

    END OF UPDATE

    And after that you may use GetTokenInformation API as follows:

    DWORD tokenSize = 0;
    ::GetTokenInformation(token, TokenUser, NULL, 0, &tokenSize);
    
    ....
    TOKEN_USER *tokenInfo; // should point to a memory location of size tokenSize.
    ....
    if(::GetTokenInformation(token, infoClass, tokenInfo, tokenSize, &tokenSize) == FALSE)
        throw win32_exception(::GetLastError(), "Failed to obtain token information");
    

    tokenInfo will contain the field User.Sid of type PSID.