From 57187c9f88e8c4f249c6763010da0a73bef6c0eb Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Thu, 10 Dec 2015 07:04:39 -0800 Subject: [PATCH] Add method to detect if a Windows user is a member of the "Hyper-V Administrators" group. Modify Hyper-V provider to require a user to either be an Administrator or a member of "Hyper-V Administrators" --- lib/vagrant/util/platform.rb | 19 +++++++++++++++++ plugins/providers/hyperv/provider.rb | 5 +++-- .../plugins/providers/hyperv/provider_test.rb | 21 +++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index e2762bca6..017a6e558 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -61,6 +61,25 @@ module Vagrant (`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil? end + # Checks if the user running Vagrant on Windows is a member of the + # "Hyper-V Administrators" group. + # + # From: https://support.microsoft.com/en-us/kb/243330 + # SID: S-1-5-32-578 + # Name: BUILTIN\Hyper-V Administrators + # + # @return [Boolean] + def windows_hyperv_admin? + begin + username = ENV["USERNAME"] + process = Subprocess.execute("net", "localgroup", "Hyper-V Administrators") + output = process.stdout.chomp + return output.include?(username) + rescue Errors::CommandUnavailableWindows + return false + end + end + # This takes any path and converts it from a Windows path to a # Cygwin or msys style path. # diff --git a/plugins/providers/hyperv/provider.rb b/plugins/providers/hyperv/provider.rb index d8fee52e7..5db9c880d 100644 --- a/plugins/providers/hyperv/provider.rb +++ b/plugins/providers/hyperv/provider.rb @@ -16,8 +16,9 @@ module VagrantPlugins raise Errors::WindowsRequired end - if !Vagrant::Util::Platform.windows_admin? - raise Errors::AdminRequired + if !Vagrant::Util::Platform.windows_admin? and + !Vagrant::Util::Platform.windows_hyperv_admin? + raise Errors::AdminRequired end if !Vagrant::Util::PowerShell.available? diff --git a/test/unit/plugins/providers/hyperv/provider_test.rb b/test/unit/plugins/providers/hyperv/provider_test.rb index 0613751d1..2a895706d 100644 --- a/test/unit/plugins/providers/hyperv/provider_test.rb +++ b/test/unit/plugins/providers/hyperv/provider_test.rb @@ -15,6 +15,7 @@ describe VagrantPlugins::HyperV::Provider do machine.stub(id: "foo") platform.stub(windows?: true) platform.stub(windows_admin?: true) + platform.stub(windows_hyperv_admin?: true) powershell.stub(available?: true) end @@ -26,11 +27,18 @@ describe VagrantPlugins::HyperV::Provider do expect(subject).to_not be_usable end - it "returns false if not an admin" do + it "returns false if neither an admin nor a hyper-v admin" do platform.stub(windows_admin?: false) + platform.stub(windows_hyperv_admin?: false) expect(subject).to_not be_usable end + it "returns true if not an admin but is a hyper-v admin" do + platform.stub(windows_admin?: false) + platform.stub(windows_hyperv_admin?: true) + expect(subject).to be_usable + end + it "returns false if powershell is not available" do powershell.stub(available?: false) expect(subject).to_not be_usable @@ -43,8 +51,17 @@ describe VagrantPlugins::HyperV::Provider do to raise_error(VagrantPlugins::HyperV::Errors::WindowsRequired) end - it "raises an exception if not an admin" do + it "raises an exception if neither an admin nor a hyper-v admin" do platform.stub(windows_admin?: false) + platform.stub(windows_hyperv_admin?: false) + + expect { subject.usable?(true) }. + to raise_error(VagrantPlugins::HyperV::Errors::AdminRequired) + end + + it "raises an exception if neither an admin nor a hyper-v admin" do + platform.stub(windows_admin?: false) + platform.stub(windows_hyperv_admin?: false) expect { subject.usable?(true) }. to raise_error(VagrantPlugins::HyperV::Errors::AdminRequired)