7

現在のセッションユーザートークンを取得しようとしているコードがあります。

#include <Wtsapi32.h>

DWORD activeSessionId = WTSGetActiveConsoleSessionId();

HANDLE currentToken;
BOOL queryRet = WTSQueryUserToken(activeSessionId, &currentToken);

if (!queryRet) {
    DWORD err = GetLastError();
    return 0;
}

errの値は1314です。

アップデート1

これまでのところ運が悪いので、現在のプロセスSE_TCB_NAMEを許可しようとしましたが、それでもWTSQueryUserToken(1314)から同じエラーが発生します。

HANDLE process = GetCurrentProcess();

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

if (!openTokenRet)
{
    DWORD err = GetLastError();
    return 0;
}

TOKEN_PRIVILEGES tokenPrivs;
BOOL lookupRet = LookupPrivilegeValue(
    NULL, SE_TCB_NAME, &tokenPrivs.Privileges[0].Luid);

if (!lookupRet)
{
    DWORD err = GetLastError();
    return 0;
}

tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

BOOL adjustRet = AdjustTokenPrivileges(
    processToken, FALSE, &tokenPrivs, 0, (PTOKEN_PRIVILEGES)NULL, 0);

if (!adjustRet)
{
    DWORD err = GetLastError();
    return 0;
}

// get the user in the active session
HANDLE currentToken;
BOOL queryRet = WTSQueryUserToken(activeSessionId, &currentToken);

if (!queryRet) {
    DWORD err = GetLastError();
    return 0;
}

アップデート2:

さらにデバッグ情報を追加しましたが、prevState.PrivilegeCountは0です。

TOKEN_PRIVILEGES prevState;
DWORD prevStateLen = 0;

BOOL adjustRet = AdjustTokenPrivileges(
    processToken, FALSE, &tokenPrivs, 
    sizeof(TOKEN_PRIVILEGES), &prevState, &prevStateLen);

DWORD adjustErr = GetLastError();
if (!adjustRet)
{
    return 0;
}

解決:

WTSQueryUserTokenは、LocalSystemとして実行している場合にのみ使用できるようです。つまり、サービスとして実行し、そこからデバッグする必要があります... Doh!

4

1 に答える 1

10

エラー1314はERROR_PRIVILEGE_NOT_HELDです。WTSQueryUserTokenを呼び出すには、SE_TCB_NAME特権が必要です。

この特権は通常、ローカルシステムとして実行されているコードによってのみ保持されます。この特権がトークンに存在するが無効になっている場合は、AdjustTokenPrivilegesを使用して有効にすることができます。SE_TCB_NAMEは潜在的に非常に危険な特権であるため、使用後すぐに再度無効にする必要があります。この権限があるかどうかを確認する簡単な方法は、プロセスプロパティウィンドウのセキュリティテーブルでProcessExplorerを使用することです。

アップデートごと1-AdjustTokenPrivilegesは成功を返しますが、GetLastError()はERROR_NOT_ALL_ASSIGNEDに設定されていますか?MSDNは、特権が有効になっていない場合にこれを返す可能性があることを示しています。プロセスにSE_TCB_NAME特権があるが、無効になっていることを確認できますか?プロセスはどのアカウントで実行されていますか?

于 2009-08-17T16:51:53.680 に答える