2011-07-28 11 views
5

soy un experto programador, por lo tanto, no tengo la menor idea de WTH que estoy haciendo :)C# Servicio de estado en la máquina remota

En una nota grave; no, no soy experto de ninguna manera. Sin embargo, tengo un problema y no sé cómo solucionarlo. Lo bueno es que yo (creo que) sé cuál es el problema, y ​​espero que alguien aquí pueda ayudar.

Aquí está la sinopsis del problema. Estoy creando un formulario en C# que me hará alguna tarea de administración de servidores y bases de datos. Tengo un botón que cuando se hace clic se supone que devuelve el estado del servicio del servicio "x" en el servidor "y". El estado se imprime en la pantalla en un cuadro de texto.

Aquí está mi código:

 private void button2_Click(object sender, EventArgs e) 
    { 
     string fs = "Service X Status = "; 
     string mr = "Service A Status = "; 
     string qp = "Service B Status = "; 
     string sp = "Spooler Service Status = "; 
     ServiceController fssc = new ServiceController("xService", "yServer"); 
     ServiceController mrsc = new ServiceController("aService", "yServer"); 
     ServiceController qpsc = new ServiceController("bService", "yServer"); 
     ServiceController spsc = new ServiceController("Spooler", "yServer"); 

     try 
     { 
      txtGtwySts.AppendText(sp + spsc.Status.ToString()); 
      txtGtwySts.AppendText(Environment.NewLine); 
      txtGtwySts.AppendText(fs + fssc.Status.ToString()); 
      txtGtwySts.AppendText(Environment.NewLine); 
      txtGtwySts.AppendText(mr + mrsc.Status.ToString()); 
      txtGtwySts.AppendText(Environment.NewLine); 
      txtGtwySts.AppendText(qp + qpsc.Status.ToString()); 
     } 
     catch (Exception crap) 
     { 
      string msg = ""; 
      int i; 
      for (i = 0; i < crap.Message.Count(); i++) 
      { 
       msg += "Error # " + i + " Message: " + crap.Message + "\n"; 

      } 
      MessageBox.Show(msg); 
      MessageBox.Show(i.ToString()); 
     } 
    } 

consigo excepciones, básicamente diciendo: "Servidor" No se puede abrir "servicio" en la Como se trata de un servidor remoto, asumo que se trata de un problema de credencial/seguridad. NO, sin embargo, tengo ningún problema con el servicio de Spooler.

Mi pregunta es ... ¿Cómo puedo pasar el ID de usuario y la contraseña a este servidor para que se autentique o ejecute para que pueda verificar el estado de estos servicios, ese es el problema. Si alguien no piensa su problema, por favor, me informen donde he salió mal :)

+0

OK, he encontrado la forma de t o haz esto, pero no entiendo muy bien cómo codificar. Por lo que he leído, debo ajustar lo que quiero hacer arriba en algún código que se haga pasar por el ID de usuario y luego, una vez que obtenga la información solicitada, deshaga la suplantación. Entiendo que codificar la información del usuario no es la forma más segura de hacerlo, pero será suficiente para lo que se va a usar. Seguiré investigando sobre cómo suplantar a C#. – Jason

Respuesta

10

Finalmente lo descubrió ...

creado una nueva clase, y se muestra a continuación:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Security.Principal; 
using System.Runtime.InteropServices; 
using System.Security.Permissions; 

public class ImpersonateUser 
{ 
    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool LogonUser(
    String lpszUsername, 
    String lpszDomain, 
    String lpszPassword, 
    int dwLogonType, 
    int dwLogonProvider, 
    ref IntPtr phToken); 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public extern static bool CloseHandle(IntPtr handle); 
    private static IntPtr tokenHandle = new IntPtr(0); 
    private static WindowsImpersonationContext impersonatedUser; 
    // If you incorporate this code into a DLL, be sure to demand that it 
    // runs with FullTrust. 
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
    public void Impersonate(string domainName, string userName, string password) 
    { 
     //try 
     { 
      // Use the unmanaged LogonUser function to get the user token for 
      // the specified user, domain, and password. 
      const int LOGON32_PROVIDER_DEFAULT = 0; 
      // Passing this parameter causes LogonUser to create a primary token. 
      const int LOGON32_LOGON_INTERACTIVE = 2; 
      tokenHandle = IntPtr.Zero; 
      // ---- Step - 1 
      // Call LogonUser to obtain a handle to an access token. 
      bool returnValue = LogonUser(
      userName, 
      domainName, 
      password, 
      LOGON32_LOGON_INTERACTIVE, 
      LOGON32_PROVIDER_DEFAULT, 
      ref tokenHandle); // tokenHandle - new security token 
      if (false == returnValue) 
      { 
       int ret = Marshal.GetLastWin32Error(); 
       throw new System.ComponentModel.Win32Exception(ret); 
      } 
      // ---- Step - 2 
      WindowsIdentity newId = new WindowsIdentity(tokenHandle); 
      // ---- Step - 3 
      { 
       impersonatedUser = newId.Impersonate(); 
      } 
     } 
    } 
    // Stops impersonation 
    public void Undo() 
    { 
     impersonatedUser.Undo(); 
     // Free the tokens. 
     if (tokenHandle != IntPtr.Zero) 
     { 
      CloseHandle(tokenHandle); 
     }    
    }   
}  

}

y el código original que he publicado es envuelta por:

ImpersonateUser iu = new ImpersonateUser(); 
iu.Impersonate("[domain]","[username]","[password]"); 
// code you want to execute as impersonated user..... 
iu.Undo(); 
+1

¿Esto solo funciona en entornos donde todo está conectado a un controlador de dominio? –

+0

Esto funcionará entre dominios solo si tienen una confianza establecida entre ellos. –

Cuestiones relacionadas