Accessing a file on a network drive

David Božjak picture David Božjak · Mar 23, 2010 · Viewed 14.8k times · Source

Background: I have an application that has to read from files on a network drive (Z:)

This works great in my office domain, however it does not work on site (in a different domain). As far as I can tell the domain users and network drives are set in the same way, however I do not have access to users etc in the customers domain.

When I couldn't access the network drive I figured I needed a token for a user. This is how I impersionate the user:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

...

const string userName = "USER";
const string pass = "PASS";
const string domainName = "VALIDDOMAIN.local"  //tried with valid domain name and with null, same result
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;

IntPtr tokenHandle = new IntPtr(0);

bool returnValue = LogonUser(userName, domainName, pass,
            LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
            ref tokenHandle);

if (!returnValue)
    throw new Exception("Logon failed.");

WindowsImpersonationContext impersonatedUser = null;
try
{
    WindowsIdentity wid = new WindowsIdentity(tokenHandle);
    impersonatedUser = wid.Impersonate();

}
finally
{
    if (impersonatedUser != null) impersonatedUser.Undo();
}

Now here is the interesting/weird part. In my network the application can already access the network drive, and if I try to impersonate the active user (exactly the same user, including the same domain) it will not be able to access the network drive.

This leaves me helpless since now I have no idea what works and what doesn't, and more to the point, will it work on site?

What am I missing?

EDIT: I forgot to write this while originally asking the question: I have tried entering a valid domain name and it didn't work, so after that I tried entering null to get the same username as I would without this code (since it works by default in our domain). This did not help, and that's how domain = null; ended up in this question.

Answer

Keith Adler picture Keith Adler · Mar 23, 2010

Some thoughts:

  • Do not use logical drive paths to access network resources from code. Always use UNC paths (e.g. \\SERVER\Share\Filename.ext).
  • Enable auditing of Logon/Logoff events from your local security policy so that when you call the Impersonate method, you can track the failure/success in great detail
  • You would be best to create an account in your own domain that has the same username and password as an account in the other domain. Authenticate off your domain and pass-through authentication will give you access to the network share on the other domain.