zoukankan      html  css  js  c++  java
  • windows32 LogonUser API Impersonate

    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; }
    }

    }

     

  • 相关阅读:
    linux 解压tgz 文件指令
    shell 脚本没有执行权限 报错 bash: ./myshell.sh: Permission denied
    linux 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid operational disruption.
    远程查询批量导入数据
    修改 MZTreeView 赋权节点父节点选中子节点自动选中的问题
    关于乱码的问题解决记录
    我的网站优化之路
    对设计及重构的一点反思
    我的五年岁月
    奔三的路上
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2729398.html
Copyright © 2011-2022 走看看