我正在尝试修改目录(及其子目录)上的现有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这是一块蛋糕(不幸的是,这对我来说不是一个选择)。关于如何做到这一点的任何想法?
答案 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)
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,而不是将其留空,以禁用该特定安全对象的继承。