Sam’s corner


Programming, music, existentialism and various sources of pain

Microsoft’s Security API baffles me!

I’ve been messing around with permissions on Windows lately. Not so pretty. Almost chocking at times.
It’s a long story though, and to shorten it just a little, I wasn’t entirely happy with the way the utility xcacls works. Its’ flaws made me curious enough to lean over the edge and dig deep into the horror known to man as The Windows API.

xcacls is a utility made by Microsoft to manipulate permissions from a command prompt, originally released as part of the Resource Kit for Windows 2000. Although the utility was released on Windows 2000, little has changed in the NTFS specification, as far as file and directory permissions go – xcacls still does its’ magic on XP and Vista as well.
Permissions on Windows are controlled in an ACL, an access control list, carried in every file and directory. Every ACL has a set of ACEs (access control entry), which is basically a compound of a user or group identifier, a deny or allow rule, and a set of flags that further describe how the ACE is to be enforced and inherited to child objects (a file is to its’ containing folder as a child is to its’ parent).
This could be a pretty clean approach to access controlled content.

A summary of what was going on is in order, so here it is. I was building a VBScript at work, to solve an annoyance of mine. The computers we’re hosting are locked down systems, clients based upon Windows XP professional. On the laptops we’re occasionally hosting, the locked down policies on the system makes working on it a little quirky while not being docked to a stationary area, where one can access the network storage and other network resources. Because users may choose to do work on the laptop several weeks unconnected, they need a temporary yet somewhat protected area to put their files in.
So basically, we create a folder in the root folder of the system drive, then add to the user group “Everyone”, the permissions to write and alter files and folders in this particular folder, but also deny them the right to delete the folder itself.
As a final convenience, we place a shortcut to it on the desktop of all users. Simple enough to do in the GUI (graphical user interface). Even the tricky part, here being to check the right checkboxes in the permissions dialog. But, as it turns out, doing this programmatically is a flagrant nightmare.
So there are utilities to make this as easy as pie. Mmmm, pie!

Apparently Microsoft didn’t read the recipe on this one, because xcacls fails. It runs fine and all, and the permissions seem to get set just fine… unless of course you check with the GUI, where you get abused by this fancy error message: “The permissions on [folder name] are incorrectly ordered, which may cause some entries to be ineffective. Press OK to continue and sort the permissions correctly, or Cancel to reset the permissions*. This guy describes the problem so well, and I qoute: “Apparently using the program in a way that is concistent with the instructions is not supported”.
At this point, when you come down to it, there are two ways to respond to this. There’s A, nod in silent distaste, reorder the entries and be happy with the fact that although you still have to manually adjust things, you’ve just automated 80% of the previously manual work. And there’s B, refuse to accept anything less than perfection, and especially refuse to accept the fact that you can’t properly adjust settings programmatically, which can otherwise be set in a GUI by the click of a mouse button.
I’m a B kind of person.

When I arrived home that evening, I searched around for clues on what had happened. There weren’t many. Especially since we’re using a multilingual version of Windows, which means all error messages are obscured at best. So I turned to the MSDN library, the main resource for all programmers programming on Windows, to read up on ACLs and access control on Windows. At this point I wanted simply to know why this error message was showing. Turns out ACLs are pretty complex, as described earlier. Didn’t really do it for me in the documentation though.

So I blew the dust away from my compiler, run Microsoft Visual Studio 2008, and took my usual approach to cocky, logical numb spots refusing to comply, I dissolved the matter into its’ building components.
It was now personal, and curiosity didn’t kill this cat!

I dug into winnt.h to find the appropriate definitions of ACLs, ACEs and headers respectively. I messed about with API calls, such as GetNamedSecurityInfo, GetSecurityDescriptorDacl, GetAclInformation and ultimately GetAce.

While reading the documentation of this last one, GetAce, I browsed its’ sibling nodes on the hierarchical tree of related topics. I came across something called “Order of ACEs in a DACL”. The “D” in DACL is discretionary. It’s complicated, I’ll address that some other time. “Order” being the right password, I checked it out.

The access control API lets you add or delete ACEs. It does not provide you with a method to insert an ACE. Rules in the ACEs are handled in the order they are defined, not by the function they have on the object it protects. If you need to insert an ACE, you are responsible for putting it in the right order in the list, or you can ultimately render the whole access control list useless, either blocking all access or allowing all access, depending on what the ACE does. If you can’t just append the ACE to the list, but indeed have to put it somewhere in the middle of all the entries, you have to create a new ACL and basically create a new ACL, GetAce the old entries and AddAce them to the new ACL, inserting your own ACE at the appropriate place in the list, then SetEntriesInAcl to the object. Of course, you have to make sure there are enough memory reserved to hold your new ACL, which of course is also your responsibility.

Suddenly it struck me. xcacls have inherited the same erroneous logic as the APIs it’s using. It just goes ahead and AddAce whatever you tell it to do, which means in my case more specific ACEs are placed below inherited ACEs, and so of course the order is wrong.

This new knowledge is infuriating. Not that a utility from the 20th century isn’t working, but the fact that the order of ACEs in an ACL this is still a pickle! This means basically that third-party utilities and/or applications addressing these APIs for whatever the reason, are responsible for placing the ACEs in a certain order, or parts of the operating system may not function properly. Are file permissions not an important enough issue? And hey, google confirms third-party applications (as well as Microsoft’s xcacls) are having trouble with the APIs.

To you and me, on our desktops at home, this may or may not qualify as eyebrow elevating material. But to a bank, for instance, incorrect file permissions may jeopardize your personal records, information private and delicate to you.

And worse yet, ACLs are not used only for protecting files in a system. ACLs have evolved to protect other, more delicate portions of the system. Keys in the registry, for instance. Certain tasks between processes/applications, inter-process communication. Permissions to the Active Directory, the main database in a domain of Windows servers. If the people coding malicious software find themselves hesitant on where to begin looking for exploitable features, I’d recommend a dart board.

The routine to check if ACEs are in the correct order is clearly there, or the GUI would never have complained in the first place. How about moving this check to the point where your are actually setting the ACEs, instead of until later, when the potential damage is already done?

Having said that, I’ve found another (third-party) utility called fileacl, that looks promising. Microsoft sort of recommends it. Check it out at!

EDIT: As seems to be almost always the case, there is a superior open source project on Sourceforge called SetACL. Blindfolded and hand-cuffed, it would still kick the sorry butt of xcacls, cacls, icacls (Vista) and probably fileacl as well, from here to orbit. In seconds.

*) On a side note, clicking on Cancel in this dialog, revert permissions to default settings – full access to everyone.


Filed under: Programming, Security, , , , , ,