# XXX If #742056 gets fixed, we should preseed slapd to use peercreds as
# RootDN once the fix enters stable.
- name: Install OpenLDAP
  apt: pkg={{ packages }}
  vars:
    packages:
    - slapd
    - ldap-utils
    - ldapvi
    - db-util
    - python3-ldap
    # for the 'slapd2' munin plugin
    - libnet-ldap-perl
    - libauthen-sasl-perl

- name: Configure slapd
  template: src=etc/default/slapd.j2
            dest=/etc/default/slapd
            owner=root group=root
            mode=0644
  register: r1
  notify:
    - Restart slapd

- name: Create directory /etc/ldap/ssl
  file: path=/etc/ldap/ssl
        state=directory
        owner=root group=root
        mode=0755
  tags:
    - genkey

- name: Generate a private key and a X.509 certificate for slapd
  command: genkeypair.sh x509
                         --pubkey=/etc/ldap/ssl/{{ item.name }}.pem
                         --privkey=/etc/ldap/ssl/{{ item.name }}.key
                         --ou=LDAP {{ item.ou }} --cn={{ item.name }}
                         --usage=digitalSignature,keyEncipherment
                         -t ed25519
                         --owner=root --group=openldap --mode=0640
  register: r2
  changed_when: r2.rc == 0
  failed_when: r2.rc > 1
  with_items:
    - { group: 'LDAP_provider', name: ldap.fripost.org, ou:               }
    - { group: 'MX',            name: mx,               ou: --ou=SyncRepl }
    - { group: 'lists',         name: lists,            ou: --ou=SyncRepl }
  when: "item.group in group_names"
  notify:
    - Restart slapd
  tags:
    - genkey

- name: Fetch the SyncProv's X.509 certificate
  # Ensure we don't fetch private data
  become: False
  fetch_cmd: cmd="openssl x509"
             stdin=/etc/ldap/ssl/ldap.fripost.org.pem
             dest=certs/ldap/ldap.fripost.org.pem
  when: "'LDAP_provider' in group_names"
  tags:
    - genkey

- name: Fetch slapd's X.509 certificate
  # Ensure we don't fetch private data
  become: False
  fetch_cmd: cmd="openssl x509"
             stdin=/etc/ldap/ssl/{{ item.name }}.pem
             dest=certs/ldap/syncrepl/{{ item.name }}@{{ inventory_hostname_short }}.pem
  with_items:
    - { group: 'MX',            name: mx               }
    - { group: 'lists',         name: lists            }
  when: "item.group in group_names"
  tags:
    - genkey

- name: Copy the SyncProv's server certificate
  copy: src=certs/ldap/ldap.fripost.org.pem
        dest=/etc/ldap/ssl/ldap.fripost.org.pem
        owner=root group=root
        mode=0644
  when: "'LDAP_provider' not in group_names"
  tags:
    - genkey

- name: Copy the SyncRepls's client certificates
  assemble: src=certs/ldap/syncrepl remote_src=no
            dest=/etc/ldap/ssl/syncrepl.pem
            owner=root group=root
            mode=0644
  when: "'LDAP_provider' in group_names"
  tags:
    - genkey
  register: r3
  notify:
    - Restart slapd

- name: Start slapd
  service: name=slapd state=started
  when: not (r1.changed or r2.changed or r3.changed)

- meta: flush_handlers

- name: Copy fripost & amavis' schema
  copy: src=etc/ldap/schema/{{ item }}
        dest=/etc/ldap/schema/{{ item }}
        owner=root group=root
        mode=0644
  # It'd certainly be nicer if we didn't have to deploy amavis' schema
  # everywhere, but we need the 'objectClass' in our replicates, hence
  # they need to be aware of the 'amavisAccount' class.
  with_items:
    - fripost.ldif
    - amavis.schema
  tags:
    - amavis

- name: Load amavis' schema
  openldap: target=/etc/ldap/schema/amavis.schema
            format=slapd.conf name=amavis

- name: Load Fripost' schema
  openldap: target=/etc/ldap/schema/fripost.ldif

- name: Load the back_monitor overlay
  openldap: module=back_monitor

# We assume a clean (=stock) cn=config
- name: Configure the LDAP database
  openldap: target=etc/ldap/database.ldif.j2 local=template

# On read-only replicates, you might have to temporarily switch back to
# read-write, delete the SyncRepl, and delete the DN manually:
#     sudo ldapdelete -Y EXTERNAL -H ldapi:// cn=admin,dc=fripost,dc=org
- name: Remove cn=admin,dc=fripost,dc=org
  openldap: name="cn=admin,dc=fripost,dc=org" delete=entry

- name: Remove the rootDN under the 'config' database
  openldap: name="olcDatabase={0}config,cn=config" delete=olcRootDN,olcRootPW

- name: Copy /usr/local/sbin/slapcat-all.sh
  copy: src=usr/local/sbin/slapcat-all.sh
        dest=/usr/local/sbin/slapcat-all.sh
        owner=root group=staff
        mode=0755


- name: Install 'slapd2' Munin plugin
  # we don't install 'slapd_' because it doesn't support SASL binds and
  # ours is more parcimonious with LDAP connections
  file: src=/usr/local/share/munin/plugins/slapd2
        dest=/etc/munin/plugins/slapd2
        owner=root group=root
        state=link force=yes
  tags:
    - munin
    - munin-node
  notify:
    - Restart munin-node