2015-02-26 9 views
0

То, что я пытаюсь достичь, - это фактический дескриптор токена из идентификатора сеанса, когда процесс запускается как администратор под пользователем без администратора (Windows вошел в систему пользователем).Получение правильного токена с идентификатора сеанса

 DWORD dwSessionId = 0; 
     if (false == ProcessIdToSessionId(dwProcessId, &dwSessionId)) 
     { 
      LOG_ERROR(L"Failed obtaining session id"); 
      return false; 
     } 

     HANDLE hToken 
     if (false == WTSQueryUserToken(dwSessionId, &hToken)) 
     { 
      LOG_ERROR(L"Failed to obtain session's handle"); 
      return false; 
     } 

Моя проблема возникает, когда я называю WTSQueryUserToken, он терпит неудачу с ошибкой 1314, что означает, что мне нужно предоставить маркер вызова с SE_TCB_NAME привилегий.

так я пытался сделать это с помощью следующего кода:

tp.PrivilegeCount = 1; 
tp.Privileges[0].Luid = luid; 
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
bool bSuccess = DynamicAPI::AdjustTokenPrivileges(
    %%WHICH_TOKEN_EXACTLLY%%, 
    FALSE, 
    &tp, 
    sizeof(TOKEN_PRIVILEGES), 
    (PTOKEN_PRIVILEGES)nullptr, 
    (DWORD)nullptr); 

Но я не совсем уверен, какой маркер должен быть обеспечен точно. Я отметил его %% WHICH_TOKEN_EXACTLLY %% placeholder. Для моих тестов я попытался настроить токен процесса для моего процесса (привилегии администратора), но это тоже не помогло.

ответ

0

Обычно вам нужно включить привилегии в токенах процесса, которые вы можете получить с помощью функции GetProcessToken(). Исключением является то, что если вы намереваетесь использовать привилегию при выдаче себя за себя, тогда вы должны включить привилегию в токенах олицетворения.

Я использую этот код для того, чтобы восстановить привилегии:

DWORD enable_restore() 
{  
    // This allows us to override security to delete files 

    HANDLE token; 
    BOOL flag; 

    struct { 
    DWORD count; 
    LUID_AND_ATTRIBUTES privilege; 
    } token_privileges; 

    token_privileges.count = 1; 
    token_privileges.privilege.Attributes = SE_PRIVILEGE_ENABLED; 

    flag = LookupPrivilegeValue(0, SE_RESTORE_NAME, &token_privileges.privilege.Luid); 
    if (!flag) return GetLastError(); 

    flag = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token); 
    if (!flag) return GetLastError(); 

    flag = AdjustTokenPrivileges(token, 0, (PTOKEN_PRIVILEGES)&token_privileges, 0, 0, 0); 
    if (!flag) return GetLastError(); 

    return 0;  
} 

Обратите внимание, что этот код не проверяет, был ли на самом деле привилегия предоставляется или нет. Чтобы сделать это, проверьте GetLastError() после вызова AdjustTokenPrivileges() - это один из редких случаев, когда последний код ошибки имеет смысл, даже если функция сообщает об успешности.

NB: Это наиболее вероятная причина, по которой ваша попытка использовать токен процесса не удалась; если вы не используете код в качестве локальной системы и не перенастроили Windows, чтобы предоставить учетную запись, для которой вы используете привилегию SE_TCB_NAME, вызов функции AdjustTokenPrivileges() будет иметь успех, но не имеет никакого эффекта.

Также имейте в виду, что независимо от того, есть ли у вас привилегия SE_TCB_NAME, вы можете использовать только WTSQueryUserToken(), если вы работаете в локальном системном контексте, то есть, как правило, только системная служба или приложение запускаются в контексте системный сервис может его использовать. (Я не уверен, достаточно ли выдавать себя за местную систему. Я подозреваю, что нет.)

0

Если поток, которому необходимо настроить привилегии, олицетворяет пользователя, используйте OpenThreadToken(GetCurrentThread()), чтобы получить выданный токен. В противном случае используйте OpenProcessToken(GetCurrentProcess()), чтобы получить токен вызывающего процесса.