Windows 撤销访问权:如何删除';撤销';继承的王牌?

Windows 撤销访问权:如何删除';撤销';继承的王牌?,windows,acl,file-permissions,Windows,Acl,File Permissions,下面的代码用于各种ACE更改、添加和撤销—当我尝试删除ACL中的ACE(显然在那里)时,它不起作用,但该ACE是继承的 用于撤销非继承ACE的setEntriesAcl()可以减少ACL ACE计数,以下SetNamedSecurityInfo()执行撤销操作,ACE消失 但是当ACE被继承时-这两个API都返回SUCCESS-但是ACE没有被删除/撤销,ACL ACE计数保持不变 我还编写了执行DeleteAce()的代码,但当该DACL再次用于SetNamedSecurityInfo()时,

下面的代码用于各种ACE更改、添加和撤销—当我尝试删除ACL中的ACE(显然在那里)时,它不起作用,但该ACE是继承的

用于撤销非继承ACE的
setEntriesAcl()
可以减少ACL ACE计数,以下
SetNamedSecurityInfo()
执行撤销操作,ACE消失

但是当ACE被继承时-这两个API都返回
SUCCESS
-但是ACE没有被删除/撤销,ACL ACE计数保持不变

我还编写了执行
DeleteAce()
的代码,但当该DACL再次用于
SetNamedSecurityInfo()
时,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 */
if(相等ID(pSid表示空间,pSid))
{/*ACE SID匹配编辑SID*/
如果(cmd_se_edit==se_REM)
{/*删除*/
rem_lst[ace_idx]=x;
exp\u ace[ace\u idx].grfAccessPermissions=dwAccessRights;
exp\u ace[ace\u idx].grfAccessMode=REVOKE\u访问;
exp\u ace[ace\u idx].grfInheritance=dwInheritance;
exp\u ace[ace\u idx].Trustee.TrusteeForm=Trustee\u是\u SID;
exp\u ace[ace\u idx].Trustee.TrusteeType=trusteer\u是众所周知的\u组;
exp_ace[ace_idx].Trustee.ptstrName=pSid;
if(ace_idx<(REMMAX-1))++ace_idx;
}/*移除*/
}/*ACE SID匹配编辑SID*/
pBA=(字节*)p_aceHdr;
ace_sz=p_aceHdr->AceSize;
p_aceHdr=(配速头)和pBA[ace_sz];
}/*通过ACE循环*/
//创建合并新ACE的新ACL
//进入现有的DACL。
如果(ace_idx)
{/*要删除的ACE*/
dwRes=setEntriesAcl(ace_idx和exp_ace[0],
pDacl和pNewDacl);
如果(错误\u成功!=dwRes)
{
printf(“setEntriesAcl错误%u\n”,dwRes);
后藤清理2;
}
//附加新ACL作为对象的DACL。
dwRes=SetNamedSecurityInfo(对象名,
对象类型,
DACL_安全信息,
无效的
无效的
pNewDacl,
无效);
如果(错误\u成功!=dwRes)
{
rc3=GetLastError();
printf(“SetNamedSecurityInfo错误%u\n”,dwRes);
后藤清理2;
}
}/*要删除的ACE*/

目前,您似乎正在从文件夹中检索现有ACL并对其进行修改。在您的情况下,最好从头开始构建新的ACL。为此,构建一个显式访问结构数组,描述所需的权限,并为OldAcl调用passingnull


要应用新的DACL,请以与代码中相同的方式调用SetNamedSecurityInfo,但要传递SecurityInfo的
DACL\u安全信息| PROTECTED\u DACL\u安全信息
。该标志禁用从父级继承。

访问权限掩码和继承设置与正在撤销的ACE相同-每毫秒指南(我找到的唯一指南)-使用上述代码设置此ACE将生成一个与我设置的内容匹配的新ACE——但原始继承的ACE仍然存在——此测试的ACL增长了1——然后此测试ACE的吊销工作正常——原始继承的ACE再次保留。删除继承的ACE将打破ACL的规则。高级API不允许您这样做;低级API会,但您不应该。相反,关闭目标对象上的继承并复制要保留的那些ACE,或者考虑使用拒绝条目。谢谢哈利-编程(通过API)如何关闭目标对象上的继承?我没能做到这一点(grrr)。。。。。一旦关闭继承-我知道如何复制ACE-在您的评论中,您说要复制我希望保留的ACE-将它们复制到哪里?一旦到了那里,你如何把它们放回“文件夹”的安全描述符——我知道一些API可以做到这一点——我很好奇你的想法/见解。。。。再次感谢,关于Kevin WaiteMy,我的第一个目标是从根目录创建一个类似“c:\program files”的文件夹,称之为“c:\ti001”--我的第二个目标是创建两个名为my_admins和my_users的组--我希望“c:\ti001”文件夹将这些组添加到其ACL中。。。。首先--需要删除“已验证的用户”新文件夹是否需要从其父文件夹继承其他(未知)权限,或者您是否已经确切知道您希望文件夹具有哪些权限?谢谢Harry!这起作用了。对于那些寻求更深入阅读/信息的人,请检查这两个URL-及-