2010-09-23 7 views
2

Je viens de passer 2 jours à lire un tas de choses sur l'usurpation d'identité en C# (y compris les articles stackoverflow et codeproject) et voici le résultat de mes investigations. Pour faire court, je veux juste commencer et arrêter un service à partir d'une application winform fonctionnant sous un compte d'utilisateur standard (non privilégié). Je veux usurper l'identité de mon utilisateur avec un compte admin. Les deux comptes sont des comptes locaux.C# Winform L'usurpation d'identité ne fonctionne pas

Dans le code ci-dessous, je ne reçois aucune erreur lors de la récupération de jeton (via des appels Interop), mais les appels à servicecontroller.Start et servicecontroller.Stop toujours échouer.

Tous les articles sur le Web décrivent le même processus pour usurper l'identité de l'utilisateur, mais jusqu'à présent, je n'ai pas réussi à le faire fonctionner ou même pour avoir la moindre idée de ce qui ne va pas.

Est-ce que quelqu'un a une idée de ce qui ne va pas là ... donw

Merci à l'avance

--Bruno

 public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    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); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
     int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 
    private void button1_Click(object sender, EventArgs e) 
    { 


     WindowsImpersonationContext wic = ImpersonateUser(
       "Administrator", 
       "machinename", 
       "password"); 

     try 
     { 
      ServiceController sc = new ServiceController("SERVICE_PERE"); 
      Process p = new Process(); 


      sc.Start(); 
     } 
     catch (Exception ex) 
     { 

      Debugger.Break(); 
     } 
     finally 
     { 
      wic.Undo(); 
     } 


    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     WindowsImpersonationContext wic = ImpersonateUser(
       "Administrator", 
       "machinename", 
       "password"); 


     try 
     { 

      ServiceController sc = new ServiceController("SERVICE_PERE"); 

      sc.Stop(); 
     } 
     catch (Exception ex) 
     { 
      Debugger.Break(); 

     } 
     finally 
     { 
      wic.Undo(); 
      //CodeAccessPermission.RevertAssert(); 
     } 
    } 
    public WindowsImpersonationContext ImpersonateUser(string sUsername, string sDomain, string sPassword) 
    { 
     // initialize tokens 

     IntPtr pExistingTokenHandle = new IntPtr(0); 
     IntPtr pDuplicateTokenHandle = new IntPtr(0); 
     pExistingTokenHandle = IntPtr.Zero; 
     pDuplicateTokenHandle = IntPtr.Zero; 

     // if domain name was blank, assume local machine 

     if (sDomain == "") 
      sDomain = System.Environment.MachineName; 

     try 
     { 
      string sResult = null; 

      const int LOGON32_PROVIDER_DEFAULT = 0; 

      // create token 

      const int LOGON32_LOGON_INTERACTIVE = 2; 
      //const int SecurityImpersonation = 2; 


      // get handle to token 

      bool bImpersonated = LogonUser(sUsername, sDomain, sPassword, 
       LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, 
        ref pExistingTokenHandle); 

      // did impersonation fail? 

      if (false == bImpersonated) 
      { 
       int nErrorCode = Marshal.GetLastWin32Error(); 
       sResult = "LogonUser() failed with error code: " + 
        nErrorCode + "\r\n"; 

       // show the reason why LogonUser failed 

       //MessageBox.Show(this, sResult, "Error", 
       // MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 

      // Get identity before impersonation 

      sResult += "Before impersonation: " + 
       WindowsIdentity.GetCurrent().Name + "\r\n"; 

      bool bRetVal = DuplicateToken(pExistingTokenHandle, 
       2, ref pDuplicateTokenHandle); 

      // did DuplicateToken fail? 

      if (false == bRetVal) 
      { 
       int nErrorCode = Marshal.GetLastWin32Error(); 
       // close existing handle 

       CloseHandle(pExistingTokenHandle); 
       sResult += "DuplicateToken() failed with error code: " 
        + nErrorCode + "\r\n"; 

       // show the reason why DuplicateToken failed 

       //MessageBox.Show(this, sResult, "Error", 
       // MessageBoxButtons.OK, MessageBoxIcon.Error); 
       return null; 
      } 
      else 
      { 
       // create new identity using new primary token 

       WindowsIdentity newId = new WindowsIdentity 
              (pDuplicateTokenHandle); 

       WindowsImpersonationContext impersonatedUser = 
              newId.Impersonate(); 

       // check the identity after impersonation 

       sResult += "After impersonation: " + 
        WindowsIdentity.GetCurrent().Name + "\r\n"; 

       //MessageBox.Show(this, sResult, "Success", 
       // MessageBoxButtons.OK, MessageBoxIcon.Information); 
       return impersonatedUser; 
      } 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      // close handle(s) 

      if (pExistingTokenHandle != IntPtr.Zero) 
       CloseHandle(pExistingTokenHandle); 
      if (pDuplicateTokenHandle != IntPtr.Zero) 
       CloseHandle(pDuplicateTokenHandle); 
     } 
    } 
} 

public enum LogonType 
{ 
    LOGON32_LOGON_INTERACTIVE = 2, 
    LOGON32_LOGON_NETWORK = 3, 
    LOGON32_LOGON_BATCH = 4, 
    LOGON32_LOGON_SERVICE = 5, 
    LOGON32_LOGON_UNLOCK = 7, 
    LOGON32_LOGON_NETWORK_CLEARTEXT = 8, 
    LOGON32_LOGON_NEW_CREDENTIALS = 9, 
} 
public enum LogonProvider 
{ 
    LOGON32_PROVIDER_DEFAULT = 0, 
} 

Répondre

1

Démarrage et arrêt des services nécessite des privilèges d'administrateur. Vous ne pouvez pas contourner l'UAC avec emprunt d'identité, vous devez afficher l'invite d'élévation. This answer vous montre comment.

+0

Ok, je vais vérifier ça. Merci. – Bruno