6

I am trying to copy existing file from a specific folder to a shared folder. So this is the code:

if (!System.IO.File.Exists(fullPath))
            {
                using (WindowsIdentity.GetCurrent().Impersonate())
                {

                    try
                    {

                        image.Save(fullPath);

                        System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
                        FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);
                        sec.AddAccessRule(accRule);
                        string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");
                        sharedFolderPath = Path.Combine(sharedFolderPath, username);
                        sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
                        sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
                        System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }

            }

And I get this error:

System.Security.Principal.IdentityNotMappedException: 'Some or all identity references could not be translated.'

at this line:

 sec.AddAccessRule(accRule);

What am I doing wrong? If you need more data, please let me know...

EDIT:

Also, the final goal is that this should actually save files into a shared folder on a specific computer in LAN network, but I am currently trying to save it in the shared folder, on the same computer, where program runs.

EDIT 2:

So I tried what suggested by @PaulKaram but I still getting the next error:

enter image description here

From the picture, it can be seen the folder in the Documents where I firstly save image. That goes without problems. When i try to copy it on the specific shared folder on a Desktop, the error above (access denied) arises for the folder already created in Documents.

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • So what *is* the identity you are impersonating, is it what you expect? Why would you need to impersonate the current user, aren't you the current user anyway? – nvoigt Nov 01 '18 at 10:07
  • @nvoigt Well the whole idea was, to save a file on a computer in LAN, not on a current one. I am the current user, yes. Actually I am pretty much new to C#, so...Maybe I am missing a lot of things here. – Whirlwind Nov 01 '18 at 10:09
  • Assuming the user that started your program could write to that shared folder on the network if they just used Windows Explorer, you don't need anything, just your final line of `File.Copy`. Can you add more details about why you need this? What goes wrong if you pick the simplest option of just calling `File.Copy`? – nvoigt Nov 01 '18 at 10:12
  • @nvoigt So the setup is like this. There is one server computer, where shared database is. And there are few other "client" computers, that runs my program. All clients can edit database, but also create folders, and save multiple files in them, on a server. That is a final goal. – Whirlwind Nov 01 '18 at 10:17
  • 1
    I still see no reason why a simple `File.Copy`, maybe with a `Directory.Create` shouldn't do the job. Don't get me wrong, maybe it doesn't, but you need to provide the information why it doesn't. Because from just a quick look, things like *impersonating yourself* don't really make much sense. So you should go back to the simple solution and work forwards by describing the problems you have on that track. – nvoigt Nov 01 '18 at 10:21
  • 1
    @nvoigt OK, I will try to do that, and come back with what I got at the evening. – Whirlwind Nov 01 '18 at 10:23
  • What's the difference between `fullPath` and `originalDocumentFolderPath`? – Paul Karam Nov 01 '18 at 11:49
  • Oh that part is irrelevant. fullPath is just where I save an image to local computer. Later on, I try to copy it to a server. I guess, I could avoid saving it . on a local computer, and then copying it to a server. But I didn't know how. – Whirlwind Nov 01 '18 at 11:55
  • The folder name (`folderName`) is an invalid NTFS directory name. – Caramiriel Nov 05 '18 at 19:39
  • Hm, but how then image is successfully saved at first? @Caramiriel I have a folder in C:\Users\whirlwind\Documents\Djelovodnik\2018-1\1 successfully created with image in it? – Whirlwind Nov 05 '18 at 19:41
  • @Whirlwind the latest error is possibly because the path has a forward slash after `2018-1`. (Should be backslash.) – Richardissimo Nov 05 '18 at 20:24
  • @Richardissimo I changed it to backslash, thanks. Still, it didn't work. This SO [answer](https://stackoverflow.com/a/24796126/3402095) solved it - *Path should be a filename, rather than path to a folder*. After that, there is no error, but still image is not saved to a shared folder. – Whirlwind Nov 05 '18 at 22:21
  • Hm. I found what is it. It is the silliest thing. The shared folder was read-only. Thanks guys to your help. Especially @PaulKaram whose answer other errors I had in code. – Whirlwind Nov 05 '18 at 22:32

1 Answers1

6

The error Some or all identity references could not be translated means that the identity/account you're using is not found. Taking a deeper look, we can see that you have a problem with this line:

FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);

Take a look at the FileSystemAccessRule constructor that you're using. Here's the signature:

public FileSystemAccessRule (string identity, System.Security.AccessControl.FileSystemRights fileSystemRights, System.Security.AccessControl.AccessControlType type);

The first argument that should be sent is the identity, as taken from the documentation:

The name of a user account.

I am not sure what you're sending there in originalDocumentFolderPath.
Assuming username hold the identity you're impersonating, that line should be changed to:

FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);

Two other things that you should be aware of:

First of all, you're working with a shared folder on a network, therefore you need to fix this line:

string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");

into this:

string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");

When you're working with a network folder, you need double back slash at the start, and since in C# a back slash escapes characters, you'll need to write it as \\\\.

Second, you should also note, that you're trying to copy the file and giving it the folder name as destination. To fix this you should add at the end of combining the path of the shared folder this:

sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");

At the end, here's your full code that should work as intended:

if (!System.IO.File.Exists(fullPath))
{
    using (WindowsIdentity.GetCurrent().Impersonate())
    {
        try
        {
            image.Save(fullPath);
            System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
            FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);
            sec.AddAccessRule(accRule);
            string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");
            sharedFolderPath = Path.Combine(sharedFolderPath, username);
            sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
            sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
            sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");
            System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
Paul Karam
  • 4,052
  • 8
  • 30
  • 53
  • Thanks for the answer, and sorry for my late response. I tried your solution but I got some error. Can you please check out my EDIT (2). – Whirlwind Nov 05 '18 at 19:35