I received a request to talk about a particular shim. And yes, I received that request over a month ago, so ... sorry about that. Nonetheless, I've managed to scratch out a little niche of time to discuss the shim:

OpenDirectoryAcl

Yep, this does exactly what you would expect it does, modifying the ACL on a directory. I had not documented this shim yet because in a typical enterprise environment, it typically is not the best approach to resolving application compatibility issues.

But, that does not mean that it is never useful, so rather than just ignoring it, I will simply go through the steps I would normally go through to eliminate the need for this shim, and allow my eminently gifted readers to re-use or modify the logic as it suits them.

Can you redirect the file write?

If I can redirect the file write to a less privileged location, then I prefer to do that. By doing so, I don't have to loosen the security profile of the system. Even if I need to share the file, I generally prefer to take writes out of Program Files and instead set something up (ACL'd appropriately) in ProgramData, so I will sometimes redirect even if I am changing directory or file permissions.

Should the application run elevated?

If the purpose of the application is to modify protected resources, it may be a better choice to require elevation rather than to remove the protection on the resources.

Can I modify the ACLs when I repackage?

If I have decided that I need to loosen the ACL. First, I re-read Changing access control on folders vs. files and think again - am I really sure I need to modify the ACL?

Let's say that I have some compelling reason to change permissions on the file or directory. Since most enterprise software is deployed using management software, such as System Center Configuration Manager, rather than simply waiting for user's to self-launch an executable file, then I would approach that by repackaging or transforming the installer (frequently an MSI) rather than shimming a setup.exe. The LockPermissions table in an MSI allows me to set ACLs. (If you're writing the installer using the fabulous WIX tool, then you can use the Permission Element.)

There are simply almost no situations where I find users self-installing setup.exe files. However, in the consumer space, this is extremely common, which is why this shim works well in that scenario and we see this bubbling up as the 11th most commonly used shim in the system shim database.

How OpenDirectoryAcl works

Why do you need to target the setup? Because that's when we apply the ACLs. Specifically, we intercept calls to the CreateDirectory APIs, and if you create a directory that matches the command line, then we put it in the queue to modify that ACL. Then, when we either call the ExitWindowsEx API or exit the process, we apply the ACL changes that were matched. That means you are modifying ACLs on directories when you create them, so you have to target the setup.

So, I think you can see now why I have never once had to use this with an enterprise customer. But just because I haven't doesn't mean you won't.

Configuring OpenDirectoryAcl

If you've gotten this far, well, let's configure this shim. The command line syntax is as such:

-<options> <dir-or-file>|<sddl> [ -<options> <dir-or-file>|<sddl> ...]

The options you can specify are:

  • r - recursively match files
  • m - match the directory part to expand to the installation directory
  • M - match the directory / file parts to expand to the installation directory
  • p - ACL the parent directory as well
  • P - ACL the parent directory only
  • f - create an empty target file if it does not exist (do not combine with "d")
  • d - create an empty target directory if it does not exist (do not combine with "f")

You then specify the directory or file you want to modify the ACL for. (Yes, the name of the shim is deceiving, because you can specify a file rather than a directory.) If the file name has spaces, then make sure you enclose the file name in quotes, as spaces are a delimiter for the command line. Also, if you use environment variables.

Finally, you don't need to specify SDDL. By default, you'll receive D:(A;OICI;FA;;;BU)

However, you can specify SDDL if you want. after the directory or file path, simply include a pipe character ( | ) and then include the SDDL you'd like to add.

Ask me about this, or other shims, at TechEd 2008

I have two sessions on Shims set up for TechEd 2008, and I invite you to come and chat with me there. Also, I am in the running to be part of a Windows Vista Bloggers' Panel hosted by Mark Russinovich at TechEd IT Pro week. Come and barrage the panel with your most challenging questions - it should be a great time for all. There is still time to register - head on over to http://www.microsoft.com/events/teched2008/itpro/registration/regprocess.mspx to register.