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.
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 usingAddAce
and similar functions.