0

I need to access a file from a network drive with a user who may not be in the domain.

My current code is:

private async Task GetUxVersionsFromServer()
{            

    string path = @$"\\{IpAddress}\...\...\...";

    if(!await GetFiles(path))
    {
        using (UNCAccessWithCredentials unc = new UNCAccessWithCredentials())
        {
            bool retry = true;
            do
            {
                (var ok, var username, var password) = _dialogService.ShowPasswordInput();

                if (ok)
                {
                    if (unc.NetUseWithCredentials(path, username, "domain", password))
                    {
                        await GetFiles(path);
                        retry = false;
                    }
                }
                else
                {
                    retry = false;
                }

            } while (retry);
        }
    }

}

private async Task<bool> GetFiles(string path)
{
    try
    {
        var zipFiles = await Task.FromResult(System.IO.Directory.GetFiles(path, "VERSION*.zip"));
        Versions = new ObservableCollection<string>(zipFiles);

        return true;
    }
    catch (IOException)
    {
        return false;
    }
}

I use the class UNCAccessWithCredential from here

It works fine.

If the user has access to the directory, the password entry should not appear. The only problem is that I can't test if the Windows user has access to the directory without catching an exception.

Is there a way to query if the logged in Windows user has access to a network directory or not?

Is there a way to query if the logged on Windows user is in the domain?

SteveZ
  • 175
  • 10
  • Side note: any sensible organization will not let you prompt user for domain password as plain text... So you should assume that you *never* get user from domain... – Alexei Levenkov Jan 20 '20 at 07:03
  • What other option would I have to grant a user access to a network directory from a computer outside the domain? – SteveZ Jan 20 '20 at 07:30
  • You should ask admins of Windows domain(s) you plan to use that in or some other folks responsible for security in organization(s) you are targeting... I expect answer to be "you simply don't give access to domain resources from outside" or maybe they give you guidance on using some form of web auth... Note: serverfault.com may be a better place to ask that particular question before you get to actually writing code... – Alexei Levenkov Jan 20 '20 at 07:40
  • For clarification: The users of the software are also users in the domain. However, the computer on which the software runs can also be outside the domain. The users could also get the desired files via the Windows Explorer, in this case the Windows security dialog would open and ask the user for username and password. However, the access to the files should be automated via software. – SteveZ Jan 20 '20 at 08:32

2 Answers2

0

Plenty of ways to figure out directory permissions here: How do you check for permissions to write to a directory or file?

As for the domain membership, use this: https://learn.microsoft.com/en-us/dotnet/api/system.environment.userdomainname?view=netframework-4.8

The UserDomainName property first attempts to get the domain name component of the Windows account name for the current user. If that attempt fails, this property attempts to get the domain name associated with the user name provided by the UserName property. If that attempt fails because the host computer is not joined to a domain, then the host computer name is returned.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
0

Finally I solved it this way:

    private async Task GetUxVersionsFromServer()
    {

        string path = @$"\\{server}\...";


        if (Environment.UserDomainName.ToLower() != "myDomain")
        {
            bool success = false;
            bool ok;
            do
            {                    
                (bool result, var username, var password) = _dialogService.ShowPasswordInput();
                ok = result;
                if (ok)
                {
                    try
                    {
                        using (new NetworkConnection(path, new NetworkCredential($@"myDomain\{username}", password)))
                        {
                            success = await GetFiles(path);                                
                        }
                    }
                    catch (System.ComponentModel.Win32Exception ex)
                    {
                        success = false;
                    }

                } 
            } while (!success && ok);

            if(!ok)
            {
                int test = 0;
            }
        }
        else
        {
            await GetFiles(path);
        }

    }

I took the class NetworkConnection from here

SteveZ
  • 175
  • 10