对于SetEntriesInAclA,如何正确地将EXPLICIT_ACCESS与jedi-winutils对齐?

问题描述 投票:1回答:1

我正在尝试使用EXPLICIT_ACCESS_A从Free Pascal中的SetEntriesInAclA数组创建一个新的ACL,但是我一直使用以下命令从SetEntriesInAclA不断得到错误代码87(无效参数)以下代码:

uses
  sysutils,
  JwaWinNT,
  JwaAclApi,
  JwaAccCtrl,
  JwaSDDL,
  jwawinbase,
  jwawinsta,
  jwawintype,
  jwawinerror; 

function SetupAccess(owner: jwawinnt.PSID; var acl: jwawinnt.PACL): bool;
  const
    EA_COUNT = 3;
  var
    sidAuthWorld: jwawinnt.SID_IDENTIFIER_AUTHORITY;
    sidAuthNT: jwawinnt.SID_IDENTIFIER_AUTHORITY;
    everyoneSID: jwawinnt.PSID;
    adminSID: jwawinnt.PSID;
    ea: Array[0..(EA_COUNT-1)] of jwaaccctrl.EXPLICIT_ACCESS_A;
    status: jwawintype.DWORD;
  begin
    try
      begin
        WriteLn(IntToStr(SizeOf(jwaaccctrl.EXPLICIT_ACCESS_A)));
        sidAuthWorld := jwawinnt.SECURITY_WORLD_SID_AUTHORITY;
        sidAuthNT := jwawinnt.SECURITY_NT_AUTHORITY;

        if not (jwawinbase.AllocateAndInitializeSid(@sidAuthWorld, 1, jwawinnt.SECURITY_WORLD_RID,
            0, 0, 0, 0, 0, 0, 0, everyoneSID)
          and AllocateAndInitializeSid(@sidAuthNT, 2, jwawinnt.SECURITY_BUILTIN_DOMAIN_RID,
          jwawinnt.DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, adminSID)) then
        begin
          WriteLn('Could not allocate SIDs: ' + SysErrorMessage(getLastError()));
          Result := false;
        end
        else
        begin
          jwawinbase.ZeroMemory(@ea, EA_COUNT * sizeOf(EXPLICIT_ACCESS_A));

          ea[0].grfAccessPermissions := GENERIC_ALL;
          ea[0].grfAccessMode := DENY_ACCESS;
          ea[0].grfInheritance := NO_INHERITANCE;
          ea[0].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
          ea[0].Trustee.pMultipleTrustee := nil;
          ea[0].Trustee.TrusteeForm := TRUSTEE_IS_SID;
          ea[0].Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
          ea[0].Trustee.ptstrName := pointer(everyoneSID);

          ea[1].grfAccessPermissions := GENERIC_ALL;
          ea[1].grfAccessMode := SET_ACCESS;
          ea[1].grfInheritance := NO_INHERITANCE;
          ea[1].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
          ea[1].Trustee.pMultipleTrustee := nil;
          ea[1].Trustee.TrusteeForm := TRUSTEE_IS_SID;
          ea[1].Trustee.TrusteeType := TRUSTEE_IS_GROUP;
          ea[1].Trustee.ptstrName := pointer(adminSID);

          ea[2].grfAccessPermissions := GENERIC_ALL;
          ea[2].grfAccessMode := SET_ACCESS;
          ea[2].grfInheritance := NO_INHERITANCE;
          ea[2].Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
          ea[2].Trustee.pMultipleTrustee := nil;
          ea[2].Trustee.TrusteeForm := TRUSTEE_IS_SID;
          ea[2].Trustee.TrusteeType := TRUSTEE_IS_USER;
          ea[2].Trustee.ptstrName := pointer(owner);

          status := jwaaclapi.SetEntriesInAclA(2, @ea, nil, acl);
          if status = ERROR_SUCCESS then
            Result := true
          else
          begin
            WriteLn('Error in SetEntriesInAcl: ' + IntToStr(status));
            Result := false;
          end;
        end;
      end
    finally
      If Assigned(everyoneSID) then
        jwawinbase.FreeSID(everyoneSID);
      If Assigned(adminSID) then
        jwawinbase.FreeSID(adminSID);
    end
  end;

[在搜索该问题时,我遇到了this question,这暗示该问题可能与EXPLICIT_ACCESS_A记录的对齐有关。

并且确定WriteLn(IntToStr(SizeOf(jwaaccctrl.EXPLICIT_ACCESS_A)));足够大,它的大小为20。这是因为jedi将该结构声明为packed。从链接的问题中,我认为EXPLICIT_ACCESS_A应该大小为24,但在C ++中测试后,实际上似乎为32。

我还尝试将EXPLICIT_ACCESS_ATRUSTEE_A结构复制到我的单位并删除packed关键字。产生大小为24的结构,但仍然是相同的错误。

结论:我可以使用jedi制作上述代码,还是jedi中的错误/疏忽?

还请注意,我正在使用Lazarus 2.0.4和FPC 3.0.4从x64交叉编译为x86。

delphi winapi acl freepascal memory-alignment
1个回答
0
投票

对于32位,EXPLICIT_ACCESS_A结构应为32字节。该记录可能很挤满,因为它包含一个联合。我在Delphi中使用Jedi ApiLib进行了测试,它返回正确的大小:

program SizeTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  JwaAccCtrl;

begin
  WriteLn(Format('EXPLICIT_ACCESS_A size: %d', [SizeOf(EXPLICIT_ACCESS_A)]));

输出:

Output

在Delphi {$ MINENUMSIZE 4}中用于将枚举强制为4个字节(如C中一样,也许您需要在Lazarus/FPC中设置它?

© www.soinside.com 2019 - 2024. All rights reserved.