0

I am writing a windows application using C#. I have a requirement where the files uploaded into the windows form are to be saved into a network share but not all users can access the network share (\\FileServer\SharedFolder). Only one user ( FileWriter)has got read / write / execute permissions on this folder. The current user EmployeeUser does not have any permissions on this share. I have verified this by opening the Start->Run \\FileServer\SharedFolder. This gives a Access Denied error box.

I have used this example from SO Post, using the WNetAddConnection2 to connect with different credentials of FileWriter to save the file Sample.txt using File.Create. So far everything was OK.WNetCancelConnection2 is called, I have verified in the code debug, and the program exited. Now from the current user, I have opened StartMenu --> Run and typed the \\FileServer\SharedFolder and the share immediately opened even though the windows user is EmployeeUser. I have closed the explorer and after a few minutes (this changes randomly through attempts) I have opened the Start->Run \\FileServer\SharedFolder. Now it gives a Access Denied error box.

I am unable to understand this, Any help on this is much appreciated.

Now after the Access Denied box I run the program again with the same steps except that the Sample.txt (using File.Create) is silently Overwritten. Isn't it supposed to give a File Exists Error?

Community
  • 1
  • 1
Kumar C
  • 100
  • 2
  • 13
  • What value is `WNetCancelConnection2` returning when called? – stuartd Nov 19 '15 at 14:38
  • 1
    The [documentation for `File.Create`](https://msdn.microsoft.com/en-us/library/d62kzs03%28v=vs.110%29.aspx) says "if the specified file does not exist, it is created; if it does exist and it is not read-only, the contents are overwritten." – stuartd Nov 19 '15 at 14:59
  • @stuartd The `WNetCancelConnection2` is returning 0. Also thanks for the `File.Create`. I have completely forgotten that. – Kumar C Nov 20 '15 at 04:13

1 Answers1

0

You can use a impersonator instead:

using (var impersonator = new Impersonator(username, password))
{
    File.Copy(source, destination, true);
}

this is a copy past from our implementation, so please adjust your domain name

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;

public class Impersonator : IDisposable
{
/// <summary>
///     The Impersonator class is used to access a network share with other credentials.
/// </summary>
private readonly WindowsImpersonationContext _impersonatedUser;

private readonly IntPtr _userHandle;

/// <summary>
///     Constructor
/// </summary>
/// <param name="username">The user of the network share</param>
/// <param name="password">The password of the network share</param>
public Impersonator(string username, string password, string userDomain =   "YOURDOMAIN")
{
    _userHandle = new IntPtr(0);
    bool returnValue = LogonUser(username, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                                 ref _userHandle);
    if (!returnValue)
        throw new ApplicationException(
            "The applications wasn't able to impersonate the user with the specified credentials!");
    var newId = new WindowsIdentity(_userHandle);
    _impersonatedUser = newId.Impersonate();
}

#region IDisposable Members

public void Dispose()
{
    if (_impersonatedUser != null)
    {
        _impersonatedUser.Undo();
        CloseHandle(_userHandle);
    }
}

#endregion

#region Interop imports/constants

public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_SERVICE = 3;
public const int LOGON32_PROVIDER_DEFAULT = 0;

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

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

#endregion
}
Andre
  • 662
  • 1
  • 8
  • 19
  • Thanks for that. It worked beautifully. Now after the using block the _EmployeeUser_ is unable to browse the _\\FileServer\SharedFolder_, even if tried immediately. Your Solution Did solve my problem. – Kumar C Nov 20 '15 at 04:26
  • However, on a Side note I would like to know the problem with `WNetCancelConnection2`, _Just for Educational Purpose, if not anything else_, which returned 0 but allowed the _EmployeeUser_ to browse the _\\FileServer\SharedFolder_ as pointed in my original post. – Kumar C Nov 20 '15 at 04:32
  • I don't know `WNetCancelConnection2`, never used it. sorry – Andre Nov 20 '15 at 08:20