using System; using System.Runtime.InteropServices; using System.Security.Principal; using System.Security.Permissions; namespace Util.Security { public class Impersonator: IDisposable { #region Constants private const Int32 IMPERSONATION_LEVEL = 2; private const Int32 LOGON32_PROVIDER_DEFAULT = 0; private const Int32 LOGON32_LOGON_INTERACTIVE = 3; #endregion #region Members private WindowsImpersonationContext _nusr = null; #endregion #region WinApi [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public extern static Boolean CloseHandle( IntPtr Handle); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public extern static Boolean DuplicateToken( IntPtr ExistingTokenHandle, Int32 SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); [DllImport("advapi32.dll", SetLastError=true)] public static extern bool LogonUser( String lpszUsername, String lpszDomain, String lpszPassword, Int32 dwLogonType, Int32 dwLogonProvider, ref IntPtr phToken); #endregion #region Methods #region Constructors public Impersonator( String user, String password): this( Environment.MachineName, user, password) { } public Impersonator( String domain, String user, String password) { _nusr = GetImpersonatedUser( domain, user, password); } #endregion #region Destructor ~Impersonator() { Dispose(); GC.SuppressFinalize(this); } #endregion #region Interface public void Dispose() { if(_nusr != null) { _nusr.Undo(); _nusr = null; } } #endregion #region Implementation private WindowsImpersonationContext GetImpersonatedUser( String domain, String user, String password) { IntPtr exst = new IntPtr(0); IntPtr dupl = new IntPtr(0); Boolean resl = true; WindowsIdentity widt = null; WindowsImpersonationContext wctx = null; exst = IntPtr.Zero; dupl = IntPtr.Zero; try { resl = LogonUser( user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref exst); if (!resl) { throw new System.ComponentModel.Win32Exception( Marshal.GetLastWin32Error()); } resl = DuplicateToken( exst, IMPERSONATION_LEVEL, ref dupl); if (!resl) { CloseHandle(exst); throw new System.ComponentModel.Win32Exception( Marshal.GetLastWin32Error()); } else { widt = new WindowsIdentity(dupl); wctx = widt.Impersonate(); return wctx; } } catch(Exception ex) { String msgs = ex.Message; return null; } finally { if (exst!= IntPtr.Zero) { CloseHandle(exst); } if (dupl != IntPtr.Zero) { CloseHandle(dupl); } } } #endregion #endregion } }