Packer: PowerShell failure with Hyper-V builder

Created on 3 Aug 2017  路  26Comments  路  Source: hashicorp/packer

BUG-ish:

I'm having an issue trying to create a Hyper-V image for Ubuntu 16.04 LTS. This seemed like a pretty simple use case (as seen in the template) and there a ton of examples. However, I'm getting an odd security error from PowerShell.

  • Packer Version: 1.0.3
  • Host platform: Windows 10 Pro
  • Debug output: gist
  • Template: gist

PowerShell execution failure:

hyperv-iso: Failed creating Hyper-V driver: PowerShell error: Exception calling "IsInRole" with "1" argument(s): "The trust relationship between the primary domain and the trusted domain failed.

PowerShell script contents:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-578')

So it looks like it's trying to see if the current user is in the Hyper V Administrators group. Is there a way to bypass this check? For some reason on my development machine it fails.

bug buildehyperv

Most helpful comment

Did some research. This may be possible:

$sid = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-578')
$group = $sid.Translate([System.Security.Principal.NTAccount])
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($group.Value)

Using PowerShell to Resolve SIDs to Friendly Names

All 26 comments

I hope you are running this locally and not via a remote shell. You may encounter double hop problem otherwise. Otherwise check below.

I think the machine you are running Packer on my not be correctly configured to the AD domain you are connected to.

If the error occurs and the host machine is not connected to AD then I would assume the user has some permission problem.

Yes, running locally on my domain machine. If I change the command to:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('DOMAIN_TRUSTED\username')

I get a 'True' response. If I try the parent domain:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('PARENT_DOMAIN\username')

It also returns true.

I think it is an artifact of my company's AD structure.

I pulled source. In file builder/hyperv/common/driver_ps_4.go I commented out lines 67-69. I am now able to build hyper-v images!

It would be nice if there was a switch to ignore verification checks. If you're able to provide a suggestion on how to implement this I can try to put together a pull request.

@mikejr83 I believe that removing the check it would result in errors in the powershell for a few users. By making this requirement explicit, it makes it obvious where the problem is.

Perhaps there is another way we can do the check? Would you try:

#Requires -RunAsAdministrator

You might want check the hyperv administrators group exists locally, otherwise https://blogs.msdn.microsoft.com/virtual_pc_guy/2010/09/28/creating-a-hyper-v-administrators-local-group-through-powershell/

Hey @taliesins,

I wasn't suggesting completely removing the check but instead adding a command line switch for disabling the check or having it in the JSON configuration. My thought was that under normal, default conditions things would work as they currently do, however if a user did something like:

--disable-role-check

it would skip that step.

I'm certainly not a PowerShell master and I have no experience with Go, but if there was a way to error handle that check it would also work. I may try taking a stab at that tomorrow.

In regards to the HyperV group, it was automatically created for me when I enabled the Hyper-V Windows feature. I have been using Docker for Windows with Hyper V which has installed its Linux guest. Until I found this issue I hadn't messed with the group. I did try adding myself (both in the child and parent domains) to no avail. Plain checking it makes it crash.

Hi,
I'm getting the exact same problem after upgrading to 1.0.3. Same template files, same execution conditions. I'm on windows 10 with local Hyper-V. Checked if my Hyper-V could manually create VM and it can.

Did something change from previous 1.0.0 version?

-------After some more digging------------------

I'm looking into the code driver_ps_4.g around line 302 that has the intention to execute

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-578')

The S-1-5-32-578 maps to a builtin group with name BUILTIN\Hyper-V Administrators as mentioned in Well-known security identifiers in Windows operating systems

SID: S-1-5-32-578
Name: BUILTIN\Hyper-V Administrators
Description: A Builtin Local group. Members of this group have complete and unrestricted access to all features of Hyper-V.

I tracked the error to this change 7bacc22825d280de4ef698dd957d00b0bd5094f0 which checks if my user is a member of the BUILTIN\Hyper-V Administrators group based on it's SSID and not by name. On my system this approach throws error

# Throws error
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-578')

# Returns false
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Hyper-V Administrators')

output

Exception calling "IsInRole" with "1" argument(s): "The trust relationship between the primary domain and the trusted domain failed.
"
At line:3 char:1
+ ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIden ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SystemException

False

When not a member of this group, packer then checks if my user is an administrator. I have the BUILTIN\Hyper-V Administrators group on my system and my user is not a member of it. I'm not sure who created this group between Hyper-V installation or domain scripts.

With this change packer crashes instead of falling back to the is "administrator check"

In my opinion the first check should be .IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") and if that fails then .IsInRole('Hyper-V Administrators').

Looks like we do need to add some more levels of checks.

Fwiw, the change was in service of this bug: https://github.com/hashicorp/packer/issues/5022 which is about group names being different in other languages, so I do think we should try to use SIDs over names if possible

@cdhunt that's an interesting idea. Is there something special about the built-in role of Hyper-V administrators? Something that is useful than being an administrator?

I'm still waiting for a response from my organization's it department with regards to why the Sid query is throwing an error instead of returning just false. If I understand better the reasons that it fails then it can help to make a decision on how to bypass this issue.

I can verify the same behavior as @Sarafian in regards to using:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Hyper-V Administrators')
True

It appears if I use any SID it fails, for example local Administrators:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-544')

Exception calling "IsInRole" with "1" argument(s): "The trust relationship between the primary domain and the trusted domain failed.

Did some research. This may be possible:

$sid = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-578')
$group = $sid.Translate([System.Security.Principal.NTAccount])
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($group.Value)

Using PowerShell to Resolve SIDs to Friendly Names

@mikejr83 That appears to work.

I just pushed up a patch at https://github.com/hashicorp/packer/pull/5289

but I didn't see @mikejr83's code until now. If my patch doesn't work, I'll add in the code

@mwhooker I should have submitted a pull request but I was busy fixing a bug in my company's software :) Your code works for me locally.

@mikejr83 that's good to hear, thanks for checking. Does the code that's in master fail locally for you? Want to make sure this is a falsifiable test. I don't have ready access to a windows environment right now, so any help testing this is greatly appreciated

@mwhooker I can try tomorrow when I'm back in the office. Home machine isn't on a domain :).

It also might take me a sec to figure out how to pull and build. The only experience I have with GO is about 25 days in the past and was for only a few hours! I remember it placing the source in some odd location, though.

@mikejr83 thanks! Let me know if you want me to make you a build. it's no problem, just need to know your architecture, and I assume the OS is windows.

@mikejr83 's code works fine.

$sid = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-578')
$group = $sid.Translate([System.Security.Principal.NTAccount])
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($group.Value)

@mwhooker I've tested a build from current master. When I'm disconnected from the VPN and can't reach a domain controller I can reproduce the error.


Error

Build 'hyperv-iso' errored: Failed creating Hyper-V driver: PowerShell error: Exception calling "IsInRole" with
 "1" argument(s): "The trust relationship between this workstation and the
primary domain failed.
"
At C:\Users\chris.hunt\AppData\Local\Temp\ps982988943.ps1:1 char:1
+ ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIden ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SystemException

==> Some builds didn't complete successfully and had errors:
--> hyperv-iso: Failed creating Hyper-V driver: PowerShell error: Exception calling "IsInRole" with "1" argumen
t(s): "The trust relationship between this workstation and the
primary domain failed.
"
At C:\Users\chris.hunt\AppData\Local\Temp\ps982988943.ps1:1 char:1
+ ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIden ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SystemException

==> Builds finished but no artifacts were created.

While connected to the VPN and able to reach a domain controller, the code in master works for me.

I validated that the code @mikejr83 provided does function for me in both cases.

And the code changes in fix5126 also appear to work.

Looks to be working for me after pulling latest on master. Also, looks like I have an issue in my template!

One suggestion, is it possible to wrap the call to IsInRole in a try/catch? When catching the exception perhaps try rolling back to the code I provided above.

Happy to use whatever powershell code someone who knows what they're doing wants to write 馃槈

I'm not able to reproduce this on my vm, so I don't feel confident changing this. Looks like this is working for now, so going to close. Will happily merge any try/catch changes. If i'm mistaken and this is not fixed, please let me know and I'll reopen

I think you need to reconsider this issue. The current implementation executes ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-578') and can raise an error

Exception calling "IsInRole" with "1" argument(s): "The trust relationship between the primary domain and the trusted domain failed.
"
At line:1 char:1
+ ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIden ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SystemException

But if you replace it with

$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = new-object System.Security.Principal.WindowsPrincipal($identity)
$hypervrole = [System.Security.Principal.SecurityIdentifier]"S-1-5-32-578"
$principal.IsInRole($hypervrole)

then it works well for the same sid.

On the side note, my IT organization can verify this issue but they can't figure out what the issue is with the domain controller. They mentioned also that there isn't enough information on what could cause this and they will probably contact Microsoft.

This issue has become a major blocker because new features are added since version 1.0.0 but we can't use them.

I am getting this issue as well. @Sarafian 's solution works for me. But the master gives me error.

@Sarafian looks like the only difference with #5289 is using the -578 identifier?

If you or @vijayinvites can verify #5510 I will merge

@mwhooker almost. I took the part from the powershell script for the isCurrentUserAHyperVAdministrator function but the rest of the changes I don't think they are required. I'm sorry not to submit a pull but real busy.

@mwhooker , It works without any error now. I have checked it. Thanks for the fix.

Was this page helpful?
0 / 5 - 0 ratings