ACL handling in Lazarus lazarus / 34-Windows ---------------------------------------------------------------------- ilyr · 2013-03-13 13:22 Hi, After a long break from programming, I just heard about Lazarus and it got my curiosity. I have some ideas which I would like to implement, but ofcourse these are coming with obstacles too... The first one is that I would like to get DACL information from files/folders. I already made some reserach on the subject and found different alternatives, but had no luck with the implementation so far. These alternatives: - Calling Windows API functions from DLL, this one seems to be a bit too complicated for me and not sure what things I have to define - Using the JEDI Windows API headers (do I see correctly that this is included in Lazarus by default?), I made a short program with this, which is compiling flawlessly, but crash with the usual SIGSEV error - The easisest would be using JWSCL (JEDI Windows Security Library), but I had no luck with making it work with Lazarus (can it be used with Lazarus at all?) Can somebody point me in the right direction? Maybe with a simple example that list the DACL usernames of a specific folder without any error handling? Thanks in advance! ---------------------------------------------------------------------- marcov · 2013-03-13 20:24 Jedi should be ok. Maybe post your code? ---------------------------------------------------------------------- ilyr · 2013-03-14 07:54 I tried with this: Code: [Select]program ACLChecker; uses JwaWindows; type   _ACE_HEADER = record   AceType : BYTE;   AceFlags : BYTE;   AceSize : WORD;   end;   ACCESS_ACE = record   Header : _ACE_HEADER;   Mask : ACCESS_MASK;   SidStart : DWORD;   end; Var   i: Longint;   Dacl: PACL;   SecDescPtr: PSECURITY_DESCRIPTOR;   aclSizeInfo: ACL_SIZE_INFORMATION;   AccLen,DomainLen,peUse: DWord;   AccName,DomainName: PChar;   Ace: ^ACCESS_ACE; begin   SecDescPtr:=nil;   Ace:=nil;   peUse:=0;   DomainLen:=0;   AccLen:=0;   DomainName:='';   AccName:='';   GetNamedSecurityInfo(PChar('D:\Temp'),SE_FILE_OBJECT,DACL_SECURITY_I NFORMATION,nil,nil,@Dacl,nil,SecDescPtr);   GetACLInformation(Dacl, @aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION), AclSizeInformation);   if aclSizeInfo.AceCount > 0 then   begin     for i := 0 to aclSizeInfo.AceCount - 1 do     begin       GetAce(Dacl, i, Pointer(Ace));       LookupAccountSid(nil,PSID(@Ace^.SidStart),AccName,AccLen,DomainN ame,DomainLen,peUse);       Writeln(Domainname+'\'+AccName);     end;   end;   LocalFree(HLOCAL(SecDescPtr)); end. ---------------------------------------------------------------------- ilyr · 2013-05-03 15:53 As I haven't received any answer, I thought I will leave a working code as well, in case somebody else would have the same question... Code: [Select]program ACLChecker; uses   JwaAccCtrl,   JwaWinBase,   JwaWinType,   JwaWinNT,   JwaWinError,   JwaAclAPI; type   _ACE_HEADER = record     AceType: byte;     AceFlags: byte;     AceSize: word;   end;   ACCESS_ACE = record     Header: _ACE_HEADER;     Mask: ACCESS_MASK;     SidStart: DWORD;   end; var   Dacl: PACL;   SecDescPtr: PSECURITY_DESCRIPTOR;   aclSizeInfo: ACL_SIZE_INFORMATION;   AccLen, DomainLen, peUse, i: DWORD;   AccName, DomainName: Array of Char;   Ace: ^ACCESS_ACE; begin   SecDescPtr := nil;   Dacl := nil;   Ace := nil;   peUse := 0;   DomainLen := 0;   AccLen := 0;   DomainName := '';   AccName := '';   GetNamedSecurityInfo(LPTSTR('E:\Temp'), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,     nil, nil, @Dacl, nil, SecDescPtr);   GetACLInformation(Dacl, @aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION),     AclSizeInformation);   if aclSizeInfo.AceCount > 0 then   begin     for i := 0 to aclSizeInfo.AceCount-1 do     begin       GetAce(Dacl, i, Ace);       If (Not LookupAccountSid(nil, PSID(@Ace^.SidStart), @AccName[0], AccLen,         @DomainName[0], DomainLen, peUse) and (GetLastError = ERROR_INSUFFICIENT_BUFFER)) Then       Begin         SetLength(DomainName,DomainLen);         Setlength(AccName,AccLen);         if LookupAccountSid(nil, PSID(@Ace^.SidStart), @AccName[0], AccLen, @DomainName[0], DomainLen, peUse) Then         Begin           Writeln(PChar(DomainName),'\',PChar(AccName));         end;       end;     end;   end;   LocalFree(HLOCAL(SecDescPtr)); end.