A: 

With your definitions, I use

LogonUser(_username, _domainname, _password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, _tokenHandle)

in my code that is authenticating across the network. I am impersonating a local user on the remote box, as you are. It was so long ago that I don't remember the rationale for using these values, however.

Don
Thanks for the reply! Unfortunately, I've tried those values to no avail. There has to be SOMETHING (probably small and stupid) that I am overlooking somewhere that is causing this to not work
Anders
I see now that I misunderstood - it was in trying to access the data through the COM object that you were having the problem. I see also that you've come up with a work around - not ideal, but as you say, since the impersonation is at the application level, one way to do it.
Don
A: 

I do a similar thing to map network drives for copying files between machines. I didn't write the code but it's pretty much the same as yours, except for two things:

  • After the Impersonate method returns I close both tokens using the CloseHandle routine, before I exit my impersonator method.

  • At the top of the impersonator the first thing that happens is a call to RevertToSelf, presumably to cancel any previous impersonation.

I don't know if they would make a difference but it's worth a try. Here are the relevant declarations:

Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Chris Tybur
+1  A: 

I have run into this before, and used two different soloution - the easiest was using a third party app: TqcRunas: http://www.quimeras.com/Products/products.asp which allows you to package the required creentials in an encrypted file. However is a pain if the password is forced to expire.

The other solution that I have used is to call a new process with alternative credentials:

        Dim myProcessStartInfo As ProcessStartInfo = New ProcessStartInfo

    With myProcessStartInfo

        .FileName = "file path and name"

        .Domain = "domainname"
        .UserName = "username"

        'password needs to be a SerureString
        Using NewPassword As New Security.SecureString
            With NewPassword
                For Each c As Char In "password".ToCharArray
                    .AppendChar(c)
                Next c
                .MakeReadOnly()
            End With
            .Password = NewPassword.Copy
        End Using

        'UseShellExecute must be false for impersonated process
        .UseShellExecute = False

    End With

    Using Process As New System.Diagnostics.Process
        With Process
            .StartInfo = myProcessStartInfo
            .Start()
        End With
    End Using
Bob
this is what I ended up using, even though I implemented it before you suggested it. credits for you for providing an accurate solution :)
Anders