Windows 2008 RenderFarm Service: CreateProcessAsUser "Session 0 Isolation" - und OpenGL -
Ich habe ein legacy-Windows-server-Dienst und (erzeugt) - Anwendung, die gut funktioniert in XP-64 und W2K3, aber nicht auf W2K8. Ich glaube, es ist wegen der neuen " Isolation der Sitzung 0 " - Funktion.
Somit bin ich auf der Suche nach code-samples/security-Einstellungen, mojo, lassen Sie Sie erstellen eines neuen Prozess aus einem windows-Dienst für Windows 2008 Server, so dass ich wiederherstellen können (und möglicherweise übertreffen die vorherigen Verhalten. Ich brauche eine Lösung, die:
- Schafft der neue Prozess in einer nicht-null-Sitzung zu bekommen, um session-0-isolation Einschränkungen (kein Zugriff auf Grafik-hardware von Sitzung 0) - das offizielle MS Linie auf dies ist:
Da Session 0 nicht mehr Nutzer
Sitzung-Dienste, die ausgeführt werden im
Sitzung 0 haben keinen Zugriff auf die
video-Treiber. Dies bedeutet, dass jede
Versuch, einen Dienst zu erbringen
Grafik ausfällt. Abfragen der Anzeige
Auflösung und Farbtiefe in der Sitzung
0 Berichte, die richtigen Ergebnisse für die
system bis zu maximal 1920 x 1200 bei
32 bits pro pixel.
-
Den neuen Prozess bekommt ein Fenster station/desktop (z.B. winsta0/Standard), die verwendet werden können zum erstellen von windows-DCs. Ich habe eine Lösung gefunden (, startet OK in einer interaktiven Sitzung) hier: Starten Sie eine Interaktive Client-Prozess in C++
-
Den windows DC, wenn als Grundlage für eine OpenGL DescribePixelFormat enumeration, ist in der Lage zu finden und zu verwenden, die hardware-beschleunigten format (auf einem system entsprechend ausgerüstet mit OpenGL-hardware). Beachten Sie, dass unsere aktuelle Lösung funktioniert auf XP-64 und W2K3, außer, wenn eine Terminaldienste-Sitzung ausgeführt wird (VNC funktioniert einwandfrei.) Eine Lösung, die auch zulässig, den Prozess zu arbeiten (D. H. laufen mit OpenGL-hardware-Beschleunigung, selbst wenn ein terminal services-Sitzung geöffnet ist), wäre die grandiose, wenn auch nicht erforderlich.
Ich bin stecken in der Position #1 zur Zeit, und obwohl es einige ähnliche postings, besprechen Sie dies (wie diese, und diese - Sie sind nicht geeignet, Lösungen, da es keine Garantie für eine Benutzer-session bereits angemeldet, um "" die Sitzungs-id aus, noch bin ich von einem Konto "LocalSystem" (ich bin mit von Sie ein Domänenkonto für den service, für die ich anpassen können, die Vorrechte, die sich im Rahmen des zumutbaren, obwohl ich würde lieber nicht haben, um zu eskalieren, Prioritäten zu gehören SeTcbPrivileges.)
Zum Beispiel - hier ist ein stub, ich denke, dass sollte funktionieren, ist aber immer wieder eine Fehlermeldung 1314 auf dem SetTokenInformation nennen (obwohl die AdjustTokenPrivileges wieder keine Fehler) ich habe einige Alternative Strategien mit "LogonUser" als auch (anstelle der öffnung der bestehenden Prozess-token), aber ich kann nicht scheinen, um die swap-session-id.
Ich bin auch skeptisch, was die Verwendung der WTSActiveConsoleSessionId in allen Fällen (zum Beispiel, wenn kein interaktiver Benutzer angemeldet ist) - obwohl ein kurzer test des Dienstes läuft mit keine Sitzungen protokolliert schien, um wieder eine vernünftige session-Wert (1).
Habe ich entfernt Fehlerbehandlung für Leichtigkeit des Lesens (noch ein bisschen chaotisch - Entschuldigung)
//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 ***
Alle die debug-Ausgabe sieht gut aus, bis die SetTokenInformation nennen - ich sehe die Sitzung 0 ist meine aktuelle Prozess-Sitzung, und in meinem Fall, versucht er zu " set session 1 (das Ergebnis der Sie wtsgetactiveconsolesessionid). (Beachten Sie, dass ich angemeldet bin die W2K8-box via VNC, nicht RDC)
So eine der Fragen:
- Ist dieser Ansatz gültig ist, oder sind alle service-initiierten Prozesse beschränkt Sitzung 0-absichtlich?
- Gibt es einen besseren Ansatz (kurz für "Start on logon" und " auto-Anmeldung für den Server?)
- Gibt es etwas falsch mit diesem code, oder eine andere Möglichkeit zum erstellen einer Prozess-token, wo ich kann tauschen Sie die session-id zu zeigen, dass ich will, um zu laichen, den Prozess in eine neue Sitzung? Ich habe versucht, mit LogonUser statt OpenProcessToken, aber das hat nicht funktioniert entweder. (I dont care, wenn alle gespawnt Prozesse teilen sich die gleichen nicht-null-Sitzung nicht oder nicht an dieser Stelle.)
Jede Hilfe sehr geschätzt - danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für alle interessierten in der Lösung des Problems:
Diskutierte ich dieses Problem mit dem MS-Support für die LogonSDK team. Es scheint, dass es nicht möglich ist, vollständig zu imitieren, eine interaktive Benutzeroberfläche programmgesteuert, so dass Sie eine physische Konsole und die zugehörigen GDI-Konstrukte, und wir haben im wesentlichen "einfach nur Glück", dass es bis jetzt funktioniert. Sie haben bestätigt, dass Sitzung 0-Isolierung wurde die Ursache der regression.
Ihre Empfehlung ist für die Aktivierung der automatischen Anmeldung zu einer interaktiven Sitzung ein, und überarbeiten Sie den service zu sprechen, um eine neue client-Komponente in der interaktiven Sitzung. Sich um die Sicherheit Nachteil, empfehlen Sie die Implementierung eines shell-Ersatz der server in einem "Kiosk" - Modus bei der Anmeldung (z.B. keine Explorer-Zugriff ohne entsprechende Anmeldeinformationen, etc.)
Auf der up-Seite, sollte diese Adresse die Probleme, die wir haben, seit der Begegnung mit terminal-Dienst-Sitzungen töten unsere hardware-Beschleunigung.
Ich werde die Einreichung einer Anfrage an MS denke über diese Art der "render-farm" use case für "proxy-Benutzer-session" - Unterstützung in zukünftigen Versionen, so dass ein server spawnen können hardware-beschleunigt Prozesse, ohne die Gefährdung der Sicherheit der dass eine bestehende client-Benutzer angemeldet sein auf der Konsole.
Habe ich nicht die Ausbildung abgeschlossen natürlich, aber ich fand eine "Session 0 isolation Abhilfe" - tutorial auf der Microsoft-MSDN-Website:
http://msdn.microsoft.com/en-us/windows7trainingcourse_sessionisolation_unit.aspx
Habe ich die gleiche session-0-isolation problem manifestiert sich in einem geplanten task.
farmComm starten Sie die Anwendung(en) Ihrer Wahl in Sitzung 0 ist, ohne GUI sichtbar, aber mit Zugriff auf Grafik-hardware, ob Benutzer angemeldet sind oder nicht. Es reagiert auch auf Benutzer-Aktivität, in welcher Sitzung aktiv ist (einschließlich session-0, oder der "secure desktop", wo Sie die aktive Sitzung). Es ist entworfen, um Anwendungen zu starten also, wenn Benutzer untätig sind, und beenden Sie Sie auf Benutzer fortsetzen aus dem Ruhezustand, aber diese Bedingungen ausführen könnte leicht verändert werden, in der Quelle AutoHotkey-scripts.
https://github.com/r-alex-hall/farmComm
Laicht Anwendungen in session 0 "unsichtbar", aber es kann sehr leicht geändert werden (ändern Sie eine variable mit dem Wert "hide" auf "show") zu haben, die GUIs hervorgebracht Prozesse sichtbar (wenn Sie eine GUI haben). Wenn Sie sichtbar sind, können Sie jedoch entweder trigger-Windows nags, um zu sehen, "Nachrichten", der in Sitzung 0, und/oder nur sichtbar sein, die von Sitzung 0 (die, so scheint es, beinhaltet jedes mal, wenn der "sichere desktop" sichtbar ist--zum Beispiel, wenn eine Arbeitsstation gesperrt ist, oder getrennt von Benutzer-sessions, oder kein Benutzer angemeldet).
In diesem schreiben, wenn alle Remote-Desktop (RDP) - Sitzung begonnen wird, während Prozesse hervorgebracht von farmComm laufen, farmComm wird, beenden Sie diese Prozesse und versucht neu zu starten, um zu reagieren, um die RDP-Sitzung, die, wenn Sie Anwendungen, die versuchen Zugriff auf Grafik-hardware, kann dazu führen Sie zum Absturz zu bringen (weil RDP-schränkt den Zugriff auf Grafik-hardware). Wahrscheinlich das RDP-problem könnte umgangen werden, auch . . . oder Sie können zwicken die Quelle nie beenden von Prozessen oder nie migrieren zu anderen Sitzungen. (HINWEIS: eine mögliche geplante änderung ist Ihnen zu ermöglichen, Skript, ob und Wann farmComm beendet, nicht beendet, angehalten oder fortgesetzt Prozesse--oder für diese Angelegenheit, Skript und es laufen ganz andere Prozesse als Benutzer resume aus dem Ruhezustand).
Die Scripte können kompiliert werden, um ausführbare Programme, die in meine distribution, die Sie sind.
Den Dreh-und Angelpunkt dieses toolset sind eine Besondere version von paexec (die startet Anwendungen in Sitzung 0), und AutoHotkey ist sehr zuverlässig Antworten auf Benutzer-Aktivität (oder deren fehlen) und abrufen von system-Informationen zu einer Sitzung. Die option zum starten von Prozessen "versteckt" (ohne GUI sichtbar ist) auch per AutoHotkey.
Offenlegung: ich gescriptet (oder codiert), farmComm, und veröffentlicht es in die Public Domain.