Copy file on a network shared drive
Asked Answered
D

4

24

I have a network shared drive ("\serveur\folder") on which I would like to copy file. I can write on the drive with a specific user ("user"/"pass"). How can I access the shared drived with write privilege using C#?

Dissection answered 16/9, 2009 at 10:41 Comment(0)
C
28

Untested code, but it will be similiar to:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

// http://pinvoke.net/default.aspx/advapi32/LogonUser.html    
IntPtr token;
LogonUser("username", "domain", "password", LogonType.LOGON32_LOGON_BATCH, LogonProvider.LOGON32_PROVIDER_DEFAULT);

WindowsIdentity identity = new WindowsIdentity(token);

WindowsImpersonationContext context = identity.Impersonate();

try
{
    File.Copy(@"c:\temp\MyFile.txt", @"\\server\folder\Myfile.txt", true);
}
finally
{
    context.Undo();
}
Candidacandidacy answered 16/9, 2009 at 10:56 Comment(3)
where is declaration of LogonUser function?Yellowgreen
@Nitin: see the comment in code? pinvoke.net/default.aspx/advapi32/LogonUser.html . It's a win32 api callCandidacandidacy
@MitchWheat: This link is dead at the momentTumulus
S
8

Here's a working example for ASP.NET applications. Original source

private void SendToFileShare(byte[] pdfData, string fileName)
{
    if(pdfData == null)
    {
        throw new ArgumentNullException("pdfData");
    }
    if (string.IsNullOrWhiteSpace(fileName))
    {
        //Assign a unique name because the programmer failed to specify one.
        fileName = Guid.NewGuid().ToString();
    }
    else
    {
        //Should probably replace special characters (windows filenames) with something.                
    }


    string networkShareLocation = @"\\your\network\share\";

    var path = $"{networkShareLocation}{fileName}.pdf";


    //Credentials for the account that has write-access. Probably best to store these in a web.config file.
    var domain = "AB";
    var userID = "Mr";
    var password = "C";


    if (ImpersonateUser(domain, userID, password) == true)
    {
        //write the PDF to the share:
        System.IO.File.WriteAllBytes(path, report);

        undoImpersonation();
    }
    else
    {
        //Could not authenticate account. Something is up.
        //Log or something.
    }
}

/// <summary>
/// Impersonates the given user during the session.
/// </summary>
/// <param name="domain">The domain.</param>
/// <param name="userName">Name of the user.</param>
/// <param name="password">The password.</param>
/// <returns></returns>
private bool ImpersonateUser(string domain, string userName, string password)
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;

    if (RevertToSelf())
    {
        if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        {
            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
            {
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                impersonationContext = tempWindowsIdentity.Impersonate();
                if (impersonationContext != null)
                {
                    CloseHandle(token);
                    CloseHandle(tokenDuplicate);
                    return true;
                }
            }
        }
    }
    if (token != IntPtr.Zero)
        CloseHandle(token);
    if (tokenDuplicate != IntPtr.Zero)
        CloseHandle(tokenDuplicate);
    return false;
}

/// <summary>
/// Undoes the current impersonation.
/// </summary>
private void undoImpersonation()
{
    impersonationContext.Undo();
}


#region Impersionation global variables
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
    int impersonationLevel,
    ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
#endregion
Summerville answered 1/8, 2016 at 17:31 Comment(1)
why are you duplicating the token?Fervor
M
4

More simple and modern approach. Works for me in an enterprise network.

 try
{
    bool validLogin = false;
    using (PrincipalContext tempcontext = new PrincipalContext(ContextType.Domain, "domain.company.com", null, ContextOptions.Negotiate))
    {
        try
        {
            validLogin = tempcontext.ValidateCredentials("USERNAME", "PASSWORD", ContextOptions.Negotiate);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    if (validLogin)
    {
        File.Copy(@"C:\folder\filename.txt", @"\\domain\folder\filename.txt", true);
        return true;
    }
    else
    {
        MessageBox.Show("Username or Password is incorrect...", "Login Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return false;
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
    return false;
}
Muss answered 20/3, 2020 at 10:48 Comment(0)
A
0

Create a user with privileges to write to the network drive and use impersonation within the c# to use that user when accessing the drive.

Arris answered 16/9, 2009 at 10:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.