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

142 lines
5.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.
/// </summary>
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
WindowsImpersonationContext impersonationContext;
#region Private methods
/// <summary>
/// Assigning rights to the current process from the specified process, by copying its token
/// </summary>
/// <param name="hProcess">Process pointer</param>
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());
ImpersonateToken(token);
}
/// <summary>
/// The method assigns a duplicate token to the current process.
/// </summary>
/// <param name="token">Token</param>
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());
}
}
#endregion
#region Public methods
/// <summary>
/// Login as a specified user
/// </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>
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());
}
}
/// <summary>
/// Вход от имени указанного пользователя с указанием способа авторизации
/// </summary>
/// <param name="userName">Имя пользователя</param>
/// <param name="domain">Домен</param>
/// <param name="password">Пароль</param>
/// <param name="logonType">Тип авторизации</param>
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());
}
}
/// <summary>
/// Копирование прав указанного процесса
/// </summary>
/// <param name="ProcessName">Имя процесса</param>
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;
}
}
}
/// <summary>
/// Copying the rights of the specified process
/// </summary>
/// <param name="ProcessID">Process id</param>
public void ImpersonateByProcess(int ProcessID)
{
Process[] myProcesses = Process.GetProcesses();
foreach (Process currentProcess in myProcesses)
{
if (currentProcess.Id == ProcessID)
{
ImpersonateByProcess(currentProcess.Handle);
break;
}
}
}
#endregion
/// <summary>
/// When releasing resources, we will return the previous user right
/// </summary>
public void Dispose()
{
impersonationContext?.Undo();
impersonationContext?.Dispose();
GC.SuppressFinalize(this);
}
}
}

Powered by TurnKey Linux.