Prepend computer name to user when created scheduled tasks

When running a shell provisioner elevated with winrm a scheduled
task is created to bypass permissions issues. If the name of the
computer has changed this may no longer work. To prevent errors
this PR updates the implementation to fetch the computer name
and prepends it to the username before creating the task.
This commit is contained in:
Chris Roberts 2018-11-08 14:21:20 -08:00
parent b7cff2de2b
commit c8f431cf44
2 changed files with 77 additions and 1 deletions

View File

@ -71,7 +71,13 @@ module VagrantPlugins
def elevated(command, opts = {}, &block)
connection.shell(:elevated) do |shell|
shell.interactive_logon = opts[:interactive] || false
execute_with_rescue(shell, command, &block)
uname = shell.username
begin
shell.username = elevated_username
execute_with_rescue(shell, command, &block)
ensure
shell.username = uname
end
end
end
@ -216,6 +222,24 @@ module VagrantPlugins
retry_delay: @config.retry_delay,
retry_limit: @config.max_tries }
end
def elevated_username
if @elevated_username
return @elevated_username
end
if username.include?("\\")
return @elevated_username = username
end
computername = ""
powershell("Write-Output $env:computername") do |type, data|
computername << data if type == :stdout
end
computername.strip!
if computername.empty?
return @elevated_username = username
end
@elevated_username = "#{computername}\\#{username}"
end
end #WinShell class
end
end

View File

@ -75,6 +75,14 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
end
describe ".elevated" do
let(:username) { double("username") }
before do
allow(subject).to receive(:elevated_username).and_return(username)
allow(shell).to receive(:username).and_return(username)
allow(shell).to receive(:username=)
end
it "should call winrm elevated" do
expect(shell).to receive(:run).with("dir").and_return(output)
expect(shell).to receive(:interactive_logon=).with(false)
@ -93,6 +101,13 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
expect { subject.powershell("dir") }.to raise_error(
VagrantPlugins::CommunicatorWinRM::Errors::ExecutionError)
end
it "should use elevated username" do
expect(subject).to receive(:elevated_username).and_return(username)
expect(shell).to receive(:run).with("dir").and_return(output)
expect(shell).to receive(:interactive_logon=).with(false)
expect(subject.elevated("dir").exitcode).to eq(0)
end
end
describe ".cmd" do
@ -178,4 +193,41 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
end
end
describe "#elevated_username" do
let(:username) { "username" }
before do
allow(subject).to receive(:username).and_return(username)
allow(subject).to receive(:powershell)
end
it "should return username" do
expect(subject.send(:elevated_username)).to eq(username)
end
it "should attempt to get computer name" do
expect(subject).to receive(:powershell).with(/computername/)
subject.send(:elevated_username)
end
it "should prepend computer name when available" do
expect(subject).to receive(:powershell).with(/computername/).and_yield(:stdout, "COMPUTERNAME")
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
end
it "should only compute elevated username once" do
expect(subject).to receive(:powershell).once.with(/computername/).and_yield(:stdout, "COMPUTERNAME")
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
end
context "when username includes computer/domain name" do
let(:username) { "machine\\username" }
it "should not attempt to get computer name" do
expect(subject).not_to receive(:powershell)
expect(subject.send(:elevated_username)).to eq(username)
end
end
end
end