using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Security;
using System.Security.Principal;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.Security;
namespace Impersonate
{
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
struct _USE_INFO_2
{
internal string ui2_local;
internal string ui2_remote;
internal IntPtr ui2_password; // don't pass a string or StringBuilder here!!
internal uint ui2_status;
internal uint ui2_asg_type;
internal uint ui2_refcount;
internal uint ui2_usecount;
internal string ui2_username;
internal string ui2_domainname;
}
class WinNet
{
[DllImport("netapi32", CharSet=CharSet.Auto, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int NetUseAdd(
string UncServerName, // not used
int Level, // use info struct level 1 or 2
IntPtr Buf, // Buffer
ref int ParmError
);
const uint USE_WILDCARD = 0xFFFFFFFF;
// Establish a use record
public static void UseRecord(string resource, string user, string
password, string domain)
{
int ret = 0;
int paramError = 0;
_USE_INFO_2 use2 = new _USE_INFO_2();
IntPtr pBuf = IntPtr.Zero;
use2.ui2_password = IntPtr.Zero;
try
{
pBuf = Marshal.AllocHGlobal(Marshal.SizeOf(use2));
use2.ui2_local = null;
use2.ui2_asg_type = USE_WILDCARD;
use2.ui2_remote = resource;
use2.ui2_password = Marshal.StringToHGlobalAuto(password);
use2.ui2_username = user;
use2.ui2_domainname = domain;
Marshal.StructureToPtr(use2, pBuf, true);
ret = NetUseAdd(null, 2, pBuf, ref paramError);
if(ret != 0)
{
throw new Exception(new
Win32Exception(Marshal.GetLastWin32Error()).Message);
}
}
finally
{
Marshal.FreeHGlobal(use2.ui2_password);
Marshal.FreeHGlobal(pBuf);
}
}
}
class Program
{
[System.Runtime.InteropServices.DllImport("advapi32.dll")]
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);
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
static public WindowsImpersonationContext wic;
//static void Main(string[] args)
//{
// IntPtr lnToken;
// if (ImpersonateValidUser("michaell", "cmp-0641", "wilma"))
// {
// using (wic)
// {
// string dir = @"\\cmp-0641\C$\" + "Test";
// System.IO.Directory.CreateDirectory(dir);
// }
// StringBuilder sb = new StringBuilder(80, 80);
// RevertToSelf();
// //CloseHandle( lnToken );
// }
// else
// {
// }
// return;
//}
static public bool ImpersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity wi;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
wi = new WindowsIdentity(tokenDuplicate);
wic = wi.Impersonate();
if (wic != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
}
public class LogOnUser
{
//LogonUser parameters
[DllImport("advapi32.dll")]
private static extern bool LogonUser(String lpszUsername,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
//CloseHandle parameters. When you are finished,
//free the memory allocated for the handle.
[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
public static WindowsIdentity GetWindowsIdentity(string pUserName, string pDomain)
{
return null;
}
public static WindowsIdentity GetWindowsIdentity(string pUserName, string pDomain, string pPassword)
{
IntPtr tokenHandle = IntPtr.Zero;
try
{
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 5;
//Call LogonUser to obtain a
//handle to an access token
bool returnValue = LogonUser(pUserName, pDomain,
pPassword,
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
if (false == returnValue)
{
return null;
}
////Check the identity
//Console.WriteLine("Before impersonation: " +
// WindowsIdentity.GetCurrent().Name);
//Create a WindowsIdentity from the impersonation
//token, then impersonate the user.
WindowsIdentity newId;
newId = new WindowsIdentity(tokenHandle);
return newId;
}
catch (Exception ex)
{
// TODO log the Exception Message.
return null;
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.Runtime.InteropServices;
using System.Web.Security;
using System.Security.Principal;
namespace Yintai.ERP.Common.utils
{
/// <summary>
/// 模拟windows用户登陆
/// 在使用文件直接拷贝的方式向其它服务器同步文件时,需要用到其它服务器的帐号密码
/// 该实现了在文件操作时登陆其它服务器
/// author: sxd 2009-10-25
/// </summary>
public class IdentityScope : IDisposable
{
// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
extern static bool CloseHandle(IntPtr handle);
[DllImport("Advapi32.DLL")]
static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("Advapi32.DLL")]
static extern bool RevertToSelf();
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NEWCREDENTIALS = 9;
const int LOGON32_LOGON_INTERACTIVE = 2; // 域控中的需要用:Interactive = 2
private bool disposed;
public IdentityScope( string sDomain)
{
string sUsername = ConfigurationManager.AppSettings["imusername"];
string sPassword = ConfigurationManager.AppSettings["impassword"];
string sSetDomain = ConfigurationManager.AppSettings["imdomain"];
// initialize tokens
IntPtr pExistingTokenHandle = new IntPtr(0);
IntPtr pDuplicateTokenHandle = new IntPtr(0);
try
{
// get handle to token
bool bImpersonated = false;
if (string.IsNullOrEmpty(sSetDomain))
{
bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
}
else
{
bImpersonated = LogonUser(sUsername, sSetDomain, sPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
}
if (true == bImpersonated)
{
if (!ImpersonateLoggedOnUser(pExistingTokenHandle))
{
int nErrorCode = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateLoggedOnUser error;Code=" + nErrorCode);
}
}
else
{
int nErrorCode = Marshal.GetLastWin32Error();
throw new Exception("LogonUser error;Code=" + nErrorCode);
}
}
catch (Exception ex) {
throw ex;
}
finally
{
// close handle(s)
if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
RevertToSelf();
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
/// <summary>
/// 同步处理
/// 包括文件Copy,Rsync同步
/// </summary>
public class SyncHandler
{
private static object _lock = new object();
private static SyncHandler _instance = null;
private Queue<SyncParam> _queue = new Queue<SyncParam>();
private Thread[] threads = null;
private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
private bool _active = true;
private SyncHandler()
{
_newItemEvent = new AutoResetEvent(false);
_exitThreadEvent = new ManualResetEvent(false);
_eventArray = new WaitHandle[2] {_newItemEvent, _exitThreadEvent};
}
public static SyncHandler Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new SyncHandler();
}
}
}
return _instance;
}
}
//启动线程
public void Start()
{
_active = true;
int count = 50;
threads = new Thread[count];
for(int i = 0; i < count; i++)
{
threads[i] = new Thread(Run);
threads[i].Start();
}
}
//停止线程
public void Stop()
{
_active = false;
_exitThreadEvent.Set();
foreach (Thread thread in threads)
{
thread.Join();
}
_exitThreadEvent.Reset();
threads = null;
}
private void Run()
{
while (_active)
{
try
{
if (_queue.Count > 0)
{
SyncParam param = null;
lock (((ICollection)_queue).SyncRoot)
{
if (_queue.Count > 0)
{
param = _queue.Dequeue();
}
}
if (param != null )
{
try
{
HandleSync(param);
}
catch (Exception ex)
{
throw ex;
}
}
}
else
{
WaitHandle.WaitAny(_eventArray);
}
}
catch (Exception exrun) {
throw exrun;
}
}
}
private void HandleSync(SyncParam param)
{
if (param == null)
{
return;
}
if (param.CopyParams != null)
{
foreach (CopyParam item in param.CopyParams)
{
if (item.DestFileName.StartsWith("\\\\"))
{
string path = item.DestFileName;
string host = path.Substring("\\\\".Length, path.IndexOf("\\", "\\\\".Length) - 2);
using (IdentityScope context = new IdentityScope(host))
{
File.Copy(item.SourceFileName, item.DestFileName, true);
}
}
else {
File.Copy(item.SourceFileName, item.DestFileName, true);
}
}
}
if (param.RsyncParams != null)
{
foreach (RsyncParam item in param.RsyncParams)
{
//Rsync(item.SavePath, item.FileUrl, item.FileName, item.SyncHost, item.SyncDir);
}
}
}
/// <summary>
/// Rsync 同步
/// </summary>
/// <param name="savePath">文档存储路径</param>
/// <param name="fileUrl">文件url地址</param>
/// <param name="fileName">文件名</param>
/// <param name="syncHost">同步主机</param>
/// <param name="syncDir">同步目录</param>
public void Rsync(string SourcePath, string FileName, string syncHost, string syncDir)
{
SyncParam param = new SyncParam();
string attPath = SourcePath + FileName;
string sourceFileName = GetRsyncFileFullPath(SourcePath, "", FileName);
string destFileName = GetRsyncFileFullPath("\\" + syncHost + "\\" + syncDir, "", FileName);
if (param.CopyParams == null)
{
param.CopyParams = new List<CopyParam>();
}
param.CopyParams.Add(new CopyParam() { SourceFileName = sourceFileName, DestFileName = destFileName });
lock (((ICollection)_queue).SyncRoot)
{
_queue.Enqueue(param);
_newItemEvent.Set();
}
}
/// <summary>
/// Rsync 同步
/// </summary>
/// <param name="SourcePath">源文件路径</param>
/// <param name="DestFilePath">目标文件路径</param>
public void Rsync(string SourcePath, string DestFilePath)
{
SyncParam param = new SyncParam();
if (param.CopyParams == null)
{
param.CopyParams = new List<CopyParam>();
}
param.CopyParams.Add(new CopyParam() { SourceFileName = SourcePath, DestFileName = DestFilePath });
lock (((ICollection)_queue).SyncRoot)
{
_queue.Enqueue(param);
_newItemEvent.Set();
}
}
/// <summary>
/// 获取完整的文件路径
/// </summary>
/// <param name="configPath"></param>
/// <param name="attPath"></param>
/// <param name="fileName"></param>
/// <returns></returns>
private string GetRsyncFileFullPath(string configPath, string attPath, string fileName)
{
string fullPath = "";
if (attPath.Length > 0)
{
fullPath = configPath + attPath;
}
else
{
if (!fullPath.EndsWith("\\"))
{
fullPath = configPath + "\\";
}
}
CheckIsExitsDir(fullPath);
return fullPath + fileName;
}
/// <summary>
/// 判断路径是否存在,如果不存在则创建
/// </summary>
/// <param name="path"></param>
private void CheckIsExitsDir(string path)
{
if ( path.StartsWith("\\\\") )
{
string host = path.Substring("\\\\".Length, path.IndexOf("\\", "\\\\".Length) - 2);
using (IdentityScope scope = new IdentityScope( host ))
{
if (!Directory.Exists(path))
{
DirectoryHandler.creatPath(path);
}
}
}
else {
DirectoryHandler.creatPath(path);
}
}
}
class CopyParam
{
public string SourceFileName { get; set; }
public string DestFileName { get; set; }
}
class RsyncParam
{
public string SavePath { get; set; }
public string FileUrl { get; set; }
public string FileName { get; set; }
public string SyncHost { get; set; }
public string SyncDir { get; set; }
}
class SyncParam
{
public IList<CopyParam> CopyParams { get; set; }
public IList<RsyncParam> RsyncParams { get; set; }
public string FileLink { get; set; }
}
}