CreateProcessAsUser vs ShellExecute
Мне необходимо ShellExecute
что-то как другой пользователь, в настоящее время я запускаю вспомогательный процесс с CreateProcessAsUser
что вызывает ShellExecute
, но это похоже на слишком много взлома (неправильный родительский процесс и т. д.) Есть ли лучший способ сделать это?
@PabloG: ImpersonateLoggedOnUser не работает:
РУЧКА hTok; ПРОВЕРКИ (LogonUser("otheruser",0,"пароль",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT, и hTok)); VERIFY(ImpersonateLoggedOnUser(hTok)); ShellExecute(0,0,"calc.exe",0,0,SW_SHOW); RevertToSelf(); CloseHandle(hTok);
просто запустит calc как зарегистрированный пользователь, а не "otheruser"
@ 1800 ИНФОРМАЦИЯ: CreateProcess
/CreateProcessAsUser
это не то же самое, что ShellExecute
с UAC на Vista, CreateProcess
бесполезно, когда у вас нет контроля над тем, какую программу выполняет пользователь (CreateProcess
вернется с ошибкой, если вы дадите ему исполняемый файл с манифестом, помеченным как requireAdmin)
@ Брайан Р. Бонди: я уже знаю эту информацию (и не поймите меня неправильно, это хорошая вещь), но это не по теме (ИМХО) Я прошу ShellExecuteAsUser
, а не о запуске процессов от имени другого пользователя, я уже знаю, как это сделать.
4 ответа
Решение действительно зависит от ваших потребностей и может быть довольно сложным (полностью благодаря Windows Vista). Это, вероятно, будет за вашими потребностями, но это поможет другим, которые находят эту страницу с помощью поиска.
- Если вам не нужен процесс для запуска с графическим интерфейсом, и вам не требуется повышение прав
- Если пользователь, которого вы хотите запустить как, уже вошел в сеанс
- Если вам нужно запустить процесс с графическим интерфейсом, и пользователь может или не может войти в систему
- Если вам нужно запустить процесс с возвышением
Относительно 1: В Windows Vista существует нечто, называемое изоляцией сеанса 0. Все сервисы работают как сеанс 0, и вы не должны иметь графический интерфейс пользователя в сеансе 0. Первый вошедший в систему пользователь регистрируется в сеансе 1. В предыдущих версиях Windows (до Vista) первый вошедший в систему пользователь также полностью запускался в сессия 0.
Вы можете запустить несколько разных процессов с разными именами пользователей в одном сеансе. Вы можете найти хороший документ об изоляции сессии 0 здесь.
Поскольку мы имеем дело с вариантом 1), вам не нужен графический интерфейс. Поэтому вы можете начать свой процесс в сеансе 0.
Вам понадобится последовательность вызовов примерно такая: LogonUser, ExpandEnvironmentStringsForUser, GetLogonSID, LoadUserProfile, CreateEnvironmentBlock, CreateProcessAsUser.
Пример кода для этого можно найти через любую поисковую систему или через поиск кода Google
Относительно 2: Если пользователь, которому вы хотите запустить процесс, уже вошел в систему, вы можете просто использовать: WTSEnumerateSessions и WTSQuerySessionInformation для получения идентификатора сеанса, а затем WTSQueryUserToken для получения токена пользователя. Оттуда вы можете просто использовать токен пользователя в Win32 API CreateProcessAsUser.
Это отличный метод, потому что вам даже не нужно входить в систему как пользователь и не знать имя пользователя / пароль пользователя. Я считаю, что это возможно только через службу, хотя она работает как локальная системная учетная запись.
Вы можете получить текущий сеанс через WTSGetActiveConsoleSessionId.
Относительно 3: Вы будете следовать тем же шагам, что и #1, но кроме того, вы будете использовать поле lpDesktop в STARTUPINFO. Установите для этого значение winsta0\Default. Вам также нужно будет попытаться использовать OpenDesktop Win32 API, и в случае неудачи вы можете создать CreateDesktop. Перед использованием дескрипторов станции и рабочего стола вы должны использовать SetSecurityInfo для каждого из них с SE_WINDOW_OBJECT и GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION.
Если рассматриваемый пользователь позже попытается войти, он фактически увидит запущенный процесс.
Относительно 4: Это также может быть сделано, но для этого требуется, чтобы вы уже запускали процесс с повышенными правами. Служба, работающая как локальная системная учетная запись, работает с повышенными правами. Я также мог заставить его работать только с подписанным аутентичным процессом, который я хотел запустить. Процесс, который вы хотите запустить, также должен иметь файл манифеста, связанный с ним с уровнем requiredExecutionLevel ="requireAdministrator"
Другие заметки:
- Вы можете установить сессию токена через SetTokenInformation и TokenSessionId.
- Вы не можете изменить идентификатор сеанса уже запущенного процесса.
- Весь этот процесс был бы значительно проще, если бы в уравнении не было Vista.
Если вам нужна семантика ShellExecute, вы можете указать следующее:
C:\windwos\system32\cmd.exe /k" start <your_target_to_be_ShellExecuted>"
в CreateProcessAsUser
и вы сделали.
Почему бы вам просто не создать CreateProcessAsUser, указав процесс, который вы хотите запустить?
Вы также можете использовать SHCreateProcessAsUserW.
Вы можете обернуть ShellExecute между ImpersonateLoggedOnUser / RevertToSelf
ссылки: ImpersonateLoggedOnUser: http://msdn.microsoft.com/en-us/library/aa378612(VS.85).aspx RevertToSelf: http://msdn.microsoft.com/en-us/library/aa379317.aspx
извините, не могу гиперссылку URL с "()"