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.
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.