MSI Error "The computer must be trusted for delegation" caused by KB2918614
Asked Answered
L

9

11

We have an MSI based installer that recently stopped working on a Windows 2008 R2 environment. The installer is copied over to the target computer using the \\servername\c$\ admin UNC shares and then is remotely executed using the create method on the WMI Win32_Process class. The remote execution now fails with the following error message in the Event Viewer:

The description for Event ID 10837 from source MsiInstaller cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

Product: OUR PRODUCT NAME -- The requested operation cannot be completed. The computer must be trusted for delegation and the current user account must be configured to allow delegation.

After searching it looks like this is caused by a recently released security patch for Windows Installer. When I uninstall KB2918614 the installer starts working again, and if I reinstall KB2918614 the MSI stops working again.

The error message indicates that to solve the issue we would have to have a Domain Administrator edit the target computer using Active Directory Users and Computers to allow delegation, however the MSI is NOT using any remote resources, so I don't see why this is required. The same MSI and remote execution process works fine on Windows Server 2012, so I wonder if this is an issue with the patch for 2008 R2.

Are there any other ways to get around this error message?

UPDATE: This doesnt appear to be an issue with the WMI remote execution, as it also occurs when we try to install the MSI remotely using Powershell, WinRM, and the Invoke-Commmand -ComputerName TargetComputer ... cmdlet. There is a change in the way the Windows Installer on 2008 R2 works after installing KB2918614 that now prevents the custom action from completing it's task.

Lease answered 29/8, 2014 at 15:50 Comment(6)
I would try allowing for delegation, at least as an experiment. I suspect the issue is not about the MSI accessing remote resources but something to do with impersonation (or not) in the various parts of an install. A pure guess, but the install moves between a user account and the system account during an install and maybe in a domain environment something happens that requires delegation to pass to or from the domain controller, something like that anyway.Likeness
Well, you are in fact using a remote resource, the file came from another machine. Windows knows this and stores that info in an alternate NTFS data stream. Ask questions about this at superuser.comHeyer
We designed the MSI and hope to find a way to rewrite it to get around this issue for our customers. I checked to see if the file was blocked, but it did not appear to have the Security: "This file came from another computer" or Unblock option in the file properties.Lease
We were also encountering issues with remotely executing an MSI after this MS Update has been applied. I spoke with a Microsoft representative today who said it was a known issue being worked on. He told me they are hoping to have an additional patch that fixes this somewhere in the time range of mid October to beginning of November.Ysabel
Any progress on this? I wonder if we're seeing a similar issue on 2012 R2 servers.Urbanity
I followed up with Microsoft today, and they told me the fix found here should resolve the issue: support2.microsoft.com/kb/3000988. However, I see that in an answer below that is down-voted. Has anyone applied this patch and had it not work for them?Ysabel
C
5

From what I understand,

With KB2918614, MS have apparently tried to fix something in the Windows Installer Service.

New stuff:

  • They are creating a file by name "SourceHash{PRODUCT-GUID}" under %windir%\Windows\Installer. This is done for every product installed on the machine(with KB2918614 already installed).
  • SECREPAIR- They are computing 'Stored Hash Value' and 'Current Hash' for a given MSI.

Error:

  1. And, in this comparison, for some reason, these mismatch! (Found these in the MSI verbose logs).

  2. Once this fails, it looks for Machine policy value 'AlwaysInstallElevated' User policy value 'AlwaysInstallElevated'

  3. Now, if you are running a silent install "qn", this error is thrown: MSI_LUA: Elevation prompt disabled for silent installs.

  4. Removing silent install cmdline option for msiexec- ex., "qr" or "qb", will throw a UAC prompt. (which most likely will not be the expected behavior).

Additional Info:

My MSI is ivkoded through a bootstrapper exe. But, it doesn't really matter. Even a manual call to msiexec through cmd line behaves the same way.

Any inputs/solutions, anyone?

Coombs answered 11/9, 2014 at 6:23 Comment(0)
C
3

This is the word from the MS Enterprise Support folks.

Apparently they are not aware of any fix to this. At-least as of now. All they are saying that this KB is to fix a security loophole. I don't understand what kind of a security fix this is- one that allows a Fresh Install without an UAC prompt, but throws an UAC prompt only for the Upgrade.

Workaround 1: Distributing hash.

Capture the Hash file* in one machine and distribute them to other machines. Hash files are created under “%windir%\installer” directory. The naming convention is as follows: “SourceHash * This file is created only when a Product is installed with KB2918614 installed on the machine.This directory is hidden. Open cmd prompt using 'run as administrator'. Traverse to this path and open the folder using "explorer ." command. [I couldn't solve the issue using this approach- may be because accessing this directory requires administrator privileges which the Windows Installer itself might not have]

Workaround 2: Whitelisting.

Only if you trust the application that it is always digitally signed and doesn't contain anything malicious(even in the future).

Step 1: Enable Whitelisting

Under Key “HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer”, create a DWORD: “SecureRepairPolicy” and set its Value to 2.

Step 2: Add the application to the whitelist

Create a new key “SecureRepairWhitelist” under "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer” and create StringValues with the product codes(Including flower brackets {}) of the product.

... Sadly though, both these workarounds need admin privileges!

Coombs answered 9/10, 2014 at 10:51 Comment(3)
Thank you Mr. DebugBreak! This was really making me a little heated. Apparently the patch is getting revised anyway so we (hopefully) don't have to screw with this stuff.Occupy
Welcome. Yeah, it's pretty bad for developers. End-users can somehow work their way around. One suggestion: if feasible: when an upgrade scenario is encountered, uninstall the product and do a fresh install.Coombs
I tried distributing the hash, but the MSI was deleting it and attempting to recreate it the failure was happening during the recreation. I also could not get whitelisting to work. The Installer key was missing, then I tried using psexec -s and that worked. The whitelisting is listed as a workaround on msdn: support.microsoft.com/en-us/kb/2918614Ensample
S
3

Here is my automatic way of utilizing the registry whitelist work around mentioned on Microsoft's site.

Now, before I run my install command against a remote machine, I look at the MSI and extract the product code with Get-ProductCodeFromMSI, and then use Add-GuidToWhitelist to add each GUID to the list on that computer. Here's an example:

$guids = Get-ChildItem -Path D:\somefolder -filter "*.msi" -recurse | % {Get-ProductCodefromMSI $_.FullName}
Add-GUIDtoWhiteList -computername "SomeServer" -GUIDs $guids

Before doing that, each machine can be tested and repaired for the workaround using Test-SecureRepairPolicy and Repair-SecureRepairPolicy, respectively.

Get-ProductCodeFromMSI will require the DLL referenced to be placed somewhere and unblocked - this DLL can be retrieved from the Wix toolset.

Code for the functions I reference is here:

Function Test-SecureRepairPolicy{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName
    )

    Process {
        foreach ($Computer in $ComputerName)
        {
            #Open Remote Base
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            #Get Windows key
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows")
            $subkeynames = $subkey.GetSubKeyNames()
            if (($subkeynames | Measure-Object).Count -lt 1){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not open base key"
                    ComputerName = $Computer
                }
            }
            if ($subkeynames -notcontains "Installer"){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not locate installer subkey"
                }
            }
            $subkey.Close();$subkey = $null
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer")
            $subkeynames = $subkey.GetSubKeyNames()
            if ($subkeynames -notcontains "SecureRepairWhitelist"){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not locate repairlist subkey"
                    ComputerName = $Computer
                }
            }
            $repairvalue = $subkey.GetValue("SecureRepairPolicy")
            if ($repairvalue -ne 2){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "SecureRepairPolicy is incorrect"
                    ComputerName = $Computer
                }
            }
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
            return New-Object -type PSObject -Property @{
                Success = $True
                Note = "SecureRepairPolicy structure is in place"
                ComputerName = $Computer
            } 
        }
    }
}

Function Repair-SecureRepairPolicy{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName

    )
    Begin{
        Function Add-RemoteRegistryKey($Computer,$Parent,$Name){
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey($Parent, $true)
            $subkey.CreateSubKey($Name)
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
        Function Add-InstallerKey($Computer){
           Add-RemoteRegistryKey $Computer "SOFTWARE\Policies\Microsoft\Windows" "Installer" 
        }
        Function Add-RepairPolicy($Computer){
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer", $true)
            $subkey.SetValue("SecureRepairPolicy",2, "DWORD")
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
        Function Add-WhitelistKey($Computer){
            Add-RemoteRegistryKey $Computer "SOFTWARE\Policies\Microsoft\Windows\Installer" "SecureRepairWhitelist"
        }

    }
    Process {
        foreach ($Computer in $ComputerName)
        {
            $audit = Test-SecureRepairPolicy $computer
            if ($audit.Success){
                Write-Output "Repair whitelist keys setup.  No repair being performed."
            }
            else{
                Write-Output "Repair whitelist keys not setup.  Attempting to resolve"
                 if ($audit.Note -match "Can not open base key"){
                    Write-Error "Unable to open computer's registry key"
                    return
                 }
                 if ($audit.Note -match "Can not locate installer subkey"){
                    Add-Installerkey $Computer
                    Add-RepairPolicy $Computer
                    Add-WhitelistKey $Computer
                 }
                 if ($audit.Note -match "Can not locate repairlist subkey"){
                    Add-RepairPolicy $Computer
                    Add-WhitelistKey $Computer
                 }
                 if ($audit.Note -match "Can not locate repairlist subkey"){
                    Add-RepairPolicy $Computer
                 }
                 Write-Output "Showing new audit"
                 Test-SecureRepairPolicy $computer
            }
        }
    }
}

Function Add-GUIDtoWhiteList{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName,
        [Parameter(mandatory=$true)][string[]]
        # Specifies the GUID(s) to add.
        $GUIDs
    )

    Process {
        foreach ($Computer in $ComputerName)
        {
            #Open Remote Base
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer\SecureRepairWhitelist", $true)
            foreach($GUID in $GUIDs){
                $subkey.SetValue($GUID,"", "String")
            }
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
    }
}

Function Get-ProductCodefromMSI ($msi){
    [Reflection.Assembly]::LoadFrom("D:\scripts\lib\Microsoft.Deployment.WindowsInstaller.dll") | out-null
    (New-Object -TypeName Microsoft.Deployment.WindowsInstaller.Database -ArgumentList $msi).ExecuteQuery("SELECT Value FROM Property WHERE Property = 'ProductCode'")
}
Standing answered 12/11, 2014 at 17:9 Comment(0)
V
1

I also encounter the issue. I got powershell script to install MSI on remote machines (using Invoke-Command cmdlet and provide the credential along with the script), but suddenly it failed to install MSI which I suppose also from this security patch.
After run the MSI installation file manually on target machine using the domain account (from remote desktop), suddenly the powershell script can run the MSI installation using domain account, but still failed to install if I used target machine local admin account.
I prefer to add this as a comment, but I don't have enough rep to do that. If the other has any solution or explanation for this I'd love to know that too. Thanks.

Vittorio answered 3/9, 2014 at 3:47 Comment(0)
L
1

This is to be to do with the SourceHash{product-code} files under \windows\installer directory. This file can be opened with Orca you can read the contents. It contains a file name, hash algorithm specifier, and hash. On Windows 2k3 this hash is a base64ed sha256 hash with the last byte changed.

If you rename the SourceHash file for your product out of the way, I found the upgrade worked and after that a new SourceHash file is generated. You can then diff the two source hash files. In the case I am investigating, when you diff the two files only the hash listed for the original msi is different. After a successful upgrade the hash of the new msi listed in the source hash file will match that of installation source. The broken sourcehash file was obviously generated from a modified/different source MSI, although I have as yet been unable to identify which.

Lumpish answered 11/9, 2014 at 9:23 Comment(0)
R
1

I have the same problem. MSIs failed to be installed with Invoke-Command PoSH. I've found that if I install any MSI on the server locally under the same account which is used for Invoke-Command the issue is fixed and Invoke-Command starts to work as usual.

Ravioli answered 9/10, 2014 at 11:14 Comment(0)
N
0

Response from Microsoft: This security update resolves a privately disclosed vulnerability in Microsoft Windows. The vulnerability could allow elevation of privilege if an attacker runs a specially crafted application that attempts to repair a previously-installed application. An attacker must have valid logon credentials and be able to log on locally to exploit this vulnerability.

Workaround if you have problems with repairing application:

  1. Uninstall the application and reinstall it with the security update installed. (sourcehash file generated with security update)

  2. Manually copy the sourcehash file to c:\windows\installer folder. As the sourcehash file is generated based on the application files, the sourcehash file generated on computer A can be used on computer B.

  3. http://happysccm.com/kb2918614-uac-gate/ - commands to uninstall it.

Nich answered 9/9, 2014 at 10:57 Comment(1)
Please include the required commands in the answer itself. Linking back for additional information is allowed but frowned upon when not disclosing a direct link to the other party. But make sure that each answer itself is fully self contained.Detta
P
0

I had this as well on different servers. After a few hours of digging I discovered that they could not reach the domain controllers. Check your DNS settings and ensure they can reach the AD. After fixing this this error disappeared.

Pericynthion answered 25/6, 2015 at 21:31 Comment(0)
E
0

If you are executing through psexec, just adding the -s argument also resolves the error. Then it is ran as the remote system user and UAC is not required.

Ensample answered 30/8, 2016 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.