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: FailedWithout 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.