Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

become win: better error messages and docs update #39936

Merged
merged 2 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/window_become-better-errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- windows become - Show better error messages when the become process fails
24 changes: 19 additions & 5 deletions docs/docsite/rst/user_guide/become.rst
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ module execution.
To determine the type of token that Ansible was able to get, run the following
task and check the output::

- win_shell: cmd.exe /c whoami && whoami /groups && whoami /priv
- win_whoami:
become: yes

Under the ``GROUP INFORMATION`` section, the ``Mandatory Label`` entry
Expand Down Expand Up @@ -453,7 +453,11 @@ or with this Ansible task:

Become Flags
------------
Ansible 2.5 adds the ``become_flags`` parameter to the ``runas`` become method. This parameter can be set using the ``become_flags`` task directive or set in Ansible's configuration using ``ansible_become_flags``. The two valid values that are initially supported for this parameter are ``logon_type`` and ``logon_flags``.
Ansible 2.5 adds the ``become_flags`` parameter to the ``runas`` become method.
This parameter can be set using the ``become_flags`` task directive or set in
Ansible's configuration using ``ansible_become_flags``. The two valid values
that are initially supported for this parameter are ``logon_type`` and
``logon_flags``.


.. Note:: These flags should only be set when becoming a normal user account, not a local service account like LocalSystem.
Expand Down Expand Up @@ -490,7 +494,7 @@ For more information, see
`dwLogonType <https://msdn.microsoft.com/en-au/library/windows/desktop/aa378184.aspx>`_.

The ``logon_flags`` key specifies how Windows will log the user on when creating
the new process. The value can be set to one of the following:
the new process. The value can be set to none or multiple of the following:

* ``with_profile``: The default logon flag set. The process will load the
user's profile in the ``HKEY_USERS`` registry key to ``HKEY_CURRENT_USER``.
Expand All @@ -500,6 +504,10 @@ the new process. The value can be set to one of the following:
resource. This is useful in inter-domain scenarios where there is no trust
relationship, and should be used with the ``new_credentials`` ``logon_type``.

By default ``logon_flags=with_profile`` is set, if the profile should not be
loaded set ``logon_flags=`` or if the profile should be loaded with
``netcredentials_only``, set ``logon_flags=with_profile,netcredentials_only``.

For more information, see `dwLogonFlags <https://msdn.microsoft.com/en-us/library/windows/desktop/ms682434.aspx>`_.

Here are some examples of how to use ``become_flags`` with Windows tasks:
Expand All @@ -519,10 +527,15 @@ Here are some examples of how to use ``become_flags`` with Windows tasks:
ansible_become_flags: logon_type=new_credentials logon_flags=netcredentials_only

- name: run a command under a batch logon
win_command: whoami
win_whoami:
become: yes
become_flags: logon_type=batch

- name: run a command and not load the user profile
win_whomai:
become: yes
become_flags: logon_flags=


Limitations
-----------
Expand All @@ -535,7 +548,8 @@ Be aware of the following limitations with ``become`` on Windows:
* By default, the become user logs on with an interactive session, so it must
have the right to do so on the Windows host. If it does not inherit the
``SeAllowLogOnLocally`` privilege or inherits the ``SeDenyLogOnLocally``
privilege, the become process will fail.
privilege, the become process will fail. Either add the privilege or set the
``logon_type`` flag to change the logon type used.

* Prior to Ansible version 2.3, become only worked when
``ansible_winrm_transport`` was either ``basic`` or ``credssp``. This
Expand Down
12 changes: 8 additions & 4 deletions lib/ansible/plugins/shell/powershell.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,10 +1161,14 @@ class NativeWaitHandle : WaitHandle
Write-Output ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Write-Output $output))))
} # end exec_wrapper

Function Dump-Error ($excep) {
Function Dump-Error ($excep, $msg=$null) {
$eo = @{failed=$true}

$eo.msg = $excep.Exception.Message
$exception_message = $excep.Exception.Message
if ($null -ne $msg) {
$exception_message = "$($msg): $exception_message"
}
$eo.msg = $exception_message
$eo.exception = $excep | Out-String
$host.SetShouldExit(1)

Expand Down Expand Up @@ -1243,7 +1247,7 @@ class NativeWaitHandle : WaitHandle
try {
$logon_type, $logon_flags = Parse-BecomeFlags -flags $payload.become_flags
} catch {
Dump-Error -excep $_
Dump-Error -excep $_ -msg "Failed to parse become_flags '$($payload.become_flags)'"
return $null
}

Expand Down Expand Up @@ -1285,7 +1289,7 @@ class NativeWaitHandle : WaitHandle
[Console]::Error.WriteLine($stderr.Trim())
} Catch {
$excep = $_
Dump-Error $excep
Dump-Error -excep $excep -msg "Failed to become user $username"
} Finally {
Remove-Item $temp -ErrorAction SilentlyContinue
}
Expand Down
46 changes: 43 additions & 3 deletions test/integration/targets/win_become/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@
- name: test with module that will return non-zero exit code (https://github.com/ansible/ansible/issues/30468)
vars: *become_vars
setup:

- name: test become with invalid password
win_whoami:
vars:
ansible_become_pass: '{{ gen_pw }}abc'
become: yes
become_method: runas
become_user: '{{ become_test_username }}'
register: become_invalid_pass
failed_when:
- '"Failed to become user " + become_test_username not in become_invalid_pass.msg'
- '"LogonUser failed (The user name or password is incorrect, Win32ErrorCode 1326)" not in become_invalid_pass.msg'

- name: test become with SYSTEM account
win_whoami:
Expand Down Expand Up @@ -215,21 +227,21 @@
become_flags: logon_type=batch invalid_flags=a
become_method: runas
register: failed_flags_invalid_key
failed_when: failed_flags_invalid_key.msg != "become_flags key 'invalid_flags' is not a valid runas flag, must be 'logon_type' or 'logon_flags'"
failed_when: "failed_flags_invalid_key.msg != \"Failed to parse become_flags 'logon_type=batch invalid_flags=a': become_flags key 'invalid_flags' is not a valid runas flag, must be 'logon_type' or 'logon_flags'\""

- name: test failure with invalid logon_type
vars: *become_vars
win_whoami:
become_flags: logon_type=invalid
register: failed_flags_invalid_type
failed_when: "failed_flags_invalid_type.msg != \"become_flags logon_type value 'invalid' is not valid, valid values are: interactive, network, batch, service, unlock, network_cleartext, new_credentials\""
failed_when: "failed_flags_invalid_type.msg != \"Failed to parse become_flags 'logon_type=invalid': become_flags logon_type value 'invalid' is not valid, valid values are: interactive, network, batch, service, unlock, network_cleartext, new_credentials\""

- name: test failure with invalid logon_flag
vars: *become_vars
win_whoami:
become_flags: logon_flags=with_profile,invalid
register: failed_flags_invalid_flag
failed_when: "failed_flags_invalid_flag.msg != \"become_flags logon_flags value 'invalid' is not valid, valid values are: with_profile, netcredentials_only\""
failed_when: "failed_flags_invalid_flag.msg != \"Failed to parse become_flags 'logon_flags=with_profile,invalid': become_flags logon_flags value 'invalid' is not valid, valid values are: with_profile, netcredentials_only\""

# Server 2008 doesn't work with network and network_cleartext, there isn't really a reason why you would want this anyway
- name: become different types
Expand Down Expand Up @@ -266,6 +278,34 @@
- become_netcredentials.label.account_name == 'High Mandatory Level'
- become_netcredentials.label.sid == 'S-1-16-12288'

- name: become logon_flags bitwise tests when loading the profile
# Error code of 2 means no file found == no profile loaded
win_shell: |
Add-Type -Name "Native" -Namespace "Ansible" -MemberDefinition '[DllImport("Userenv.dll", SetLastError=true)]public static extern bool GetProfileType(out UInt32 pdwFlags);'
$profile_type = $null
$res = [Ansible.Native]::GetProfileType([ref]$profile_type)
if (-not $res) {
$last_err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($last_err -eq 2) {
return $false
} else {
throw [System.ComponentModel.Win32Exception]$last_err
}
} else {
return $true
}
vars: *admin_become_vars
become_flags: logon_flags={{item.flags}}
register: become_logon_flags
failed_when: become_logon_flags.stdout_lines[0]|bool != item.actual
with_items:
- flags:
actual: False
- flags: netcredentials_only
actual: False
- flags: with_profile,netcredentials_only
actual: True

- name: echo some non ascii characters
win_command: cmd.exe /c echo über den Fußgängerübergang gehen
vars: *become_vars
Expand Down