I’m trying to modify the existing ACL on a directory (and its sub-directories) to remove write access for the built-in Users group. The directory is inheriting this particular right from its parent directory. I’ve tried using AtlSetDacl() to set a new ACL but this doesn’t clear out the inherited write permission. Fragment:
ATL::CDacl dacl;
ATL::AtlGetDacl(directoryName.c_str(), SE_FILE_OBJECT, &dacl);
UINT aceCount = dacl.GetAceCount();
ATL::CDacl newDacl;
for (UINT i = 0; i < aceCount; ++i)
{
ATL::CSid sid;
ACCESS_MASK mask = 0;
BYTE flags = 0;
dacl.GetAclEntry(i,
&sid,
&mask,
(BYTE*) 0,
&flags);
if (sid != Sids::Users())
newDacl.AddAllowedAce(sid, mask, flags);
}
newDacl.AddAllowedAce(Sids::Users(),FILE_LIST_DIRECTORY | FILE_READ_EA | FILE_EXECUTE | FILE_READ_ATTRIBUTES, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
AtlSetDacl(directoryName.c_str(), SE_FILE_OBJECT, newDacl);
I’ve also tried SetNamedSecurityInfo() and related APIs to wipe the existing ACL and create a new one, but no luck here either. Doesn’t seem like this should be that hard. Using cacls.exe this is a piece of cake (unfortunately not an option for me). Any ideas on how to do this?
To remove inherited ACEs, call SetNamedSecurityInfo and pass
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATIONfor the SecurityInfo parameter.The
PROTECTED_DACL_SECURITY_INFORMATIONflag prevents inheritable ACEs from the parent from being added to the ACL you specify.If you don’t need to copy other inherited permissions, but can just specify a particular ACL to use, that would be simpler. If you do need to copy other inherited permissions, you’ll need to keep the read-compare-add loop in your existing code, but you should also be clearing the INHERITED_ACE flag since these are now explicit permissions.