You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Impersonation/Impersonation.cs

149 lines
5.8 KiB

6 years ago
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security.Principal;
namespace ZeroLevel.Services.Impersonation
{
/// <summary>
/// The class implements the translation of the program execution to the rights of the specified user.
6 years ago
/// </summary>
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
private WindowsImpersonationContext impersonationContext;
6 years ago
#region Private methods
6 years ago
/// <summary>
/// Assigning rights to the current process from the specified process, by copying its token
6 years ago
/// </summary>
/// <param name="hProcess">Process pointer</param>
6 years ago
private void ImpersonateByProcess(IntPtr hProcess)
{
MySafeTokenHandle token;
if (!ImpersonationNativeMethods.OpenProcessToken(hProcess, ImpersonationNativeMethods.TokenDesiredAccess.TOKEN_DUPLICATE, out token))
throw new ApplicationException("Failed to get the process token. Win32 error code: " + Marshal.GetLastWin32Error());
6 years ago
ImpersonateToken(token);
}
6 years ago
/// <summary>
/// The method assigns a duplicate token to the current process.
6 years ago
/// </summary>
/// <param name="token">Token</param>
6 years ago
private void ImpersonateToken(MySafeTokenHandle token)
{
MySafeTokenHandle tokenDuplicate;
WindowsIdentity tempWindowsIdentity;
using (token)
{
if (ImpersonationNativeMethods.DuplicateToken(token, (int)ImpersonationNativeMethods.SecurityImpersonationLevel.SecurityImpersonation, out tokenDuplicate) != 0)
{
using (tokenDuplicate)
{
if (!tokenDuplicate.IsInvalid)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate.DangerousGetHandle());
impersonationContext = tempWindowsIdentity.Impersonate();
return;
}
}
}
else
throw new Exception("Failed to create a duplicate of the specified token. Win32 error code: " + Marshal.GetLastWin32Error());
6 years ago
}
}
#endregion Private methods
6 years ago
#region Public methods
6 years ago
/// <summary>
/// Login as a specified user
6 years ago
/// </summary>
/// <param name="userName">User name</param>
/// <param name="domain">User domain</param>
/// <param name="password">User password</param>
/// <returns>false - if failed to log in with the specified data</returns>
6 years ago
public void ImpersonateByUser(String userName, String domain, String password)
{
MySafeTokenHandle token;
if (ImpersonationNativeMethods.LogonUserA(userName, domain, password, (int)ImpersonationNativeMethods.LogonType.LOGON32_LOGON_INTERACTIVE, (int)ImpersonationNativeMethods.LogonProvider.LOGON32_PROVIDER_DEFAULT, out token) != 0)
{
ImpersonateToken(token);
}
else
{
throw new Exception("LogonUser failed: " + Marshal.GetLastWin32Error().ToString());
}
}
6 years ago
/// <summary>
6 years ago
/// Login on behalf of the specified user with the authorization method
6 years ago
/// </summary>
6 years ago
/// <param name="userName">Login</param>
/// <param name="domain">Domain</param>
/// <param name="password">Password</param>
/// <param name="logonType">Authorization Type</param>
6 years ago
public void ImpersonateByUser(String userName, String domain, String password, ImpersonationNativeMethods.LogonType logonType)
{
MySafeTokenHandle token;
if (ImpersonationNativeMethods.LogonUserA(userName, domain, password, (int)logonType, (int)ImpersonationNativeMethods.LogonProvider.LOGON32_PROVIDER_DEFAULT, out token) != 0)
{
ImpersonateToken(token);
}
else
{
throw new Exception("LogonUser failed: " + Marshal.GetLastWin32Error().ToString());
}
}
6 years ago
/// <summary>
6 years ago
/// Copying the rights of the specified process
6 years ago
/// </summary>
6 years ago
/// <param name="ProcessName">Process name</param>
6 years ago
public void ImpersonateByProcess(string ProcessName)
{
Process[] myProcesses = Process.GetProcesses();
foreach (Process currentProcess in myProcesses)
{
if (currentProcess.ProcessName.Equals(ProcessName, StringComparison.OrdinalIgnoreCase))
{
ImpersonateByProcess(currentProcess.Handle);
break;
}
}
}
6 years ago
/// <summary>
/// Copying the rights of the specified process
6 years ago
/// </summary>
/// <param name="ProcessID">Process id</param>
6 years ago
public void ImpersonateByProcess(int ProcessID)
{
Process[] myProcesses = Process.GetProcesses();
foreach (Process currentProcess in myProcesses)
{
if (currentProcess.Id == ProcessID)
{
ImpersonateByProcess(currentProcess.Handle);
break;
}
}
}
#endregion Public methods
6 years ago
/// <summary>
/// When releasing resources, we will return the previous user right
6 years ago
/// </summary>
public void Dispose()
{
impersonationContext?.Undo();
impersonationContext?.Dispose();
GC.SuppressFinalize(this);
}
}
}

Powered by TurnKey Linux.