Search code examples
c++tokenrights

Basics of GetTokenInformation


I've been trying to get this call to cooperate, but to no success.

I'm trying to get the SID value for the current user in order to get the User's account rights (using LsaEnumerateAccountRights). Although I'm lost as to why My call to GetTokenInformation is returning false. No error in retrieving the process token.

Here is my work so far on the subject:

    HANDLE h_Process;
HANDLE h_Token;
HANDLE h_retToken;

TOKEN_USER tp;
DWORD cb = sizeof(TOKEN_USER);
PDWORD ret;

DWORD dw_TokenLength;

h_Process = GetCurrentProcess();

if (OpenProcessToken(h_Process, TOKEN_READ, &h_Token) == FALSE)
{
    printf("Error: Couldn't open the process token\n");
    return -1;
}

if (GetTokenInformation(h_Token, TokenUser, &tp, cb, &dw_TokenLength) == FALSE)
{
    printf("Error: Could not retrieve Token User information");
    return -1;
}

And along with it, I might as well ask a follow up question that I have not yet encountered, how to retrieve the SID from the formed TOKEN_USER structure?

I apologize ahead of time for such a simple question, I'm just stumped and would like some help to continue. All the questions related to this one are far more complicated and give little insight to my current problem.

Thanks in advance, Jon


Solution

  • According to the documentation For GetTokenInformation, if the function fails you can retrieve more information via a call to GetLastError.

    Return Value

    If the function succeeds, the return value is nonzero.

    If the function fails, the return value is zero. To get extended error information, call GetLastError.

    So you need to implement some checking for the extended error:

    if (!GetTokenInformation(h_Token, TokenUser, &tp, cb, &dw_TokenLength))
    {
        int lastError = GetLastError();
    
        // Should be a switch, of course. Omitted for brevity
        if (lastError == ERROR_INSUFFICIENT_BUFFER) 
        {
            //
        }
    }  
    

    As a general rule of thumb when using WinAPI functions that have varying buffer requirements, you typically

    • Call the function with a NULL buffer to determine the buffer size needed (in this case, returned in the ReturnLength parameter)
    • Allocate a buffer of the indicated size
    • Call the function again, passing the allocated buffer, to obtain the information