0

我正在尝试将两个条目设置为同一组的对象文件夹,具有不同的继承,(一个为 FILE_TRAVERSE 的 NO_INHERITANCE,另一个为 SUB_CONTAINERS_AND_OBJECTS_INHERIT,用于 GENERIC_READ)。我看到每次最后一次通话都会覆盖先例。我在 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);

第二个调用替代第一个。最后,我没有得到同一组的两个条目。

4

1 回答 1

0

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

这不是大多数安全 API 的行为。就 DACL API 而言,您只需创建 DACL,它只是一个 ACE 列表并将 DACL 交给操作系统。操作系统不执行任何类型的折叠或类似的操作,这就是为什么通过将 ACE 以错误的顺序放置可能(很容易)做错事的原因。(拒绝 ACE 需要在允许 ACE 之前进行...)

现在,您使用的 API 是一个例外——SetEntriesInAcl尝试将多个权限集“合并”在一起。如果您不想要这种行为,您需要自己使用AddAce和类似功能构建 DACL。

于 2012-08-07T15:34:30.563 回答