Как установить несколько 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 и аналогичные функции.

Другие вопросы по тегам