0

刚才我正在考虑使用在安装软件包期间触发的小型应用程序修复本地化错误。小应用程序本质上是暴力破解应用程序数据中我们自己的文件夹的权限,以将每个人设置为完全访问权限。

问题是每个人都没有被本地化。我知道我需要使用 SID,这对每个人来说都是S-1-1-0. 我找不到使用 SID 设置权限的 WinAPI 函数。

刚才用到的函数BuildExplicitAccessWithNameSetNamedSecurityInfo如下图

function setfullaccess(foldername:string):boolean;    //B2415 MDE
var
 pDACL: PACL;
 pEA: PEXPLICIT_ACCESS_A;
 R: DWORD;
begin
 result := true;
 pEA := AllocMem(SizeOf(EXPLICIT_ACCESS));
 BuildExplicitAccessWithName(pEA, 'EVERYONE', GENERIC_ALL{GENERIC_READ},GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT{NO_INHERITANCE});
 R := SetEntriesInAcl(1, pEA, nil, pDACL);
 if R = ERROR_SUCCESS then
 begin
  if SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then result := false;
  LocalFree(Cardinal(pDACL));
 end
 else result := false;//ShowMessage('SetEntriesInAcl failed: ' + SysErrorMessage(R));
end;

我应该考虑使用哪些功能?

4

2 回答 2

1

在对 WinAPI 文档进行了一些搜索后,我找到了以下解决方案。本质上,我使用 SID 来查找“可读”名称,然后使用它。这不会是最优雅的解决方案,但它对我有用。

procedure TTestform.Button4Click(Sender: TObject);
var
 Sid: PSID;
 peUse: DWORD;
 cchDomain: DWORD;
 cchName: DWORD;
 Name: array of Char;
 Domain: array of Char;
 pDACL: PACL;
 pEA: PEXPLICIT_ACCESS_A;
 R: DWORD;
 foldername: String; //Temp to hardcode
begin
 foldername := 'C:\TEMP'; //Temp to hardcode
 Sid := nil;
 Win32Check(ConvertStringSidToSidA(PChar('S-1-1-0'), Sid));
 cchName := 0;
 cchDomain := 0;
 //Get Length
 if (not LookupAccountSid(nil, Sid, nil, cchName, nil, cchDomain, peUse)) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
 begin
  SetLength(Name, cchName);
  SetLength(Domain, cchDomain);
  if LookupAccountSid(nil, Sid, @Name[0], cchName, @Domain[0], cchDomain, peUse) then
  begin
   pEA := AllocMem(SizeOf(EXPLICIT_ACCESS));
   BuildExplicitAccessWithName(pEA, PChar(Name), GENERIC_ALL{GENERIC_READ},GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT{NO_INHERITANCE});
   R := SetEntriesInAcl(1, pEA, nil, pDACL);
   if R = ERROR_SUCCESS then
   begin
    if SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then ShowMessage('SetNamedSecurityInfo failed: ' + SysErrorMessage(GetLastError));
    LocalFree(Cardinal(pDACL));
   end
   else ShowMessage('SetEntriesInAcl failed: ' + SysErrorMessage(R));
  end;
 end;
end;
于 2012-06-29T13:32:51.807 回答
0

避免同时使用lookup和的替代方法build

var SID: JwaWinNT.PSid; // JWA clashes with Delphi XE2 Windows.Windows.PSID type
    pDACL: PACL;
    EA: EXPLICIT_ACCESS;
    SID_DATA: array[1..SECURITY_MAX_SID_SIZE] of byte;
    SID_DATA_SIZE: DWORD;

   SID_DATA_SIZE := Length(SID_DATA);
   Pointer(SID) := @SID_DATA; // @SID_DATA[Low(SID_DATA)]  for non-static arrays 

    pDACL := nil;
//   if ConvertStringSidToSid(Auth_Users_SID, SID) then
   if CreateWellKnownSid(WinAuthenticatedUserSid, nil, SID, SID_DATA_SIZE) then
   try
      EA.grfInheritance := SUB_CONTAINERS_AND_OBJECTS_INHERIT; // NO_INHERITANCE; // 0
      EA.grfAccessMode :=  GRANT_ACCESS;
      EA.grfAccessPermissions := GENERIC_ALL;

      EA.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
      EA.Trustee.pMultipleTrustee := nil;
      EA.Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
      EA.Trustee.TrusteeForm := TRUSTEE_IS_SID;
      EA.Trustee.ptstrName   := pointer(SID); 

      if ERROR_SUCCESS = SetEntriesInAcl(1, @EA, nil, pDACL) then begin

       // optional creation of PATH and 0-bytes dummy file skipped 

        SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT, ....  {see the author's answer above }
      end;

   finally
     LocalFree(pDACL); // SID is not allocated on heap - no need to free it
   end;

也可以在http://forum.vingrad.ru/forum/topic-374131/0.html#st_15_view_0的第 2 页对照单元检查此片段

于 2016-03-21T15:46:15.627 回答