how to set multiple ACEs of a same trustee in an ACL of an object

480 views Asked by At

I am trying to set two Entries to an object folder of a same group, with difference inheritance, (one NO_INHERITANCE for FILE_TRAVERSE, the other as SUB_CONTAINERS_AND_OBJECTS_INHERIT, for GENERIC_READ). I see that everytime the last call overwrite the precedent. I wrote this in delphi (but is the same if C++ or C...). Can someone help me in what is wrong?

this is the calling function:

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;

and I call it two times in this way:

  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);

the second call substitude the first one. At the end I don't get two entries for the same group.

1

There are 1 answers

0
Billy ONeal On

I see that everytime the last call overwrite the precedent.

That is not the behavior of the majority of the security APIs. As far as the DACL APIs are concerned, you just create the DACL, which is just a list of ACEs and hand the DACL to the operating system. The OS doesn't perform any kind of folding or anything like that, which is why it's possible to (easily) do it wrong by putting your ACEs in the wrong order. (Deny ACEs need to go before Allow ACEs...)

Now, you're using the API that is the exception -- SetEntriesInAcl attempts to "merge" multiple permission sets together. If you don't want this behavior, you need to build the DACL yourself using AddAce and similar functions.