psexec: Handle socket errors (Connection timeout) (Backport) (#47407)

* psexec: Handle socket errors (Connection timeout)

This ensures we get a nicer error message from psexec.

* Add changelog fragment
This commit is contained in:
Dag Wieers 2018-10-22 20:34:25 +02:00 committed by Toshio Kuratomi
parent a636562818
commit 5a0e016b4b
2 changed files with 33 additions and 12 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- psexec - Handle socket.error exceptions properly

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# (c) 2018, Jordan Borean <jborean93@gmail.com> # Copyright: (c) 2018, Jordan Borean <jborean93@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
@ -31,6 +31,7 @@ options:
description: description:
- The remote Windows host to connect to, can be either an IP address or a - The remote Windows host to connect to, can be either an IP address or a
hostname. hostname.
type: str
required: yes required: yes
connection_username: connection_username:
description: description:
@ -43,6 +44,7 @@ options:
local credential cache if the Kerberos library is installed. local credential cache if the Kerberos library is installed.
- If I(process_username) is not specified, then the remote process will run - If I(process_username) is not specified, then the remote process will run
under a Network Logon under this account. under a Network Logon under this account.
type: str
connection_password: connection_password:
description: description:
- The password for I(connection_user). - The password for I(connection_user).
@ -51,9 +53,11 @@ options:
- Can be omitted to use a Kerberos principal ticket for the principal set - Can be omitted to use a Kerberos principal ticket for the principal set
by I(connection_user) if the Kerberos library is installed and the by I(connection_user) if the Kerberos library is installed and the
ticket has already been retrieved with the C(kinit) command before. ticket has already been retrieved with the C(kinit) command before.
type: str
port: port:
description: description:
- The port that the remote SMB service is listening on. - The port that the remote SMB service is listening on.
type: int
default: 445 default: 445
encrypt: encrypt:
description: description:
@ -65,22 +69,26 @@ options:
- When setting to C(no), the packets are in plaintext and can be seen by - When setting to C(no), the packets are in plaintext and can be seen by
anyone sniffing the network, any process options are included in this. anyone sniffing the network, any process options are included in this.
type: bool type: bool
default: 'yes' default: yes
connection_timeout: connection_timeout:
description: description:
- The timeout in seconds to wait when receiving the initial SMB negotiate - The timeout in seconds to wait when receiving the initial SMB negotiate
response from the server. response from the server.
type: str
default: 60 default: 60
executable: executable:
description: description:
- The executable to run on the Windows host. - The executable to run on the Windows host.
type: str
required: yes required: yes
arguments: arguments:
description: description:
- Any arguments as a single string to use when running the executable. - Any arguments as a single string to use when running the executable.
type: str
working_directory: working_directory:
description: description:
- Changes the working directory set when starting the process. - Changes the working directory set when starting the process.
type: str
default: C:\Windows\System32 default: C:\Windows\System32
asynchronous: asynchronous:
description: description:
@ -92,12 +100,12 @@ options:
- The I(stdin) option does not work with this type of process. - The I(stdin) option does not work with this type of process.
- The I(rc) return value is not set when this is C(yes) - The I(rc) return value is not set when this is C(yes)
type: bool type: bool
default: 'no' default: no
load_profile: load_profile:
description: description:
- Runs the remote command with the user's profile loaded. - Runs the remote command with the user's profile loaded.
type: bool type: bool
default: 'yes' default: yes
process_username: process_username:
description: description:
- The user to run the process as. - The user to run the process as.
@ -111,10 +119,12 @@ options:
- If I(encrypt) is C(no), the username and password are sent as a simple - If I(encrypt) is C(no), the username and password are sent as a simple
XOR scrambled byte string that is not encrypted. No special tools are XOR scrambled byte string that is not encrypted. No special tools are
required to get the username and password just knowledge of the protocol. required to get the username and password just knowledge of the protocol.
type: str
process_password: process_password:
description: description:
- The password for I(process_username). - The password for I(process_username).
- Required if I(process_username) is defined and not C(System). - Required if I(process_username) is defined and not C(System).
type: str
integrity_level: integrity_level:
description: description:
- The integrity level of the process when I(process_username) is defined - The integrity level of the process when I(process_username) is defined
@ -123,6 +133,7 @@ options:
- When C(elevated), the command will be run with Administrative rights. - When C(elevated), the command will be run with Administrative rights.
- When C(limited), the command will be forced to run with - When C(limited), the command will be forced to run with
non-Administrative rights. non-Administrative rights.
type: str
choices: choices:
- limited - limited
- default - default
@ -136,19 +147,21 @@ options:
to C(yes). to C(yes).
- The I(stdin) option does not work with this type of process. - The I(stdin) option does not work with this type of process.
type: bool type: bool
default: 'no' default: no
interactive_session: interactive_session:
description: description:
- The Windows session ID to use when displaying the interactive process on - The Windows session ID to use when displaying the interactive process on
the remote Windows host. the remote Windows host.
- This is only valid when I(interactive) is C(yes). - This is only valid when I(interactive) is C(yes).
- The default is C(0) which is the console session of the Windows host. - The default is C(0) which is the console session of the Windows host.
type: int
default: 0 default: 0
priority: priority:
description: description:
- Set the command's priority on the Windows host. - Set the command's priority on the Windows host.
- See U(https://msdn.microsoft.com/en-us/library/windows/desktop/ms683211.aspx) - See U(https://msdn.microsoft.com/en-us/library/windows/desktop/ms683211.aspx)
for more details. for more details.
type: str
choices: choices:
- above_normal - above_normal
- below_normal - below_normal
@ -162,17 +175,19 @@ options:
- Shows the process UI on the Winlogon secure desktop when - Shows the process UI on the Winlogon secure desktop when
I(process_username) is C(System). I(process_username) is C(System).
type: bool type: bool
default: 'no' default: no
process_timeout: process_timeout:
description: description:
- The timeout in seconds that is placed upon the running process. - The timeout in seconds that is placed upon the running process.
- A value of C(0) means no timeout. - A value of C(0) means no timeout.
type: int
default: 0 default: 0
stdin: stdin:
description: description:
- Data to send on the stdin pipe once the process has started. - Data to send on the stdin pipe once the process has started.
- This option has no effect when I(interactive) or I(asynchronous) is - This option has no effect when I(interactive) or I(asynchronous) is
C(yes). C(yes).
type: str
requirements: requirements:
- pypsexec - pypsexec
- smbprotocol[kerberos] for optional Kerberos authentication - smbprotocol[kerberos] for optional Kerberos authentication
@ -193,7 +208,7 @@ author:
''' '''
EXAMPLES = r''' EXAMPLES = r'''
- name: run a cmd.exe command - name: Run a cmd.exe command
psexec: psexec:
hostname: server hostname: server
connection_username: username connection_username: username
@ -201,7 +216,7 @@ EXAMPLES = r'''
executable: cmd.exe executable: cmd.exe
arguments: /c echo Hello World arguments: /c echo Hello World
- name: run a PowerShell command - name: Run a PowerShell command
psexec: psexec:
hostname: server.domain.local hostname: server.domain.local
connection_username: username@DOMAIN.LOCAL connection_username: username@DOMAIN.LOCAL
@ -209,7 +224,7 @@ EXAMPLES = r'''
executable: powershell.exe executable: powershell.exe
arguments: Write-Host Hello World arguments: Write-Host Hello World
- name: send data through stdin - name: Send data through stdin
psexec: psexec:
hostname: 192.168.1.2 hostname: 192.168.1.2
connection_username: username connection_username: username
@ -261,9 +276,9 @@ EXAMPLES = r'''
- name: Download and run ConfigureRemotingForAnsible.ps1 to setup WinRM - name: Download and run ConfigureRemotingForAnsible.ps1 to setup WinRM
psexec: psexec:
hostname: windows-pc hostname: '{{ ansible_host }}'
connection_username: Administrator connection_username: '{{ ansible_user }}'
connection_password: Password01 connection_password: '{{ ansible_password }}'
encrypt: yes encrypt: yes
executable: powershell.exe executable: powershell.exe
arguments: '-' arguments: '-'
@ -275,6 +290,7 @@ EXAMPLES = r'''
$url = "https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1" $url = "https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
Invoke-Expression ((New-Object Net.WebClient).DownloadString($url)) Invoke-Expression ((New-Object Net.WebClient).DownloadString($url))
exit exit
delegate_to: localhost
''' '''
RETURN = r''' RETURN = r'''
@ -319,6 +335,7 @@ try:
from pypsexec.paexec import ProcessPriority from pypsexec.paexec import ProcessPriority
from smbprotocol.exceptions import SMBException, SMBAuthenticationError, \ from smbprotocol.exceptions import SMBException, SMBAuthenticationError, \
SMBResponseException SMBResponseException
import socket
HAS_PYPSEXEC = True HAS_PYPSEXEC = True
except ImportError: except ImportError:
PYPSEXEC_IMP_ERR = traceback.format_exc() PYPSEXEC_IMP_ERR = traceback.format_exc()
@ -452,6 +469,8 @@ def main():
'the Windows host: %s' % to_text(exc)) 'the Windows host: %s' % to_text(exc))
except (SMBException, PypsexecException) as exc: except (SMBException, PypsexecException) as exc:
module.fail_json(msg=to_text(exc)) module.fail_json(msg=to_text(exc))
except socket.error as exc:
module.fail_json(msg=to_text(exc))
# create PAExec service and run the process # create PAExec service and run the process
result['changed'] = True result['changed'] = True