ehh
ehh

Reputation: 3480

Copying a file, using impersonator, throw an Unauthorized Access Exception

I am using this Impersonator class to copy files to a Directory with access rights.

public void CopyFile(string sourceFullFileName,string targetFullFileName)
{
    var fileInfo = new FileInfo(sourceFullFileName);

    try
    {
        using (new Impersonator("username", "domain", "pwd"))
        {
            // The following code is executed under the impersonated user.
            fileInfo.CopyTo(targetFullFileName, true);
        }
    }
    catch (IOException)
    {
        throw;
    }
}

This code work almost perfectly. The problem I am facing is when the sourceFullFileName is a file located in folder like C:\Users\username\Documents where the original user has access but the impersonator not.

The exception I am getting while trying to copy a file from such location is:

An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll Additional information: Access to the path 'C:\Users\username\Documents\file.txt' is denied.

Upvotes: 1

Views: 3351

Answers (2)

Uwe Keim
Uwe Keim

Reputation: 40736

Before impersonation, the current user has access to the source file path but not to the destination file path.

After impersonation, it is quite the opposite: the impersonated user has access to the destination file path but not to the source file path.

If the files are not too large, my idea would be the following:

public void CopyFile(string sourceFilePath, string destinationFilePath)
{
    var content = File.ReadAllBytes(sourceFilePath);

    using (new Impersonator("username", "domain", "pwd"))
    {
        File.WriteAllBytes(destinationFilePath, content);
    }
}

I.e.:

  1. Read all content from the source file path into a byte array in memory.
  2. Do the impersonation.
  3. Write all content from the byte array in memory into the destination file path.

Methods and classes used here:

Upvotes: 3

ehh
ehh

Reputation: 3480

Thanks to @Uwe Keim idea, the following solution works perfectly:

    public void CopyFile(string sourceFullFileName,string targetFullFileName)
    {
        var fileInfo = new FileInfo(sourceFullFileName);

        using (MemoryStream ms = new MemoryStream())
        {
            using (var file = new FileStream(sourceFullFileName, FileMode.Open, FileAccess.Read))
            {
                 byte[] bytes = new byte[file.Length];
                 file.Read(bytes, 0, (int)file.Length);
                 ms.Write(bytes, 0, (int)file.Length);
             }

            using (new Impersonator("username", "domain", "pwd"))
            {
                 using (var file = new FileStream(targetFullFileName, FileMode.Create, FileAccess.Write))
                 {
                       byte[] bytes = new byte[ms.Length];
                       ms.Read(bytes, 0, (int)ms.Length);
                       file.Write(bytes, 0, bytes.Length);
                       ms.Close();
                 }
            }
        }
    }

Upvotes: 1

Related Questions