Merge pull request #7797 from lukebakken/features/lrb/better-windows-admin-detection
Improve user permission detection on Windows
This commit is contained in:
commit
4d0ecc14f7
|
@ -3,6 +3,7 @@ require "shellwords"
|
||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
require "vagrant/util/subprocess"
|
require "vagrant/util/subprocess"
|
||||||
|
require "vagrant/util/powershell"
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Util
|
module Util
|
||||||
|
@ -42,27 +43,17 @@ module Vagrant
|
||||||
# Checks if the user running Vagrant on Windows has administrative
|
# Checks if the user running Vagrant on Windows has administrative
|
||||||
# privileges.
|
# privileges.
|
||||||
#
|
#
|
||||||
|
# From: https://support.microsoft.com/en-us/kb/243330
|
||||||
|
# SID: S-1-5-19
|
||||||
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def windows_admin?
|
def windows_admin?
|
||||||
return @_windows_admin if defined?(@_windows_admin)
|
return @_windows_admin if defined?(@_windows_admin)
|
||||||
|
|
||||||
# We lazily-load this because it is only available on Windows
|
|
||||||
require "win32/registry"
|
|
||||||
|
|
||||||
# Verify that we have administrative privileges. The odd method of
|
|
||||||
# detecting this is based on this StackOverflow question:
|
|
||||||
#
|
|
||||||
# https://stackoverflow.com/questions/560366/
|
|
||||||
# detect-if-running-with-administrator-privileges-under-windows-xp
|
|
||||||
@_windows_admin = -> {
|
@_windows_admin = -> {
|
||||||
begin
|
ps_cmd = "[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { if ($_.Value -eq 'S-1-5-19'){ Write-Host 'true'; break }}"
|
||||||
Win32::Registry::HKEY_USERS.open("S-1-5-19") {}
|
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
|
||||||
|
return output == 'true'
|
||||||
# The above doesn't seem to be 100% bullet proof. See GH-5616.
|
|
||||||
return (`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil?
|
|
||||||
rescue Win32::Registry::Error
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
}.call
|
}.call
|
||||||
|
|
||||||
return @_windows_admin
|
return @_windows_admin
|
||||||
|
@ -78,15 +69,13 @@ module Vagrant
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def windows_hyperv_admin?
|
def windows_hyperv_admin?
|
||||||
return @_windows_hyperv_admin if defined?(@_windows_hyperv_admin)
|
return @_windows_hyperv_admin if defined?(@_windows_hyperv_admin)
|
||||||
|
|
||||||
@_windows_hyperv_admin = -> {
|
@_windows_hyperv_admin = -> {
|
||||||
begin
|
ps_cmd = "[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { if ($_.Value -eq 'S-1-5-32-578'){ Write-Host 'true'; break }}"
|
||||||
username = ENV["USERNAME"]
|
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
|
||||||
process = Subprocess.execute("net", "localgroup", "Hyper-V Administrators")
|
return output == 'true'
|
||||||
return process.stdout.include?(username)
|
|
||||||
rescue Errors::CommandUnavailableWindows
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
}.call
|
}.call
|
||||||
|
|
||||||
return @_windows_hyperv_admin
|
return @_windows_hyperv_admin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,9 @@ module Vagrant
|
||||||
def self.execute(path, *args, **opts, &block)
|
def self.execute(path, *args, **opts, &block)
|
||||||
command = [
|
command = [
|
||||||
"powershell",
|
"powershell",
|
||||||
|
"-NoLogo",
|
||||||
"-NoProfile",
|
"-NoProfile",
|
||||||
|
"-NonInteractive",
|
||||||
"-ExecutionPolicy", "Bypass",
|
"-ExecutionPolicy", "Bypass",
|
||||||
"&('#{path}')",
|
"&('#{path}')",
|
||||||
args
|
args
|
||||||
|
@ -32,14 +34,37 @@ module Vagrant
|
||||||
Subprocess.execute(*command, &block)
|
Subprocess.execute(*command, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Execute a powershell command.
|
||||||
|
#
|
||||||
|
# @param [String] command PowerShell command to execute.
|
||||||
|
# @return [Subprocess::Result]
|
||||||
|
def self.execute_cmd(command)
|
||||||
|
c = [
|
||||||
|
"powershell",
|
||||||
|
"-NoLogo",
|
||||||
|
"-NoProfile",
|
||||||
|
"-NonInteractive",
|
||||||
|
"-ExecutionPolicy", "Bypass",
|
||||||
|
"-Command",
|
||||||
|
command
|
||||||
|
].flatten
|
||||||
|
|
||||||
|
r = Subprocess.execute(*c)
|
||||||
|
return nil if r.exit_code != 0
|
||||||
|
return r.stdout.chomp
|
||||||
|
end
|
||||||
|
|
||||||
# Returns the version of PowerShell that is installed.
|
# Returns the version of PowerShell that is installed.
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def self.version
|
def self.version
|
||||||
command = [
|
command = [
|
||||||
"powershell",
|
"powershell",
|
||||||
|
"-NoLogo",
|
||||||
"-NoProfile",
|
"-NoProfile",
|
||||||
|
"-NonInteractive",
|
||||||
"-ExecutionPolicy", "Bypass",
|
"-ExecutionPolicy", "Bypass",
|
||||||
|
"-Command",
|
||||||
"$PSVersionTable.PSVersion.Major"
|
"$PSVersionTable.PSVersion.Major"
|
||||||
].flatten
|
].flatten
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue