Setting permissions in MSI packages
When packaging legacy applications, a common issue facing the packager is how to deal with changing permissions for some items in the package. There are various reasons for why this can be necessary. This blog post address several of the reasons.
Setting permissions in MSI packages
When packaging legacy applications, a common issue facing the packager is how to deal with changing permissions for some items in the package. There are various reasons for why this can be necessary, but it is generally because an application was created before, or without regard to proper separation of user scope and machine scope data when installed on the target PC.
A very common example of this is an application that stores its configuration information in the same directory as itself. In this case, to have an MSI package that works correctly when the application is used by a user who is not an administrator on the target PC, write access will have to be granted to one or more items in the installation directory.
LockPermissions
The oldest method for setting permissions in MSI packages is the LockPermissions table. (https://docs.microsoft.com/en-us/windows/desktop/msi/lockpermissions-table)
The LockPermissions table supports setting permissions for files, registry keys, and directories. The permissions are set using a Win32 bitflag value for a specified user name and domain name.
Here is an example of a row in the LockPermissions table:
LockObject | Table | Domain | User | Permission |
HB001.wmf | File | Everyone | 268435456 |
In this case, the value of the Permission column corresponds to setting GENERIC_ALL as the permission. Detailed information on the possible values, which vary between registry keys and files can be found here: https://docs.microsoft.com/en-us/windows/desktop/secauthz/access-rights-and-access-masks
LockPermissions is the only built-in method in MSI packages to set permissions on operating systems older than Windows 7, and it has several issues:
- Permissions set overwrite existing permissions, so it is important to not only grant the target user permissions but also to the administrators’ group.
- The only group names that are guaranteed to be available are “Everyone” and “Administrators”. All other group names, even for built-in groups, are not guaranteed to work if the localization of the target operating system isn’t English. This makes it impossible to set permissions across different Windows locales.
MsiLockPermissionsEx
The other method for setting permissions available, starting with Windows Installer 5.0 on Windows 7, is the MsiLockPermissionsEx table. This allows for much finer control over the permissions set, as well as supports setting permissions for services created by the installation package.
Instead of the bitflags used by the LockPermissions table, a Security Descriptor String (SDDL) is used to specify the permissions to set for the target object. Instead of creating an entry per user or group and setting the permissions for that particular target, the SDDL string contains both the list of users or groups to apply the permissions to, and the permissions to apply.
Detailed information on the SDDL format can be found here: https://docs.microsoft.com/en-us/windows/desktop/SecAuthZ/security-descriptor-string-format
Here is an example of an entry in the MsiLockPermissionsEx table:
|
Condition | |||||||||||||
SDDL strings are unfortunately quite complicated to create manually, and the usual way to implement them using the MsiLockPermissionsEx table is to generate the SDDL from an existing item on the target PC, or to use a standard SDDL string.
Smart Package Studio uses the following string as the default SDDL for giving non-administrative users write access:
D:AI(A;OICIID;SDFWFRFXKRKWKX;;;AU)(A;OICIID;GA;;;SY)(A;OICIID;GA;;;BA)
This sets the following permissions:
- Authenticated users: Generic read/write (but not change permissions etc.)
- LocalSystem: Full access
- Built-in administrators: Full access
Unlike LockPermissions, the MsiLockPermissionsEx table has no issues handling built-in groups on localized versions of Windows.
Conclusion
In summary, while it can be more complicated to create the necessary permission strings, the MsiLockPermissionsEx table supports much more finely tunable permissions and should be used wherever possible. However, if you do need to create a package that works on operating systems older than Windows 7, and you want to stick with built-in MSI functionality then you will need to use the LockPermissions table instead.
Download your free 10-day trial today
- Downloading and evaluating Smart Package Studio is quick and easy
- Includes a short introductory guide that suggests smart features to try
- Access the full functionality of Smart Package Studio during the trial