From ab33a0e666ef9644dd94fe7710c40efa99a6b83e Mon Sep 17 00:00:00 2001 From: Kirk Strauser Date: Tue, 10 Feb 2015 07:39:07 -0800 Subject: [PATCH] Adds Kerberos authentication to winrm if available If the `kerberos` module is available, winrm will attempt to establish a Kerberized connection to a Windows server. This allows use of Windows domain accounts, which are quite often the only kinds of accounts enabled on enterprise networks. This also pulls the `transport_schemes` variable up into the `winrm.Connection` class. This lets tests or future modifications alter the list of available schemas without reaching into `Connection.__init__`. --- .../runner/connection_plugins/winrm.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/ansible/runner/connection_plugins/winrm.py b/lib/ansible/runner/connection_plugins/winrm.py index 0251839ccea..79e7ed58890 100644 --- a/lib/ansible/runner/connection_plugins/winrm.py +++ b/lib/ansible/runner/connection_plugins/winrm.py @@ -37,6 +37,13 @@ try: except ImportError: raise errors.AnsibleError("winrm is not installed") +HAVE_KERBEROS = False +try: + import kerberos + HAVE_KERBEROS = True +except ImportError: + pass + _winrm_cache = { # 'user:pwhash@host:port': } @@ -47,6 +54,11 @@ def vvvvv(msg, host=None): class Connection(object): '''WinRM connections over HTTP/HTTPS.''' + transport_schemes = { + 'http': [('kerberos', 'http'), ('plaintext', 'http'), ('plaintext', 'https')], + 'https': [('kerberos', 'https'), ('plaintext', 'http'), ('plaintext', 'https')], + } + def __init__(self, runner, host, port, user, password, *args, **kwargs): self.runner = runner self.host = host @@ -72,11 +84,10 @@ class Connection(object): if cache_key in _winrm_cache: vvvv('WINRM REUSE EXISTING CONNECTION: %s' % cache_key, host=self.host) return _winrm_cache[cache_key] - transport_schemes = [('plaintext', 'https'), ('plaintext', 'http')] # FIXME: ssl/kerberos - if port == 5985: - transport_schemes = reversed(transport_schemes) exc = None - for transport, scheme in transport_schemes: + for transport, scheme in self.transport_schemes['http' if port == 5985 else 'https']: + if transport == 'kerberos' and not HAVE_KERBEROS: + continue endpoint = urlparse.urlunsplit((scheme, netloc, '/wsman', '', '')) vvvv('WINRM CONNECT: transport=%s endpoint=%s' % (transport, endpoint), host=self.host)