代码之家  ›  专栏  ›  技术社区  ›  Ahmed

是否在其他用户和域下打开共享文件?

  •  2
  • Ahmed  · 技术社区  · 17 年前

    我有一个C控制台应用程序,它需要读取另一个域中计算机上的共享文件。 当应用程序尝试访问该文件时,会发生异常,因为本地用户没有访问共享资源的权限。

    如何以编程方式完成?

    3 回复  |  直到 17 年前
        1
  •  3
  •   Anton Tykhyy    17 年前

    a) p/调用 LogonUser 具有 LOGON32_LOGON_NEW_CREDENTIALS 创造一个新的 WindowsIdentity 使用新令牌,然后使用普通文件访问。

    b) p/调用 WNetAddConnection3 . 请注意,这将使您的远程共享可以访问您的计算机上的其他所有进程。

    c) WMI通过 System.Management CIM_DataFile ;甚至不需要p/invoke。 系统管理

        2
  •  3
  •   CarenRose    6 年前

    我使用了Anton建议的“a”点,为一个类开发了两个版本,第一个使用win32api,第二个使用 WindowsIdentity 班级。

    class UserImpersonation : IDisposable
    {       
        [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;
    
        WindowsImpersonationContext wic;
        string _userName;
        string _domain;
        string _passWord;
        
        public UserImpersonation(string userName, string domain, string passWord)
        {
            _userName = userName;
            _domain = domain;
            _passWord = passWord;
        }
        
        public bool ImpersonateValidUser()
        {
            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;
        }
    
        #region IDisposable Members
        public void Dispose()
        {
            if (wic != null)
            {
                wic.Dispose();
            }
            RevertToSelf();
        }
        #endregion
    }
    

    版本2(自 MSDN

    class UserImpersonation2 : IDisposable
    {
        [DllImport("advapi32.dll")]
        public static extern bool LogonUser(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);
    
        WindowsImpersonationContext wic;
        IntPtr tokenHandle;
        string _userName;
        string _domain;
        string _passWord;
    
        public UserImpersonation2(string userName, string domain, string passWord)
        {
            _userName = userName;
            _domain = domain;
            _passWord = passWord;
        }
    
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;
    
        public bool ImpersonateValidUser()
        {
            bool returnValue = LogonUser(_userName, _domain, _passWord,
                    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                    ref tokenHandle);
    
            Console.WriteLine("LogonUser called.");
    
            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                return false;
            }
    
            Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
            Console.WriteLine("Value of Windows NT token: " + tokenHandle);
    
            // Check the identity.
            Console.WriteLine("Before impersonation: "
                + WindowsIdentity.GetCurrent().Name);
                
            // Use the token handle returned by LogonUser.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            wic = newId.Impersonate();
    
            // Check the identity.
            Console.WriteLine("After impersonation: "
                + WindowsIdentity.GetCurrent().Name);
                
            return true;
        }
        
        #region IDisposable Members
        public void Dispose()
        {
            if(wic!=null)
            {
                wic.Undo();
            }
            if (tokenHandle != IntPtr.Zero)
            {
                CloseHandle(tokenHandle);
            }
        }
        #endregion
    }
    

    使用方法(两者相同):

    const string file = @"\\machine\test\file.txt";
    
    using (UserImpersonation user = new UserImpersonation("user", "domain", "password"))
    {
        if (user.ImpersonateValidUser())
        {
            StreamReader reader = new StreamReader(file);
            Console.WriteLine(reader.ReadToEnd());
            reader.Close();
        }
    }
    
        3
  •  0
  •   Kane    17 年前

    link 举个例子。

    另一种方法是使用RunAs命令行参数读取文件并将其保存到本地域/服务器上的文件中。