2011-07-28 13 views
5

Jestem programista ekspert, więc w związku z tym, nie mam pojęcia, WTH robię :)C# stan usługi na komputerze zdalnym

Na serio; Nie, nie jestem ekspertem w żaden sposób. Mam jednak problem i nie wiem, jak to naprawić. Dobrą rzeczą jest to, że (myślę, że) wiem, na czym polega problem, i mam nadzieję, że ktoś tu może pomóc.

Oto streszczenie problemu. Tworzę formularz w języku C#, który wykona dla mnie zadanie administrowania serwerem i bazą danych. Mam przycisk, który po kliknięciu ma przywrócić status usługi "x" na serwerze "y". Status jest drukowany na ekranie do pola tekstowego.

Oto mój kod:

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

otrzymuję wyjątki, w zasadzie mówiąc: "Server" nie można otworzyć "usługa" na Ponieważ jest to serwer zdalny, zakładam, że jest to problem z poświadczeniami/bezpieczeństwem. NIE mam jednak żadnych problemów z usługą Spooler.

Moje pytanie brzmi ... Jak mogę przekazać identyfikator użytkownika i hasło do tego serwera, aby uwierzytelnił się lub uruchomił, aby sprawdzić stan tych usług, to jest problem. Jeśli ktoś robi, że jego problem, to proszę poinformować mnie gdzie mam poszło :)

+0

OK, znalazłem jak t o zrób to, ale nie bardzo rozumiem, jak kodować. Z tego, co przeczytałem, muszę zawijać to, co chcę zrobić powyżej, w jakimś kodzie, który podszywa się pod ID użytkownika, a następnie po otrzymaniu żądanej informacji, cofa podszywanie się. Rozumiem, że trudne kodowanie informacji o użytkowniku nie jest najbezpieczniejszym sposobem, aby to zrobić, ale wystarczy na to, do czego to będzie przeznaczone. Będę badać jak podszywać się pod C#. – Jason

Odpowiedz

10

końcu zorientowaliśmy się ...

Utworzono nową klasę, i przedstawiono poniżej:

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

}

i oryginalny kod, który napisałem jest owinięty przez:

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

Czy działa to tylko w środowiskach, w których wszystko jest podłączone do kontrolera domeny? –

+0

To będzie działać w wielu domenach tylko wtedy, gdy skonfigurujesz zaufanie między nimi. –

Powiązane problemy