Files @ 5eb7821a1e4d
Branch filter:

Location: majic-ansible-roles/roles/ldap_server/tasks/main.yml - annotation

branko
MAR-218: Switch to using ldap_attrs module:

- Update invocations and syntax.
- Drop the workaround for configuring TLS on the LDAP server (should
be possible to set all relevant attributes at the same time at this
point).
- Group some invocations where it makes sense.
dcd5e6e08117
dcd5e6e08117
dcd5e6e08117
c10934519e18
e994537dd735
e994537dd735
e994537dd735
e994537dd735
dcd5e6e08117
dcd5e6e08117
c10934519e18
e994537dd735
e994537dd735
e994537dd735
e994537dd735
dcd5e6e08117
dcd5e6e08117
c10934519e18
e994537dd735
c082a26b62ff
dcd5e6e08117
284ed92d40bb
c10934519e18
e994537dd735
c082a26b62ff
e994537dd735
a6633bcc83d1
a6633bcc83d1
a3d247bb2e09
a3d247bb2e09
0bc967a67750
0bc967a67750
0bc967a67750
c10934519e18
e994537dd735
e994537dd735
a6633bcc83d1
284ed92d40bb
7d6c2d8f03bf
c10934519e18
cb01d2d10fca
c082a26b62ff
7d6c2d8f03bf
97be416e882e
c10934519e18
e994537dd735
e994537dd735
c082a26b62ff
e994537dd735
e994537dd735
97be416e882e
97be416e882e
97be416e882e
aa7b596ef595
c10934519e18
e994537dd735
e994537dd735
aa7b596ef595
ec982756013f
ea92f99d9c33
5eb7821a1e4d
e994537dd735
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
ea92f99d9c33
d077bd1afabb
c10934519e18
d077bd1afabb
d077bd1afabb
d077bd1afabb
d077bd1afabb
c10934519e18
fcf5abdd3ad5
2d15529786b7
d077bd1afabb
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
c10934519e18
8d272d91d3d2
8d272d91d3d2
7cabc17c71c3
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
8d272d91d3d2
0ad9410c243a
c10934519e18
064760bdc9d5
064760bdc9d5
7cabc17c71c3
064760bdc9d5
064760bdc9d5
0ad9410c243a
0ad9410c243a
0ad9410c243a
0ad9410c243a
c10934519e18
064760bdc9d5
064760bdc9d5
7cabc17c71c3
064760bdc9d5
064760bdc9d5
0ad9410c243a
0ad9410c243a
0ad9410c243a
aa2802e42d9d
c10934519e18
e994537dd735
e994537dd735
e994537dd735
e994537dd735
7cabc17c71c3
aa2802e42d9d
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
5eb7821a1e4d
5eb7821a1e4d
5eb7821a1e4d
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
a6f0fe607199
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
5eb7821a1e4d
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
58e1c3121e77
308745f2c2a8
5eb7821a1e4d
e994537dd735
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
308745f2c2a8
308745f2c2a8
c10934519e18
b0e7faa211ae
a6f0fe607199
a6f0fe607199
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
f3f487ef0454
f3f487ef0454
f3f487ef0454
308745f2c2a8
dcd5e6e08117
b6f7eccea487
63d26c0b3d86
63d26c0b3d86
b1e6de7dd8a7
3a03065f2240
c10934519e18
3a03065f2240
3a03065f2240
3a03065f2240
9f804c9501da
c10934519e18
9f804c9501da
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
9f804c9501da
9f804c9501da
9f804c9501da
9f804c9501da
9f804c9501da
9f804c9501da
c10934519e18
9f804c9501da
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
9f804c9501da
9f804c9501da
c10934519e18
9f804c9501da
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
9f804c9501da
9f804c9501da
9f804c9501da
9f804c9501da
9f804c9501da
c10934519e18
9f804c9501da
a6f0fe607199
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
f3f487ef0454
9f804c9501da
922cda0a1834
9f804c9501da
a6f0fe607199
5eb7821a1e4d
a6f0fe607199
5eb7821a1e4d
5eb7821a1e4d
a6f0fe607199
a6f0fe607199
a6f0fe607199
a6f0fe607199
9f804c9501da
c10934519e18
9f804c9501da
a6f0fe607199
a6f0fe607199
f3f487ef0454
f3f487ef0454
f3f487ef0454
a6f0fe607199
922cda0a1834
9f804c9501da
9f804c9501da
c10934519e18
922cda0a1834
a6f0fe607199
922cda0a1834
fcf5abdd3ad5
922cda0a1834
eb9a1b525c77
eb9a1b525c77
c10934519e18
e994537dd735
e994537dd735
e994537dd735
e994537dd735
7cabc17c71c3
eb9a1b525c77
e29b656fbf7a
e29b656fbf7a
3a03065f2240
3a03065f2240
3a03065f2240
e29b656fbf7a
c10934519e18
e994537dd735
e994537dd735
e994537dd735
e994537dd735
7cabc17c71c3
c082a26b62ff
e29b656fbf7a
e29b656fbf7a
c10934519e18
e29b656fbf7a
e29b656fbf7a
c082a26b62ff
e29b656fbf7a
e29b656fbf7a
5eb7821a1e4d
3a03065f2240
5eb7821a1e4d
5eb7821a1e4d
3a03065f2240
e29b656fbf7a
e29b656fbf7a
e29b656fbf7a
c10934519e18
e994537dd735
e994537dd735
c082a26b62ff
881a85f08e22
881a85f08e22
c10934519e18
7387caca37f3
7387caca37f3
7387caca37f3
c10934519e18
fcf5abdd3ad5
7387caca37f3
7c07f17e46ba
---

- name: Set domain for slapd
  ansible.builtin.debconf:
    name: slapd
    question: slapd/domain
    vtype: string
    value: "{{ ldap_server_domain }}"

- name: Set organisation for slapd
  ansible.builtin.debconf:
    name: slapd
    question: shared/organization
    vtype: string
    value: "{{ ldap_server_organization }}"

- name: Install slapd
  ansible.builtin.apt:
    name: slapd
    state: present

- name: Allow OpenLDAP user to traverse the directory with TLS private keys
  ansible.builtin.user:
    name: openldap
    append: true
    groups: ssl-cert
  register: openldap_in_ssl_cert

- name: Restart slapd if group membership has changed (apply immediatelly)  # noqa no-handler
  # [no-handler] Tasks that run when changed should likely be handlers
  #   In order to be able to change LDAP server TLS configuration, it must be
  #   able to read both the private key and certificate. Therefore we need to
  #   immediatelly restart (since configuration is done live on the server.
  ansible.builtin.service:
    name: slapd
    state: restarted
  when: openldap_in_ssl_cert.changed

- name: Install Python LDAP bindings
  ansible.builtin.apt:
    name: python3-pyldap
    state: present

- name: Set-up LDAP server to listen on legacy SSL port
  ansible.builtin.lineinfile:
    dest: /etc/default/slapd
    state: present
    backrefs: true
    regexp: '^SLAPD_SERVICES=.*'
    line: 'SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"'
  notify:
    - Restart slapd

- name: Enable and start slapd service
  ansible.builtin.service:
    name: slapd
    state: started
    enabled: true

- name: Change log level for slapd
  community.general.ldap_attrs:
    dn: cn=config
    attributes:
      olcLogLevel: "{{ ldap_server_log_level }}"
    state: exact

- name: Test if LDAP misc schema has been applied
  ansible.builtin.command: "ldapsearch -H ldapi:/// -Q -LLL -A -Y EXTERNAL -b cn=schema,cn=config -s one '(cn={*}misc)' cn"
  register: ldap_misc_schema_present
  changed_when: false

- name: Deploy LDAP misc schema
  ansible.builtin.command: "ldapadd -H ldapi:/// -Q -Y EXTERNAL -f /etc/ldap/schema/misc.ldif"
  when: not ldap_misc_schema_present.stdout
  changed_when: true  # Always results in change due to task logic.

# Technically, the only thing this does is pick the size of DH
# parameters to use, with GnuTLS (against which slapd is linked
# against under Debian) picking a matching DH parameter from RFC-7919
# (https://www.ietf.org/rfc/rfc7919.txt).
- name: Generate the LDAP server Diffie-Hellman parameter
  community.crypto.openssl_dhparam:
    owner: root
    group: openldap
    mode: "0640"
    path: "/etc/ssl/private/{{ ansible_fqdn }}_ldap.dh.pem"
    size: 2048
  notify:
    - Restart slapd

- name: Deploy LDAP TLS private key
  ansible.builtin.template:
    src: "ldap_tls_key.j2"
    dest: "/etc/ssl/private/{{ ansible_fqdn }}_ldap.key"
    mode: "0640"
    owner: root
    group: openldap
  notify:
    - Restart slapd

- name: Deploy LDAP TLS certificate
  ansible.builtin.template:
    src: "ldap_tls_cert.j2"
    dest: "/etc/ssl/certs/{{ ansible_fqdn }}_ldap.pem"
    mode: "0644"
    owner: root
    group: root
  notify:
    - Restart slapd

- name: Deploy configuration file for checking certificate validity via cron
  ansible.builtin.copy:
    content: "/etc/ssl/certs/{{ ansible_fqdn }}_ldap.pem"
    dest: "/etc/check_certificate/{{ ansible_fqdn }}_ldap.conf"
    owner: root
    group: root
    mode: "0644"

- name: Configure TLS
  community.general.ldap_attrs:
    dn: cn=config
    attributes:
      olcTLSCertificateFile: "/etc/ssl/certs/{{ ansible_fqdn }}_ldap.pem"
      olcTLSCertificateKeyFile: "/etc/ssl/private/{{ ansible_fqdn }}_ldap.key"
      olcTLSDHParamFile: "/etc/ssl/private/{{ ansible_fqdn }}_ldap.dh.pem"
      olcTLSCipherSuite: "{{ ldap_tls_ciphers }}"
    state: exact

- name: Configure required SSF (make sure local unix socket connections are allowed)
  community.general.ldap_attrs:
    dn: cn=config
    attributes:
      olcLocalSSF: "{{ ldap_server_ssf }}"
      olcSecurity: "ssf={{ ldap_server_ssf }}"
    state: exact

- name: Enable the memberof module
  community.general.ldap_attrs:
    dn: "cn=module{0},cn=config"
    attributes:
      olcModuleLoad: "{1}memberof"
    state: present

- name: Enable the memberof overlay for database
  community.general.ldap_entry:
    dn: "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"
    objectClass:
      - olcConfig
      - olcMemberOf
      - olcOverlayConfig
    attributes:
      olcOverlay: memberof
      olcMemberOfRefInt: "TRUE"
      olcMemberOfGroupOC: groupOfUniqueNames
      olcMemberOfMemberAD: uniqueMember

- name: Apply database permissions
  m_ldap_permissions:
    filter: "(olcSuffix={{ ldap_server_int_basedn }})"
    rules: "{{ ldap_permissions }}"

- name: Drop the admin entry corresponding to olcRootDN for database from directory
  community.general.ldap_entry:
    dn: "cn=admin,{{ ldap_server_int_basedn }}"
    state: absent

- name: Create basic LDAP directory structure
  community.general.ldap_entry:
    dn: "ou={{ item }},{{ ldap_server_int_basedn }}"
    objectClass:
      - organizationalUnit
    attributes:
      ou: "{{ item }}"
  with_items:
    - people
    - groups
    - services

- name: Create the entry that will contain mail service information
  community.general.ldap_entry:
    dn: "ou=mail,ou=services,{{ ldap_server_int_basedn }}"
    objectClass:
      - organizationalUnit
    attributes:
      ou: mail

- name: Create LDAP directory structure for mail service
  community.general.ldap_entry:
    dn: "ou={{ item }},ou=mail,ou=services,{{ ldap_server_int_basedn }}"
    objectClass:
      - organizationalUnit
    attributes:
      ou: "{{ item }}"
  with_items:
    - domains
    - aliases

- name: Create or remove login entries for services
  community.general.ldap_entry:
    dn: "cn={{ item.name }},ou=services,{{ ldap_server_int_basedn }}"
    objectClass:
      - applicationProcess
      - simpleSecurityObject
    attributes:
      cn: "{{ item.name }}"
      userPassword: "{{ item.password }}"
    state: "{{ item.state | default('present') }}"
  with_items: "{{ ldap_server_consumers }}"

- name: Update services login passwords
  community.general.ldap_attrs:
    dn: "cn={{ item.name }},ou=services,{{ ldap_server_int_basedn }}"
    attributes:
      userPassword: "{{ item.password }}"
    state: exact
  with_items: "{{ ldap_server_consumers }}"
  when: "item.state | default('present') == 'present'"

- name: Create or remove user-supplied groups
  community.general.ldap_entry:
    dn: "cn={{ item.name }},ou=groups,{{ ldap_server_int_basedn }}"
    objectClass:
      - groupOfUniqueNames
    attributes:
      cn: "{{ item.name }}"
      uniqueMember: "cn=NONE"
    state: "{{ item.state | default('present') }}"
  with_items: "{{ ldap_server_groups }}"

- name: Create user-supplied LDAP entries
  community.general.ldap_entry:
    dn: "{{ item.dn }}"
    objectClass: "{{ item.attributes.objectClass }}"
    attributes: "{{ item.attributes }}"
    state: "{{ item.state | default('present') }}"
  with_items: "{{ ldap_entries }}"

- name: Deploy firewall configuration for LDAP
  ansible.builtin.copy:
    src: "ferm_ldap.conf"
    dest: "/etc/ferm/conf.d/10-ldap.conf"
    owner: root
    group: root
    mode: "0640"
  notify:
    - Restart ferm

# @TODO: This whole thing could be dropped if newer version of Ansible
#        was in use (where community collection has the ldap_search
#        module.
- name: Deploy temporary file with LDAP admin password
  ansible.builtin.template:
    src: "ldap_admin_password.j2"
    dest: "/root/.ldap_admin_password"
    owner: root
    group: root
    mode: "0400"
  changed_when: false

- name: Test if LDAP admin password needs to be changed
  ansible.builtin.command: "ldapwhoami -H ldapi:/// -D 'cn=admin,{{ ldap_server_int_basedn }}' -x -y /root/.ldap_admin_password"
  register: ldap_admin_password_check
  changed_when: ldap_admin_password_check.rc != 0
  failed_when: false

- name: Update LDAP admin password
  community.general.ldap_attrs:
    dn: "olcDatabase={1}mdb,cn=config"
    attributes:
      olcRootPW: "{{ ldap_admin_password | ldap_password_hash }}"
    state: exact
  when: ldap_admin_password_check.rc != 0

- name: Remove temporary file with LDAP admin password
  ansible.builtin.file:
    path: "/root/.ldap_admin_password"
    state: absent
  changed_when: false

- name: Enable backup
  ansible.builtin.include_tasks: backup.yml
  when: enable_backup

- name: Explicitly run all handlers
  ansible.builtin.include_tasks: ../handlers/main.yml
  when: "run_handlers | default(False) | bool()"
  tags:
    - handlers