如何将文件写入非Windows计算机上的映射文件夹

时间:2019-07-02 17:54:02

标签: c# impersonation

我正在尝试以编程方式在映射的网络驱动器上写入文件。该共享托管在运行DSM的Synology NAS上。

在Windows 10上映射驱动器时,我指定共享“ \\ 192.1.1.1 \ Share”,并在提示输入凭据时提供“ DS3617XS \ admin”和“密码”。

我试图在写入文件之前模拟用户。

static void Main( string[] args )
{
    using ( new Impersonator("admin", "DS3617XS", "password" ) )
    {
        //Write the file
    }
}


public class Impersonator
{
    [DllImport("advapi32.dll", SetLastError=true)]
    private 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)]
    private static extern int DuplicateToken(
        IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);

    [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    private static extern bool RevertToSelf();

    [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
    private static extern  bool CloseHandle(
        IntPtr handle);
    private const int LOGON32_LOGON_INTERACTIVE = 2;
    private const int LOGON32_PROVIDER_DEFAULT = 0;

    public Impersonator(
        string userName,
        string domainName,
        string password )
    {
        ImpersonateValidUser( userName, domainName, password );
    }
    private void ImpersonateValidUser(
        string userName, 
        string domain, 
        string password )
    {
        WindowsIdentity tempWindowsIdentity = null;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;

        try
        {
            if ( RevertToSelf() )
            {
                if ( LogonUser(
                    userName, 
                    domain, 
                    password, 
                    LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, 
                    ref token ) != 0 )
                {
                    if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
                    {
                        tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
                        impersonationContext = tempWindowsIdentity.Impersonate();
                    }
                    else
                    {
                        throw new Win32Exception( Marshal.GetLastWin32Error() );
                    }
                }
                else
                {
                    throw new Win32Exception( Marshal.GetLastWin32Error() );
                }
            }
            else
            {
                throw new Win32Exception( Marshal.GetLastWin32Error() );
            }
        }
        finally
        {
            if ( token!= IntPtr.Zero )
            {
                CloseHandle( token );
            }
            if ( tokenDuplicate!=IntPtr.Zero )
            {
                CloseHandle( tokenDuplicate );
            }
        }
    }

    private WindowsImpersonationContext impersonationContext = null;

}

引发异常“当前没有可用于登录请求的登录服务器”

0 个答案:

没有答案