почему CreateProcessWithTokenW завершается с ошибкой ERROR_ACCESS_DENIED - PullRequest
6 голосов
/ 27 марта 2011

У меня есть вызов CreateProcessWithTokenW, который терпит неудачу с отказом в доступе.Любые идеи, как отладить это?

Звонок CreateProcessWithTokenW здесь: https://github.com/fschwiet/PShochu/blob/master/PShochu/PInvoke/NetWrappers/ProcessUtil.cs

Пока я использую токен доступа для текущего процесса, в конце концов я буду использовать токенот другого пользователя.Сейчас я использую https://github.com/fschwiet/PShochu/blob/master/PShochu/PInvoke/NetWrappers/AccessToken.cs для получения токена доступа.

Если вы хотите отладить, снимите исходный код и запустите build_and_test.ps1.Стек ошибок:

1) Test Error : PShochu.Tests.can_run_remote_interactive_tasks, given a psake script which writes the current process id to output, when that script is invoked interactively, then the script succeeds
   System.ComponentModel.Win32Exception : Access is denied
   at PShochu.PInvoke.NetWrappers.ProcessUtil.CreateProcessWithToken(IntPtr userPrincipalToken, String applicationName,
String applicationCommand, Boolean dontCreateWindow, Boolean createWithProfile, StreamReader& consoleOutput, StreamReader& errorOutput) in c:\src\PShochu\PShochu\PInvoke\NetWrappers\ProcessUtil.cs:line 52
   at PShochu.ProcessHandling.RunNoninteractiveConsoleProcessForStreams2(String command, String commandArguments, String& newLine) in c:\src\PShochu\PShochu\ProcessHandling.cs:line 36
   at PShochu.ProcessHandling.RunNoninteractiveConsoleProcess(String command, String commandArguments) in c:\src\PShochu\PShochu\ProcessHandling.cs:line 20
   at PShochu.Tests.can_run_remote_interactive_tasks.<>c__DisplayClass16.<>c__DisplayClass18.<Specify>b__2() in c:\src\PShochu\PShochu.Tests\can_run_remote_interactive_tasks.cs:line 27
   at NJasmine.Core.Execution.DescribeState.<>c__DisplayClass7`1.<visitBeforeEach>b__3() in c:\src\NJasmine\NJasmine\Core\Execution\DescribeState.cs:line 62

Позднее обновление: в некоторых документах я видел, что необходимы дополнительные привилегии (http://msdn.microsoft.com/en-us/library/aa374905%28v=vs.85%29.aspx). У меня возникают проблемы при получении тестов для проверки наличия у меня этих отдельных ценных бумаг (ониустанавливается в secpol.msc перед перезагрузкой)

SE_ASSIGNPRIMARYTOKEN_NAME  "Replace a process level token"
SE_TCB_NAME "Act as part of the operatin system"
SE_INCREASE_QUOTA_NAME  "Adjust memory quotas for a process"

Эти тесты постоянно говорят мне, что у меня нет разрешений, которые я установил в пользовательском интерфейсе, https://github.com/fschwiet/PShochu/blob/master/PShochu.Tests/verify_privileges.cs

1 Ответ

13 голосов
/ 29 марта 2011

Методом проб и ошибок я выяснил, что токен, который вы передаете CreateProcessWithTokenW (), нуждается в следующих флагах доступа (по крайней мере, в 64-разрядной версии Windows 7 с пакетом обновления 1):

  • TOKEN_ASSIGN_PRIMARY
  • TOKEN_DUPLICATE
  • TOKEN_QUERY
  • TOKEN_ADJUST_DEFAULT
  • TOKEN_ADJUST_SESSIONID

Последние два, выделенные жирным шрифтом, очень не упоминаются вообще в документации для CreateProcessWithTokenW ().

РЕДАКТИРОВАТЬ : следующий код работает нормально для меня (при работе с повышенными правами):

HANDLE hToken = NULL;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken))
{
    HANDLE hDuplicate = NULL;
    if(DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID, NULL, SecurityImpersonation, TokenPrimary, &hDuplicate))
    {
        TCHAR szCommandLine[MAX_PATH];
        _tcscpy_s(szCommandLine, MAX_PATH, _T("C:\\Windows\\system32\\notepad.exe"));
        STARTUPINFO StartupInfo;
        ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
        StartupInfo.cb = sizeof(STARTUPINFO);
        PROCESS_INFORMATION ProcessInformation;
        ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
        if(CreateProcessWithTokenW(hDuplicate, LOGON_WITH_PROFILE, NULL, szCommandLine, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
        {
            WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
            CloseHandle(ProcessInformation.hThread);
            ProcessInformation.hThread = NULL;
            CloseHandle(ProcessInformation.hProcess);
            ProcessInformation.hProcess = NULL;
        }
        CloseHandle(hDuplicate);
        hToken = hDuplicate;
    }
    CloseHandle(hToken);
    hToken = NULL;
}
...