using System;
using System.
Runtime.
InteropServices;
using System.
Security.
Principal;
using System.
Security.
Permissions;
namespace Util.
Security
{
public class Impersonator: IDisposable
{
#region Constants
private const Int32 IMPERSONATION_LEVEL =
2;
private const Int32 LOGON32_PROVIDER_DEFAULT =
0;
private const Int32 LOGON32_LOGON_INTERACTIVE =
3;
#endregion
#region Members
private WindowsImpersonationContext _nusr =
null;
#endregion
#region WinApi
[DllImport
("kernel32.dll", CharSet=CharSet.
Auto)]
public extern static Boolean CloseHandle
(
IntPtr Handle
);
[DllImport
("advapi32.dll", CharSet=CharSet.
Auto, SetLastError=
true)]
public extern static Boolean DuplicateToken
(
IntPtr ExistingTokenHandle,
Int32 SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle
);
[DllImport
("advapi32.dll", SetLastError=
true)]
public static extern bool LogonUser
(
String lpszUsername,
String lpszDomain,
String lpszPassword,
Int32 dwLogonType,
Int32 dwLogonProvider,
ref IntPtr phToken
);
#endregion
#region Methods
#region Constructors
public Impersonator
(
String user,
String password
):
this(
Environment.
MachineName,
user,
password
)
{
}
public Impersonator
(
String domain,
String user,
String password
)
{
_nusr = GetImpersonatedUser
(
domain,
user,
password
);
}
#endregion
#region Destructor
~Impersonator
()
{
Dispose
();
GC.
SuppressFinalize(this);
}
#endregion
#region Interface
public void Dispose
()
{
if(_nusr !=
null)
{
_nusr.
Undo();
_nusr =
null;
}
}
#endregion
#region Implementation
private WindowsImpersonationContext GetImpersonatedUser
(
String domain,
String user,
String password
)
{
IntPtr exst =
new IntPtr
(0);
IntPtr dupl =
new IntPtr
(0);
Boolean resl =
true;
WindowsIdentity widt =
null;
WindowsImpersonationContext wctx =
null;
exst = IntPtr.
Zero;
dupl = IntPtr.
Zero;
try
{
resl = LogonUser
(
user,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref exst
);
if (!resl
)
{
throw new System.
ComponentModel.
Win32Exception(
Marshal.
GetLastWin32Error());
}
resl = DuplicateToken
(
exst,
IMPERSONATION_LEVEL,
ref dupl
);
if (!resl
)
{
CloseHandle
(exst
);
throw new System.
ComponentModel.
Win32Exception(
Marshal.
GetLastWin32Error());
}
else
{
widt =
new WindowsIdentity
(dupl
);
wctx = widt.
Impersonate();
return wctx;
}
}
catch(Exception ex
)
{
String msgs = ex.
Message;
return null;
}
finally
{
if (exst!= IntPtr.
Zero)
{
CloseHandle
(exst
);
}
if (dupl != IntPtr.
Zero)
{
CloseHandle
(dupl
);
}
}
}
#endregion
#endregion
}
}