У меня есть сервис Windows Server прежней версии и (порожденное) приложение, которое хорошо работает в XP-64 и W2K3, но перестало работать на W2K8. Я полагаю, что это из-за новой функции "Session 0 isolation".
Следовательно, я ищу заклинание образцов/настроек безопасности кода, которые позволяют Вам создать новый процесс из сервиса окон для Windows 2008 Server, таким образом, что я могу восстановить (и возможно превзойти), предыдущее поведение. Мне нужно решение что:
Поскольку Сессия 0 больше не является сеансом пользователя, сервисы, которые работают на Сессии 0, не имеют доступа к видеодрайверу. Это означает, что любая попытка, которую сервис предпринимает для рендеринга графических сбоев. Запросы разрешения дисплея и глубины цвета на Сессии 0 отчетов корректные результаты для системы до максимума 1920x1200 на уровне 32 бит на пиксель.
Новый процесс получает окна, station/desktop (например, winsta0/default), который может использоваться для создания окон DCs. Я нашел решение (который запускается хорошо на интерактивной сессии) для этого здесь: Запуск Интерактивного Клиентского процесса в C++
Окна DC при использовании в качестве основания для перечисления OpenGL DescribePixelFormat могут найти и использовать аппаратно ускоренный формат (в системе, соответственно оборудованной аппаратными средствами OpenGL.) Отмечают, что наше текущее решение работает хорошо над XP-64 и W2K3, кроме того, если сессия служб удаленных рабочих столов работает (VNC хорошо работает.) Решением, которое также позволило процессу работать (т.е. работать с аппаратным ускорением OpenGL, даже когда заседание служб удаленных рабочих столов открыто) был бы fanastic, хотя не требуемый.
Я застреваю в объекте № 1 в настоящее время, и хотя существуют некоторые подобные регистрации, которые обсуждают это (как это и это - они не подходящие решения, поскольку нет никакой гарантии сеанса пользователя, зарегистрированного уже для "взятия" идентификатора сессии от, и при этом я не работаю из учетной записи LocalSystem (я работаю от учетной записи домена за сервисом, для которого я могу скорректировать полномочия в причине, хотя я предпочел бы не должным быть наращивать приоритеты включать SeTcbPrivileges.)
Например - здесь незавершен, что я думаю, должен работать, но всегда возвращает ошибку 1314 на вызове SetTokenInformation (даже при том, что AdjustTokenPrivileges не возвратил ошибок), я использовал некоторые альтернативные стратегии, включающие "LogonUser" также (вместо того, чтобы открыть существующий маркер процесса), но я, может казаться, не выгружаю идентификатор сессии.
Я также сомнителен об использовании WTSActiveConsoleSessionId во всех случаях (например, если никакой интерактивный пользователь не зарегистрирован) - хотя быстрый тест сервиса, работающего без сессий, вошел в систему, казалось, возвращал разумное значение сессии (1).
Я удалил обработку ошибок для простоты чтения (все еще немного грязный - извинения)
//Also tried using LogonUser(..) here
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_SESSIONID
| TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE, &hToken)
GetTokenInformation( hToken, TokenSessionId, &logonSessionId, sizeof(DWORD), &dwTokenLength )
DWORD consoleSessionId = WTSGetActiveConsoleSessionId();
/* Can't use this - requires very elevated privileges (LOCAL only, SeTcbPrivileges as well)
if( !WTSQueryUserToken(consoleSessionId, &hToken))
...
*/
DuplicateTokenEx(hToken, (TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE), NULL, SecurityIdentification, TokenPrimary, &hDupToken))
// Look up the LUID for the TCB Name privilege.
LookupPrivilegeValue(NULL, SE_TCB_NAME, &tp.Privileges[0].Luid))
// Enable the TCB Name privilege in the token.
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hDupToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, 0))
{
DisplayError("AdjustTokenPrivileges");
...
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
DEBUG( "Token does not have the necessary privilege.\n");
} else {
DEBUG( "No error reported from AdjustTokenPrivileges!\n");
} // Never errors here
DEBUG(LM_INFO, "Attempting setting of sessionId to: %d\n", consoleSessionId );
if (!SetTokenInformation(hDupToken, TokenSessionId, &consoleSessionId, sizeof(DWORD)))
*** ALWAYS FAILS WITH 1314 HERE ***
Весь вывод отладки выглядит хорошо вплоть до вызова SetTokenInformation - я вижу, что сессия 0 является моей сессией текущего процесса, и в моем случае, это пытается установить сессию 1 (результат WTSGetActiveConsoleSessionId). (Обратите внимание, что я зарегистрирован в поле W2K8 через VNC, не RDC),
Таким образом - вопросы:
Любая справка, очень ценившая - Спасибо!
Для всех, кто интересуется решением этой проблемы:
Я обсуждал эту проблему со службой поддержки MS для команды LogonSDK. Похоже, что невозможно полностью олицетворять интерактивного пользователя программно, например, получить физическую консоль и связанные с ней конструкции GDI, и нам, по сути, «просто повезло», что это работало до сих пор. Они подтвердили, что изоляция сеанса 0 была основной причиной регресса.
Их рекомендация состоит в том, чтобы включить автоматический вход в интерактивный сеанс и провести рефакторинг службы для взаимодействия с новым клиентским компонентом в интерактивном сеансе. Чтобы устранить недостаток безопасности, связанный с этим, они рекомендуют реализовать замену оболочки, чтобы перевести сервер в режим «киоска» при входе в систему (например, запретить доступ к обозревателю без соответствующих учетных данных и т. Д.)
С другой стороны, это должно решить проблемы, с которыми мы столкнулись в сеансах обслуживания терминалов, убивают наше аппаратное ускорение.
Я отправлю запрос в MS, чтобы рассмотреть этот вариант использования «фермы рендеринга» для поддержки «сеанса прокси-пользователя» в будущих выпусках, чтобы сервер мог запускать процессы с аппаратным ускорением без нарушения безопасности, требующего наличия существующего клиентский пользовательский процесс, который должен войти в систему с консоли.