2020-03-09 10:11:07 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2022-08-05 13:17:19 +02:00
|
|
|
# Copyright (c) 2017-2018, Keller Fuchs <kellerfuchs@hashbang.sh>
|
|
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2020-03-09 10:11:07 +01:00
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
---
|
|
|
|
module: ldap_passwd
|
2022-11-09 07:33:03 +01:00
|
|
|
short_description: Set passwords in LDAP
|
2020-03-09 10:11:07 +01:00
|
|
|
description:
|
|
|
|
- Set a password for an LDAP entry. This module only asserts that
|
|
|
|
a given password is valid for a given entry. To assert the
|
2020-06-29 14:59:15 +02:00
|
|
|
existence of an entry, see M(community.general.ldap_entry).
|
2020-03-09 10:11:07 +01:00
|
|
|
notes:
|
|
|
|
- The default authentication settings will attempt to use a SASL EXTERNAL
|
|
|
|
bind over a UNIX domain socket. This works well with the default Ubuntu
|
|
|
|
install for example, which includes a cn=peercred,cn=external,cn=auth ACL
|
|
|
|
rule allowing root to modify the server configuration. If you need to use
|
|
|
|
a simple bind to access your server, pass the credentials in I(bind_dn)
|
|
|
|
and I(bind_pw).
|
|
|
|
author:
|
|
|
|
- Keller Fuchs (@KellerFuchs)
|
|
|
|
requirements:
|
|
|
|
- python-ldap
|
|
|
|
options:
|
|
|
|
passwd:
|
|
|
|
description:
|
|
|
|
- The (plaintext) password to be set for I(dn).
|
2020-12-01 21:28:40 +01:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
extends_documentation_fragment:
|
|
|
|
- community.general.ldap.documentation
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
EXAMPLES = """
|
|
|
|
- name: Set a password for the admin user
|
2020-07-13 21:50:31 +02:00
|
|
|
community.general.ldap_passwd:
|
2020-03-09 10:11:07 +01:00
|
|
|
dn: cn=admin,dc=example,dc=com
|
|
|
|
passwd: "{{ vault_secret }}"
|
|
|
|
|
|
|
|
- name: Setting passwords in bulk
|
2020-07-13 21:50:31 +02:00
|
|
|
community.general.ldap_passwd:
|
2020-03-09 10:11:07 +01:00
|
|
|
dn: "{{ item.key }}"
|
|
|
|
passwd: "{{ item.value }}"
|
|
|
|
with_dict:
|
|
|
|
alice: alice123123
|
|
|
|
bob: "|30b!"
|
|
|
|
admin: "{{ vault_secret }}"
|
|
|
|
"""
|
|
|
|
|
|
|
|
RETURN = """
|
|
|
|
modlist:
|
|
|
|
description: list of modified parameters
|
|
|
|
returned: success
|
|
|
|
type: list
|
2022-08-04 21:10:48 +02:00
|
|
|
sample:
|
|
|
|
- [2, "olcRootDN", ["cn=root,dc=example,dc=com"]]
|
2020-03-09 10:11:07 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
import traceback
|
|
|
|
|
|
|
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
|
|
|
from ansible_collections.community.general.plugins.module_utils.ldap import LdapGeneric, gen_specs
|
|
|
|
|
|
|
|
LDAP_IMP_ERR = None
|
|
|
|
try:
|
|
|
|
import ldap
|
|
|
|
|
|
|
|
HAS_LDAP = True
|
|
|
|
except ImportError:
|
|
|
|
LDAP_IMP_ERR = traceback.format_exc()
|
|
|
|
HAS_LDAP = False
|
|
|
|
|
|
|
|
|
|
|
|
class LdapPasswd(LdapGeneric):
|
|
|
|
def __init__(self, module):
|
|
|
|
LdapGeneric.__init__(self, module)
|
|
|
|
|
|
|
|
# Shortcuts
|
|
|
|
self.passwd = self.module.params['passwd']
|
|
|
|
|
|
|
|
def passwd_check(self):
|
|
|
|
try:
|
|
|
|
tmp_con = ldap.initialize(self.server_uri)
|
|
|
|
except ldap.LDAPError as e:
|
|
|
|
self.fail("Cannot initialize LDAP connection", e)
|
|
|
|
|
|
|
|
if self.start_tls:
|
|
|
|
try:
|
|
|
|
tmp_con.start_tls_s()
|
|
|
|
except ldap.LDAPError as e:
|
|
|
|
self.fail("Cannot start TLS.", e)
|
|
|
|
|
|
|
|
try:
|
|
|
|
tmp_con.simple_bind_s(self.dn, self.passwd)
|
|
|
|
except ldap.INVALID_CREDENTIALS:
|
|
|
|
return True
|
|
|
|
except ldap.LDAPError as e:
|
|
|
|
self.fail("Cannot bind to the server.", e)
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
finally:
|
|
|
|
tmp_con.unbind()
|
|
|
|
|
|
|
|
def passwd_set(self):
|
|
|
|
# Exit early if the password is already valid
|
|
|
|
if not self.passwd_check():
|
|
|
|
return False
|
|
|
|
|
|
|
|
# Change the password (or throw an exception)
|
|
|
|
try:
|
|
|
|
self.connection.passwd_s(self.dn, None, self.passwd)
|
|
|
|
except ldap.LDAPError as e:
|
|
|
|
self.fail("Unable to set password", e)
|
|
|
|
|
|
|
|
# Password successfully changed
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
module = AnsibleModule(
|
|
|
|
argument_spec=gen_specs(passwd=dict(no_log=True)),
|
|
|
|
supports_check_mode=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
if not HAS_LDAP:
|
|
|
|
module.fail_json(msg=missing_required_lib('python-ldap'),
|
|
|
|
exception=LDAP_IMP_ERR)
|
|
|
|
|
|
|
|
ldap = LdapPasswd(module)
|
|
|
|
|
|
|
|
if module.check_mode:
|
|
|
|
module.exit_json(changed=ldap.passwd_check())
|
|
|
|
|
|
|
|
module.exit_json(changed=ldap.passwd_set())
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|