UAC in MSI Notes: The NoImpersonate Bit Mistake


This is the twelfth 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
This entry will talk about the forth common mistake we found packages making with UAC in MSI: omitting the NoImpersonate bit for a custom action modifying the system in the InstallExecuteSequence.

Server Custom Actions Modifying the System


Given the pre-Vista operating systems did not enforce the architectural intent to that modifying the system requires the NoImpersonate bit set on a custom action in the InstallExecuteSequence, application compatibility testing found a number of packages that had custom actions failing. Here’s the “saw tooth” diagram I draw on my whiteboard to illustrate this mistake.


 


With the permissions changes in the context of UAC, the server-side custom actions inside are script are executed as Standard User by default causes the Application Compatibility problems to show up. The green circle is where this mistake is generally made. Unlike the previous common custom action mistakes, mitigating this problem does not require moving the custom action. This mistake is generally mitigated by the package author flipping the NoImpersonate bit on the custom action.


Conversations Around this Mistake


Generally folks make this mistake due to lack of awareness as they followed that they needed to flip the NoImpersonate bit


If the custom action is logging its errors, the trick is to look for an error code that translates to Access Denied.

Comments (15)

  1. Windows Vista introduces a security concept called User Account Control (UAC) which has multiple impacts

  2. Visual Studio 2005 works for the most part on Windows Vista, but there are some known issues being addressed…

  3. RandomGuy says:

    Hmm… that works for everything except for custom actions which run after Installfinalize… Because they are not deferred custom actions and hence the noimpersonate bit cannot be set.

  4. This is the nineteenth in a series of notes about UAC in MSI. Per the earlier caveat, these are…

  5. Lack of awareness is not the only reason for this mistake. Visual Studio is another. If you build your setups using Setup & Deployment Projects in VS your custom actions are scheduled as deferred but the NoImpersonate flag isn’t set and as far as I know there’s no way in VS to set this flag (at least not in VS 2003, I haven’t checked in VS 2005).

  6. Visual Studio 2005 works for the most part on Windows Vista, but there are some known issues being addressed

  7. Ajay Ladsaria says:

    Another thing to consider is custom actions that need both user impersonation and elevation.

    The only way to do it on Vista is to use an Immediate custom action and always run with a bootstrapper that has an administrator token.  At least this is what I have seen, so I normally advise to try to not have this requirement in the first place.

  8. Jeff West says:

    I’ve noticed that if I set MsiInstallDrivers to "Impersonate=’no’" it seems to occur in the admin context and work just fine for a non-admin user in Vista.  However, if I set MsiUninstallDrivers to "Impersonate=’no’" I still seem to get an ACCESS DENIED error when a non-admin user tries to uninstall in Vista (and, oddly enough, it seems to work fine for admin users…).

    I really don’t see the distinction since either one should have to be elevated, but I was just wondering if perhaps the root cause of the problem is that MsiInstallDrivers and MsiUninstallDrivers live in different places in the sawtooth diagram?