Re[6]: иконки интерактивных служб под Windows 7
От: Maclaud  
Дата: 29.06.11 14:39
Оценка:
Здравствуйте, okman, Вы писали:

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


M>>Опиши пожалуйста второй способ.

M>>У меня как раз задача, есть сервис и нужно чтобы он запускал себя же (в смысле свой exe) с теми же правами но в консольной сессии.
M>>За ранее благодарю.

O>Несколько основных положений:


O>1. Сервис должен выполняться от имени LocalSystem, иначе некоторые функции будут недоступны.


O>2. При старте нужно подписаться на событие SERVICE_ACCEPT_SESSIONCHANGE.

O>Любые события, связанные со входом и выходом пользователя из системы, включая
O>терминальный доступ, будут проходить через обработчик (HandlerEx), а по параметрам
O>легко определить тип события (например, WTS_SESSION_LOGON, см. WTSSESSION_NOTIFICATION).
O>Я настоятельно рекомендую сделать демо-сервис с записью событий в журнал, а затем
O>поэкспериментировать с тем, какие события и когда вызываются, особенно в контексте
O>быстрого переключения пользователей и терминальных сеансов. Потому что кроме событий
O>logon/logoff есть еще connect/disconnect, которые вносят некоторую путаницу.

O>3. Id сессии, в которой произошло событие, нужно получать именно из обработчика, а

O>не путем всяких WTSGetActiveConsoleSessionId, потому что так можно будет вести учет того,
O>какие сеансы у нас запускаются, а какие отключаются.

O>4. Есть один подводный камень, связанный с запуском службы и перехватом первого логина.

O>Дело в том, что если используется простой вход в систему (минуя окно ввода имя
O>пользователя и пароля), служба в некоторых случаях может не успеть запуститься.
O>То есть, событие первого входа в систему не будет перехвачено.
O>Я не знаю, каков рекомендованный MSDN способ обхода этого ограничения и поступаю так -
O>всегда указываю принадлежность своей службы группе "Boot Bus Extender".
O>Радикально, но работает.

O>5. Id сессии, в которой произошел вход в систему, нужно запомнить.

O>Потому что это — "наше все". По нему можно определить имя пользователя, тип сеанса
O>(консольный или терминальный) и многие другие данные, см. WTSQuerySessionInformation.
O>Еще один ключевой показатель — маркер безопасности пользователя.
O>Получается с помощью WTSQueryUserToken.

O>Допустим, некто вошел в систему и мы знаем Id его сессии, а также получили маркер безопасности.

O>И нужно создать в его сессии интерактивный процесс, выполняющийся в контексте безопасности
O>нашей службы (LocalSystem).

O>Последовательность действий примерно такова:


O>1. Заполняем структуру STARTUPINFO, в lpDesktop пишем "WinSta0\Default".


O>2. Создаем новый маркер безопасности:


O>
O>DuplicateTokenEx(hProcessToken, // получается с помощью OpenProcessToken.
O>    MAXIMUM_ALLOWED,
O>    NULL,
O>    SecurityDelegation,
O>    TokenPrimary,
O>    &hNewToken);
O>


O>В созданном маркере устанавливаем Id сессии:


O>
O>SetTokenInformation(hNewToken,
O>    TokenSessionId,
O>    &IdSession,
O>    sizeof (IdSession));
O>


O>3. Создаем процесс с помощью CreateProcessAsUser, первым

O>аргументом передается новый маркер безопасности.
O>Созданный процесс будет отображаться в диспетчере задач как SYSTEM и его
O>нельзя будет "прибить" из-под неадминистраторской учетки, но при этом он
O>приаттачен к пользовательской сессии и полностью интерактивен.
O>Со всеми, так сказать, вытекающими.

O>Процессы, создаваемые описанным выше способом, имеют несколько особенностей.

O>Во-первых, происходит путаница с пользовательскими профилями.
O>Во-вторых, такой процесс представляет собой потенциальную дыру в безопасности.
O>В-третьих, при выходе из системы пользователя процесс уничтожается как и все
O>оконные — то есть, не позже обработки WM_ENDSESSION.

O>Есть и другие особенности, но они специфичны и к теме отношения не имеют.


O>Собственно, все.


Спасибо за ответ. Я так понял тут основной момент это установка ID сессии в новом маркере.
А OpenProcessToken как процесс сервиса я так понял делается?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.