Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Net;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
- using System.Text;
- namespace DomainModel.Services
- {
- //http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v=vs.85%29.aspx
- 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, // Win2K or higher
- LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
- };
- public enum LogonProvider
- {
- LOGON32_PROVIDER_DEFAULT = 0,
- LOGON32_PROVIDER_WINNT35 = 1,
- LOGON32_PROVIDER_WINNT40 = 2,
- LOGON32_PROVIDER_WINNT50 = 3
- };
- public enum ImpersonationLevel
- {
- SecurityAnonymous = 0,
- SecurityIdentification = 1,
- SecurityImpersonation = 2,
- SecurityDelegation = 3
- }
- class Win32NativeMethods
- {
- [DllImport("advapi32.dll", SetLastError = true)]
- public 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)]
- public static extern int DuplicateToken(IntPtr hToken,
- int impersonationLevel,
- ref IntPtr hNewToken);
- [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern bool RevertToSelf();
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public static extern bool CloseHandle(IntPtr handle);
- }
- /// <summary>
- /// Allows code to be executed under the security context of a specified user account.
- /// </summary>
- /// <remarks>
- ///
- /// Implements IDispose, so can be used via a using-directive or method calls;
- /// ...
- ///
- /// var imp = new Impersonator( "myUsername", "myDomainname", "myPassword" );
- /// imp.UndoImpersonation();
- ///
- /// ...
- ///
- /// var imp = new Impersonator();
- /// imp.Impersonate("myUsername", "myDomainname", "myPassword");
- /// imp.UndoImpersonation();
- ///
- /// ...
- ///
- /// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
- /// {
- /// ...
- /// [code that executes under the new context]
- /// ...
- /// }
- ///
- /// ...
- /// </remarks>
- public class Impersonator : IDisposable
- {
- private WindowsImpersonationContext _wic;
- public Impersonator(NetworkCredential credentials, LogonType logonType, LogonProvider logonProvider)
- {
- Impersonate(credentials, logonType, logonProvider);
- }
- public Impersonator(NetworkCredential credentials)
- : this(credentials, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50)
- {
- }
- public Impersonator()
- { }
- public void Dispose()
- {
- UndoImpersonation();
- }
- public void Impersonate(NetworkCredential credentials, LogonType logonType, LogonProvider logonProvider)
- {
- if (credentials == null) {
- return;
- }
- UndoImpersonation();
- IntPtr logonToken = IntPtr.Zero;
- IntPtr logonTokenDuplicate = IntPtr.Zero;
- try {
- // revert to the application pool identity, saving the identity of the current requestor
- _wic = WindowsIdentity.Impersonate(IntPtr.Zero);
- // do logon & impersonate
- if (Win32NativeMethods.LogonUser(
- credentials.UserName,
- credentials.Domain,
- credentials.Password,
- (int)logonType,
- (int)logonProvider,
- ref logonToken) != 0) {
- if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation, ref logonTokenDuplicate) != 0) {
- var wi = new WindowsIdentity(logonTokenDuplicate);
- wi.Impersonate(); // discard the returned identity context (which is the context of the application pool)
- } else
- throw new Win32Exception(Marshal.GetLastWin32Error());
- } else
- throw new Win32Exception(Marshal.GetLastWin32Error());
- }
- finally {
- if (logonToken != IntPtr.Zero)
- Win32NativeMethods.CloseHandle(logonToken);
- if (logonTokenDuplicate != IntPtr.Zero)
- Win32NativeMethods.CloseHandle(logonTokenDuplicate);
- }
- }
- /// <summary>
- /// Stops impersonation.
- /// </summary>
- private void UndoImpersonation()
- {
- // restore saved requestor identity
- if (_wic != null)
- _wic.Undo();
- _wic = null;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement