Domanda

Ho un servizio server Windows legacy e di applicazione (generato), che funziona bene in XP-64 e W2K3, ma non riesce a W2K8. Credo che sia a causa della nuova " sessione 0 isolamento " caratteristica.

Di conseguenza, sto cercando esempi di codice / impostazioni di sicurezza mojo che consentono di creare un nuovo processo da un servizio di Windows per Windows 2008 Server in modo che posso ripristinare (e possibilmente superare) il comportamento precedente. Ho bisogno di una soluzione che:

  1. Crea nuovo processo in una sessione non-zero per aggirare session-0 restrizioni di isolamento (non ha accesso a hardware grafico dalla sessione 0) - la linea MS ufficiale su questo è:
  

A causa Session 0 non è più un utente   sessione, servizi in esecuzione in   Session 0 non hanno accesso al   driver video. Ciò significa che qualsiasi   tentativo che un servizio fa da rendere   la grafica non riesce. Interrogazione del display   la risoluzione e profondità di colore nella Sessione   0 riporta i risultati corretti per il   sistema fino ad un massimo di 1920x1200 a   32 bit per pixel.

  1. Il nuovo processo ottiene una stazione di finestre / desktop (ad esempio winsta0 / default) che può essere utilizzato per creare finestre DC. Ho trovato una soluzione (che lancia OK in una sessione interattiva) per questo qui: Avvio di un processo client interattivo in C ++

  2. Le finestre DC, quando viene utilizzato come base per un OpenGL DescribePixelFormat enumerazione , è in grado di trovare e utilizzare il formato accelerazione hardware (su un sistema opportunamente dotato di hardware OpenGL.) si noti che la nostra soluzione attuale funziona bene su XP-64 e W2K3, a meno che una sessione di servizi terminal è esecuzione (VNC funziona bene.) una soluzione che ha permesso anche il processo di lavoro (cioè eseguito con accelerazione hardware OpenGL anche quando una sessione di servizi terminal è aperto) sarebbe fanastic, anche se non richiesto.

Sono bloccato al punto # 1 attualmente, e anche se ci sono alcuni messaggi simili che trattano questo (come questo , e questo - non sono soluzioni adeguate, in quanto non v'è alcuna garanzia di una sessione utente registrato già a" prendere" un ID di sessione da, né sono in esecuzione da un account LocalSystem (sto correndo da un account di dominio per il servizio, per il quale posso modificare i privilegi della, entro limiti ragionevoli, anche se preferirei non avere a crescere le priorità da includere SeTcbPrivileges.)

Per esempio - ecco uno stub che penso dovrebbe funzionare, ma restituisce sempre un errore 1314 sulla chiamata SetTokenInformation (anche se le AdjustTokenPrivileges restituito nessun errore) Ho usato alcune strategie alternative che coinvolgono "LogonUser" così (al posto di l'apertura del token di processo già esistente), ma io non riesco a scambiare l'id di sessione.

Sono anche dubbia sull'utilizzo del WTSActiveConsoleSessionId in tutti i casi (per esempio, se nessun utente interattivo è connesso) - anche se un test rapido del servizio in esecuzione con sessioni registrate nel sembrava restituire un valore di sessione ragionevole (1 ).

Ho gestione per facilità di lettura di errore (ancora un po 'confuso - scuse) rimosso

    //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 ***

Tutto l'output di debug guarda bene fino a quando la chiamata SetTokenInformation - vedo sessione 0 è la mia sessione di processo in corso, e nel mio caso, si sta cercando di impostare la sessione 1 (il risultato della WTSGetActiveConsoleSessionID). (Si noti che ho effettuato l'accesso nella casella di W2K8 tramite VNC, non RDC)

Così - una delle domande:

  1. E 'questo approccio valido, o sono tutti i processi di servizio avviato limitate alla sessione 0 intenzionalmente?
  2. C'è un approccio migliore (a corto di "Launch on logon" e auto-logon per i server?)
  3. C'è qualcosa di sbagliato in questo codice, o un modo diverso per creare un token processo dove I possono di swap fuori l'id di sessione per indicare Voglio deporre le uova il processo in una nuova sessione? Ho provato utilizzando LogonUser invece di OpenProcessToken, ma che non ha funzionato neanche. (Non mi importa se tutti i processi generati condividere lo stesso non-zero di sessione o non a questo punto.)

Qualsiasi aiuto molto apprezzato - grazie

È stato utile?

Soluzione

Per chiunque sia interessato nella risoluzione di questo problema:

Ho discusso questo problema con MS supporto per la squadra LogonSDK. Sembra che non sia possibile impersonare completamente un utente interattivo programmaticamente, in modo tale che si ottiene una console fisica e costrutti GDI associati, e siamo essenzialmente stati "solo fortunato" che ha funzionato fino ad ora. Hanno fatto confermano che la sessione 0 isolamento è stata la causa principale della regressione.

La loro raccomandazione è quello di consentire l'auto-logon ad una sessione interattiva, e refactoring il servizio di parlare con un nuovo componente client nella sessione interattiva. Per affrontare lo svantaggio sicurezza di questo, si consiglia di implementare una sostituzione della shell per porre il server in modalità "Kiosk" su di accesso (ad esempio, non ha accesso Explorer senza credenziali appropriate, ecc.)

Sul up-side, questo dovrebbe affrontare i problemi che stiamo incontrando con le sessioni di servizio terminale uccidendo la nostra accelerazione hardware.

Sarò inviando una richiesta a MS in considerazione questo tipo di "render farm" caso d'uso per "sessione utente proxy" sostegno nelle versioni future, in modo tale che un server può generare processi di accelerazione hardware senza compromettere la sicurezza di richiedere una esistente processo all'utente client di aver effettuato il login alla console.

Altri suggerimenti

Non ho completato il corso di formazione, ma ho trovato un tutorial "sessione 0 isolamento soluzione" sul sito Microsoft MSDN-:

http://msdn.microsoft.com/en-us/windows7trainingcourse_sessionisolation_unit.aspx

Ho lo stesso problema session-0-isolamento si manifesta all'interno di un'operazione pianificata.

farmComm lancerà l'applicazione (s) di vostra scelta nella sessione 0, senza interfaccia grafica visibile, ma con accesso a hardware grafico, se gli utenti siano collegati o non collegati. E risponde anche alle attività degli utenti in qualsiasi sessione è attiva (compreso sessione 0 o il "desktop sicuro", quando cioè la sessione attiva). È stato progettato per avviare applicazioni così quando gli utenti sono inattivi, e terminare in seguito al ripristino utente inattivo, ma tali condizioni eseguire potrebbe essere facilmente modificato in script AutoHotkey sorgente.

https://github.com/r-alex-hall/farmComm

Si genera applicazioni in sessione 0 "invisibile", ma può essere facilmente modificato (cambiare una variabile con il valore "nascondere" per "mostrare") per avere le interfacce grafiche di processi generati visibili (se hanno una GUI) . Se sono visibili, tuttavia, possono innescare o di Windows ronzini per vedere "messaggi" in sessione 0, e / o solo essere visibile dalla sessione 0 (che, a quanto pare, include qualsiasi momento il "desktop sicuro" è visibile - per ad esempio quando una workstation è bloccata, o scollegato da sessioni utente, o gli utenti non sono connessi).

In questa scrittura, se del caso Desktop (RDP) sessione remota è iniziata mentre i processi generati dalla corsa farmComm, farmComm terminerà quei processi e tentare di rilanciare loro di rispondere alla sessione RDP, che, se sono le applicazioni che tentare di accedere all'hardware grafico, può causare loro di crash (perché RDP limita l'accesso a hardware grafico). Probabilmente questo problema RDP potrebbe essere aggirato, anche. . . oppure si può modificare la fonte di non terminare i processi, o mai più migrare verso altre sessioni. (NOTA: un possibile cambiamento previsto è quello di consentire allo script se e quando farmComm termina, non pone fine, sospende o riprende i processi - o per quella materia, lo script l'esecuzione dei processi del tutto diverse quando gli utenti riprendono dal minimo) <. / p>

Gli script possono essere compilati eseguibili, che nella mia distribuzione, lo sono.

I cardini di questo set di strumenti sono una particolare versione di paexec (che lancia le applicazioni in sessione 0), e le risposte molto affidabili di AutoHotkey per l'attività degli utenti (o la sua assenza), e il recupero delle informazioni di sistema relativi a una sessione. L'opzione per lanciare i processi "nascosto" (senza interfaccia grafica visibile) anche tramite AutoHotkey.

Disclosure: ho sceneggiato (o codificati) farmComm, e rilasciato in pubblico dominio

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top