How do I manually recalculate ACLs on a file based on the containing directory?

A customer wanted to move a file and have it forget all its old ACLs and instead inherit its ACLs from its new location. They found an old article of mine that said

If you use SH­File­Operation to move a file and pass the FOF_NO­COPY­SECURITY­ATTRIBUTES flag, then it will not preserve the original ACLs on the moved files but will rather recalculate them from the destination’s inheritable properties. (If you want to do the same thing in your own code, you can call the Set­Named­Security­Info function, specifying that you want an empty, unprotected DACL.)

They were having trouble implementing the recommendation in parentheses.

We set the file to have an SDDL of D:S: in order to give it an empty DACL and SACL, but instead of inheriting its ACL from the container, that gave nobody any permissions at all! How do I get this to work?

The customer was halfway there. D:S: is an empty DACL. Now they need to make it unprotected.

UNPROTECTED_DACL_SECURITY_INFORMATION The DACL inherits ACEs from the parent object.

The customer confirmed that passing that flag to Set­Named­Security­Info did the trick.

Comments (11)
  1. Joshua says:

    The Security API is an absolute mess. This can only be forgiven as nobody knew what they were doing at the time. Even if MS had looked aside at the UNIX world they would have found the ACL APIs still an unstandardized mess, and MS was trying to separate local and domain accounts. UNIX didn't bother.

  2. Medinoc says:

    This reminds me of the fact that empty DACLs mean no one can access the file (save the owner, of course), while null DACLs mean Everyone Full Control.

  3. alegr1 says:

    Instead of building an ACL by hand, why not use ConvertStringSecurityDescriptorToSecurityDescriptor?

    [Um, that's what they were using, as evidenced by the SDDL string "D:S:". -Raymond]
  4. MNGoldenEagle says:

    @Medinoc: That makes sense though if you think about it historically.  FAT filesystems didn't support ACL metadata, so all of the files and directories effectively had "null ACLs" as far as the operating system was concerned.  Since you have to maintain backwards compatibility with these filesystems, you map the behavior to FAT: everyone can change everything.

  5. Mike says:

    @Medinoc: Be glad ACLs are not stored in an Oracle database, or else you wouldn't be able to distinguish them :)

  6. alanapz says:

    @ Mike – I blame you for ruining my keyboard, burst out laughing and spilt my orange juice – funniest comment have read this year :-)

  7. Ian Boyd says:

    Sometimes when answering questions related to issues with non-Administrator users, the answer is to adjust the permissions on your installation folder at install time. You know your installer will have the ability to adjust permissions on your folder, because if it didn't it wouldn't be able to install!

    But the thing i never answer is actually **how** to adjust NTFS permissions in code. i'm sure it's possible, i understand a lot of the concepts; but actually translating that into functional code that actually does the correct thing, in the correct way, is very complicated.

    Chris Jackson talked about this once in his blog post *"How to Set Directory Permissions at Install Time using an MSI Created Using Windows Installer XML (WIX)"*

    > Now, here’s the part that makes people nuts (and rightly so!) – we then never bother to tell you how you can set that at install time! At best, we’ll give you some hints. Want to know something interesting? You’d probably be surprised at how many people don’t know how to do this themselves, but nonetheless will happily tell you that it’s what you ought to be doing.

    He goes on to explain how to do it using MSI (via WiX).

    But i've never bothered to actually sit down and spend a few hours figuring out Authorization API. i've never sat down to figure out which of the 211 functions need to be called, in what order, to accomplish the equivalent of "grant Modify to Users".

    So i can certainly understand when a guy misses a `UNPROTECTED_DACL_SECURITY_INFORMATION` flag.

  8. Fleet Command says:

    When I read the title, I thought it is an article on the topic of moving a file that is set to inherit permissions and eventually not inheriting new permissions.

  9. xpclient says:

    In the case when a file is copied/moved to another NTFS volume, there is no way for end users to copy ACLs using Explorer as ForceCopyAclwithFile reg value is ignored. It now always inherits the permissions of the new folder.

  10. Azarien says:

    @MNGoldenEagle: although I don't know how it looks on the API level, the exFAT filesystem also does not support ACLs (except on WinCE), and it's hardly a "backwards compatibilty" filesystem.

  11. Neil says:

    That's not what I want when I move a file, I want it to keep explicit entries and only update the inherited entries (I once used an app which did something along the above lines and that failed horribly on a file which wasn't inheriting anything) which is presumably solved via a prior call to GetNamedSecurityInfo instead of using an empty unprotected DACL.

Comments are closed.