UAC in MSI Notes: When General Custom Action Mitigation Fails

This is the eighteenth in a series of notes about UAC in MSI. Per the earlier caveat, these are just my notes and not an official position from the Windows Installer team. The previous entries

  1. Introduce...
    1. ...the UAC in MSI Notes series
    2. ...my view of the root problem
    3. ...the conflicting per-user definition
    4. ...it'll be just like Managed Installs
    5. ...the jagged edge to user
    6. ...my relief providing framework
  2. Architecture Insights
    1. The "Saw Tooth" Diagram
    2. Credential Prompt and Permissions
  3. Common Package Mistakes
    1. The AdminUser Mistake
    2. Modify System with InstallUISequence Custom Action
    3. Modify System with InstallExecuteSequence Custom Action Outside of Script
    4. The NoImpersonate Bit Mistake
  4. More Architectural Insights
    1. My "Four Square" Diagram
    2. Challenges for a Beautiful Custom Action
    3. O Whitepaper, Where Art Thou?
    4. Read the Friendly Manual
  5. Conversations with Customers
    1. Should I write my installer as a Standard User install? If yes, how?

This entry continues a section specifically focused on Question and Answers that often come up in the UAC in MSI dialogs.  For this topic, the question is: what do I do when the general mitigation for custom action fails?

What do I do when the general mitigation for custom action fails?

Earlier in this series, I'd written about the general mitigation for custom actions under the topics Modify System with InstallUISequence Custom Action, Modify System with InstallExecuteSequence Custom Action Outside of Script, and The NoImpersonate Bit Mistake.  These don't always work and problems are difficult to run down.  Here are the cases we've found...

When I switch my immediate custom action to deferred and noImpersonate I can no longer access the source image on a network share.  How do I adjust for this?

The fact that you can’t access the network when running as Local System (meaning of noImpersonate bit) is a security feature.  There are two tracks to work within this security feature.

The one track is to cut your dependency on accessing the source image by embedding the needed files in the binary table of the package or installing the files and then running the custom action from the installed copies of the files. 

The other track is to access the network using an immediate custom action which can then communicate to a deferred custom action via setting the CustomActionData for that action.  If the CustomActionData pipe is not big enough, then some will create a temporary directory on the disk and use that as a working dir, however care should be taken to mitigate the security implications of this approach.

When I switch my immediate custom action to deferred and noImpersonate I can no longer write the correct user locations.  How do I adjust for this?

In the case of an Over The Shoulder elevation, the fact that you have access to the admin users’ account is as expected in the design.  There are two tracks to mitigate for this problem.

One of the tracks is to eliminate the user state from your package.  Windows Installer has since inception guided package providers to write their user state during the first run of the application.  If one were following this guidance, there should be fewer (and possibly no) instances of the deferred, noImpersonate custom action writing the wrong users profile.

The other track is to use WTSQueryUserToken to try and get the identity of the person that launched the program so that you can write their profile.  This technique requires code to then use the token to impersonate a user.  This technique is not guaranteed to work in 100% of the cases.

No matter how I adjust the position or elevation level of the custom action, the custom action continues to fail. How do I adjust for this?

These instances usually are calling an underlying API that is not UAC compatible. From here you need to debug into your custom action and check the different return codes from the APIs between the XP and Vista experience. How to debug your custom action depends on the type of action.

My custom action is triggering another UAC prompt. How do I adjust for this?

This can happen with an EXE custom action which Installer Detection heuristically evaluates to bootstrapper that need elevation.  One fix for this is to add a security manifest to the EXE.  The other fix for this is to move to a non-EXE custom action such as a DLL custom action.