删除/修改 ACL 中继承的 ACE (Windows)

Remove/Modify an inherited ACE in an ACL (Windows)

本文关键字:ACE Windows 继承 修改 ACL 删除      更新时间:2023-10-16

我正在尝试修改目录(及其子目录)上的现有ACL以删除内置用户组的写入权限。 目录从其父目录继承此特定权限。 我尝试使用 AtlSetDacl() 设置新的 ACL,但这并没有清除继承的写入权限。 片段:

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);

我还尝试了 SetNamedSecurityInfo() 和相关 API 来擦除现有的 ACL 并创建一个新 ACL,但这里也没有运气。 似乎这应该不难。 使用 cacls.exe这是小菜一碟(不幸的是,这对我来说不是一个选择)。 关于如何做到这一点的任何想法?

若要删除继承的 ACE,请调用 SetNamedSecurityInfo 并为 SecurityInfo 参数传递DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION

PROTECTED_DACL_SECURITY_INFORMATION标志可防止将父级的可继承 ACE 添加到指定的 ACL 中。

如果不需要复制其他继承的权限,但只需指定要使用的特定 ACL,那会更简单。 如果确实需要复制其他继承的权限,则需要在现有代码中保留读取-比较-添加循环,但也应清除 INHERITED_ACE 标志,因为这些现在是显式权限。