Search code examples
windowsfile-permissionsexplorerntfshardlink

What happens to permissions when a file goes to the recycle bin?


I have a problem related to file management done by a service application. My problem is that users are able to move files to the recycle bin for which I've created a hardlink, and once they do this, I loose the ability to list the hardlinks available.

This appears to only happen when the removed hardlink file sits inside the $RECYCLER folder but not on a folder with similar permissions on the same disk.

To replicate my problem assume one has a user account named Service with a suitable password.

On the current user account:

md C:\tmp
echo CONTENTS>C:\tmp\1
fsutil hardlink create C:\tmp\2 C:\tmp\1

That would have created a file named C:\tmp\1 and a hardlink to it named C:\tmp\2.

Now if you runas another terminal with user Service you can:

fsutil hardlink list C:\tmp\1
\tmp\1
\tmp\2

That works fine.

Now if you (as the original user) move the 2 file to the recycle bin, you cannot access the files as Service.

type C:\tmp\1
Access is denied.
fsutil hardlink list C:\tmp\1
Error:  Access is denied.

That's because Explorer will have changed the DACL on the file to a restrictive one where only the current user, SYSTEM and an Administrator have access to the file.

If you do a icacls C:\tmp\1 /reset as the original user, now you can access the contents of the file as Service:

type C:\tmp\1
CONTENTS

But if you try to list the hardlinks, it will show you the first link and an access denied error:

fsutil hardlink list C:\tmp\1
\tmp\1
Error:  Access is denied.

If you list the hardlinks on the file as the original user, you get to know the recycle bin path of the original file:

fsutil hardlink list C:\tmp\1
\tmp\1
\$Recycle.Bin\S-1-5-21-111111111-2222222222-3333333333-1002\$R1GX1HN

And if you move that file to another (as the original user) folder:

md C:\tmp2
move \$Recycle.Bin\S-1-5-21-111111111-2222222222-3333333333-1002\$R1GX1HN C:\tmp2

Now as Service you can list all the hardlinks:

fsutil hardlink list C:\tmp\1
\tmp\1
\tmp2\$R1GX1HN

Any idea why this may be happening?

Does this have anything to do with Mandatory Integrity Control?


Solution

  • As explained in the comments by @Eryk Sun, the problem is related to the way hardlinks are reported by Win32 API.

    It appears that fsutil uses FindFirstFileName and FindNextFileName functions, both of which use NtQueryInformationFile which in turn returns a structure with entries of type FILE_LINK_ENTRY_INFORMATION which have the hardlink name and the parent folder NTFS ID.

    The problem manifests itself when the caller does not have permission to open the containing folder to get its name (probably using OpenFileById and GetFinalPathByHandle).