Using impersonation in windows service
Video link:
Usage of below code:
using (new Impersonator("kumahk", "cabijklk", "hjkk"))
{
WriteToFile("Service is recall at
" +
DateTime.Now);
}
Impersonation.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace DummyWindowService
{
public class Impersonator : IDisposable
{
private WindowsImpersonationContext _wic;
/// <summary>
/// Begins impersonation with the given
credentials, Logon type and Logon provider.
/// </summary>
///<param name="userName">Name of the user.</param>
///<param name="domainName">Name of the domain.</param>
///<param name="password">The password. <see cref="System.String"/></param>
///<param name="logonType">Type of the logon.</param>
///<param name="logonProvider">The logon provider. <see cref="Mit.Sharepoint.WebParts.EventLogQuery.Network.LogonProvider"/></param>
public Impersonator(string userName, string domainName, string password, LogonType logonType,
LogonProvider logonProvider)
{
Impersonate(userName, domainName,
password, logonType, logonProvider);
}
/// <summary>
/// Begins impersonation with the given
credentials.
/// </summary>
///<param name="userName">Name of the user.</param>
///<param name="domainName">Name of the domain.</param>
///<param name="password">The password. <see cref="System.String"/></param>
public Impersonator(string userName, string domainName, string password)
{
Impersonate(userName, domainName,
password, LogonType.LOGON32_LOGON_INTERACTIVE,
LogonProvider.LOGON32_PROVIDER_DEFAULT);
}
/// <summary>
/// Initializes a new instance of the <see cref="Impersonator"/> class.
/// </summary>
public Impersonator()
{ }
/// <summary>
/// Performs application-defined tasks
associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
UndoImpersonation();
}
/// <summary>
/// Impersonates the specified user account.
/// </summary>
///<param name="userName">Name of the user.</param>
///<param name="domainName">Name of the domain.</param>
///<param name="password">The password. <see cref="System.String"/></param>
public void
Impersonate(string userName, string domainName, string password)
{
Impersonate(userName, domainName,
password, LogonType.LOGON32_LOGON_INTERACTIVE,
LogonProvider.LOGON32_PROVIDER_DEFAULT);
}
/// <summary>
/// Impersonates the specified user account.
/// </summary>
///<param name="userName">Name of the user.</param>
///<param name="domainName">Name of the domain.</param>
///<param name="password">The password. <see cref="System.String"/></param>
///<param name="logonType">Type of the logon.</param>
///<param name="logonProvider">The logon provider. <see cref="Mit.Sharepoint.WebParts.EventLogQuery.Network.LogonProvider"/></param>
public void
Impersonate(string userName, string domainName, string password, LogonType logonType,
LogonProvider logonProvider)
{
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(userName,
domainName,
password,
(int)logonType,
(int)logonProvider,
ref logonToken) != 0)
{
if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation,
ref logonTokenDuplicate) != 0)
{
WindowsIdentity 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;
}
}
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);
}
}
Service code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace DummyWindowService
{
public partial class Service1 : ServiceBase
{
Timer timer = new Timer();
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// using (new
Impersonator("kup", "cabk", "273"))
{
WriteToFile("Service is started at
" + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 5000; //number in milisecinds
timer.Enabled = true;
}
}
protected override void OnStop()
{
WriteToFile("Service is stopped at
" +
DateTime.Now);
}
private void
OnElapsedTime(object source, ElapsedEventArgs e)
{
using (new Impersonator("kumarp", "cabi_uk", "2738"))
{
WriteToFile("Service is recall at
" +
DateTime.Now);
}
}
public void
WriteToFile(string Message)
{
string path =
AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath =
AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" +
DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw =
File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw =
File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
Simple way
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
IntPtr th = IntPtr.Zero;
bool log = LogonUser("kup", "cab", "27", 2, 0, ref th);
}
[DllImport("advapi32.dll")]
public static extern bool LogonUser(string name, string domain, string pass
, int logType, int logpv, ref IntPtr pht);
// Impersonate a Windows identity.
private static void ImpersonateIdentity(IntPtr logonToken)
{
// Retrieve the Windows identity using the
specified token.
WindowsIdentity windowsIdentity = new WindowsIdentity(logonToken);
// Create a WindowsImpersonationContext
object by impersonating the
// Windows identity.
WindowsImpersonationContext
impersonationContext =
windowsIdentity.Impersonate();
Console.WriteLine("Name of the identity
after impersonation: "
+
WindowsIdentity.GetCurrent().Name + ".");
Console.WriteLine(windowsIdentity.ImpersonationLevel);
// Stop impersonating the user.
impersonationContext.Undo();
// Check the identity name.
Console.Write("Name of the identity
after performing an Undo on the");
Console.WriteLine(" impersonation: " +
WindowsIdentity.GetCurrent().Name);
}
}
}
0 comments:
Post a Comment