Запуск процесса под другим пользователем

Тема в разделе "WASM.WIN32", создана пользователем Dmitry_Koteroff, 5 июл 2005.

  1. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    Пытаюсь запустить консольный процесс на текущей машине под "безопасным" пользователем, отличным от Администратора. Создаю этого пользователя (имя dyn1) и исключаю его из всех групп, чтобы он был с максимально низкими правами в системе. Проверяю через runas:



    runas /user:dyn1 process.exe



    Все запускается нормально.



    Теперь делаю то же самое на WINAPI:



    LogonUser(user, ".", password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);



    Результат: логон проходит, но попытка вызова



    CreateProcessAsUser(hToken, 0, (LPSTR)cmd, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, pi);



    дает (GetLastError/FormatMessage):



    A required privilege is not held by the client.



    Что это за "привилегии" такие, интересно, которые он хочет затребовать?



    Если же попробовать LOGON32_LOGON_BATCH:



    LogonUser(user, 0, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hToken);



    получаю сразу же после этого вызова:



    Logon failure: the user has not been granted the requested logon type at this computer.



    Вопрос: как же тогда, черт возьми, работает runas? Ведь работает же, запускает процесс...
     
  2. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    может какой нибудь Debug-privilege нужен?


    Код (Text):
    1.  
    2. #define SE_CREATE_TOKEN_NAME              TEXT("SeCreateTokenPrivilege")
    3. #define SE_ASSIGNPRIMARYTOKEN_NAME        TEXT("SeAssignPrimaryTokenPrivilege")
    4. #define SE_LOCK_MEMORY_NAME               TEXT("SeLockMemoryPrivilege")
    5. #define SE_INCREASE_QUOTA_NAME            TEXT("SeIncreaseQuotaPrivilege")
    6. #define SE_UNSOLICITED_INPUT_NAME         TEXT("SeUnsolicitedInputPrivilege")
    7. #define SE_MACHINE_ACCOUNT_NAME           TEXT("SeMachineAccountPrivilege")
    8. #define SE_TCB_NAME                       TEXT("SeTcbPrivilege")
    9. #define SE_SECURITY_NAME                  TEXT("SeSecurityPrivilege")
    10. #define SE_TAKE_OWNERSHIP_NAME            TEXT("SeTakeOwnershipPrivilege")
    11. #define SE_LOAD_DRIVER_NAME               TEXT("SeLoadDriverPrivilege")
    12. #define SE_SYSTEM_PROFILE_NAME            TEXT("SeSystemProfilePrivilege")
    13. #define SE_SYSTEMTIME_NAME                TEXT("SeSystemtimePrivilege")
    14. #define SE_PROF_SINGLE_PROCESS_NAME       TEXT("SeProfileSingleProcessPrivilege")
    15. #define SE_INC_BASE_PRIORITY_NAME         TEXT("SeIncreaseBasePriorityPrivilege")
    16. #define SE_CREATE_PAGEFILE_NAME           TEXT("SeCreatePagefilePrivilege")
    17. #define SE_CREATE_PERMANENT_NAME          TEXT("SeCreatePermanentPrivilege")
    18. #define SE_BACKUP_NAME                    TEXT("SeBackupPrivilege")
    19. #define SE_RESTORE_NAME                   TEXT("SeRestorePrivilege")
    20. #define SE_SHUTDOWN_NAME                  TEXT("SeShutdownPrivilege")
    21. #define SE_DEBUG_NAME                     TEXT("SeDebugPrivilege")
    22. #define SE_AUDIT_NAME                     TEXT("SeAuditPrivilege")
    23. #define SE_SYSTEM_ENVIRONMENT_NAME        TEXT("SeSystemEnvironmentPrivilege")
    24. #define SE_CHANGE_NOTIFY_NAME             TEXT("SeChangeNotifyPrivilege")
    25. #define SE_REMOTE_SHUTDOWN_NAME           TEXT("SeRemoteShutdownPrivilege")
    26.  
     
  3. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
  4. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    А как это использовать в данной задаче?



    И не совсем понятно, при чем тут Debug-привилегия? Я ж ничего не отлаживаю, а просто процесс запускаю, так же, как это делает runas...
     
  5. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    Короче, похоже, что все понятно.



    http://www.codeguru.com/Cpp/misc/misc/system/article.php/c3805 (совсем немножко!)

    http://www.microsoft.com/msj/0200/logon/logon.aspx

    http://www.codeguru.com/Cpp/W-P/win32/cursors/article.php/c6745/



    Оказывается, этот код можно выполнять только из сервисов. В обычной сессии нет нужный привилегий, а чтобы их выставить, требуется перелогиниваться минимум, что неприемлемо.
     
  6. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    Как-то только это все нелогично малек. Мало того, что нужно знать plaintext-пароль (!) для запуска процесса под другим юзером из-под Администратора (в Unix, например, пароль знать не нужно, что весьма логично). Так еще и у Администратора по умолчанию нет прав на запуск чужих процессов, и приходится извращаться с сервисами! В общем, усложнено все, что только можно было усложить.
     
  7. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Должна помочь функция CreateProcessWithLogonW - именно ей пользуется runas. Сам еще не пробовал - все руки не доходят.
     
  8. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    Она только начиная с Win2000 только, в этом ее беда... Ладно, попробую через нее.
     
  9. Dmitry_Koteroff

    Dmitry_Koteroff New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2003
    Сообщения:
    20
    Адрес:
    Russia
    Да, CreateProcessWithLogonW прокатила:


    Код (Text):
    1.  
    2.     STARTUPINFOW si;
    3.     memset(&si, 0, sizeof(si));
    4.     si.cb = sizeof(si);
    5.  
    6.     PROCESS_INFORMATION pi;
    7.     memset(&pi, 0, sizeof(pi));
    8.  
    9.     WCHAR wuser[128], wpassword[128], wcmd[4096];
    10.     MultiByteToWideChar(CP_ACP, 0, user, strlen(user)+1, wuser, sizeof(wuser)/sizeof(WCHAR));
    11.     MultiByteToWideChar(CP_ACP, 0, password, strlen(password)+1, wpassword, sizeof(wpassword)/sizeof(WCHAR));
    12.     MultiByteToWideChar(CP_ACP, 0, cmd, strlen(cmd)+1, wcmd, sizeof(wcmd)/sizeof(WCHAR));
    13.  
    14.     bool result = CreateProcessWithLogonW(
    15.         wuser,
    16.         L".",
    17.         wpassword,
    18.         0,
    19.         0,
    20.         wcmd,
    21.         CREATE_NEW_PROCESS_GROUP,
    22.         0,
    23.         0,
    24.         &si,
    25.         &pi
    26.     );
    27.