如何在对象的ACL中设置同一受托者的多个ACE

时间:2012-08-06 13:57:19

标签: security permissions acl dacl

我正在尝试将两个条目设置为同一组的对象文件夹,具有差异继承(对于GENERIC_READ,一个为NO_INHERITANCE为FILE_TRAVERSE,另一个为SUB_CONTAINERS_AND_OBJECTS_INHERIT)。 我看到每次最后一次调用都会覆盖先例。 我在delphi中写了这个(但是如果是C ++或者C则是相同的)。 有人可以帮我解决问题吗?

这是调用函数:

function setACL(const foldername:string;const SID:PSID;const AccessPermissions:cardinal;
              const AccessMode:ACCESS_MODE;const Inheritance:cardinal;
              const TrusteeType:TRUSTEE_TYPE):boolean;
var
 pEA: PEXPLICIT_ACCESS_W;
 pDACL: PACL;
 R: DWORD;
begin
  pEA := AllocMem(SizeOf(EXPLICIT_ACCESS_W));
  pEA^.grfAccessPermissions:=AccessPermissions;
  pEA^.grfAccessMode:=AccessMode;
  pEA^.grfInheritance:=Inheritance ;
  pEA^.Trustee.TrusteeForm:=TRUSTEE_IS_SID;
  pEA^.Trustee.TrusteeType:=TrusteeType;
  pEA^.Trustee.ptstrName:=PWideChar(sid);

  R := SetEntriesInAcl(1, pEA, nil, pDACL);

  if R = ERROR_SUCCESS then
  begin
    if SetNamedSecurityInfo(pchar(foldername),
      SE_FILE_OBJECT,
      DACL_SECURITY_INFORMATION,
      nil,
      SID,
      pDACL,
      nil) <> ERROR_SUCCESS then ShowMessage('SetNamedSecurityInfo failed: ' + SysErrorMessage(GetLastError));
    LocalFree(Cardinal(pDACL));
 end
 else ShowMessage('SetEntriesInAcl failed: ' + SysErrorMessage(R));

end;

我以这种方式称呼它两次:

  Groupname:='myNet\aGroup';
  Get_SID('wbox0',groupname,sid);//this function just to get SID

  foldername := '\\wbox0\temp\filippo'; //the folder to set permissions
  setACLGroupFolder(foldername,sid,FILE_TRAVERSE,SET_ACCESS,NO_INHERITANCE,TRUSTEE_IS_GROUP);
  setACLGroupFolder(foldername,sid,GENERIC_READ,SET_ACCESS,SUB_CONTAINERS_AND_OBJECTS_INHERIT,TRUSTEE_IS_GROUP);

第二个呼叫代理第一个。最后,我没有得到同一组的两个条目。

1 个答案:

答案 0 :(得分:0)

  

我看到每次最后一次通话都会覆盖先例。

这不是大多数安全API的行为。就DACL API而言,您只需创建DACL,它就是ACE列表并将DACL传递给操作系统。操作系统不会执行任何类型的折叠或类似的操作,这就是为什么通过将ACE放在错误的顺序中(轻易地)做错了。 (拒绝ACE需要在允许ACE之前进行......)

现在,您正在使用异常的API - SetEntriesInAcl尝试将多个权限集“合并”在一起。如果您不想要这种行为,则需要使用AddAce和类似函数自行构建DACL。