Re: Запуск программы под правами юзера из NT сервиса
От: Alex Fedotov США  
Дата: 30.11.03 03:02
Оценка: 19 (2)
Здравствуйте, Disappear, Вы писали:

D>Сразу скажу, что я перечитал все похожие топики, — не нужно на них ссылаться.


Видимо, все-таки, не все, потому что года полтора-два назад это уже обсуждалось. Что-то вроде "Запуск Outlook Express из службы".

D>Такова проблема:

D>Нужно запустить любую программу из моего системного севиса, да так, чтобы программа запустилась не в виде системного процесса, а как процесс текущего пользователя. Того, кто в настоящий момент залогинен в системе.
D>В статье http://www.microsoft.com/msj/0200/logon/logon.aspx я этого найти не смог, либо чего не понял.

D>Сейчас процессы запускается через CreateProcess, также реализована интерактивность через OpenWindowStation и OpenDesktop, но всеравно все процессы запускаются, как системные, поэтому им недоступен пользовательский реестр и т.д...


D>Как запустить процесс под текущим юзером, если я не знаю его username and pass????


Очень просто. Надо вызвать СreateProcessAsUser, указав в качестве токена токен интерактивного пользователя. Прежде чем приступить к перечислению способов получения этого токена, напомню, что в системе может быть более одного интерактивного пользователя. Поэтому прежде всего предлагаю подумать о том, как узнать, в контексте какого из интерактивных пользователей нужно запустить процесс. Именно эта часть задачи представляется мне наиболее интересной.

А токен можно получить несколькими способами:

1) [простой и надежный способ, работает на всех системах] Делается небольшая программа, которая регистируется в HKLM\Software\Microsoft\Windows\CurrentVersion\Run. При запуске программа соединяется со службой используя COM, RPC или named pipes. C одной стороны, это позволяет узнать службе о факте входа интерактивного пользователя в систему, а с другой — служба может имперсонировать соединение (CoImpersonateClient, RpcImpersonateClient, ImpersonateNamedPipeClient) и получить токен пользователя (OpenThreadToken). Tаким образом получается так называемый impersonation token, который нужно преобразовать в primary token с помощью DuplicateTokenEx, прежде чем можно будет вызвать CreateProcessAsUser.

2) [очень простой и в тоже время надежный способ, WinXP and later] WTSEnumerateSessions и WTSQueryUserToken. Таким образом получаются токены для всех интерактивных сессий в системе.

3) [вариация первого способа, Win2K and later] Написать Winlogon notification package, в котором отследить вход пользователя в систему и получить его токен.

4) [не очень надежный способ, к которому у меня персональная антипатия] Перечислить все процессы, найти процесс оболочки и получить токен этого процесса с помощью OpenProcessToken. Очевидная проблема в том, что процесса оболочки может и не существовать. Кроме того, надо аккуратно обрабатывать ситуации когда таких процессов несколько, так как они могут принадлежать как одной интерактивной сессии, так и разным.
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.