This week I came across a question that I had not had to ask myself in a while. What solution should we use for setting NTFS permissions on Windows 7. Back around 2009 I was tasked with investigating different solutions for setting permissions on Windows 7 within an MSI Package.
If migrating from Windows XP to Windows 7, it’s likely this is a question you will also have to ask yourself. Some solutions have been deprecated in the post XP world such as Cacls.exe and XCacls.exe and so, if you used these solutions for setting NTFS Permissions previously, well, you should really start looking at alternatives.
With the advent of Windows Installer 5.0 came a new solution, this solution was an improvement on the LockPermissions table in a Windows Installer file (.MSI) or at least that was the idea. Unfortunately MsiLockPermissionsEx is not really the well rounded solution you would hope for. A major stumbling block on every single migration project that I have worked on, is the fact that for some time at least while migrating, the enterprise wanted to support dual platforms. i.e. Applications that install and work consistently on both Windows XP and Windows 7. It is for this reason that most chose not to use MsiLockPermissionsEx as this table can only be used in conjunction with Windows Installer 5.0 and later which is not supported on Windows XP. Furthermore, you may think to yourself well it’s an MSI so maybe I can set permissions within LockPermissions for XP and MsiLockPermissionsEx for Windows 7 and use logic so Windows Installer will know to use the correct method for the targetted OS. Alas, that’s no deal! You cannot have both tables in your MSI, if you use MsiLockPermissions you need to remove the LockPermissions table as they will conflict with one another on install. LockPermissions itself can still be used in the newer Windows Installer and the older versions and is a somewhat desirable solution as it’s set directly within the MSI tables.
Similarly to the above issue regards dual platforms. iCacls has been introduced in the post XP world 🙂 . This is the new and improved version of Cacls.exe and is pretty dang cool. It allows you to get a lot more granular with how you set permissions, you can set integrity levels, in which something with an integrity level of Low for example, would not be have permissions to action something that has a High integrity setting. iCacls also appears to append permissions from what I have seen. It’s a great option but may not be an option for many out there due to the effort and complexity required, I will explain this in my summary below.
My favorite solution that I have worked with thus far in my short IT career has been SetACL. I’m not sure of the history of this tool but I was under the impression that at one time this became a licensed tool which ended up deterring administrators from using it as a solution. From what I can see online, it is now a free tool. This is a third party tool, it is not part of Microsoft or part of the Windows OS. This may not be a major consideration for you, depending on your environment but you should take into consideration the level of support you could avail of and also the variable for change. If the solution is bought tomorrow by a company, could this lead to you needing to then explore other avenues. It may not even be a huge concern, especially in 2013 when Windows 7 and even the Windows XP Secure Locked down environment white paper has been out in the industry for years. Software Vendors have started to develop a little more cleverly around the OS, so setting NTFS permissions should be an exceptional process, not the norm at all.
SecEdit.exe is another solution. This one is part of both Windows XP and Windows 7 which makes it a pretty attractive option when migrating. It can also set permissions on Registry, files and folders unlike Cacls and XCacls. Personally I find this solution a little more complicated than SetAcl from a scripting perspective but it does seem to check all the boxes! It even outputs a text file with permissions being set which could then be used by a security team to query. Below you can find a table which I created years ago and updated with some side notes. If anybody has any other solutions they like, please feel free to give feedback, I’m open to suggestions for new solutions!
|Cacls.exe||Folder/File||Deprecated component, may be buggy. Should not be used on Windows 7.|
|xCacls.exe||Folder/File||Deprecated component, may be buggy. Should not be used on Windows 7.|
|iCacls.exe||Folder/File||Will require to be set via a script e.g. custom action. Is part of the Windows 7 OS. Offers extra granularity.|
|Regini.exe||Registry||Cannot apply explicit Deny permissions|
|SetACL.exe||Folder/File /Registry||This is not part of the OS and is a third party solution.|
|LockPermissions||Folder/File/Registry||Overwrites existing permissions and all inherited permissions, does not append. Due to this, solution requires careful planning.|
|MsiLockPermissionsEx||Folder/File /Registry||Overwrites existing permissions but will not overwrite existing inherited permissions. Can only set permissions on components which are part of the package. Will only work on Windows 7 as it requires Windows Installer 5.0 or later|
|SecEdit.exe||Folder/File /Registry||Will require custom action template and standards to be applied.|
All solutions have their potential pitfalls. In my opinion, it’s a case of what works best for your environment. If you are not supporting a dual environment then perhaps MsiLockPermissionsEx is a good solution for you. It would be my preference, simply due to the fact it is called directly within the MSI which means Windows Installer performs the error handling for you and it’s standardized in a database table format and easy to query. If you are supporting a dual environment and can identify exactly what applications require permissions to be set, then LockPermissions might be right for you, just ensure you map out the permissions required and account for any applications which may later require to set permissions on the same directory that may have already had it’s permissions changed as these will be overwritten. Like I said earlier, from a third party app perspective at least, permissions required during run time should be the exception and not the rule so it is very much an environment driven decision as to what can work for you. If you are a solutions architect for your company, it is well worth the time and effort to look at SetAcl as it is a very well rounded solution but it is third party so it can lead to some issues, again all depending on your environment! Hell you could even go ahead and use Cacls.exe and Regini.exe for setting your File, Folder and Registry permissions if you’d like but you need to accept the risks of using a deprecated component. Personally, that is not a risk that I am willing to accept. iCacls is excellent, One path you could go down, if willing to put in the work, would be to set permissions via a Custom Action using iCacls and condition this to run on Windows 7 and then use an alternative solution (which you may already be doing anyways) such as Cacls and condition that custom action to only run Windows XP. This is why earlier in this post, I suggested it was a little bit complicated…
Of course another consideration, may be to just stop setting permissions via the MSI or scripting altogether but let’s not get into that right now!
I hope this helps somebody out there, also if anybody has other solutions or feedback, please provide it!