【发布时间】:2012-02-21 04:41:54
【问题描述】:
下面的代码适用于各种 ACE 更改以及添加和撤销 - 当我尝试删除 ACL 中的 ACE(显然存在)时它不起作用,但这个 ACE 是继承的。
用于撤销非继承 ACE 的 SetEntriesInAcl() 有效,减少了 ACL ACE 计数,随后的 SetNamedSecurityInfo() 执行撤销并且 ACE 消失了。
当 ACE 被继承时 - 这两个 API 返回 SUCCESS - 但 ACE 未被删除/撤销,ACL ACE 计数保持不变。
我还编写了 DeleteAce() 的代码,但是当在 SetNamedSecurityInfo() 中再次使用该 DACL 时,RC 为 SUCCESS(无返回码)并且 ACE 保留在我正在处理的文件夹中 - 显然有一个技巧关于如何删除继承的 ACE。
顺便说一句,对于有问题的同一个文件夹,SUBINACL 命令行工具可以毫无问题地撤销这个继承的 ACE。
if( EqualSid( pSid_for_ace, pSid ) )
{ /* ACE SID matched edit SID */
if( cmd_se_edit == SE_REM )
{ /* remove */
rem_lst[ ace_idx ] = x;
exp_ace[ ace_idx ].grfAccessPermissions = dwAccessRights;
exp_ace[ ace_idx ].grfAccessMode = REVOKE_ACCESS;
exp_ace[ ace_idx ].grfInheritance = dwInheritance;
exp_ace[ ace_idx ].Trustee.TrusteeForm = TRUSTEE_IS_SID;
exp_ace[ ace_idx ].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
exp_ace[ ace_idx ].Trustee.ptstrName = pSid;
if( ace_idx < (REMMAX-1) ) ++ace_idx;
} /* remove */
} /* ACE SID matched edit SID */
pBA = (BYTE *)p_aceHdr;
ace_sz = p_aceHdr->AceSize;
p_aceHdr = (PACE_HEADER)&pBA[ ace_sz ];
} /* loop through ACEs */
// Create a new ACL that merges the new ACE
// into the existing DACL.
if( ace_idx )
{ /* ACEs to remove */
dwRes = SetEntriesInAcl( ace_idx, &exp_ace[0],
pDacl, &pNewDacl );
if( ERROR_SUCCESS != dwRes )
{
printf( "SetEntriesInAcl Error %u\n", dwRes );
goto Cleanup2;
}
// Attach the new ACL as the object's DACL.
dwRes = SetNamedSecurityInfo( ObjName,
ObjectType,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
pNewDacl,
NULL );
if( ERROR_SUCCESS != dwRes )
{
rc3 = GetLastError();
printf( "SetNamedSecurityInfo Error %u\n", dwRes );
goto Cleanup2;
}
} /* ACEs to remove */
【问题讨论】:
-
访问权限掩码和继承设置与被撤销的 ACE 相同 - 根据 MS 指南(我找到的唯一指南。) - 使用上述代码设置此 ACE 会生成一个匹配的新 ACE我设置的内容——但原始继承的 ACE 仍然存在——该测试的 ACL 增加了 1——然后该测试 ACE 的撤销正常工作——原始继承的 ACE 再次保留。
-
删除继承的 ACE 会破坏 ACL 的规则。高级 API 不允许您这样做;低级 API 会,但你不应该。相反,请关闭目标对象的继承并复制您想要保留的那些 ACE,或者考虑改用拒绝条目。
-
感谢 Harry - 以编程方式(通过 API)如何关闭目标对象的继承? - 我无法做到这一点(grrr).....一旦关闭继承 - 我知道如何复制 ACE - 在你的评论中你说复制我希望保留的 ACE - 将它们复制到哪里?一旦到了那里,您如何将它们放回“文件夹的”安全描述符-我知道一些API可以做到这一点-我很好奇您的想法/见解....再次感谢凯文·韦特(Kevin Waite)
-
我的第一个目标是在根目录下创建一个文件夹,类似于“c:\program files”,将其命名为“c:\ti001”——我的第二个目标是调用两个组my_admins 和 my_users——我希望“c:\ti001”文件夹将这些组添加到其 ACL 中......首先要做的事情——需要删除“经过身份验证的用户”
-
新文件夹是否需要从其父文件夹继承其他(未知)权限,或者您是否已经确切知道您希望该文件夹拥有哪些权限?
标签: windows acl file-permissions