0

I want to fetch an access token of a logged in user using WTSQueryUserToken(), but it returns error code: 1314.

My code for reference:

DWORD sessionId = -1;
DWORD sessionCount = 0;
WTS_SESSION_INFOW* pSession = NULL;
if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &sessionCount))
{
    if (pSession != NULL)
    {
        for (int i = 0; i < sessionCount; i++)
        {
            sessionId = pSession[i].SessionId;
            WTS_CONNECTSTATE_CLASS wts_connect_state = pSession[i].State;
            if (wts_connect_state == WTSActive)
            {
                HANDLE currentToken;
                if (WTSQueryUserToken(sessionId, &currentToken)) {
                    printf("Access token is obtained \n");
                }
                else
                {
                    printf("WTSQueryUserToken : failed - %d\n", GetLastError());
                }
            }
        }
        WTSFreeMemory(pSession);
    }
}

I have confirmed that the application runs with LocalSystem account privilege and SE_TCB_NAME privilege is already enabled for it.

I confirmed the account by using the following code:

HANDLE process = GetCurrentProcess();
HANDLE processToken;
BOOL openTokenRet = OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);

SID returned by the process token is S-1-5-18

Also, I have checked the privileges enabled for the SYSTEM account by using "whoami /priv" and got to see that SeTcbPrivilege is enabled for the same.

I want to know if any other privilege is required, or anything I am missing here, to get the token using WTSQueryUserToken().

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 3
    system say to you that A required privilege is not held by the client. and obvious you wrong that you have SeTcbPrivilege enabled – RbMm Nov 22 '22 at 11:00
  • 1
    I'm guessing that the `SE_TCB_NAME` privilege is merely *present but not enabled* on your process token. Have you tried using `AdjustTokenPrivileges()` to actually *enable* it before calling `WTSQueryUserToken()`? See [Enabling and Disabling Privileges in C++](https://learn.microsoft.com/en-us/windows/win32/secauthz/enabling-and-disabling-privileges-in-c--) – Remy Lebeau Nov 23 '22 at 01:11
  • @RemyLebeau - I have confirmed that LocalSystem account has the SE_TCB_NAME privilege. Also when I tried running a console app with the above code in cmd opened by PSEXEC. I am able to run the WTSQueryUserToken() – Arun Kumar S Nov 23 '22 at 14:57
  • I found you have said [the issue may be with the machine that I was testing on before](https://learn.microsoft.com/en-us/answers/questions/1099621/wtsqueryuser-token-returning-error-code-1314.html). Would you like to answer yourself? – YangXiaoPo-MSFT Nov 25 '22 at 05:38
  • The issue occurs in other machines too. I can run the console app in system cmd using PSExec utility. But when I try the application in runtime, the code fails with error : 1314 – Arun Kumar S Dec 05 '22 at 12:03
  • How do you try the application in runtime? You may compare enabled privileges your application holds with enabled privileges the local system account which *PSExec* supplies holds. – YangXiaoPo-MSFT Dec 07 '22 at 06:36
  • My application runs during the login process inside a credential provider and it is running with LocalSystem account privilege. Basically I want to find whether the CP usage scenario is UNLOCK or LOGON (as after windows 10 Microsoft does not differentiate Logon and Unlock). So to find this I have to find whether the user has existing session in the machine. I tried WTSQuerySessionInformationW (gives only sAMAccountName. so this fails when user enters UPN to Login) and LsaEnumerateLogonSessions (gives both logged out and logged in user sessions) – Arun Kumar S Dec 08 '22 at 19:09
  • So finally found that I can get sid of active users from WTSQueryUserToken, from which I can find whether a user is logged in or not. But this fails when it is run in Credential provider – Arun Kumar S Dec 08 '22 at 19:12

0 Answers0