Re[2]: Запуск программы под правами юзера из NT сервиса
От: Disappear  
Дата: 30.11.03 14:35
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:

AF>Здравствуйте, Disappear, Вы писали:


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


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


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

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

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


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


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


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


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


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


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


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


У меня COM server;
Пробую первый метод:
в теле одного из методов интерфейса, я вызываю
CoImpersonateClient()

затем получаю
OpenThreadToken(GetCurrentThread(), ...)


все ок, но когда я хочу получить primary token с помощью функции DuplicateTokenEx ничего не выходит
DuplicateTokenEx(ImpToken, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &PrimToken)

возвращяет FALSE
Может быть я неправильно указываю параметры??
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.