Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Tools
- {
- #region Using directives.
- // ----------------------------------------------------------------------
- using System;
- using System.Security.Principal;
- using System.Runtime.InteropServices;
- using System.ComponentModel;
- // ----------------------------------------------------------------------
- #endregion
- /////////////////////////////////////////////////////////////////////////
- /// <summary>
- /// Impersonation of a user. Allows to execute code under another
- /// user context.
- /// Please note that the account that instantiates the Impersonator class
- /// needs to have the 'Act as part of operating system' privilege set.
- /// </summary>
- /// <remarks>
- /// This class is based on the information in the Microsoft knowledge base
- /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
- ///
- /// Encapsulate an instance into a using-directive like e.g.:
- ///
- /// ...
- /// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
- /// {
- /// ...
- /// [code that executes under the new context]
- /// ...
- /// }
- /// ...
- ///
- /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
- /// for questions regarding this class.
- /// </remarks>
- public class Impersonator : IDisposable
- {
- // ------------------------------------------------------------------
- /// <summary>
- /// Constructor. Starts the impersonation with the given credentials.
- /// Please note that the account that instantiates the Impersonator class
- /// needs to have the 'Act as part of operating system' privilege set.
- /// </summary>
- /// <param name="userName">The name of the user to act as.</param>
- /// <param name="domainName">The domain name of the user to act as.</param>
- /// <param name="password">The password of the user to act as.</param>
- public Impersonator(string userName, string domainName, string password)
- {
- ImpersonateValidUser(userName, domainName, password);
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- UndoImpersonation();
- if (impersonationContext != null)
- {
- impersonationContext.Dispose();
- }
- }
- /// <summary>
- /// Does the actual impersonation.
- /// </summary>
- /// <param name="userName">The name of the user to act as.</param>
- /// <param name="domainName">The domain name of the user to act as.</param>
- /// <param name="password">The password of the user to act as.</param>
- private void ImpersonateValidUser(string userName, string domainName, string password)
- {
- RevertToSelf();
- IntPtr token = IntPtr.Zero;
- try
- {
- token = LogOnUser(userName, domainName, password);
- CreateImpersonationContext(token);
- }
- finally
- {
- if (token != IntPtr.Zero)
- {
- NativeMethods.CloseHandle(token);
- }
- }
- }
- private static void RevertToSelf()
- {
- if (!NativeMethods.RevertToSelf())
- {
- throw new Win32Exception(Marshal.GetLastWin32Error());
- }
- }
- private static IntPtr LogOnUser(string userName, string domainName, string password)
- {
- IntPtr token = IntPtr.Zero;
- if (NativeMethods.LogonUser(userName, domainName, password, NativeMethods.LOGON32_LOGON_INTERACTIVE, NativeMethods.LOGON32_PROVIDER_DEFAULT, ref token) != 0)
- {
- return token;
- }
- throw new Win32Exception(Marshal.GetLastWin32Error());
- }
- private void CreateImpersonationContext(IntPtr token)
- {
- IntPtr tokenDuplicate = IntPtr.Zero;
- try
- {
- if (NativeMethods.DuplicateToken(token, 2, ref tokenDuplicate) == 0)
- {
- throw new Win32Exception(Marshal.GetLastWin32Error());
- }
- using (var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate))
- {
- impersonationContext = tempWindowsIdentity.Impersonate();
- }
- }
- finally
- {
- if (tokenDuplicate != IntPtr.Zero)
- {
- NativeMethods.CloseHandle(tokenDuplicate);
- }
- }
- }
- /// <summary>
- /// Reverts the impersonation.
- /// </summary>
- private void UndoImpersonation()
- {
- if (impersonationContext != null)
- {
- impersonationContext.Undo();
- }
- }
- private WindowsImpersonationContext impersonationContext = null;
- private static class NativeMethods
- {
- [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
- [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- internal static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
- [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool RevertToSelf();
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool CloseHandle(IntPtr handle);
- internal const int LOGON32_LOGON_INTERACTIVE = 2;
- internal const int LOGON32_PROVIDER_DEFAULT = 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement