Unable to connect to UNC share with WindowsIdentity.Impersonate, but works fine using LogonUser
- by Rob
Hopefully I'm not missing something obvious here, but I have a class that needs to create some directories on a UNC share and then move files to the new directory. When we connect using LogonUser things work fine with no errors, but when we try and use the user indicated by Integrated Windows authentication we run into problems. Here's some working and non-working code to give you an idea what is going on.
The following works and logs the requested information:
[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", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
IntPtr token;
WindowsIdentity wi;
if (LogonUser("user", "network", "password",
8, // LOGON32_LOGON_NETWORK_CLEARTEXT
0, // LOGON32_PROVIDER_DEFAULT
out token))
{
wi = new WindowsIdentity(token);
WindowsImpersonationContext wic = wi.Impersonate();
Logging.LogMessage(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
Logging.LogMessage(path);
DirectoryInfo info = new DirectoryInfo(path);
Logging.LogMessage(info.Exists.ToString());
Logging.LogMessage(info.Name);
Logging.LogMessage("LastAccessTime:" + info.LastAccessTime.ToString());
Logging.LogMessage("LastWriteTime:" + info.LastWriteTime.ToString());
wic.Undo();
CloseHandle(token);
}
The following fails and gives an error message indicating the network name is not available, but the correct user name is indicated by GetCurrent().Name:
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity;
using (identity.Impersonate())
{
Logging.LogMessage(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
Logging.LogMessage(path);
DirectoryInfo info = new DirectoryInfo(path);
Logging.LogMessage(info.Exists.ToString());
Logging.LogMessage(info.Name);
Logging.LogMessage("LastAccessTime:" + info.LastAccessTime.ToString());
Logging.LogMessage("LastWriteTime:" + info.LastWriteTime.ToString());
}