2

I am trying to copy files from Server A to Server B.

So basically, it's fast and easy, File.Copy.

File.Copy("\\ServerA\c$\CopyImageTest\Server61.txt", "\\ServerB\c$\CopyImageTest\Server61.txt")  
File.Copy("\\ServerB\c$\CopyImageTest\Server182.txt", "\\ServerA\c$\CopyImageTest\Server182.txt")

Since Server A requires login to use, it's obvious that I got this error:

System.IO.IOException: Logon failure: unknown user name or bad password.

I've looked around and found that I should use Impersonation in order to access that server and copy the files. I found this answer which is in C# and converted it to VB.NET.

Here's the code that I am using:

Module Module1

    <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
    Sub Main()
        Try
           'Some declarations omitted for clearance.
            Const LOGON32_PROVIDER_DEFAULT As Integer = 0
            Const LOGON32_LOGON_INTERACTIVE As Integer = 2
            Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9

            Try
                Dim bImpersonated As Boolean = LogonUser(sUsername, sDomain, sPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, pExistingTokenHandle)

                If (Not bImpersonated) Then
                    Dim nErrorCode As Integer = Marshal.GetLastWin32Error()
                    Return
                End If

                Dim bRetVal As Boolean = DuplicateToken(pExistingTokenHandle, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, pDuplicateTokenHandle)

                If (Not bRetVal) Then
                    Dim nErrorCode As Integer = Marshal.GetLastWin32Error()
                    CloseHandle(pExistingTokenHandle)
                    Return
                Else
                    Dim newId As WindowsIdentity = New WindowsIdentity(pDuplicateTokenHandle)
                    Dim impersonateduser As WindowsImpersonationContext = newId.Impersonate()

                    'Shouldn't I be copying now?
                    File.Copy("\\ServerA\c$\CopyImageTest\Server61.txt", "\\ServerB\c$\CopyImageTest\Server61.txt")  
                    File.Copy("\\ServerB\c$\CopyImageTest\Server182.txt", "\\ServerA\c$\CopyImageTest\Server182.txt")

                    sResult = sResult & "After impersonation: " & WindowsIdentity.GetCurrent.Name & Environment.NewLine
                    impersonateduser.Undo()
                End If

            Catch ex As Exception
                'Omitted
            Finally
                If (Not pExistingTokenHandle = IntPtr.Zero) Then
                    CloseHandle(pExistingTokenHandle)
                End If

                If (Not pDuplicateTokenHandle = IntPtr.Zero) Then
                    CloseHandle(pDuplicateTokenHandle)
                End If
            End Try
        Catch ex As Exception
            'Omitted
        End Try
    End Sub

    ' DLL Imports and Enum Omitted.
End Module

Some code to output the results has been omitted, but here's the results from the console:

User was able to login. (This is used after LogonUser()) (Previously it was throwing an error (1326) Logon failure: unknown user name or bad password)
Before impersonation: User-PC\User (Result of WindowsIdentity.GetCurrent().Name; Before Impersonate())
After impersonation: User-PC\User (Result of WindowsIdentity.GetCurrent().Name; After Impersonate())

System.IO.IOException: Logon failure: unknown user name or bad password.

What's confusing is that the name before and after impersonation is the same as my local PC. However the login is working. (I am positive about that because, as stated, it was failing previously.)

Secondly, the file still doesn't get copied with same error as before:

Logon failure: unknown user name or bad password.

Is this how actually Impersonation should be working, or am I missing something obvious?

After digging a bit more, I also found this answer and I used the same exact code from the answer, but with no luck at all.

Some information about the Server A that I am trying to access and copy the files from:

  • I can connect through remote desktop connecting using the same username/password.
  • I can open the file explorer from my own PC using the server IP address as shown in the code: \\ServerA\c$\CopyImageTest.
  • Both my PC and the server are on the same network, but different domains.

Update:

@Esko's comment guided me to make two or three tests.

Here's the scenario:

  • With Impersonation I tried this code:

    File.Copy("\\ServerA\c$\CopyImageTest\Server61.txt", "C:\CopyImageTest\Server61.txt")
    File.Copy("C:\CopyImageTest\Server182.txt", "\\ServerA\c$\CopyImageTest\Server182.txt")
    

    Which means that I only copied the files from ServerA to local and vice versa.
    Result: Passed.

  • With Impersonation

    File.Copy("C:\CopyImageTest\Server61.txt", "\\ServerB\c$\CopyImageTest\Server61.txt")
    File.Copy("\\ServerB\c$\CopyImageTest\Server182.txt", "C:\CopyImageTest\Server182.txt")
    

    Which means I tried to copy from ServerB to local and vice verca
    Result: Failed

  • Without impersonation

    File.Copy("C:\CopyImageTest\Server61.txt", "\\ServerB\c$\CopyImageTest\Server61.txt")
    File.Copy("\\ServerB\c$\CopyImageTest\Server182.txt", "C:\CopyImageTest\Server182.txt")
    

    Copying from and to ServerB
    Result: Passed

So at the end, I think the problem is that when Impersonating the user to access ServerA it fails to access ServerB, knowing that ServerB doesn't require username password when trying to access it from my PC. Maybe because my PC and ServerB uses same domain on same network but ServerA uses another domain on same network?

Is there any workaround to access both servers with a single impersonation?

Note: I am aware of being able to copy files from ServerA to local then undo impersonation and copy to ServerB, I am just looking for a more straight way.

Paul Karam
  • 4,052
  • 8
  • 30
  • 53
  • Is this a Asp.Net-application or a windows-application? I think the reason why it's not working is that delegation of credentials is not enabled on server A. Server A is unable to transfer credentials to third party (server B) if delegation is not enabled for the server in Active Directory. – Esko Apr 16 '18 at 11:25
  • Currently it's just a proof of concept console application. Later on it will be implemented in a windows form application. So to answer your question, it's a windows-application. – Paul Karam Apr 16 '18 at 11:26
  • You don't need any impersonation of you simply run the console application with the credentials that you want to use. – Esko Apr 16 '18 at 11:31
  • @Esko Your comment made me think of something else and I did three tests. Updating the question to show what I found out. – Paul Karam Apr 16 '18 at 11:32

0 Answers0