Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Tools;
- using Microsoft.Win32.SafeHandles;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
- /// <summary>
- /// Impersonation of a user. Allows to execute code under another
- /// user context.
- /// 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.:
- /// ...
- /// new Impersonator( "myUsername", "myDomainname", "myPassword" ).RunImpersonated(
- /// true,
- /// () => {
- /// ...
- /// [code that executes under the new context]
- /// ...
- /// });
- /// ...
- /// </remarks>
- [PublicAPI]
- public sealed class Impersonator(
- string? userName,
- string? domainName,
- string? password)
- {
- // https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.runimpersonated
- private const int LOGON32_PROVIDER_DEFAULT = 0;
- private const int LOGON32_LOGON_INTERACTIVE = 2;
- public T RunImpersonated<T>(bool active, Func<T> func)
- {
- if (active)
- {
- var r = LogonUser(
- userName ?? string.Empty,
- domainName ?? string.Empty,
- password ?? string.Empty,
- LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
- out var safeAccessTokenHandle);
- if (r && safeAccessTokenHandle != null)
- {
- try
- {
- #pragma warning disable CA1416 // Validate platform compatibility
- return WindowsIdentity.RunImpersonated(safeAccessTokenHandle, func);
- #pragma warning restore CA1416 // Validate platform compatibility
- }
- finally
- {
- safeAccessTokenHandle.Dispose();
- }
- }
- else
- {
- var ret = Marshal.GetLastWin32Error();
- throw new Win32Exception(ret);
- }
- }
- else
- {
- return func();
- }
- }
- public async Task<T> RunImpersonatedAsync<T>(bool active, Func<Task<T>> func)
- {
- if (active)
- {
- var r = LogonUser(
- userName ?? string.Empty, domainName ?? string.Empty, password ?? string.Empty,
- LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
- out var safeAccessTokenHandle);
- if (r && safeAccessTokenHandle != null)
- {
- try
- {
- #pragma warning disable CA1416 // Validate platform compatibility
- return await WindowsIdentity.RunImpersonatedAsync(safeAccessTokenHandle, func);
- #pragma warning restore CA1416 // Validate platform compatibility
- }
- finally
- {
- safeAccessTokenHandle.Dispose();
- }
- }
- else
- {
- var ret = Marshal.GetLastWin32Error();
- throw new Win32Exception(ret);
- }
- }
- else
- {
- return await func();
- }
- }
- public void RunImpersonated(bool active, Action action)
- {
- if (active)
- {
- var r = LogonUser(
- userName ?? string.Empty,
- domainName ?? string.Empty,
- password ?? string.Empty,
- LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
- out var safeAccessTokenHandle);
- if (r && safeAccessTokenHandle != null)
- {
- try
- {
- #pragma warning disable CA1416 // Validate platform compatibility
- WindowsIdentity.RunImpersonated(safeAccessTokenHandle, action);
- #pragma warning restore CA1416 // Validate platform compatibility
- }
- finally
- {
- safeAccessTokenHandle.Dispose();
- }
- }
- else
- {
- var ret = Marshal.GetLastWin32Error();
- throw new Win32Exception(ret);
- }
- }
- else
- {
- action();
- }
- }
- public async Task RunImpersonatedAsync(bool active, Func<Task> action)
- {
- if (active)
- {
- var r = LogonUser(
- userName ?? string.Empty,
- domainName ?? string.Empty,
- password ?? string.Empty,
- LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
- out var safeAccessTokenHandle);
- if (r && safeAccessTokenHandle != null)
- {
- try
- {
- #pragma warning disable CA1416 // Validate platform compatibility
- await WindowsIdentity.RunImpersonatedAsync(safeAccessTokenHandle, action);
- #pragma warning restore CA1416 // Validate platform compatibility
- }
- finally
- {
- safeAccessTokenHandle.Dispose();
- }
- }
- else
- {
- var ret = Marshal.GetLastWin32Error();
- throw new Win32Exception(ret);
- }
- }
- else
- {
- await action();
- }
- }
- [DllImport(@"advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern bool LogonUser(
- string lpszUsername,
- string lpszDomain,
- string lpszPassword,
- int dwLogonType,
- int dwLogonProvider,
- out SafeAccessTokenHandle? phToken);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement