using System.Runtime.InteropServices;
using System.Text;
using System.Security.Principal;
using System;
public class IdentityImpersonation
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// 要模拟的用户的用户名、密码、域(机器名)
private String _sImperUsername;
private String _sImperPassword;
private String _sImperDomain;
// 记录模拟上下文
private WindowsImpersonationContext _imperContext;
private IntPtr _adminToken;
private IntPtr _dupeToken;
// 是否已停止模拟
private Boolean _bClosed;
public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain)
{
_sImperUsername = impersonationUsername;
_sImperPassword = impersonationPassword;
_sImperDomain = impersonationDomain;
_adminToken = IntPtr.Zero;
_dupeToken = IntPtr.Zero;
_bClosed = true;
}
~IdentityImpersonation()
{
if (!_bClosed)
{
StopImpersonate();
}
}
public Boolean BeginImpersonate()
{
Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);
if (!bLogined)
{
return false;
}
Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);
if (!bDuped)
{
return false;
}
WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
_imperContext = fakeId.Impersonate();
_bClosed = false;
return true;
}
public void StopImpersonate()
{
_imperContext.Undo();
CloseHandle(_dupeToken);
CloseHandle(_adminToken);
_bClosed = true;
}
//判断用户名字是否存在
[DllImport("advapi32.dll", CharSet = CharSet.Auto,
SetLastError = true, PreserveSig = true)]
private static extern bool LookupAccountName(
string lpSystemName, string lpAccountName,
System.IntPtr psid, ref int cbsid,
StringBuilder domainName, ref int cbdomainLength,
ref int use);
public bool LookUpAccount(string accountName)
{
//pointer an size for the SID
IntPtr sid = IntPtr.Zero;
int sidSize = 0;
//StringBuilder and size for the domain name
StringBuilder domainName = new StringBuilder();
int nameSize = 0;
//account-type variable for lookup
int accountType = 0;
//get required buffer size
LookupAccountName(String.Empty, accountName, sid,
ref sidSize, domainName, ref nameSize, ref accountType);
//allocate buffers
domainName = new StringBuilder(nameSize);
sid = Marshal.AllocHGlobal(sidSize);
//lookup the SID for the account
bool result = LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType);
if (result)
{
if (accountName.ToLower().IndexOf(domainName.ToString().ToLower()) < 0)
{
accountName = domainName + "\\" + accountName;
}
//throw.Exception; .Show("The account is : " + accountName);
}
else
{
//MessageBox.Show("Can't find the account.");
}
Marshal.FreeHGlobal(sid);
return result;
}
}