function AddAccessRights(lpszFileName : PChar; lpszAccountName : PChar; dwAccessMask : DWORD) : boolean;
const
HEAP_ZERO_MEMORY = $00000008;
ACL_REVISION = 2;
ACL_REVISION2 = 2;
INHERITED_ACE = $10;
type
ACE_HEADER = Record
AceType,
AceFlags : BYTE;
AceSize : WORD;
end;
PACE_HEADER = ^ACE_HEADER;
ACCESS_ALLOWED_ACE = Record
Header : ACE_HEADER;
Mask : ACCESS_MASK;
SidStart : DWORD;
end;
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
ACL_SIZE_INFORMATION = Record
AceCount,
AclBytesInUse,
AclBytesFree : DWORD;
end;
SetSecurityDescriptorControlFnPtr = function (pSecurityDescriptor : PSecurityDescriptor;
ControlBitsOfInterest : SECURITY_DESCRIPTOR_CONTROL;
ControlBitsToSet : SECURITY_DESCRIPTOR_CONTROL) : boolean; stdcall;
var
snuType : SID_NAME_USE;
szDomain : PChar;
cbDomain : DWORD;
pUserSID : Pointer;
cbUserSID : DWORD;
pFileSD : PSecurityDescriptor;
cbFileSD : DWORD;
newSD : TSecurityDescriptor;
ptrACL : PACL;
fDaclPresent,
fDaclDefaulted : BOOL;
AclInfo : ACL_SIZE_INFORMATION;
pNewACL : PACL;
cbNewACL : DWORD;
pTempAce : Pointer;
CurrentAceIndex,
newAceIndex : UINT;
fResult,
fAPISuccess : boolean;
secInfo : SECURITY_INFORMATION;
_SetSecurityDescriptorControl : SetSecurityDescriptorControlFnPtr;
controlBitsOfInterest,
controlBitsToSet,
oldControlBits : SECURITY_DESCRIPTOR_CONTROL;
dwRevision : DWORD;
AceFlags : BYTE;
function myheapalloc(x : integer) : Pointer;
begin
Result := HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, x);
end;
function myheapfree(x : Pointer) : boolean;
begin
Result := HeapFree(GetProcessHeap(), 0, x);
end;
function SetFileSecurityRecursive(lpFileName: PChar; SecurityInformation: SECURITY_INFORMATION;
pSecurityDescriptor: PSecurityDescriptor): BOOL;
var
sr : TSearchRec;
begin
Result := SetFileSecurity(lpFileName, SecurityInformation, pSecurityDescriptor);
if Not Result then
Exit;
if (FileGetAttr(lpFileName) AND faDirectory) = faDirectory then
begin
if FindFirst(IncludeTrailingPathDelimiter(lpFileName) + '*', $EFFF, sr) = 0 then
begin
Repeat
if (sr.Name <> '.') AND (sr.Name <> '..') then
SetFileSecurityRecursive(PChar(IncludeTrailingPathDelimiter(lpFileName) + sr.Name),
SecurityInformation, pSecurityDescriptor);
until FindNext(sr) <> 0;
FindClose(sr);
end;
end;
end;
begin
szDomain := nil;
cbDomain := 0;
pUserSID := nil;
cbUserSID := 0;
pFileSD := nil;
cbFileSD := 0;
ptrACL := nil;
pNewACL := nil;
cbNewACL := 0;
pTempAce := nil;
CurrentAceIndex := 0;
newAceIndex := 0;
fResult := FALSE;
secInfo := DACL_SECURITY_INFORMATION;
_SetSecurityDescriptorControl := nil;
Result := FALSE;
try
fAPISuccess := LookupAccountName(nil, lpszAccountName,
pUserSID, cbUserSID, szDomain, cbDomain, snuType);
if (Not fAPISuccess) AND (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
raise Exception.Create('LookupAccountName Error=' + IntToStr(GetLastError()));
pUserSID := myheapalloc(cbUserSID);
if pUserSID = nil then
raise Exception.Create('myheapalloc Error=' + IntToStr(GetLastError()));
szDomain := PChar(myheapalloc(cbDomain * sizeof(PChar)));
if szDomain = nil then
raise Exception.Create('myheapalloc Error=' + IntToStr(GetLastError()));
fAPISuccess := LookupAccountName(nil, lpszAccountName,
pUserSID, cbUserSID, szDomain, cbDomain, snuType);
if Not fAPISuccess then
raise Exception.Create('LookupAccountName Error=' + IntToStr(GetLastError()));
fAPISuccess := GetFileSecurity(lpszFileName,
secInfo, pFileSD, 0, cbFileSD);
if (Not fAPISuccess) AND (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
raise Exception.Create('GetFileSecurity Error=' + IntToStr(GetLastError()));
pFileSD := myheapalloc(cbFileSD);
if pFileSD = nil then
raise Exception.Create('myheapalloc Error=' + IntToStr(GetLastError()));
fAPISuccess := GetFileSecurity(lpszFileName,
secInfo, pFileSD, cbFileSD, cbFileSD);
if Not fAPISuccess then
raise Exception.Create('GetFileSecurity Error=' + IntToStr(GetLastError()));
if Not InitializeSecurityDescriptor(@newSD,
SECURITY_DESCRIPTOR_REVISION) then
raise Exception.Create('InitializeSecurityDescriptor Error=' + IntToStr(GetLastError()));
if Not GetSecurityDescriptorDacl(pFileSD, fDaclPresent, ptrACL,
fDaclDefaulted) then
raise Exception.Create('GetSecurityDescriptorDacl Error=' + IntToStr(GetLastError()));
AclInfo.AceCount := 0;
AclInfo.AclBytesFree := 0;
AclInfo.AclBytesInUse := sizeof(ACL);
if ptrACL = nil then
fDaclPresent := FALSE;
if Not fDaclPresent then
if Not GetAclInformation(ptrACL^, @AclInfo,
sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) then
raise Exception.Create('GetAclInformation ' + IntToStr(GetLastError()));
cbNewACL := AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
+ GetLengthSid(pUserSID) - sizeof(DWORD);
pNewACL := PACL(myheapalloc(cbNewACL));
if pNewACL = nil then
raise Exception.Create('myheapalloc ' + IntToStr(GetLastError()));
if Not InitializeAcl(pNewACL^, cbNewACL, ACL_REVISION2) then
raise Exception.Create('InitializeAcl ' + IntToStr(GetLastError()));
newAceIndex := 0;
if (fDaclPresent) AND (AclInfo.AceCount > 0) then
begin
for CurrentAceIndex := 0 to AclInfo.AceCount - 1 do
begin
if Not GetAce(ptrACL^, CurrentAceIndex, pTempAce) then
raise Exception.Create('GetAce ' + IntToStr(GetLastError()));
if PACCESS_ALLOWED_ACE(pTempAce)^.Header.AceFlags AND INHERITED_ACE > 0 then
break;
if EqualSid(pUserSID, @(PACCESS_ALLOWED_ACE(pTempAce)^.SidStart)) then
continue;
if Not AddAce(pNewACL^, ACL_REVISION, MAXDWORD, pTempAce,
PACE_HEADER(pTempAce)^.AceSize) then
raise Exception.Create('AddAce ' + IntToStr(GetLastError()));
Inc(newAceIndex);
end;
end;
AceFlags := $1 (* OBJECT_INHERIT_ACE *)
OR $2 (* CONTAINER_INHERIT_ACE *)
OR $10 (* INHERITED_ACE*);
if Not AddAccessAllowedAceEx(pNewACL^, ACL_REVISION2, AceFlags, dwAccessMask,
pUserSID) then
raise Exception.Create('AddAccessAllowedAce ' + IntToStr(GetLastError()));
if (fDaclPresent) AND (AclInfo.AceCount > 0) then
begin
while CurrentAceIndex < AclInfo.AceCount do
begin
if Not GetAce(ptrACL^, CurrentAceIndex, pTempAce) then
raise Exception.Create('GetAce ' + IntToStr(GetLastError()));
if Not AddAce(pNewACL^, ACL_REVISION, MAXDWORD, pTempAce,
PACE_HEADER(pTempAce)^.AceSize) then
raise Exception.Create('AddAce ' + IntToStr(GetLastError()));
end;
Inc(CurrentAceIndex);
end;
if Not SetSecurityDescriptorDacl(@newSD, TRUE, pNewACL, FALSE) then
raise Exception.Create('SetSecurityDescriptorDacl ' + IntToStr(GetLastError()));
_SetSecurityDescriptorControl := SetSecurityDescriptorControlFnPtr(
GetProcAddress(GetModuleHandle('advapi32.dll'),
'SetSecurityDescriptorControl'));
if @_SetSecurityDescriptorControl <> nil then
begin
controlBitsOfInterest := 0;
controlBitsToSet := 0;
oldControlBits := 0;
dwRevision := 0;
if Not GetSecurityDescriptorControl(pFileSD, oldControlBits,
dwRevision) then
raise Exception.Create('GetSecurityDescriptorControl ' + IntToStr(GetLastError()));
if (oldControlBits AND SE_DACL_AUTO_INHERITED) <> 0 then
begin
controlBitsOfInterest := SE_DACL_AUTO_INHERIT_REQ OR SE_DACL_AUTO_INHERITED;
controlBitsToSet := controlBitsOfInterest;
end
else if (oldControlBits AND SE_DACL_PROTECTED) <> 0 then
begin
controlBitsOfInterest := SE_DACL_PROTECTED;
controlBitsToSet := controlBitsOfInterest;
end;
if controlBitsOfInterest <> 0 then
if Not _SetSecurityDescriptorControl(@newSD, controlBitsOfInterest, controlBitsToSet) then
raise Exception.Create('SetSecurityDescriptorControl ' + IntToStr(GetLastError()));
end;
if Not SetFileSecurityRecursive(lpszFileName, secInfo, @newSD) then
raise Exception.Create('SetFileSecurity ' + IntToStr(GetLastError()));
except
on E: Exception do
begin
MessageDlg(E.Message, mtError, [mbAbort], -1);
Exit;
end;
end;
if pUserSID <> nil then
myheapfree(pUserSID);
if szDomain <> nil then
myheapfree(szDomain);
if pFileSD <> nil then
myheapfree(pFileSD);
if pNewACL <> nil then
myheapfree(pNewACL);
fResult := TRUE;
end;
Beispiel :
procedure TForm1.Button1Click(Sender: TObject);
begin
AddAccessRights('c:\Windows', 'Jeder', $FFFFFFFF);
end;
Keine Kommentare:
Kommentar veröffentlichen