2010-03-09 14 views
10

Tengo un exe de C# que necesita ejecutarse usando WMI y acceder a un recurso compartido de red. Sin embargo, cuando accedo a compartir, obtengo una Access Access no autorizada. Si ejecuto el archivo exe directamente, se puede acceder al recurso compartido. Estoy usando la misma cuenta de usuario en ambos casos.Autenticación de red al ejecutar exe desde WMI

Mi aplicación tiene dos partes, un cliente de GUI que se ejecuta en una PC local y un proceso de back-end que se ejecuta en una PC remota. Cuando el cliente necesita conectarse al backend, primero inicia el proceso remoto usando WMI (código reproducido a continuación). El proceso remoto hace varias cosas, incluido el acceso a un recurso compartido de red usando Directory.GetDirectories() e informa al cliente.

Cuando el cliente inicia automáticamente el proceso remoto utilizando WMI, no puede acceder al recurso compartido de red. Sin embargo, si me conecto a la máquina remota usando Escritorio Remoto e inicio manualmente el proceso de back-end, el acceso al recurso compartido de red se realiza correctamente.

El usuario especificado en la llamada WMI y el usuario que inició sesión en el Escritorio remoto son los mismos, por lo que los permisos deben ser los mismos, ¿no es así?

Veo en la entrada de MSDN Directory.Exists() que dice "El método Exists no realiza autenticación de red. Si consulta un recurso compartido de red existente sin autenticación previa, el método Exists devolverá falso". Supongo que esto está relacionado? ¿Cómo puedo asegurarme de que el usuario esté autenticado correctamente en una sesión de WMI?

ConnectionOptions opts = new ConnectionOptions(); 

opts.Username = username; 
opts.Password = password; 

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost)); 

ManagementScope scope = new ManagementScope(path, opts); 

scope.Connect(); 

ObjectGetOptions getOpts = new ObjectGetOptions(); 
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts)) 
{ 
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create"); 
    inParams["CommandLine"] = commandLine; 
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null); 
} 
+1

problema similar http://stackoverflow.com/questions/2291921/c-wmi-runs-an-exe-on-a-remote-computer-that-then-runs-another-exe-on-the- same-co/2291991 # 2291991 – lsalamon

+0

Gracias, mi búsqueda no lo había demostrado. Voy a leer y ver si me ayuda. – Andy

+0

He agregado al usuario y me han otorgado todas las permanentes, pero no hay ninguna diferencia :( – Andy

Respuesta

2

Después de haber seguido el enlace sugerido por Isalamon anterior (gracias) He seguido el consejo de Jestro y reescrito usando psexec.exe (que se puede descargar desde http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) en lugar de WMI. Parece un poco incierto hacerlo de esta manera, pero parece funcionar.

nuevo código para cualquier persona que está experimentando problemas similares:

Process proc = new Process(); 
proc.StartInfo.FileName = "PsExec.exe"; 
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}", 
             remoteHost, 
             domain, 
             username, 
             password, 
             commandLine); 
proc.StartInfo.CreateNoWindow = true; 
proc.StartInfo.UseShellExecute = false; 
proc.Start(); 
1

WMI sólo utiliza suplantación cuando se ejecuta el proceso remoto, que no le da acceso a la red. Si está bien saliendo del código administrado, puede asignar una ruta UNC en el proceso remoto. WMI comenzó a usar las credenciales que desee. Entonces, tiene el acceso a la red que desea. Utilizo NetUseAdd y NetUseDel desde netapi32.dll para mapear la ruta UNC. Consulte http://pinvoke.net/ para obtener detalles sobre el uso de las API.

0

Puede escribir todos los comandos en el archivo por lotes en la máquina remota, que incluye el uso de la red (no es necesario usar una letra de unidad) para realizar una autenticación. Funciona bien de esa manera. Todavía estoy trabajando en una alternativa.

+0

En realidad, si haces algo como esto funcionará también, acabo de probarlo: – Will

+0

OOps aquí está: inParams ["CommandLine"] = "cmd/c \" "+" net use \\\\ server \\ c $ password/user: domain \\ username && <\\ server \ share \ whatever.bat> "+" \ "> c: \\ temp \\ r_output.txt"; Lo registro para recuperar el resultado más tarde en mi código. En este caso registra el funcionamiento del archivo de proceso por lotes no los comandos en él. – Will

1

Sé que haya ordenado mediante el uso de PSEXEC, que es un programa fantástico, pero si quería volver a WMI, ¿ha intentado que permite lo siguiente en sus ConnectionOptions:

  • La bandera EnablePrivileges
  • configurando la suplantación en ImpersonationLevel.Suplantar a

que hace lo siguiente:

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx

Creo que deberían informar a su WMI para permitir que en realidad el programa tenga las credenciales correctas y así acceder al recurso compartido de red

Cuestiones relacionadas