REVOKE_ACCESS :如何删除“撤销”;继承的 ACE?
我有下面的代码用于各种 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 */
I have the code below working for various ACE changes and adds and revoking - it just does NOT work when I try and remove an ACE that is in the ACL (clearly there), but this ACE is inherited.
The SetEntriesInAcl()
for revoke of non-inherited ACEs works, reduces the ACL ACE count and the following SetNamedSecurityInfo()
does the revoke and the ACE is gone.
When the ACE is inherited though - both these API return SUCCESS
- but the ACE is not removed/revoked, the ACL ACE count remains the same.
I have also coded doing DeleteAce()
but when that DACL is used in SetNamedSecurityInfo()
again the RC is SUCCESS
(no return codes) and the ACE remains for the folder I am dealing with - clearly there is a trick on how to remove an inherited ACE.
Btw, for the same folder in question SUBINACL command line tool does the revoke of this inherited ACE without problem.
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 */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
目前,您似乎正在从文件夹中检索现有的 ACL 并对其进行修改。根据您的情况,您最好从头开始构建新的 ACL。为此,请构建一个描述所需权限的 EXPLICIT_ACCESS 结构数组,并调用 SetEntriesInAcl 为 OldAcl 传递 NULL。
要应用新的 DACL,请按照与代码中相同的方式调用 SetNamedSecurityInfo,但传递 DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION 用于安全信息。 PROTECTED_DACL_SECURITY_INFORMATION 标志禁用从父级的继承。
At present it looks as if you are retrieving the existing ACL from the folder and modifying it. In your situation, you will be better off building a new ACL from scratch. To do this, build an array of EXPLICIT_ACCESS structures describing the permissions that you want, and call SetEntriesInAcl passing NULL for OldAcl.
To apply the new DACL, call SetNamedSecurityInfo in the same way you do in your code, but pass
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION
for SecurityInfo. The PROTECTED_DACL_SECURITY_INFORMATION flag disables inheritance from the parent.