views:

226

answers:

3

Is there some way to authenticate as a local (not network) user in order to copy files over the network in .Net?

net use is not an option, and I can't seem to get LogonUser to work.

Any ideas?


[Edit] Here is some code:

public class UserImpersonator : IDisposable
{
    private WindowsImpersonationContext _impersonationContext;
    private IntPtr _userHandle = IntPtr.Zero;

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool LogonUser(
        string lpszUsername,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        out IntPtr phToken
        );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hHandle);

    public UserImpersonator(string username, string password)
    {
        LogonUser(username, "", password, (int)LogonType.LOGON32_LOGON_NETWORK,
                  (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, out _userHandle);
        _impersonationContext = WindowsIdentity.Impersonate(_userHandle);
    }

    public void Dispose()
    {
        CloseHandle(_userHandle);
        _impersonationContext.Undo();
    }

    private enum LogonType : int
    {
        LOGON32_LOGON_INTERACTIVE = 2,
        LOGON32_LOGON_NETWORK = 3,
        LOGON32_LOGON_BATCH = 4,
        LOGON32_LOGON_SERVICE = 5,
        LOGON32_LOGON_UNLOCK = 7,
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
        LOGON32_LOGON_NEW_CREDENTIALS = 9,
    }

    private enum LogonProvider
    {
        LOGON32_PROVIDER_DEFAULT = 0,
    }
}

When I wrap the File.Copy operation in using(new UserImpersonator(username, password)), I get:

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

If, however, I first try to connect to the share in explorer (entering the authentication info when it asks for it), the File.Copy works. It appears that the above code doesn't do anything at all.

A: 

You really need to logon to either a local account that is a member of a group on the domain controller, or just log directly onto a DC account. Without more information, though, I'm not sure what you're having trouble with. Could you post code?

edit

Ok, I see two problems.

The main problem is that you're passing an empty string for the domain parameter of LogonUser. Try passing in the name of the local machine or the network DC.

The side problem is that you need to log in using Batch or Interactive, not Network. Network login gives you an impersonation token, not a primary logon, which may prevent you from reaching network resources unless delegation is enabled.

Also, once you get this working, you're going to want to remove the IntPtr entirely and replace it with a SafeHandle.

Steven Sudit
@Steven: See edit.
BlueRaja - Danny Pflughoeft
Please let us know if that helps.
Steven Sudit
And if the computer name is unknown..? (I only know the IP)
BlueRaja - Danny Pflughoeft
I don't believe an IP will work here. One possibility is to do a reverse DNS lookup to get a machine name from the IP. The other is to use the name of the current machine so as to log into a local account that is in a DC group. But, really, you should know the name of the DC, and it's not a significant security risk to place it in your app.config.
Steven Sudit
The only account that has access to the share is a local one on the computer. This is not my doing - they are connected to large machines, which we have no access to.
BlueRaja - Danny Pflughoeft
Ok, so you just need to logon to the local account. Just use Environment.MachineName.
Steven Sudit
Actually, according to http://msdn.microsoft.com/en-us/library/aa378184(VS.85).aspx, you can just pass "." as the machine name.
Steven Sudit
I tried that, it did not work
BlueRaja - Danny Pflughoeft
For more general information, check out http://msdn.microsoft.com/en-us/library/ms998351.aspx.
Steven Sudit
+1  A: 

You can use WNetUseConnection with p/invokes.

See this thread:

Accessing a Shared File (UNC) From a Remote, Non-Trusted Domain With Credentials

Joe
Works perfectly without having to know the computer name - thank you!
BlueRaja - Danny Pflughoeft
A: 

Might I direct you to my answer I put over here? It should work for your needs.

Jesse C. Slicer