Как установить несколько ACE одного и того же опекуна в ACL объекта
Я пытаюсь установить две записи в папку объектов одной и той же группы с наследованием различий (одна NO_INHERITANCE для FILE_TRAVERSE, другая как 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);
второй вызов заменит первый. В конце я не получаю две записи для одной группы.
1 ответ
Я вижу, что каждый раз, когда последний вызов перезаписывает прецедент.
Это не поведение большинства API безопасности. Что касается API DACL, вы просто создаете DACL, который представляет собой просто список ACE, и передаете DACL в операционную систему. ОС не выполняет никаких операций свертывания или чего-либо в этом роде, поэтому можно (легко) сделать это неправильно, разместив ACE в неправильном порядке. (Запретить ACE нужно, прежде чем разрешить ACE...)
Теперь вы используете API, который является исключением - SetEntriesInAcl
пытается "объединить" несколько наборов разрешений вместе. Если вы не хотите такого поведения, вам нужно создать DACL самостоятельно, используя AddAce
и аналогичные функции.