Network Share Authentication using username and password

Challenge:

  1. Access files located in the network shared folder.
  2. Shared folder is restricted to specific users only.
  3. Last but not least, do all the above programatically using C#.Net.

 

Solution:

Achieved it by using the below judiciously

[DllImport(“mpr.dll”)]
private static extern int WNetAddConnection2(NetResource netResource,
string password, string username, int flags);

[DllImport(“mpr.dll”)]
private static extern int WNetCancelConnection2(string name, int flags,
bool force);

First, Create the class to make the connection to the networkshare as below.

public class NetworkConnection : IDisposable
{
    string _networkName;

    public NetworkConnection(string networkName, 
        NetworkCredential credentials)
    {
        _networkName = networkName;

        var netResource = new NetResource()
        {
            Scope = ResourceScope.GlobalNetwork,
            ResourceType = ResourceType.Disk,
            DisplayType = ResourceDisplaytype.Share,
            RemoteName = networkName
        };

        var result = WNetAddConnection2(
            netResource, 
            credentials.Password,
            credentials.UserName,
            0);

        if (result != 0)
        {
            throw new Win32Exception(result, "Error connecting to remote share");
        }   
    }

    ~NetworkConnection()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        WNetCancelConnection2(_networkName, 0, true);
    }

    [DllImport("mpr.dll")]
    private static extern int WNetAddConnection2(NetResource netResource, 
        string password, string username, int flags);

    [DllImport("mpr.dll")]
    private static extern int WNetCancelConnection2(string name, int flags,
        bool force);
}

[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
    public ResourceScope Scope;
    public ResourceType ResourceType;
    public ResourceDisplaytype DisplayType;
    public int Usage;
    public string LocalName;
    public string RemoteName;
    public string Comment;
    public string Provider;
}

public enum ResourceScope : int
{
    Connected = 1,
    GlobalNetwork,
    Remembered,
    Recent,
    Context
};

public enum ResourceType : int
{
    Any = 0,
    Disk = 1,
    Print = 2,
    Reserved = 8,
}

public enum ResourceDisplaytype : int
{
    Generic = 0x0,
    Domain = 0x01,
    Server = 0x02,
    Share = 0x03,
    File = 0x04,
    Group = 0x05,
    Network = 0x06,
    Root = 0x07,
    Shareadmin = 0x08,
    Directory = 0x09,
    Tree = 0x0a,
    Ndscontainer = 0x0b
}

Second, Access the file using the above class as below

[TestMethod]
        public void TestConnectivity_Using_Credentials()
        {
            try
            {
                System.Net.NetworkCredential readCredentials = new NetworkCredential(@"Domain\UserName", "Password");

                string filepath = @"\\Servername\DevTest\MyFiles";
                using (new NetworkConnection(filepath, readCredentials))
                {
                    File.Copy(@"\\Servername\DevTest\MyFiles\XXX.txt", @"\\Servername\DevTest\MyFiles\XXX-Copy.txt");
                }
                Assert.AreEqual<string>("01", "01", "Success");
            }
            catch
            {
                Assert.Fail();
            }
        }

 

Errors encountered

When i used the WNetAddConnection2 method, it returned 1219 as result code. Well, it worked for my own credentials, but when i passed the service credentials to access the files. I was facing this problem.

After querying uncle Google, I realized that the natively windows allows only one user to be used to map the network drive, i.e, i cannot use my own credentials and service credentials (both being different) to access the same network share from the same server concurrently.

As as alternative, i use the ip Address to access the networkshare using my service account. and Violla, it worked like a charm.

 

Links referred to develop:

http://stackoverflow.com/questions/295538/how-to-provide-user-name-and-password-when-connecting-to-a-network-share

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385413(v=vs.85).aspx

 

Links referred to troubleshoot

http://stackoverflow.com/questions/6207289/wnetaddconnection2-returns-1219

http://social.msdn.microsoft.com/Forums/sv/wsk/thread/f43c2faf-3df3-4f11-9f5e-1a9101753f93

http://forums.asp.net/t/1788841.aspx/1

 

Adios.