Just now I'm looking at fixing a localization bug with a small application that get's fired during the install of a software package. The small application essentially brute forces permissions on our own folder within Application Data to set EVERYONE to full access.
The problem arises with EVERYONE not being localized. I know I need to use SID's, which for EVERYONE, is S-1-1-0
. I can't find a WinAPI function for setting permissions using an SID.
The function just now uses BuildExplicitAccessWithName
and SetNamedSecurityInfo
as shown below
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;
Which functions should I be looking at using instead?
After some searching through the WinAPI documentation I went for the solution below. Essentially I use the SID to lookup the "readable" name and then use that. It won't be the most elegant solution but it works for me.
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;