2010-06-04 13 views
7

Tengo una aplicación con un manifiesto que requiere ejecutarse como administrador, pero parte de la aplicación es asignar una unidad usando WNetAddConnection2 que creo que requiere que se ejecute en el contexto normal de usuario debido a credenciales ¿Hay alguna forma de ejecutar este código en el contexto normal del usuario sin crear un proceso separado?Ejecutar código en contexto de otros usuarios

EDITAR

A partir de los comentarios que he llegado hasta aquí, pero no funciona. Esperaba que no, ya que no entiendo muy bien cómo debería usar esto. ¿Quizás sea mejor si abro una nueva pregunta?

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(); 
    } 
} 

EDITAR

Si el usuario actual tiene privilegios de administrador, entonces el proceso principal está elevada con el manifiesto, en el código que se eleva Quiero ejecutar un comando en los usuarios no elevado espacio ya que parece tener diferentes variables de entorno, etc. Creo que una vez que se inicia un hilo, no puede cambiar, necesita ejecutar uno nuevo.

+0

La manera de obtener el token de autenticación de usuario actual es a través de WindowsIdentity.GetCurrent(). Token. Sin embargo, creo que en su caso devolverá el token del usuario administrador (ya que su aplicación se está ejecutando como administrador). –

+0

Esto es suplantación. Un muy útil [paquete nuget] (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) y [la publicación relacionada] (https://stackoverflow.com/a/7250145/465053) para lograr el mismo a través de 'LogonUser()' p/invocar llamada. – RBT

Respuesta

0

Im no estoy seguro de que esto es una manera de hacer esto sin crear un nuevo proceso, ImpersonateLoggedOnUser solo funcionará desde un servicio, y no quiero proporcionar credenciales.

me corrija si estoy equivocado

+0

¿Cómo desea suplantar a un usuario sin proporcionar las credenciales? Quiero decir, ¿quieres proporcionar solo el nombre de usuario? ¿O qué más? –

+0

Si el usuario actual tiene privilegios de administrador, entonces el proceso principal se eleva con el manifiesto, en este código que es elevado, quiero ejecutar un comando en el espacio no elevado del usuario, ya que parece tener diferentes variables de entorno, etc. Creo que una vez se inicia un subproceso no se puede cambiar solo, necesita ejecutar uno nuevo –

+0

Así es como se hace la suplantación en proc. Un muy útil [paquete nuget] (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) y [la publicación relacionada] (https://stackoverflow.com/a/7250145/465053) para lograr el mismo a través de 'LogonUser()' p/invocar llamada. – RBT

1

Primero debe obtener el token de usuario que desea iniciar la aplicación, puede hacerlo usando WTSQueryUserToken. Si el usuario aún no ha iniciado sesión, puede usar LogonUser Win32 API para obtener una nueva en una nueva sesión. Para obtener todas las sesiones en su computadora, puede usar WTSEnumerateSessions.

Luego, una vez que tenga el token, puede usar CreateProcessAsUser o bien ImpersonateLoggedOnUser Win32 APIs.

Por favor, asegúrese de llamar al CloseHandle en los mangos que obtenga, son especialmente malas fugas para este tipo de trabajo.

+0

No olvide mencionar para llamar a la función CloseHandle una vez que termine de usar el token devuelto por la función LogonUser. Si no lo hace, puede tener una fuga de identificador de nivel de sistema operativo. He visto esto suceder antes. –

+0

@Carlos: también son especialmente malas fugas. Agregué un comentario sobre eso. –

+0

Arent ambos CreateProcessAsUser y ImpersonateLoggedOnUser utilizados para crear un nuevo hilo con credenciales diferentes? ¿Cómo puedo obtener WNetAddConnections2 para ejecutar en este nuevo proceso? –

4

eche un vistazo al artículo del proyecto de código A small C# Class for impersonating a User. Implementa una clase IDisposable (que libera el token de autenticación después de su uso). He visto fugas de código .NET debido a que no se han liberado los tokens de suplantación.

Puede suplantar a un usuario solo por un bloque de código que accederá al recurso de red al que necesita acceder como un usuario diferente. Su código se verá como

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

Espero que ayude.

Cuestiones relacionadas