November 05, 2002

The Powers of the ACL

The powers of the ACL. One of the biggest beefs I have had with Windows environments has been the fact you can't simply change perms on files (ie: chmod 750 foo) as you can in Unix environments. On the flip side, I have always thought Windows Access Control was much easier to understand. However, whenever you need to programmatically change access control, Win32 has been a NIGHTMARE to create ACLs. Well, in exploring the bowels of VC++ and cross referencing that with the latest book I am reading I found some good ATL template libs that make it CONSIDERABLY easier. Some background for myself later, and hopefully something worth showing you guys.

An ACL is an Access Control List. This is basically a container holding Access Control Entries or "ACE entries". These are in a canonical order which is quite easy to understand. Anyways, you build as many ACE entries as you need and make it part of the ACL. The ACL then is applied to
a Security Descriptor and is finally hooked in with any Security Attributes. Finally... these Security Attributes can be passed to your file/pipe/registry/sockets functions with the fine grained security you created to it. Walla. Sound easy? Well in old Win32 code I have, this took about 40 lines of code EACH TIME I wanted to do that.

Well, in the new IPSec client I am writing I was able to shorten that considerably. Here are the amazing objects to make life easier:


  • CSid - Security Identifier Object
  • CDacl - Discretionary Access Control List Object
  • CSecurityDesc - SECURITY_DESCRIPTOR wrapper
  • CSecurityAttributes - SECURITY_ATTRIBUTES wrapper

So, instead of 30-40 lines of ugly Win32 code... I can get it down significantly, and make it easier to read and understand. Lets take an example. Lets say I want to allow Alice to be able to read a particular directory on the accounting server. Bob on the other hand is allowed full access as he is an administrator. Guests... they should have no access. Knowing this, it is easy to set up the proper access control on Windows environments.


#include <atlsecurity.h> // The hidden secret jem
.
.
.

// In some function that needs a discretionary ACL

try {
CSid sidAlice( "cogscompany\\alice" );
CSid sidAdmin( "BUILDTIN\\administrators" );
CSid sidGuests( "Guests" );

// Create an ACL and apply ACEs. Due to the canocial nature of the ACL,
// DENY rules must go before ACCEPT ones.
CDacl dacl;

dacl.AddDeniedAce( sidGuests, GENERIC_ALL );
dacl.AddAllowedAce( sidAlice, GENERIC_READ );
dacl.AddAllowedAce( sidAdmin, GENERIC_ALL );

// Create the SD
CSecurityDesc sd;
sd.SetDacl( dacl );
CSecurityAttributes sa( sd );

// Create the directory on the accounting server
if( CreateDirectory( "c:\\payroll", &sa ))
AfxMessageBox( "Directory created correctly" );
}
catch( CAtlException e ) {
// Some witty error here
}

.
.
.


Well, now you can easily apply discretionary access control to basically anything that will take security attributes within just a few lines of code. Of course, this will only work on volumes that support it. So Win95/98 is right out. Of course.... since MS has EOL it anyways... no big whoop.

On that note, I should get back to work. I need to crack some HEX that MS is hiding deep in the registry so I can figure out what the heck they are hiding in their ipsecData fields. They are all REG_BINARY and there is NO documentation to the struct of the raw data. *sigh*. TTYL

Posted by SilverStr at November 5, 2002 05:18 PM