From efb717fe73139e5fe5e3aa957e1aa1fbb6cf41f9 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 6 Apr 2017 01:34:30 -0700 Subject: [PATCH] improve become_method: runas error handling (#23328) Prescriptive errors for username/password issues and NTLM/Kerb auth failures, cleans up exception noise. (cherry picked from commit 8d291f91eee18ca30b737eb1ca17e53c0632a7cc) --- lib/ansible/playbook/play_context.py | 7 ++++++ lib/ansible/plugins/shell/powershell.py | 30 ++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index 6f875bb6e27..ba483b59a4a 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -552,6 +552,13 @@ class PlayContext(Base): elif self.become_method == 'runas': # become is handled inside the WinRM connection plugin display.warning("The Windows 'runas' become method is experimental, and may change significantly in future Ansible releases.") + + if not self.become_user: + raise AnsibleError(("The 'runas' become method requires a username " + "(specify with the '--become-user' CLI arg, the 'become_user' keyword, or the 'ansible_become_user' variable)")) + if not self.become_pass: + raise AnsibleError(("The 'runas' become method requires a password " + "(specify with the '-K' CLI arg or the 'ansible_become_password' variable)")) becomecmd = cmd elif self.become_method == 'doas': diff --git a/lib/ansible/plugins/shell/powershell.py b/lib/ansible/plugins/shell/powershell.py index 3005e74d561..9d9238e4d23 100644 --- a/lib/ansible/plugins/shell/powershell.py +++ b/lib/ansible/plugins/shell/powershell.py @@ -316,6 +316,15 @@ Write-Output $output } # end exec_wrapper +Function Dump-Error ($excep) { + $eo = @{failed=$true} + + $eo.msg = $excep.Exception.Message + $eo.exception = $excep | Out-String + $host.SetShouldExit(1) + + $eo | ConvertTo-Json -Depth 10 +} Function Run($payload) { # NB: action popping handled inside subprocess wrapper @@ -371,14 +380,25 @@ Function Run($payload) { $psi.Username = $username $psi.Password = $($password | ConvertTo-SecureString -AsPlainText -Force) - [Ansible.Shell.ProcessUtil]::GrantAccessToWindowStationAndDesktop($username) + Try { + [Ansible.Shell.ProcessUtil]::GrantAccessToWindowStationAndDesktop($username) + } + Catch { + $excep = $_ + throw "Error granting windowstation/desktop access to '$username' (is the username valid?): $excep" + } Try { $proc.Start() | Out-Null # will always return $true for non shell-exec cases } Catch { - Write-Output $_.Exception.InnerException - return + $excep = $_ + if ($excep.Exception.InnerException -and ` + $excep.Exception.InnerException -is [System.ComponentModel.Win32Exception] -and ` + $excep.Exception.InnerException.NativeErrorCode -eq 5) { + throw "Become method 'runas' become is not currently supported with the NTLM or Kerberos auth types" + } + throw "Error launching under identity '$username': $excep" } $payload_string = $payload | ConvertTo-Json -Depth 99 -Compress @@ -405,6 +425,10 @@ Function Run($payload) { Throw "failed, rc was $rc, stderr was $stderr, stdout was $stdout" } } + Catch { + $excep = $_ + Dump-Error $excep + } Finally { Remove-Item $temp -ErrorAction SilentlyContinue }