2010-06-04 11 views
7

Ho un'app con un manifest che richiede l'esecuzione come amministratore, ma una parte dell'app consiste nel mappare un'unità utilizzando WNetAddConnection2 che, a mio avviso, richiede l'esecuzione nel normale contesto utente a causa delle credenziali ecc. Esiste un modo per eseguire questo bit di codice nel normale contesto utente senza creare un processo separato.Esegui codice in un altro contesto utente

EDIT

Dai commenti che ho ottenuto fino a questo punto, ma pretende molto lavoro. Mi aspettavo di non farlo perché non capisco davvero come dovrei usarlo. Forse è meglio se apro una nuova domanda?

class Program 
{ 
    [DllImport("advapi32.DLL")] 
    public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); 
    [DllImport("advapi32.DLL")] 
    public static extern bool RevertToSelf(); 

    static void Main(string[] args) 
    { 
     IntPtr phToken = IntPtr.Zero; 
     ImpersonateLoggedOnUser(phToken); 
     MapDrives(); 
     RevertToSelf(); 
    } 
} 

EDIT

Se l'utente corrente dispone dei privilegi di amministratore, allora il processo principale è elevata con il manifesto, nel codice, che è elevata voglio correre un comando negli utenti non elevati spazio poiché questo sembra avere diverse variabili d'ambiente, ecc. Credo che una volta avviato un thread non può cambiare da solo, è necessario eseguirne uno nuovo.

+0

Il modo per ottenere il token di autenticazione dell'utente corrente è attraverso WindowsIdentity.GetCurrent(). Token. Tuttavia, penso che nel tuo caso restituirà il token dell'utente amministratore (dato che l'applicazione è in esecuzione come amministratore). –

+0

Questa è la rappresentazione. Un [pacchetto nuget] molto utile (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) e [il post correlato] (https://stackoverflow.com/a/7250145/465053) per raggiungere il stesso tramite 'LogonUser()' p/invoca la chiamata. – RBT

risposta

0

Non sono sicuro che questo sia un modo per farlo senza creare un nuovo processo, ImpersonateLoggedOnUser funzionerà solo da un servizio e non desidero fornire credenziali.

mi corregga se sbaglio

+0

Come si desidera impersonare un utente senza fornire le credenziali? Voglio dire, ti piacerebbe fornire solo il nome utente? O che altro? –

+0

Se l'utente corrente ha privilegi di amministratore, il processo principale viene elevato con manifest, in questo codice che è elevato voglio eseguire un comando nello spazio non elevato degli utenti poiché questo sembra avere variabili d'ambiente diverse ecc. Credo una volta si avvia una discussione non è possibile cambiarla, è necessario eseguirne una nuova –

+0

Ecco come si esegue la rappresentazione in-process. Un [pacchetto nuget] molto utile (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) e [il post correlato] (https://stackoverflow.com/a/7250145/465053) per raggiungere il stesso tramite 'LogonUser()' p/invoca la chiamata. – RBT

1

Per prima cosa è necessario ottenere il token utente per il quale si desidera avviare l'app, è possibile farlo utilizzando WTSQueryUserToken. Se l'utente non è ancora connesso, è possibile utilizzare l'API Win32 LogonUser per ottenerne uno nuovo in una nuova sessione. Per ottenere tutte le sessioni sul tuo computer puoi usare WTSEnumerateSessions.

Quindi, una volta ottenuto il token, è possibile utilizzare le API Win32 ImpersonateLoggedOnUser.

Si prega di assicurarsi di chiamare CloseHandle sulle maniglie che si ottiene, sono particolarmente cattive perdite per questo tipo di lavoro.

+0

Si prega di non dimenticare di menzionare per chiamare la funzione CloseHandle dopo aver finito di utilizzare il token restituito dalla funzione LogonUser. Se non si esegue questa operazione, è possibile che si verifichi una perdita di gestione a livello di sistema operativo. Ho visto questo accadere prima. –

+0

@Carlos: Idem anche loro sono in particolare cattive perdite. Ho aggiunto un commento a riguardo. –

+0

Arent sia CreateProcessAsUser che ImpersonateLoggedOnUser utilizzati per creare un nuovo thread con credenziali diverse? Come faccio a ottenere WNetAddConnections2 per l'esecuzione in questo nuovo processo? –

4

dai un'occhiata all'articolo di progetto codice A small C# Class for impersonating a User. Implementa una classe IDisposable (che rilascia il token di autenticazione dopo il suo utilizzo). Ho visto perdite di codice .NET a causa del mancato rilascio dei token di rappresentazione.

È possibile impersonare un utente solo per un blocco di codice che accederà alla risorsa di rete a cui è necessario accedere come utente diverso. Il tuo codice sarà simile a

using (new Impersonator("myUsername", "myDomainname", "myPassword")) 
{ 
    /* code that executes under the new context */ 
    ... 
} 

Spero che sia d'aiuto.