BPSoftware.com
Home   Utilities   Purchase   FAQ   Support   Contact        
Shareware Utilities
 APrintDirect
 AIconExtract
 AFile Attribute Manager
Freeware Utilities
 AddrMon
 AFileSync
 ASysIcon
 B&P Table Utilities
 BPACLer
 BPSNMPMon
 BPSNMPUtil
 CharCount
 Delphi® Components
 MacAddr
Miscellaneous
 BPSoftware Blog
 Purchase Shareware
 Support

 Subscribe!

Sunday, November 27, 2005
Delphi® and GetExplicitEntriesFromAcl

I have been doing quite a bit with the Windows® security (see BPACLer and an earlier post). At first glance it may seem complicated (what other unknowns don’t) but once you get the hang of it, it is rather ‘logical’. Each object has its own Access Control List (ACL) that either grants or denies access (via authorization) to that object.
ACLs are made up of Access Control Entries (ACE). Each ACE contains the authorization information for a Trustee. An ACE can either be an Effective or Explicit entry. In order to retrieve a list of Explicit Entries (EA) a call to GetExplicitEntriesFromAcl does the trick. I haven’t seen many examples (actually I haven’t seen a one) of using this from within Delphi® so I figured I’d post a sample use of this API. If you have any questions please let me know.

procedure GetEAList(filename: string; listbox: TListBox);
type
TEAArray = Array [0..0] of EXPLICIT_ACCESS;
PEAArray = ^TEAArray;

var
pSD: PSECURITY_DESCRIPTOR;
countofexplicitentries: Cardinal;
ListOfExplicitEntries: PEXPLICIT_ACCESS_A;
EAList: PEAArray;
pExplicitAccess: EXPLICIT_ACCESS;
pDACL: PACL;
i: integer;

begin
if not (GetNamedSecurityInfo(PChar(filename),SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION, Nil, Nil, @pDACL, Nil,
pSD)=0) then
Exit;

GetMem(ListOfExplicitEntries,SizeOf(ListOfExplicitEntries));

if GetExplicitEntriesFromAcl(pDACL^,countofexplicitentries,@EAList) <>
ERROR_SUCCESS then
begin
FreeMem(ListOfExplicitEntries);
Exit;
end;

if (countofexplicitentries > 0) then
for i:= 0 to countofexplicitentries - 1 do
begin
pExplicitAccess:= EAList[i];
listbox.Items.Add(GetName(pExplicitAccess.Trustee.ptstrName));
case pExplicitAccess.Trustee.trusteetype of
TRUSTEE_IS_USER: listbox.Items.Add('TRUSTEE_IS_USER');
TRUSTEE_IS_GROUP: listbox.Items.Add('TRUSTEE_IS_GROUP');
TRUSTEE_IS_DOMAIN: listbox.Items.Add('TRUSTEE_IS_DOMAIN');
TRUSTEE_IS_ALIAS: listbox.Items.Add('TRUSTEE_IS_ALIAS');
TRUSTEE_IS_DELETED: listbox.Items.Add('TRUSTEE_IS_DELETED');
TRUSTEE_IS_INVALID: listbox.Items.Add('TRUSTEE_IS_INVALID');
TRUSTEE_IS_WELL_KNOWN_GROUP: listbox.Items.Add('TRUSTEE_IS_WELL_KNOWN_GROUP');
TRUSTEE_IS_UNKNOWN: listbox.Items.Add('TRUSTEE_IS_UNKNOWN');
end;

case pExplicitAccess.grfAccessMode of
NOT_USED_ACCESS: listbox.Items.Add('NOT_USED_ACCESS');
GRANT_ACCESS: listbox.Items.Add('GRANT_ACCESS');
SET_ACCESS: listbox.Items.Add('SET_ACCESS');
DENY_ACCESS: listbox.Items.Add('DENY_ACCESS');
REVOKE_ACCESS: listbox.Items.Add('REVOKE_ACCESS');
SET_AUDIT_FAILURE: listbox.Items.Add('SET_AUDIT_FAILURE');
end;
end;

FreeMem(ListOfExplicitEntries);
end;


In my opinion, it is extremely important that an administrator reviews the ACLs for the objects within their directory. I have been often times surprised by some of the holes that are permission based. It is not always that a Trustee would intentionally cause damage, however accidents do occur. There are also those cases where a Trustee may be impersonated and well, we all know what happens from there. I am often criticized for being overly restrictive, however I feel it is better to be safe than sorry. After all, people don't typically tell you what then can do, rather what they can't.

Labels: , ,

posted by Brad Prendergast at 9:44:00 AM
Comments:
verry good!
But how do you get the name of the trustee? Where is the function getname declared?
posted by Anonymous Anonymous Thursday, March 16, 2006 12:57:00 PM  
I use:
function GetName(OwnerSID: PSID):String;
var
OwnerName, DomainName: Array[0..100] of Char;
cbSize: DWORD;
OwnerType: SID_NAME_USE;
begin
cbSize := SizeOf(OwnerName);
if not LookupAccountSID(nil, OwnerSID, OwnerName,
cbSize, DomainName, cbSize, OwnerType) then
result:= SIDToStr(OwnerSID)
else
result:= Format('%s\%s',[DomainName,OwnerName]);
end;
posted by Blogger Brad Prendergast Thursday, March 16, 2006 1:25:00 PM  
Thanks for posting this -- very helpful. I wish there was more reources availble for integrating this COM object into Delphi! Your post here was useful though -- the most useful thing I've found yet... so THANKS for that...
posted by Anonymous Cass Friday, May 19, 2006 6:39:00 PM  
which version of delphi did you use to test this code? it does not work on delphi 7 because length(ealist) is only 1 and it tries to write to ealist(1).

also, what is listofexplicitentries for except using memory?

regards
posted by Anonymous Anonymous Wednesday, July 05, 2006 4:48:00 AM  
I use BDS2005 and BDS2006. For this example listofexplicitentries can be omitted; I used it for something else I was working on and it was left in when I pulled it out.
posted by Blogger Brad Prendergast Saturday, July 08, 2006 7:06:00 PM  
Links to this post:

Create a Link

Recent Posts
 Ode to Backup
 What's on my spreadsheet?
 Free Gems Do Exist (Part 2)
 Free Gems Do Exist (Part 1)
 What’s in a word?
 Delphi™ Components and Freeware Updates
 FASTMM Saves the Day
 Shareware: APrintDirect version 5.1.2.7 available
 Conditional Format
 Delphi™ Components: TFileEdit Updated

 Subscribe!


Labels



Archives
 October 2005
 November 2005
 December 2005
 January 2006
 February 2006
 March 2006
 April 2006
 May 2006
 June 2006
 July 2006
 August 2006
 September 2006
 December 2006
 January 2007
 February 2007
 March 2007
 September 2007
 October 2007
 November 2007
 July 2008
 November 2008
Powered by Blogger