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

时间:2012-04-28 07:07:29

标签: c++ windows acl

我正在尝试修改目录(及其子目录)上的现有ACL,以删除内置Users组的写访问权限。该目录从其父目录继承此特定权限。我尝试使用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这是一块蛋糕(不幸的是,这对我来说不是一个选择)。关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:4)

要删除继承的ACE,请调用SetNamedSecurityInfo并传递DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION以获取SecurityInfo参数。

PROTECTED_DACL_SECURITY_INFORMATION标志阻止父项的可继承ACE添加到您指定的ACL中。

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

答案 1 :(得分:0)

阅读ATL::AtlSetDacl

的文档

inline bool AtlSetDacl( HANDLE hObject, SE_OBJECT_TYPE ObjectType, const CDacl& rDacl, DWORD dwInheritanceFlowControl= 0 ) throw(...);

  

dwInheritanceFlowControl:
  继承流控制。该值可以是0(默认值),PROTECTED_DACL_SECURITY_INFORMATION或UNPROTECTED_DACL_SECURITY_INFORMATION。

设置PROTECTED_DACL_SECURITY_INFORMATION,而不是将其留空,以禁用该特定安全对象的继承。