This post tries to deal with the eternal problem of users accidentally moving data around on an NTFS volume just because they can, describing my understanding of the problem and the lack of a solution with NTFS permissions only, and a method I've used to work around this problem.
This problem is most apparent with a single share containing top-level directories with different security. When a user has change control to more than one directory, it then becomes possible to drag and drop whole top-level folders into other folders.
When this occurs on the same NTFS volume, it seems the file MoveFileEx function is smart enough to re-link the object to a new parent in the MFT FRS entry for the directory, rather than a recursive copy/delete operation. This is very efficient if it's what you're expecting, but the less than intuitive impacts of this include:
- Permissions on child objects - subfolders or files - are ignored in the re-link move, including lack of permissions and specific access denied ACLs
- The ACL on the source directory is not reset when it gets to the target, including inheritance from the new parent, and inheritance that was valid in the old parent
For example:
Share\A - Ausers:C
Share\B - Busers:C
Share\B\File.txt - Busers:R
Share\B\Data - Busers:C (inherited from the parent B)
- A user that's in AUsers and BUsers accidentally drags the B directory into A. If the destination A\B directory doesn't exist and the user has the delete right to B, the file will be re-linked in NTFS, totally ignoring the fact that the user only has read-only access to B\file.txt.
- Instead of dragging the whole top-level directory, the user drags B\Data into A. Again, if A\Data doesn't exist and the user has Delete to Data, the directory is re-linked in NTFS. Looking at the permissions of the new A\Data, it still lists an ACE of BUsers:C, inherited from the 'parent object' that is obviously no longer the parent.
There are many ways of dealing with this problem, for example, you could:
- Remove change control and use Write. This would be very simple security to manage, but this would prevent users from deleting/renaming files and subdirectories. If creator owner:C were added, this would allow users to delete/rename their own data, but not move/delete/rename data that already exists. This is probably a better solution and would prevent accidental moves/deletes of any kind by normal users, but requires a lot more effort to manage.
- A small group of custodians could be responsible for managing the creation and deletion of directories, reducing the risk by removing the right to delete from most users.
- Prevent drag-and-drop through explorer on workstations.
- Develop a filesystem mini-filter that sits at an altitude to interpret file system operations that are the result of a drag and drop request, and deny requests that involve too much change (or the top 3 levels of each top-level directory for example)
- Develop a WH_GETMESSAGE hook to intercept explorer drag-and-drop messages and cancel them before the request gets to the server
- Develop a DropHandler for Directory/Folder objects to filter requests.
However, these solutions generally require too much effort, so I've come up with the following relatively simple workaround:
Prevent a move operation completed as a copy/delete on top-level folders by:
- Creating a placeholder file within each top-level directory, with users having read-only access to the file. This file will be processed first due to the name beginning with a space (0x20 – processed first in tests), and explorer will immediately return an access denied message. The file should have the hidden attribute set, eg ‘ placeholder.txt’
Prevent users from performing NTFS re-link moves within a volume on top-level directories by:
- Removing Delete from the top-level directory - part of Change, which general practice is to give users - typically this folder, subfolders and files. As part of a move (drag/drop, cut/paste), if users have the Delete right to the source directory object and a same-named target folder doesn't already exist, NTFS will re-link the directory to the new parent regardless of permissions on the source subfolders and files. This could be achieved by using C: OICIIO (object-inherit, container-inherit, inherit-only), and RWX to the top-level directory, ensuring that a recursive copy/delete operation is performed, which does check access control, and re-inherit permissions in the target.
For example, a user has access to both A and B, with the placeholders secured for read-only:
Share - Users:R
Share\A - AUsers:C
Share\A\placeholder.txt - AUsers:R
Share\B - BUsers:C
Share\B\ placeholder.txt - BUsers:R
In the example above, these changes will prevent the user from:
- Deleting an entire directory, either A or B, prevented by the placeholder file (deleting the contents) and the lack of Delete on the container.
- An accidental drag-and-drop of B into A, made into a copy/delete operation by the lack of Delete on the container and prevented as a copy/delete by the placeholder file which is processed first. Note that A\B folder would still be created with inherited permissions of A, but no contents would be copied/deleted.
- Renaming either A or B. Users only have read on the root, delete is required to rename.
Under normal circumstances with drag and drop in explorer from XP workstation to a 2003 file server, if the following is true then the move operation will re-link the top-level directory within NTFS by attaching it to a new parent, as opposed to a copy/delete operation:
- If the data is on the same volume, presented to the user through a share, with or without Access Based Enumeration
- If the user has the delete right to the directory object that is the source of the drag operation.
- If in the drop target, a folder does not already exist with the same name.
In this scenario, access control is not validated on child objects within the drag source and permissions are not reset in the new drop target (inherited or direct).
Notes:
- The user must have access to read the placeholder when using Access Based Enumeration, otherwise the file will simply be hidden and all other objects will be moved (as a copy/delete)
- Testing with a re-link move operation and a copy/delete move operation was completed, using diskedit.exe to find the File Record Segment number for the file from the NTFS MFT. When copy/delete was used, a new target directory was created with a new MFT entry, whereas when the object was re-linked, the FRS number remained the same, and the FILE_REFERENCE ParentDirectory entry in the $FILE_NAME attribute was updated to reflect the new parent.
- If an object in the drag source is locked by another user (eg command prompt chdir to a subfolder on the console of the server), and in the scenario where the folder would normally be moved at the top-level (instead of copy/delete), explorer on the workstation will automatically fall-back to the copy/delete method).
- The same occurs on the console of the file server managing the local volume, moving folders is changing the parent object at a MFT/FRS level, nothing to do with access control on the objects (assuming Delete on the source and create directory on the target)
- Using the MoveSecurityAttributes registry value (310316) on the server does ensure that permissions are not copied, which does inherit new permission in the target. However, this can also be confusing, as moving and then moving back would lose permissions.
- To determine processing order, several test directories and files were created, and testing shows that directories are processed last-first, ie ASCII character 126 (0x7e) ‘~’ is processed first for directory moves. However, files within a directory are ‘moved’ before directories, and files are processed first-last, and 32 (0x20)
is the first common printable character. - Preferably secedit security templates would be used to control the security on the filesystem, providing a repeatable method to apply security.
References:
Inherited permissions are not automatically updated when you move folders
http://support.microsoft.com/kb/320246
MoveFileEx Function
http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx
How NTFS Works
http://technet2.microsoft.com/windowsserver/en/library/8cc5891d-bf8e-4164-862d-dac5418c59481033.mspx?mfr=true
How to configure file sharing in Windows XP
http://support.microsoft.com/kb/304040
How permissions are handled when you copy and move files and folders
http://support.microsoft.com/kb/310316
When you try to move files from one network drive to another network drive, the files keep permissions from the source folders on a client computer that is running Windows XP or Windows Server 2003
http://support.microsoft.com/kb/945272
Viewing NTFS information with nfi and diskedit
http://waynes-world-it.blogspot.com/2008/03/viewing-ntfs-information-with-nfi-and.html
Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.
15 comments:
Wayne,
This is very good information and I've been trying to implement it on some of my servers. One issue I've had when trying to implement this is the ability of users to delete the actual placeholder. I set the NTFS permissions to Domain Admins only for full permissions and the users can still delete the placeholder. It stops the accidental moves but what if someone deletes the placeholder? I am going to check with MS to see if this is an NTFS bug. It appears to occur on Windows 2003 & 2008 server standard. Can you test it in your environment?
Thanks,
Brian
Thanks Brian. I have tried to reproduce what you describe, but I got the expected response 'could not find " placeholder.txt"' when I tried to delete the file that a test account didn't have the delete right on.
Can you confirm the ACE for delete (modify) is not being inherited from the parent container for files? I am replacing the ACE on the placeholder file with the read-only permissions.
I have not seen the case when trying to directly delete one file that you only have read access to and it actually allows the delete.
I have a housekeeping process in place that will run daily checks to make sure the placeholder files exist in each subdirectory off the root (more to clean up after people making unmanaged changes). This is not a solution to your problem, but it might mitigate the risk somewhat?
Hi Wayne,
I am also trying to implement your solution in my environment. However, I just couldn't figure out how to set a text file's name begin with a space, every time I added a space, after I pressed enter to confirm the change, the space would disappear. Could you please advise?
David
Hi David,
If you start a command prompt, use 'cd' to change directory to the location where you want the file, and then run:
notepad " placeholder.txt"
This will start notepad and prompt you to create the file (unless it already exists, in which case it will load the file).
Hope this helps,
Wayne.
Thanks, Wayne, but I wish I could get this to work. When I try just the placeholder trick, it doesn't prevent the user from being able to move a directory within a volume. If I leave the placeholder file itself unhidden and then as a user try to move it, I at least do get a prompt "are you sure you want to move a read-only file" but the user can say "yes" and the file is moved. If the user moves the directory containing the placeholder file, no prompt at all, everything just gets moved. Am I missing something?
Hi,
If you're getting a prompt about moving the read-only file and the move works, then the user has delete access to the file. So make sure that NTFS permissions for the placeholder file allow Read-only access to users.
If the whole directory is being moved, then the user has the delete NTFS permissions on the directory. So make sure that NTFS permissions have been modified to remove delete for the directory only (if you do more than directory only then users won't be able to create/write to sub-objects).
Removing delete on the directory object forces a copy/delete operation on the entire contents, and RO on the " placeholder.txt" should cause that operation to fail.
Wayne,
Very very clever solution to an incredibly annoying problem. Thank you sir.
Hi Wayne, thanks for this article but I can't seem to get it to work 100%. (Also sorry for digging up an oldish post)
The placeholder is doing most of the good work. However I'm confused as to how you mention take the delete permission away from the folder level only.
My situation is that the Everyone group needs to have modify permissions to everything inside those top level folders and below.
Inside those folders are the read only placeholders. And the root folder is readonly. So the effect is that they can't create any new folders at the root level and the readonly placeholder prevents them from being able to delete the folder. They can still drag and drop those folders into each other. I looked to try and remove the delete permission and apply it to 'This folder only' but it ends up preventing the users from being able to delete anything in those folders. Likewise I tried to apply the Modify permission set to 'Subfolders and Files only' however that prevents the users from being able to create any files. So I seem to be missing something here or is this solution only going to work in a Creator / Owner scenario?
Cheers
Andrew
I'd love to see some screenshots, can't seem to get this working
This helped us solve a related situation... we have a large directory of projects folders and on a regular basis projects will "disapear" - almost always because a user has accidently dropped and dragged it into another folder when trying to double click on it...
The first step was to setup advanced NTFS permissions on the top level folders - allowing Everyone Full Control to Subfolders and files only and Special Permission (Transverse, List, Read Attributes, CreateFiles Write Data, Create Folder Append Data, and Read Permissions) to This Folder, Subfolder, and files.
This seemed to work not quite - if a user tried to delete (or move) the top level folder it would be protected - but all of the contents would be deleted (or moved).
The trick of using placeholders seems to work... because it's the first file processed it seems to block the rest of the move or delete operation.
Thanks so much!
Was playing around with the same problem and found out following:
On folder that i neded to protect i have following deny rights "Delete" and "Delete subfolders and files" for "Domain Users" group (if you will test delete or move of this folder loks like the rigts are doing nothing), replicate the same rights to top level folder and now it does the trick, you can't rename or move this folder.
With following structure in place:
Folder A (Deny rigts to this folder only)
Folder A\Folder B (Deny rights to this folder only)
Folder B gets fully protected, you can't rename or move it. You stil can mofe folder A with all its contents, to avoid that simply do the same trick with deny to this folder only.
Hopefully someone else will test this out on different enviroment and will confirm that it works.
Good luck with it
Ivars
Hi Wayne great way of overcoming this problem, is there any way to get a copy of the housekeeping utility that you made to make sure the placeholder file is in each directory?
Very nice tips....
The placeholder file does not consistently appear to be copied as the first file on the NAS storage. Therefore, some of the files within the top level folder are still moved by accident.
What the topic should read is "Preventing accidental Folder moves"
What we need is for Microsoft to implement a shell command into the right-click shell menu to "Lock Folder", or "Lock Folder Position" from the explorer tool menu. Period.
A customer of mine called frantic that she could not find her photos. claimed the entire folder had disappeared.
what happened is she accidentally dragged and dropped the folder in a sub-folder.
accidentally moving the contents of these folders is another issue.
maybe a dialog warning.
Lou
Post a Comment