Labels

Friday, June 27, 2008

Preventing accidental NTFS data moves

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:

  1. Permissions on child objects - subfolders or files - are ignored in the re-link move, including lack of permissions and specific access denied ACLs
  2. 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)

  1. 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.
  2. 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:

  1. If the data is on the same volume, presented to the user through a share, with or without Access Based Enumeration
  2. If the user has the delete right to the directory object that is the source of the drag operation.
  3. 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:

  1. 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)
  2. 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.
  3. 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).
  4. 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)
  5. 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.
  6. 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.
  7. 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.

14 comments:

Brian said...

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

Wayne Martin said...

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?

David said...

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

Wayne Martin said...

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.

chrisemoz said...

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?

Wayne Martin said...

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.

Anonymous said...

Wayne,

Very very clever solution to an incredibly annoying problem. Thank you sir.

Andrew said...

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

usher said...

I'd love to see some screenshots, can't seem to get this working

Jon said...

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!

Anonymous said...

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

Mark said...

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?

kaka folder protect said...

Very nice tips....

Anonymous said...

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.


All Posts

printQueue AD objects for 2003 ClusterVirtualCenter Physical to VirtualVirtual 2003 MSCS Cluster in ESX VI3
Finding duplicate DNS recordsCommand-line automation – Echo and macrosCommand-line automation – set
Command-line automation - errorlevels and ifCommand-line automation - find and findstrBuilding blocks of command-line automation - FOR
Useful PowerShell command-line operationsMSCS 2003 Cluster Virtual Server ComponentsServer-side process for simple file access
OpsMgr 2007 performance script - VMware datastores...Enumerating URLs in Internet ExplorerNTLM Trusts between 2003 and NT4
2003 Servers with Hibernation enabledReading Shortcuts with PowerShell and VBSModifying DLL Resources
Automatically mapping printersSimple string encryption with PowerShellUseful NTFS and security command-line operations
Useful Windows Printer command-line operationsUseful Windows MSCS Cluster command-line operation...Useful VMware ESX and VC command-line operations
Useful general command-line operationsUseful DNS, DHCP and WINS command-line operationsUseful Active Directory command-line operations
Useful command-linesCreating secedit templates with PowerShellFixing Permissions with NTFS intra-volume moves
Converting filetime with vbs and PowerShellDifference between bat and cmdReplica Domain for Authentication
Troubleshooting Windows PrintingRenaming a user account in ADOpsMgr 2007 Reports - Sorting, Filtering, Charting...
WMIC XSL CSV output formattingEnumerating File Server ResourcesWMIC Custom Alias and Format
AD site discoveryPassing Parameters between OpsMgr and SSRSAnalyzing Windows Kernel Dumps
Process list with command-line argumentsOpsMgr 2007 Customized Reporting - SQL QueriesPreventing accidental NTFS data moves
FSRM and NTFS Quotas in 2003 R2PowerShell Deleting NTFS Alternate Data StreamsNTFS links - reparse, symbolic, hard, junction
IE Warnings when files are executedPowerShell Low-level keyboard hookCross-forest authentication and GP processing
Deleting Invalid SMS 2003 Distribution PointsCross-forest authentication and site synchronizati...Determining AD attribute replication
AD Security vs Distribution GroupsTroubleshooting cross-forest trust secure channels...RIS cross-domain access
Large SMS Web Reports return Error 500Troubleshooting SMS 2003 MP and SLPRemotely determine physical memory
VMware SDK with PowershellSpinning Excel Pie ChartPoke-Info PowerShell script
Reading web content with PowerShellAutomated Cluster File Security and PurgingManaging printers at the command-line
File System Filters and minifiltersOpsMgr 2007 SSRS Reports using SQL 2005 XMLAccess Based Enumeration in 2003 and MSCS
Find VM snapshots in ESX/VCComparing MSCS/VMware/DFS File & PrintModifying Exchange mailbox permissions
Nested 'for /f' catch-allPowerShell FindFirstFileW bypassing MAX_PATHRunning PowerSell Scripts from ASP.Net
Binary <-> Hex String files with PowershellOpsMgr 2007 Current Performance InstancesImpersonating a user without passwords
Running a process in the secure winlogon desktopShadow an XP Terminal Services sessionFind where a user is logged on from
Active Directory _msdcs DNS zonesUnlocking XP/2003 without passwords2003 Cluster-enabled scheduled tasks
Purging aged files from the filesystemFinding customised ADM templates in ADDomain local security groups for cross-forest secu...
Account Management eventlog auditingVMware cluster/Virtual Center StatisticsRunning scheduled tasks as a non-administrator
Audit Windows 2003 print server usageActive Directory DiagnosticsViewing NTFS information with nfi and diskedit
Performance Tuning for 2003 File ServersChecking ESX/VC VMs for snapshotsShowing non-persistent devices in device manager
Implementing an MSCS 2003 server clusterFinding users on a subnetWMI filter for subnet filtered Group Policy
Testing DNS records for scavengingRefreshing Computer Account AD Group MembershipTesting Network Ports from Windows
Using Recovery Console with RISPAE Boot.ini Switch for DEP or 4GB+ memoryUsing 32-bit COM objects on x64 platforms
Active Directory Organizational Unit (OU) DesignTroubleshooting computer accounts in an Active Dir...260+ character MAX_PATH limitations in filenames
Create or modify a security template for NTFS perm...Find where a user is connecting from through WMISDDL syntax in secedit security templates

About Me

I’ve worked in IT for over 13 years, and I know just about enough to realise that I don’t know very much.