2014-11-21 12 views
5

Sto utilizzando CreateProcessAsUser per creare un processo con credenziali specificate dall'utente.CreateProcessAsUser crea una finestra vuota/nera

Sto postando quelle che si spera siano le parti rilevanti del codice. Fammi sapere se vuoi vedere di più.

Prima LogonUser per ottenere il token:

result = LogonUser(
     username, 
     wcschr(username, '@') ? NULL : (domain ? domain : L"."), 
     password, 
     LOGON32_LOGON_INTERACTIVE, 
     LOGON32_PROVIDER_DEFAULT, 
     &hrunastoken); 

Ho poi caricare il profilo, impostare il valore lpDesktop della struttura STARTUPINFO a NULL (che lo rende usare il desktop del processo chiamante), e chiamare CreateProcessAsUser :

result = CreateProcessAsUser(
     hrunastoken, 
     NULL, 
     apptorun, 
     NULL, 
     NULL, 
     FALSE, 
     CREATE_UNICODE_ENVIRONMENT, 
     envblock ? envblock : NULL, 
     NULL, 
     &si, 
     &pi); 

Questo funziona correttamente: esegue l'accesso e crea il processo con esito positivo e il processo "funziona". Il problema è che le finestre che crea sono nero, come in questo screenshot di un processo di blocco note iniziato con il mio programma:

notepad screenshot

contesto Forse rilevanti:

Il mio account è un account locale su un Windows 7 macchina con diritti di amministratore completi e sono connesso con tale account. Ho usato psexec (utility Sysinternals) per aprire un prompt dei comandi in esecuzione in modo interattivo con l'account di sistema locale. Sto lanciando il mio programma da quel prompt dei comandi. Le credenziali che sto passando ad esso sono dal mio account.

Non ho fatto nulla con permessi alle finestre/desktop; Presumo che il processo che creo debba avere diritti su quelli in quanto il processo viene creato nella mia sessione e utilizzando lo stesso account con cui ho già effettuato l'accesso, anche se prima devo passare attraverso l'account SYSTEM. Utilizzando Process Explorer, non vedo alcuna differenza nelle autorizzazioni sui valori e sugli handle di windowstation/desktop dal processo aperto tramite il mio programma o aperto normalmente. Forse è del tutto irrilevante.

Non riesco neanche a utilizzare la funzione CreateProcessWithLogonW perché deve funzionare quando viene eseguito dall'account SYSTEM: quella funzione e il programma "runas" fornito con Windows non funzionano in SYSTEM.

Stranamente, non posso usare il mio metodo attuale per aprire i processi a meno che non lo stia eseguendo sotto l'account SYSTEM, poiché "un privilegio richiesto non è mantenuto dal client", quindi non posso confrontare le finestre creato all'avvio del mio programma sotto il mio account vs l'account SYSTEM ...

+0

Stai passando | envblock |?Questo assomiglia molto al codice che uso con successo. Differenze essendo (forse): passo sempre un blocco ambiente creato con CreateEnvironmentBlock() e il token utente nel mio caso proviene da WTSQueryUserToken(). – NuSkooler

+0

@NuSkooler Se la chiamata a CreateEnvironmentBlock() ha avuto esito positivo, passo il blocco dell'ambiente. E la chiamata ha successo come il programma mi informa se non lo è, e ho controllato l'ambiente di processo con Process Explorer e l'ambiente dell'utente è stato caricato. – eurotrash

+1

@NuSkooler: WTSQueryUserToken ti fornirà un token che include il SID di accesso per la sessione di destinazione, in modo che il processo figlio disponga già di tutte le autorizzazioni necessarie per la stazione della finestra e il desktop. Ecco perché funziona per te ma non per l'OP. –

risposta

4

Il DACL predefinito per finestre e desktop concede l'accesso completo al SID di accesso (che è unico per l'attuale logon session) anziché per il SID dell'utente. Il SID dell'utente appare anche nel DACL per la stazione finestra ma ha solo autorizzazioni limitate. Non viene visualizzato nel DACL desktop.

La chiamata a LogonUser genera una nuova sessione (e il SID di accesso associato) anziché riutilizzare quello esistente, quindi il tuo processo non ha accesso al desktop e ha solo un accesso minimo alla stazione della finestra. (In realtà sono un po 'perplesso su come il processo riesca a funzionare, quando ho cercato di riprodurre i risultati il ​​processo è terminato immediatamente con codice di uscita 0xC0000142, come previsto.)

Il secondo pezzo di codice negli spettacoli this answer come cambiare il DACL sulla stazione della finestra e sul desktop per consentire al processo di funzionare correttamente. (Questa potrebbe non essere la soluzione migliore, tuttavia, a seconda dei tuoi obiettivi specifici.)

+0

Aggiunta di autorizzazioni alla stazione della finestra e desktop risolti, grazie mille. Ri: i processi che escono immediatamente con il codice 0xC0000142, in effetti sto sperimentando anche quello, se l'utente con le credenziali che passo al mio programma non è un membro del gruppo degli amministratori. Se si tratta di un membro, il processo inizia correttamente. E sto ancora riscontrando questo comportamento dopo aver apportato le modifiche per mostrare correttamente la GUI. Ancora risoluzione dei problemi ... – eurotrash

+0

Immagino che il codice nella risposta collegata sia stato testato solo per gli utenti amministrativi, probabilmente è sufficiente regolare una o entrambe le maschere delle autorizzazioni. Ho modificato la mia risposta per includere la modifica che consiglio di provare prima. Per favore fatemi sapere se funziona, in tal caso modificheremo l'altra risposta di conseguenza. –

+0

Posso confermare l'aggiunta di 'READ_CONTROL' e anche di' WINSTA_ALL_ACCESS' alle autorizzazioni di accesso per la stazione della finestra che l'ha risolto: i processi creati in account non-admin vengono avviati correttamente. Grazie enormi! – eurotrash

Problemi correlati