问题
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?
回答1:
To remove inherited ACEs, call SetNamedSecurityInfo and pass DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION
for the SecurityInfo parameter.
The PROTECTED_DACL_SECURITY_INFORMATION
flag 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.
回答2:
Read the documentation of ATL::AtlSetDacl
inline bool AtlSetDacl(
HANDLE hObject,
SE_OBJECT_TYPE ObjectType,
const CDacl& rDacl,
DWORD dwInheritanceFlowControl= 0
) throw(...);
dwInheritanceFlowControl :
The inheritance flow control. This value can be 0 (the default), PROTECTED_DACL_SECURITY_INFORMATION or UNPROTECTED_DACL_SECURITY_INFORMATION.
Set PROTECTED_DACL_SECURITY_INFORMATION, instead of leaving it blank, to disable inheritance for that particular securable object.
来源:https://stackoverflow.com/questions/10361410/remove-modify-an-inherited-ace-in-an-acl-windows