Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy files over network via file share, user authentication

I am building a .net C# console program to deploy file to a windows file share server (folder that is being shared). The path is :: \\192.168.0.76\htdocs\public

On running I am getting the error:

[09:35:29]: [Step 1/3] Unhandled Exception: System.UnauthorizedAccessException: Access to the path '\\192.168.0.76\htdocs\public' is denied.
[09:35:29]: [Step 1/3]    at DeployFileShare.Program.CopyDir(String source, String dest, String[] exclude, Boolean overwrite)
[09:35:29]: [Step 1/3]    at DeployFileShare.Program.Deploy(String num, String source)
[09:35:29]: [Step 1/3]    at DeployFileShare.Program.Main(String[] args)
[09:35:29]: [Step 1/3] Process exited with code -532459699

I think I need to authenticate myself. I've come across this:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsIdentity idnt = new WindowsIdentity(username, password);
WindowsImpersonationContext context = idnt.Impersonate();

I've also tried:

AppDomain.CreateDomain("192.168.0.76").SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsIdentity idnt = new WindowsIdentity("user", "pass");
WindowsImpersonationContext context = idnt.Impersonate();

I am not sure how to use it. When I run the application I get:

C:\Users\Administrator>DeployFileShare 1 R:\BuildOutput\_PublishedWebsites\Web 2
1
Deploy Started Web, version 21
-- Deploy Prepared
-- Deploying to 1

Unhandled Exception: System.Security.SecurityException: There are currently no l
ogon servers available to service the logon request.

   at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn)
   at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName,
 String type)
   at DeployFileShare.Program.Authenticate(String server)
   at DeployFileShare.Program.Deploy(String num, String source)
   at DeployFileShare.Program.Main(String[] args)
The Zone of the assembly that failed was:
MyComputer

Here is the basic code:

static void Main()
{
Copy();
}
static void Copy()
{
AppDomain.CreateDomain(GetServerInfo(server, "server")).SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            WindowsIdentity idnt = new WindowsIdentity(GetServerInfo(server, "user"), GetServerInfo(server, "pass"));
            WindowsImpersonationContext context = idnt.Impersonate();
string source = "C:\\someDir";
string dest = "\\192.168.0.76\shareFolder"
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
            foreach (string file in sourceFiles)
            {
                string local = file.Replace(source, "");
                if (exclude.Contains(local))
                    continue;
                if (!Directory.Exists(Path.GetDirectoryName(dest + "\\" + local)))
                    Directory.CreateDirectory(Path.GetDirectoryName(dest + "\\" + local));
                File.Copy(file, dest + "\\" + local, overwrite);
                Console.WriteLine("-- -- [copied] {0} -> {1}", file, dest + "\\" + local);
            }
}

The code copy system in the for loop works, I've tested it on my local system.

If anyone knows how I should use WindowsIdentity and WindowsIdentity to get this to work please enlighten me. I've been looking around and window's documentation doesn't help much.

Basically how can I copy to a remote directory being shared by logging into the system?

like image 835
Patrick Lorio Avatar asked Nov 17 '11 18:11

Patrick Lorio


People also ask

How do I transfer files over network sharing?

To share a file or folder over a network in File Explorer, do the following: Right-click (or long-press) a file, and then select Show more options > Give access to > Specific people. Select a user on the network to share the file with, or select Everyone to give all network users access to the file.

How do you give credentials in a batch script that copies files to a network location?

Try using the net use command in your script to map the share first, because you can provide it credentials. Then, your copy command should use those credentials.

How do I access files shared over a network?

Double-click the name of the computer from which the folder you want to open is being shared. Select a folder. Double-click the folder you want to open. Enter a username and password if prompted.

How do I access a network path with different credentials?

In the Folder box, type the path of the folder or computer, or select Browse to find the folder or computer. To connect every time you log on to your PC, select the Reconnect at sign-in check box. ** This is the point where you should also choose "Connect using different credentials".


2 Answers

VB but easily translated to C#. Do this before your copy:

Private Sub Open_Remote_Connection(ByVal strComputer As String, ByVal strUserName As String, ByVal strPassword As String)
    Dim ProcessStartInfo As New System.Diagnostics.ProcessStartInfo
    ProcessStartInfo.FileName = "net"
    ProcessStartInfo.Arguments = "use \\" & strComputer & "\c$ /USER:" & strUsername & " " & strPassword
    ProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden
    System.Diagnostics.Process.Start(ProcessStartInfo)
    System.Threading.Thread.Sleep(2000)
End Sub
like image 104
Jimmy D Avatar answered Sep 22 '22 11:09

Jimmy D


If you want to authenticate to a remote computer in order to move a file, you can use the LogonUser function to and WindowsIdentity to impersonate your user.

/// <summary>
/// Exécute une fonction en empruntant les credentials
/// </summary>
private T ApplyCredentials<T>(Func<T> func)
{
    IntPtr token;

    if (!LogonUser(
        _credentials.UserName,
        _credentials.Domain,
        _credentials.Password,
        LOGON32_LOGON_INTERACTIVE,
        LOGON32_PROVIDER_DEFAULT,
        out token))
    {
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
    }

    try
    {
        // On doit être impersonifié seulement le temps d'ouvrir le handle.
        using (var identity = new WindowsIdentity(token))
        using (var context = identity.Impersonate())
        {
            return func();
        }
    }
    finally
    {
        CloseHandle(token);
    }
}

// ...

if (_credentials != null)
{
    return this.ApplyCredentials(() => File.Open(path, mode, access, share));
}

return File.Open(path, mode, access, share);
like image 21
Francis Avatar answered Sep 24 '22 11:09

Francis