I'm trying to get a function working in Lazarus that should add a File-ACL to the yet existing ACL of that object. Obviously I'm doing somethinh wrong: The program crashes with a SIGSEGV when it reaches BuildExplicitAccessWithName. Regarding the debugger, this function calls BuildTrusteeWithObjectsAndName iternally which then leads to the SIGSEGV. What am I doing wrong here? Here's my code:
program acltest;
uses JwaWindows;
function AddFileACL(Filename, TrusteeName: AnsiString; AccessMode: ACCESS_MODE; Inheritance: dWord): Boolean; stdcall;
var
pExplicitAccess : PEXPLICIT_ACCESS;
ExistingDacl : PACL;
pExistingDacl : PPACL;
NewAcl : PACL;
psd : PSECURITY_DESCRIPTOR;
begin
NewAcl := nil;
psd := nil;
pExistingDacl := nil;
Result := false;
try
if ERROR_SUCCESS = GetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pExistingDacl, nil, psd) then
begin
try
BuildExplicitAccessWithName(pExplicitAccess, PAnsiChar(TrusteeName), GENERIC_ALL, AccessMode, Inheritance);
ExistingDacl := pExistingDacl^;
if ERROR_SUCCESS = SetEntriesInAcl(1, pExplicitAccess, ExistingDacl, NewAcl) then
begin
if ERROR_SUCCESS = SetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, NewAcl, nil) then
begin
Result := true;
end;
end;
finally
end;
end;
finally
end;
end;
begin
if AddFileACL('C:\Users\keckc\Desktop\test.txt', 'Everyone', GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT) = true then
begin
writeln('Yep, it works!');
end
else begin
writeln('Nope, try again!');
end;
end.
You pass pExplicitAccess
which is an uninitialized pointer variable of type PEXPLICIT_ACCESS
. You are expected instead to allocate an EXPLICIT_ACCESS
structure, and pass its address.
var
ExplicitAccess: EXPLICIT_ACCESS;
....
BuildExplicitAccessWithName(@ExplicitAccess, ...);
In the call to GetNamedSecurityInfo
, passing psd
is somewhat pointless. Since it has the value nil
, you may as well delete pass nil
. At which point you'll be able to remove the psd
variable.
As for pExistingDacl
, again you initialise it to nil
. And so pExistingDacl^
is going to be another SIGSEV. Instead you should remove the pExistingDacl
variable, and pass @ExistingDacl
.
It would seem that you have similar problems with the calls to SetEntriesInAcl
and SetNamedSecurityInfo
, but hopefully by now, you can understand the pattern and will be able to resolve the problems.
Finally, I do also wonder why you are using the ANSI version of the function rather than the Unicode version.