Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Impersonator without CA warnings

By: a guest on Apr 26th, 2012  |  syntax: C#  |  size: 5.83 KB  |  views: 1,406  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. namespace Tools
  2. {
  3.    #region Using directives.
  4.    // ----------------------------------------------------------------------
  5.  
  6.    using System;
  7.    using System.Security.Principal;
  8.    using System.Runtime.InteropServices;
  9.    using System.ComponentModel;
  10.  
  11.    // ----------------------------------------------------------------------
  12.    #endregion
  13.  
  14.  
  15.    /////////////////////////////////////////////////////////////////////////
  16.    /// <summary>
  17.    /// Impersonation of a user. Allows to execute code under another
  18.    /// user context.
  19.    /// Please note that the account that instantiates the Impersonator class
  20.    /// needs to have the 'Act as part of operating system' privilege set.
  21.    /// </summary>
  22.    /// <remarks>       
  23.    /// This class is based on the information in the Microsoft knowledge base
  24.    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
  25.    ///
  26.    /// Encapsulate an instance into a using-directive like e.g.:
  27.    ///
  28.    ///          ...
  29.    ///          using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
  30.    ///          {
  31.    ///                  ...
  32.    ///                  [code that executes under the new context]
  33.    ///                  ...
  34.    ///          }
  35.    ///          ...
  36.    ///
  37.    /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
  38.    /// for questions regarding this class.
  39.    /// </remarks>
  40.    public class Impersonator : IDisposable
  41.    {
  42.       // ------------------------------------------------------------------
  43.  
  44.       /// <summary>
  45.       /// Constructor. Starts the impersonation with the given credentials.
  46.       /// Please note that the account that instantiates the Impersonator class
  47.       /// needs to have the 'Act as part of operating system' privilege set.
  48.       /// </summary>
  49.       /// <param name="userName">The name of the user to act as.</param>
  50.       /// <param name="domainName">The domain name of the user to act as.</param>
  51.       /// <param name="password">The password of the user to act as.</param>
  52.       public Impersonator(string userName, string domainName, string password)
  53.       {
  54.          ImpersonateValidUser(userName, domainName, password);
  55.       }
  56.  
  57.       public void Dispose()
  58.       {
  59.          Dispose(true);
  60.          GC.SuppressFinalize(this);
  61.       }
  62.  
  63.       protected virtual void Dispose(bool disposing)
  64.       {
  65.          UndoImpersonation();
  66.          if (impersonationContext != null)
  67.          {
  68.             impersonationContext.Dispose();
  69.          }
  70.       }
  71.  
  72.       /// <summary>
  73.       /// Does the actual impersonation.
  74.       /// </summary>
  75.       /// <param name="userName">The name of the user to act as.</param>
  76.       /// <param name="domainName">The domain name of the user to act as.</param>
  77.       /// <param name="password">The password of the user to act as.</param>
  78.       private void ImpersonateValidUser(string userName, string domainName, string password)
  79.       {
  80.          RevertToSelf();
  81.          IntPtr token = IntPtr.Zero;
  82.          try
  83.          {
  84.             token = LogOnUser(userName, domainName, password);
  85.             CreateImpersonationContext(token);
  86.          }
  87.          finally
  88.          {
  89.             if (token != IntPtr.Zero)
  90.             {
  91.                NativeMethods.CloseHandle(token);
  92.             }
  93.          }
  94.       }
  95.  
  96.       private static void RevertToSelf()
  97.       {
  98.          if (!NativeMethods.RevertToSelf())
  99.          {
  100.             throw new Win32Exception(Marshal.GetLastWin32Error());
  101.          }
  102.       }
  103.  
  104.       private static IntPtr LogOnUser(string userName, string domainName, string password)
  105.       {
  106.          IntPtr token = IntPtr.Zero;
  107.          if (NativeMethods.LogonUser(userName, domainName, password, NativeMethods.LOGON32_LOGON_INTERACTIVE, NativeMethods.LOGON32_PROVIDER_DEFAULT, ref token) != 0)
  108.          {
  109.             return token;
  110.          }
  111.          throw new Win32Exception(Marshal.GetLastWin32Error());
  112.       }
  113.  
  114.       private void CreateImpersonationContext(IntPtr token)
  115.       {
  116.          IntPtr tokenDuplicate = IntPtr.Zero;
  117.          try
  118.          {
  119.             if (NativeMethods.DuplicateToken(token, 2, ref tokenDuplicate) == 0)
  120.             {
  121.                throw new Win32Exception(Marshal.GetLastWin32Error());
  122.             }
  123.             using (var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate))
  124.             {
  125.                impersonationContext = tempWindowsIdentity.Impersonate();
  126.             }
  127.          }
  128.          finally
  129.          {
  130.             if (tokenDuplicate != IntPtr.Zero)
  131.             {
  132.                NativeMethods.CloseHandle(tokenDuplicate);
  133.             }
  134.          }
  135.       }
  136.  
  137.       /// <summary>
  138.       /// Reverts the impersonation.
  139.       /// </summary>
  140.       private void UndoImpersonation()
  141.       {
  142.          if (impersonationContext != null)
  143.          {
  144.             impersonationContext.Undo();
  145.          }
  146.       }
  147.  
  148.       private WindowsImpersonationContext impersonationContext = null;
  149.  
  150.       private static class NativeMethods
  151.       {
  152.          [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  153.          internal static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
  154.  
  155.          [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  156.          internal static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
  157.  
  158.          [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  159.          [return: MarshalAs(UnmanagedType.Bool)]
  160.          internal static extern bool RevertToSelf();
  161.  
  162.          [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  163.          [return: MarshalAs(UnmanagedType.Bool)]
  164.          internal static extern bool CloseHandle(IntPtr handle);
  165.  
  166.          internal const int LOGON32_LOGON_INTERACTIVE = 2;
  167.          internal const int LOGON32_PROVIDER_DEFAULT = 0;
  168.       }
  169.  
  170.    }
  171. }