From 7a01c5809cc2c7d74b4c300b1cb3bd3acc6c75f1 Mon Sep 17 00:00:00 2001 From: Wim Van Leuven Date: Wed, 27 Jan 2021 08:15:38 +0100 Subject: [PATCH] Feature/ldap gssapi sasl authentication (#1595) * add sasl_class as parameter * type str not string * recreate .gitignore with vscode support * document sasl_class parameter * revert .gitignore changes (separate PR) * docs - add version and end lines with . * add changelog entry * add sasl_class choices to docs as well * changelog should link to issue Co-authored-by: Felix Fontein Co-authored-by: Wim Van Leuven Co-authored-by: Felix Fontein --- .../fragments/1595-ldap-gssapi-sasl-authentication.yml | 2 ++ plugins/doc_fragments/ldap.py | 10 +++++++++- plugins/module_utils/ldap.py | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/1595-ldap-gssapi-sasl-authentication.yml diff --git a/changelogs/fragments/1595-ldap-gssapi-sasl-authentication.yml b/changelogs/fragments/1595-ldap-gssapi-sasl-authentication.yml new file mode 100644 index 0000000000..117d084e40 --- /dev/null +++ b/changelogs/fragments/1595-ldap-gssapi-sasl-authentication.yml @@ -0,0 +1,2 @@ +bugfixes: +- "ldap modules - add ``sasl_class`` parameter to support passwordless SASL authentication via GSSAPI (kerberos), next to external (https://github.com/ansible-collections/community.general/issues/1523)." diff --git a/plugins/doc_fragments/ldap.py b/plugins/doc_fragments/ldap.py index b3d21bf423..1c9931fb85 100644 --- a/plugins/doc_fragments/ldap.py +++ b/plugins/doc_fragments/ldap.py @@ -15,7 +15,7 @@ class ModuleDocFragment(object): options: bind_dn: description: - - A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism. + - A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism as default. - If this is blank, we'll use an anonymous bind. type: str bind_pw: @@ -53,4 +53,12 @@ options: - This should only be used on sites using self-signed certificates. type: bool default: yes + sasl_class: + description: + - The class to use for SASL authentication. + - possible choices are C(external), C(gssapi). + type: str + choices: ['external', 'gssapi'] + default: external + version_added: "2.0.0" ''' diff --git a/plugins/module_utils/ldap.py b/plugins/module_utils/ldap.py index 75405b3537..999d7e67ee 100644 --- a/plugins/module_utils/ldap.py +++ b/plugins/module_utils/ldap.py @@ -17,6 +17,11 @@ try: import ldap.sasl HAS_LDAP = True + + SASCL_CLASS = { + 'gssapi': ldap.sasl.gssapi, + 'external': ldap.sasl.external, + } except ImportError: HAS_LDAP = False @@ -30,6 +35,7 @@ def gen_specs(**specs): 'server_uri': dict(default='ldapi:///'), 'start_tls': dict(default=False, type='bool'), 'validate_certs': dict(default=True, type='bool'), + 'sasl_class': dict(choices=['external', 'gssapi'], default='external', type='str'), }) return specs @@ -46,6 +52,7 @@ class LdapGeneric(object): self.server_uri = self.module.params['server_uri'] self.start_tls = self.module.params['start_tls'] self.verify_cert = self.module.params['validate_certs'] + self.sasl_class = self.module.params['sasl_class'] # Establish connection self.connection = self._connect_to_ldap() @@ -77,7 +84,8 @@ class LdapGeneric(object): if self.bind_dn is not None: connection.simple_bind_s(self.bind_dn, self.bind_pw) else: - connection.sasl_interactive_bind_s('', ldap.sasl.external()) + klass = SASCL_CLASS.get(self.sasl_class, ldap.sasl.external) + connection.sasl_interactive_bind_s('', klass()) except ldap.LDAPError as e: self.fail("Cannot bind to the server.", e)