Default variables

LDAP schemas

These variables define what additional LDAP schemas will be imported by the debops.slapd role to the managed OpenLDAP server. See custom LDAP schemas for more details.

slapd__rfc2307bis_enabled

Enable or disable support for an upgraded nis schema defined as rfc2307bis, that changes the posixGroup object type from STRUCTURAL to AUXILIARY. This allows better management of UNIX groups in the LDAP directory, but may require additional changes in existing databases. See the rfc2307bis schema for more details.

slapd__rfc2307bis_enabled: '{{ ansible_local.slapd.rfc2307bis|d(True)|bool }}'
slapd__debops_schema_path

Absolute path to the directory that contains custom DebOps schema definitions on the remote host.

slapd__debops_schema_path: '/etc/ldap/schema/debops'
slapd__default_schemas

List of the default LDAP schemas imported into the OpenLDAP server, defined by the role.

slapd__default_schemas:

  # Base schema for LDAP schemas developed in DebOps, other custom schemas will
  # depend on object identifiers defined here
  - '{{ slapd__debops_schema_path + "/debops.schema" }}'

  # Custom DebOps schema that defines the missing 'gid' posixGroup attribute
  - '{{ slapd__debops_schema_path + "/posixgroupid.schema" }}'

  # Custom DebOps schema that creates LDAP object definitions used for tracking
  # the next available POSIX UID/GID numbers
  - '{{ slapd__debops_schema_path + "/nextuidgid.schema" }}'

  # Custom DebOps schema that creates LDAP object definition of the
  # 'organizationalStructure' object, used to define basic directory structure.
  - '{{ slapd__debops_schema_path + "/orgstructure.schema" }}'

  # Password Policy schema, included in the 'slapd' APT package
  - '/etc/ldap/schema/ppolicy.schema'

  # Support for 'host' and 'authorizedService' attributes, useful for granular
  # access control to services and machines
  - '/etc/ldap/schema/fusiondirectory/ldapns.schema'

  # Custom schema which defines a 'groupOfEntries' LDAP object which can create
  # empty groups
  - '{{ slapd__debops_schema_path + "/groupofentries.schema" }}'

  # Support for SSH public keys in LDAP directory
  - '{{ slapd__debops_schema_path + "/openssh-lpk.schema" }}'

  # Support for 'sudo' rules in LDAP directory
  - '/etc/ldap/schema/fusiondirectory/sudo.schema'

  # Support for 'eduPerson' and 'eduOrg' schema, included in DebOps
  - '{{ slapd__debops_schema_path + "/eduperson.schema" }}'

  # Support for 'schac' schema, SCHema for ACademia
  - '{{ slapd__debops_schema_path + "/schac.schema" }}'

  # Support for 'nextcloud' schema, included in DebOps
  - '{{ slapd__debops_schema_path + "/nextcloud.schema" }}'

  # Custom DebOps schema that defines mail-related LDAP objects and attributes
  - '{{ slapd__debops_schema_path + "/mailservice.schema" }}'

  # Custom DebOps schema that adds support for Dynamic Groups maintained by AutoGroup overlay
  - '{{ slapd__debops_schema_path + "/dyngroup.schema" }}'

  # Base schema for FreeRADIUS LDAP objects, which defines objectIdentifiers
  # for other FreeRADIUS schema files included in DebOps
  - '{{ slapd__debops_schema_path + "/freeradius.schema" }}'

  # FreeRADIUS RADIUS Client schema
  - '{{ slapd__debops_schema_path + "/freeradius-client.schema" }}'

  # FreeRADIUS RADIUS Profile schema
  - '{{ slapd__debops_schema_path + "/freeradius-profile.schema" }}'

  # FreeRADIUS RADIUS Accounting schema
  - '{{ slapd__debops_schema_path + "/freeradius-radacct.schema" }}'

  # FreeRADIUS DHCPv4 schema
  - '{{ slapd__debops_schema_path + "/freeradius-dhcpv4.schema" }}'

  # FreeRADIUS DHCPv6 schema
  - '{{ slapd__debops_schema_path + "/freeradius-dhcpv6.schema" }}'
slapd__schemas

Lisf of LDAP schemas imported into the OpenLDAP server on all hosts in the Ansible inventory.

slapd__schemas: []
slapd__group_schemas

List of LDAP schemas imported into the OpenLDAP server on hosts in a specific Ansible inventory group.

slapd__group_schemas: []
slapd__host_schemas

List of LDAP schemas imported into the OpenLDAP server on specific hosts in the Ansible inventory.

slapd__host_schemas: []
slapd__combined_schemas

Variable which combines all of the schema lists together and is used in the role tasks. The list is not merged intelligently and is only additive.

slapd__combined_schemas: '{{ slapd__default_schemas
                             + slapd__schemas
                             + slapd__group_schemas
                             + slapd__host_schemas }}'

APT packages

slapd__base_packages

List of required APT packages for OpenLDAP service.

slapd__base_packages: [ 'slapd', 'ldap-utils', 'ssl-cert', 'libldap-common' ]
slapd__rfc2307bis_packages

List of APT packages to install in preparation to use rfc2307bis schema instead of the nis schema.

slapd__rfc2307bis_packages: [ 'fusiondirectory-schema' ]
slapd__schema_packages

List of APT packages that contain LDAP schemas loaded into the directory by the server. Debian has multiple fusiondirectory-*-schema and gosa-*-schema packages that conflict with each other, therefore the list of packages should be synchronized.

slapd__schema_packages:

  # Support for 'sudo' rules in LDAP
  - 'fusiondirectory-plugin-sudo-schema'
slapd__packages

List of additional APT packages to install with OpenLDAP service.

slapd__packages: []

OpenLDAP UNIX environment

slapd__user

Name of the UNIX account used by the OpenLDAP service.

slapd__user: 'openldap'
slapd__group

Name of the UNIX group used by the OpenLDAP service.

slapd__group: 'openldap'
slapd__additional_groups

List of additional UNIX groups the OpenLDAP account should have access to.

slapd__additional_groups: [ 'ssl-cert' ]
slapd__additional_database_dirs

The default "main" OpenLDAP database is stored in the /var/lib/ldap/ directory. This variable contains a list of additional database directories which should be present on the host, specified as absolute paths. These directories will be owned by the OpenLDAP UNIX account and can be used to store additional OpenLDAP databases.

slapd__additional_database_dirs: []
slapd__log_dir

Absolute path to the directory which contains OpenLDAP logs.

slapd__log_dir: '/var/log/slapd'

LDAP database environment

slapd__domain

DNS domain name which will be used for OpenLDAP BaseDN. This value is also defined in the debconf database before OpenLDAP installation to create the BaseDN LDAP object in the initialized database.

slapd__domain: '{{ ansible_domain }}'
slapd__base_dn

BaseDN value of the main OpenLDAP server that contains the LDAP data, defined as a YAML list.

slapd__base_dn: '{{ slapd__domain.split(".")
                    | map("regex_replace", "^(.*)$", "dc=\1")
                    | list }}'
slapd__basedn

BaseDN value of the main OpenLDAP server that contains the LDAP data, defined as a string.

slapd__basedn: '{{ slapd__base_dn | join(",") }}'
slapd__superuser_config_password

The hashed password defined for the superuser of the cn=config LDAP database.

slapd__superuser_config_password: '{{ "{CRYPT}" + lookup("password", secret
                                                         + "/slapd/credentials/"
                                                         + slapd__config_rootdn | to_uuid + ".password"
                                                         + " encrypt=sha512_crypt length=32") }}'
slapd__config_rootdn

The Distinguished Name of the cn=config database root account.

slapd__config_rootdn: 'cn=admin,cn=config'
slapd__config_rootpw

The plaintext password of the cn=config database root account, useful for Sync Replication authentication.

slapd__config_rootpw: '{{ lookup("file", secret + "/slapd/credentials/"
                                         + slapd__config_rootdn | to_uuid
                                         + ".password").split()[0] }}'
slapd__superuser_data_password

The password defined for the superuser of the main LDAP database.

slapd__superuser_data_password: '{{ "{CRYPT}" + lookup("password", secret
                                                       + "/slapd/credentials/"
                                                       + slapd__data_rootdn | to_uuid + ".password"
                                                       + " encrypt=sha512_crypt length=32") }}'
slapd__data_rootdn

The Distinguished Name of the main database root account.

slapd__data_rootdn: '{{ ([ "cn=admin" ] + slapd__base_dn) | join(",") }}'
slapd__data_rootpw

The plaintext password of the cn=config database root account, useful for Sync Replication authentication.

slapd__data_rootpw: '{{ lookup("file", secret + "/slapd/credentials/"
                                       + slapd__data_rootdn | to_uuid
                                       + ".password").split()[0] }}'

LDAP POSIX environment

These variables define default parameters of the POSIX environment expected by the LDAP directory, not the OpenLDAP service itself. These parameters should be the same as the POSIX environment defined in the debops.ldap Ansible role for consistency. See LDAP - POSIX environment integration for more details.

slapd__uid_gid_min

First UID/GID which is considered to be managed by the LDAP directory and not by the local NSS database.

slapd__uid_gid_min: '2000000000'
slapd__groupid_min

First UID/GID reserved for shared groups in the LDAP directory. Default: the same as the start of the LDAP directory UID/GID range.

slapd__groupid_min: '{{ slapd__uid_gid_min }}'
slapd__groupid_max

Last UID/GID reserved for shared groups in the LDAP directory. Higher UID/GID numbers are meant to be used for people, machine or service accounts with matching User Private Groups. Default: 2001999999

Ref: https://wiki.debian.org/UserPrivateGroups

slapd__groupid_max: '{{ slapd__uid_gid_min|int + 1999999 }}'
slapd__uid_gid_max

Last UID/GID which is considered to be managed by the LDAP directory and not by the local NSS database. Default: 2099999999

slapd__uid_gid_max: '{{ slapd__uid_gid_min|int + 99999999 }}'

LDAP database tuning

slapd__saslauthd_enabled

Boolean, whether the saslauthd configuration should be managed.

slapd__saslauthd_enabled: True
slapd__data_max_size

Specify the maximum size of the main database, in bytes, default is 10 GB. The value shouldn't be smaller than the size of the existing data; increasing the existing size should be safe.

slapd__data_max_size: '{{ (1024 * 1024 * 1024) * 10 }}'

Support for DebOps PKI and TLS

slapd__pki

Enable or disable support for X.509 certificates using the debops.pki Ansible role.

slapd__pki: '{{ ansible_local.pki.enabled|d(False) | bool }}'
slapd__pki_path

Absolute path to the directory that contains PKI realms.

slapd__pki_path: '{{ ansible_local.pki.base_path|d("/etc/pki/realms") }}'
slapd__pki_realm

Default PKI realm used by the OpenLDAP server. In a multi-master clustered setup the configuration is shared, therefore all cluster nodes should use the same PKI realm name.

slapd__pki_realm: '{{ slapd__domain
                      if (slapd__domain in ansible_local.pki.known_realms|d([]))
                      else ansible_local.pki.realm|d("domain") }}'
slapd__pki_ca

Name of the Root CA certificate file used by the OpenLDAP server, relative to the PKI realm directory.

slapd__pki_ca: 'CA.crt'
slapd__pki_crt

Name of the X.509 certificate file used by the OpenLDAP server, relative to the PKI realm directory.

slapd__pki_crt: 'default.crt'
slapd__pki_key

Name of the private key used by the OpenLDAP server, relative to the PKI realm directory.

slapd__pki_key: 'default.key'
slapd__dhparam_set

Specify the Diffie-Hellman parameter set to use by the OpenLDAP server. See debops.dhparam Ansible role for more details.

slapd__dhparam_set: 'default'
slapd__dhparam_file

Absolute path to the file with Diffie-Hellman parameters used by the OpenLDAP server. If it's empty, the custom Diffie-Hellman parameters will not be configured.

slapd__dhparam_file: '{{ ansible_local.dhparam[slapd__dhparam_set]|d("") }}'
slapd__tls_ca_certificate

Absolute path to the Root CA certificate used by the OpenLDAP server to authenticate TLS client certificates.

slapd__tls_ca_certificate: '{{ slapd__pki_path + "/" + slapd__pki_realm + "/" + slapd__pki_ca }}'
slapd__tls_certificate

Absolute path to the X.509 certificate used by the OpenLDAP server.

slapd__tls_certificate: '{{ slapd__pki_path + "/" + slapd__pki_realm + "/" + slapd__pki_crt }}'
slapd__tls_private_key

Absolute path to the private key used by the OpenLDAP server.

slapd__tls_private_key: '{{ slapd__pki_path + "/" + slapd__pki_realm + "/" + slapd__pki_key }}'
slapd__tls_cipher_suite

TLS cipher suite required by the server. On Debian, you need to use the GnuTLS cipher suite names, because slapd daemon is compiled against GnuTLS instead of OpenSSL.

slapd__tls_cipher_suite: 'SECURE256:PFS:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:-SHA1:-ARCFOUR-128'

OpenLDAP configuration tasks

These variables define a dynamic set of tasks to perform in the OpenLDAP server cn=config database. See slapd__tasks for more details.

slapd__default_tasks

List of the default tasks performed on the OpenLDAP server, defined by the role.

slapd__default_tasks:

  - name: 'Define the maximum size of the main database'
    dn: [ 'olcDatabase={1}mdb', 'cn=config' ]
    attributes:
      olcDbMaxSize: '{{ slapd__data_max_size }}'
    state: 'exact'

  - name: 'Load dynamic OpenLDAP modules'
    dn: 'cn=module{0},cn=config'
    attributes:
      olcModuleLoad:
        - '{0}back_mdb'
        - '{1}syncprov'
        - '{2}ppolicy'
        - '{3}unique'
        - '{4}memberof'
        - '{5}refint'
        - '{6}auditlog'
        - '{7}constraint'
        - '{8}back_monitor'
        - '{9}lastbind'
        - '{10}autogroup'
    ordered: True

  - name: 'Enable Sync Provider overlay in the cn=config database'
    dn: 'olcOverlay={0}syncprov,olcDatabase={0}config,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcSyncProvConfig' ]
    attributes:
      olcOverlay: '{0}syncprov'

  - name: 'Enable Sync Provider overlay in the main database'
    dn: 'olcOverlay={0}syncprov,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcSyncProvConfig' ]
    attributes:
      olcOverlay: '{0}syncprov'

  - name: 'Enable Password Policy overlay in the main database'
    dn: 'olcOverlay={1}ppolicy,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcPPolicyConfig' ]
    attributes:
      olcOverlay: '{1}ppolicy'

  - name: 'Enable Unique overlay in the main database'
    dn: 'olcOverlay={2}unique,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcUniqueConfig' ]
    attributes:
      olcOverlay: '{2}unique'

  - name: 'Enable memberOf overlay in the main database for groupOfNames'
    dn: 'olcOverlay={3}memberof,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcMemberOf' ]
    attributes:
      olcOverlay: '{3}memberof'

  - name: 'Enable memberOf overlay in the main database for groupOfEntries'
    dn: 'olcOverlay={4}memberof,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcMemberOf' ]
    attributes:
      olcOverlay: '{4}memberof'

  - name: 'Enable memberOf overlay in the main database for AutoGroups'
    dn: 'olcOverlay={5}memberof,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcMemberOf' ]
    attributes:
      olcOverlay: '{5}memberof'

  - name: 'Enable memberOf overlay in the main database for Roles'
    dn: 'olcOverlay={6}memberof,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcMemberOf' ]
    attributes:
      olcOverlay: '{6}memberof'

  - name: 'Enable Referential Integrity overlay in the main database'
    dn: 'olcOverlay={7}refint,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcRefintConfig' ]
    attributes:
      olcOverlay: '{7}refint'

  - name: 'Enable Audit Logging overlay in the main database'
    dn: 'olcOverlay={8}auditlog,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcAuditLogConfig' ]
    attributes:
      olcOverlay: '{8}auditlog'

  - name: 'Enable Constraint overlay in the main database'
    dn: 'olcOverlay={9}constraint,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcConstraintConfig' ]
    attributes:
      olcOverlay: '{9}constraint'

  - name: 'Enable AutoGroup overlay in the main database'
    dn: 'olcOverlay={10}autogroup,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcAutomaticGroups' ]
    attributes:
      olcOverlay: '{10}autogroup'

  - name: 'Enable LastBind overlay in the main database'
    dn: 'olcOverlay={11}lastbind,olcDatabase={1}mdb,cn=config'
    objectClass: [ 'olcOverlayConfig', 'olcLastBindConfig' ]
    attributes:
      olcOverlay: '{11}lastbind'

  - name: 'Configure Password Policy overlay in the main database'
    dn: 'olcOverlay={1}ppolicy,olcDatabase={1}mdb,cn=config'
    attributes:
      olcPPolicyDefault: 'cn=Default Password Policy,ou=Password Policies,{{ slapd__basedn }}'
      olcPPolicyHashCleartext: 'TRUE'
      olcPPolicyUseLockout: 'FALSE'
      olcPPolicyForwardUpdates: 'FALSE'
    state: 'exact'

  - name: 'Configure Unique overlay in the main database'
    dn: 'olcOverlay={2}unique,olcDatabase={1}mdb,cn=config'
    attributes:
      olcUniqueURI:
        - 'ldap:///{{ slapd__basedn }}?uidNumber?sub'
        - 'ldap:///{{ slapd__basedn }}?gidNumber?sub'
        - 'ldap:///{{ slapd__basedn }}?mail?sub'
        - 'ldap:///{{ slapd__basedn }}?mailAddress,mailAlternateAddress?sub'
        - 'ldap:///ou=People,{{ slapd__basedn }}?employeeNumber?sub'
        - 'ldap:///ou=People,{{ slapd__basedn }}?uid?sub'
        - 'ldap:///ou=People,{{ slapd__basedn }}?gid?sub'
    state: 'exact'

  - name: 'Configure memberOf overlay in the main database for groupOfNames'
    dn: 'olcOverlay={3}memberof,olcDatabase={1}mdb,cn=config'
    attributes:
      olcMemberOfDangling: 'ignore'
      olcMemberOfRefInt: 'TRUE'
      olcMemberOfGroupOC: 'groupOfNames'
      olcMemberOfMemberAD: 'member'
      olcMemberOfMemberOfAD: 'memberOf'
    state: 'exact'

  - name: 'Configure memberOf overlay in the main database for groupOfEntries'
    dn: 'olcOverlay={4}memberof,olcDatabase={1}mdb,cn=config'
    attributes:
      olcMemberOfDangling: 'ignore'
      olcMemberOfRefInt: 'TRUE'
      olcMemberOfGroupOC: 'groupOfEntries'
      olcMemberOfMemberAD: 'member'
      olcMemberOfMemberOfAD: 'memberOf'
    state: 'exact'

  - name: 'Configure memberOf overlay in the main database for AutoGroups'
    dn: 'olcOverlay={5}memberof,olcDatabase={1}mdb,cn=config'
    attributes:
      olcMemberOfDangling: 'ignore'
      olcMemberOfRefInt: 'TRUE'
      olcMemberOfGroupOC: 'groupOfURLs'
      olcMemberOfMemberAD: 'member'
      olcMemberOfMemberOfAD: 'memberOf'
    state: 'exact'

  - name: 'Configure memberOf overlay in the main database for Roles'
    dn: 'olcOverlay={6}memberof,olcDatabase={1}mdb,cn=config'
    attributes:
      olcMemberOfDangling: 'ignore'
      olcMemberOfRefInt: 'TRUE'
      olcMemberOfGroupOC: 'organizationalRole'
      olcMemberOfMemberAD: 'roleOccupant'
      olcMemberOfMemberOfAD: 'memberOf'
    state: 'exact'

  - name: 'Configure Referential Integrity overlay in the main database'
    dn: 'olcOverlay={7}refint,olcDatabase={1}mdb,cn=config'
    attributes:
      olcRefintAttribute:
        - 'member'
        - 'memberOf'
        - 'uniqueMember'
        - 'manager'
        - 'owner'
        - 'roleOccupant'
        - 'seeAlso'
        - 'secretary'
        - 'documentAuthor'
    state: 'exact'

  - name: 'Configure Audit Logging overlay in the main database'
    dn: 'olcOverlay={8}auditlog,olcDatabase={1}mdb,cn=config'
    attributes:
      olcAuditlogFile: '{{ slapd__log_dir + "/slapd-auditlog-main.ldif" }}'
    state: 'exact'

  - name: 'Configure Constraint overlay in the main database'
    dn: 'olcOverlay={9}constraint,olcDatabase={1}mdb,cn=config'
    attributes:
      olcConstraintAttribute:
        - 'jpegPhoto size 524288'  # 512 KiB
        - 'userPassword count 5'
        - 'employeeNumber regex ^[[:digit:]]+$'
        - 'uidNumber regex ^[[:digit:]]+$'
        - 'gidNumber regex ^[[:digit:]]+$'
        - 'macAddress regex ^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'
        - 'mailAddress set "this/mailAddress & this/mail"'
        - 'mailAlternateAddress set "this/mailAlternateAddress & this/mail"'
    state: 'exact'

  - name: 'Configure AutoGroup overlay in the main database'
    dn: 'olcOverlay={10}autogroup,olcDatabase={1}mdb,cn=config'
    attributes:
      olcAGattrSet:
        - '{0}groupOfURLs memberURL member'
      olcAGmemberOfAd: 'memberOf'
    state: 'exact'

  - name: 'Configure LastBind overlay in the main database'
    dn: 'olcOverlay={11}lastbind,olcDatabase={1}mdb,cn=config'
    attributes:
      olcLastBindPrecision: '{{ (60 * 60 * 24) }}'
    state: 'exact'

  - name: 'Configure the OpenLDAP server log level'
    dn: 'cn=config'
    attributes:
      olcLogLevel: 'none'
    state: 'exact'

  - name: 'Define the default password hashing method'
    dn: [ 'olcDatabase={-1}frontend', 'cn=config' ]
    attributes:
      olcPasswordHash: '{CRYPT}'
    state: 'exact'

  - name: 'Configure password salt format used by the crypt(3) hash function'
    dn: 'cn=config'
    attributes:
      olcPasswordCryptSaltFormat: '$6$rounds=100001$%.16s'
    state: 'exact'

  - name: 'Set the cn=config database root credentials'
    dn: [ 'olcDatabase={0}config', 'cn=config' ]
    attributes:
      olcRootDN: '{{ slapd__config_rootdn }}'
      olcRootPW: '{{ slapd__superuser_config_password }}'
    state: 'exact'
    no_log: True

  - name: 'Set the cn=config database access control list'
    dn: [ 'olcDatabase={0}config', 'cn=config' ]
    attributes:
      olcAccess:
        - |-
          {0}to dn.subtree="cn=config"
             by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
             by group/organizationalRole/roleOccupant.exact="cn=LDAP Administrator, ou=Roles,{{ slapd__basedn }}" manage
             by * break
    state: 'exact'

  - name: 'Set the main database root credentials'
    dn: [ 'olcDatabase={1}mdb', 'cn=config' ]
    attributes:
      olcRootDN: '{{ slapd__data_rootdn }}'
      olcRootPW: '{{ slapd__superuser_data_password }}'
    state: 'exact'
    no_log: True

  - name: 'Configure idle and write timeouts'
    dn: 'cn=config'
    attributes:
      olcIdleTimeout: '900'
      olcWriteTimeout: '900'
    state: 'exact'

  - name: 'Configure TLS certificates'
    dn: 'cn=config'
    attributes:
      olcTLSCACertificateFile:  '{{ slapd__tls_ca_certificate }}'
      olcTLSCertificateFile:    '{{ slapd__tls_certificate }}'
      olcTLSCertificateKeyFile: '{{ slapd__tls_private_key }}'
    state: '{{ "exact" if slapd__pki|bool else "init" }}'

  - name: 'Configure Diffie-Hellman parameters'
    dn: 'cn=config'
    attributes:
      olcTLSDHParamFile: '{{ slapd__dhparam_file }}'
    state: '{{ "exact" if (slapd__pki|bool and slapd__dhparam_file|d()) else "init" }}'

  - name: 'Configure TLS cipher suites'
    dn: 'cn=config'
    attributes:
      olcTLSCipherSuite: '{{ slapd__tls_cipher_suite }}'
    state: '{{ "exact" if slapd__pki|bool else "init" }}'

  - name: 'Set default Security Strength Factors enforced by the server'
    dn: 'cn=config'
    attributes:
      olcLocalSSF: '128'
      olcSecurity: 'ssf=128 update_ssf=128 simple_bind=128'
    state: '{{ "exact" if slapd__pki|bool else "init" }}'

  - name: 'Configure supported SASL authentication methods'
    dn: 'cn=config'
    attributes:
      olcSaslSecProps: 'noanonymous,minssf={{ "128" if slapd__pki|bool else "0" }}'
    state: 'exact'

    # Warning: OpenLDAP v2.4.x requires a restart when this attribute is changed
  - name: 'Define SASL regex matching rules'
    dn: 'cn=config'
    attributes:
      olcAuthzRegexp:
        - '{0}uid=([^,]*),cn=[^,]*,cn=auth uid=$1,ou=People,{{ slapd__basedn }}'
        - '{1}uid=([^,]*),cn=([^,]*),cn=[^,]*,cn=auth ldap:///ou=Hosts,{{ slapd__basedn }}??sub?(&(objectClass=account)(uid=$1)(host=$2))'
    state: 'exact'

  - name: 'Define indexes present in the main database'
    dn: [ 'olcDatabase={1}mdb', 'cn=config' ]
    attributes:
      olcDbIndex:
        - 'dc eq'
        - 'cn,uid eq'
        - 'member,memberUid eq'
        - 'roleOccupant eq'
        - 'memberOf eq'
        - 'objectClass eq'
        - 'sn eq,pres'
        - 'gn eq,pres'
        - 'gecos eq,pres'
        - 'homeDirectory,loginShell eq'
        - 'employeeNumber eq'
        - 'uidNumber,gidNumber eq'
        - 'entryCSN,entryUUID eq'
        - 'sudoHost,sudoUser eq,sub'
        - 'modifyTimestamp eq'
        - 'authorizedService eq'
        - 'host eq,sub'
        - 'gid eq'
        - 'mail eq,sub'
        - 'mailAddress eq,sub'
        - 'mailAlternateAddress eq,sub'

  - name: 'Enable the monitor database'
    dn: 'olcDatabase={2}monitor,cn=config'
    objectClass: [ 'olcDatabaseConfig', 'olcMonitorConfig' ]
    attributes:
      olcDatabase: '{2}monitor'
      olcAccess:
        - |-
          {0}to dn.subtree="cn=Monitor"
             by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth read
             by group/organizationalRole/roleOccupant.exact="cn=LDAP Administrator, ou=Roles,{{ slapd__basedn }}" read
             by group/organizationalRole/roleOccupant.exact="cn=LDAP Monitor,       ou=Roles,{{ slapd__basedn }}" read
             by group/groupOfNames/member.exact="cn=LDAP Administrators, ou=System Groups,{{ slapd__basedn }}" read
             by group/groupOfNames/member.exact="cn=LDAP Monitors,       ou=System Groups,{{ slapd__basedn }}" read
             by * none
    state: 'present'
slapd__acl_tasks

Separate list of tasks performed on the OpenLDAP server, defined by the role, meant for the Access Control List configuration. Check the LDAP Access Control List documentation for more details.

slapd__acl_tasks:

  - name: 'Configure Access Control List'
    dn: 'olcDatabase={1}mdb,cn=config'
    ordered: True
    attributes:
      olcAccess:

        - |-
          to dn.subtree="{{ slapd__basedn }}"
          by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Administrator, ou=Roles,{{ slapd__basedn }}" manage
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Replicator,    ou=Roles,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=LDAP Administrators, ou=System Groups,{{ slapd__basedn }}" manage
          by group/groupOfNames/member.exact="cn=LDAP Replicators,    ou=System Groups,{{ slapd__basedn }}" read
          by * break

        - |-
          to dn.subtree="{{ slapd__basedn }}" filter="(memberOf=cn=Hidden Objects, ou=Groups,{{ slapd__basedn }})"
             attrs="children,entry"
          by self break
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Administrator,    ou=Roles,{{ slapd__basedn }}" break
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor,           ou=Roles,{{ slapd__basedn }}" break
          by group/organizationalRole/roleOccupant.exact="cn=Hidden Object Viewer,  ou=Roles,{{ slapd__basedn }}" break
          by group/groupOfNames/member.exact="cn=LDAP Administrators,    ou=System Groups,{{ slapd__basedn }}" break
          by group/groupOfNames/member.exact="cn=LDAP Editors,           ou=System Groups,{{ slapd__basedn }}" break
          by * none

        - |-
          to filter="(| (objectClass=posixAccount) (objectClass=posixGroup) (objectClass=posixGroupId) (objectClass=uidNext) (objectClass=gidNext) )"
             attrs="uid,uidNumber,gid,gidNumber,homeDirectory"
          by group/groupOfNames/member="cn=UNIX Administrators, ou=Groups,{{ slapd__basedn }}"        write
          by group/groupOfNames/member="cn=UNIX Administrators, ou=System Groups,{{ slapd__basedn }}" write
          by users read

        - |-
          to dn.subtree="ou=SUDOers,{{ slapd__basedn }}"
          by group/groupOfNames/member="cn=UNIX Administrators, ou=Groups,{{ slapd__basedn }}"        write
          by group/groupOfNames/member="cn=UNIX Administrators, ou=System Groups,{{ slapd__basedn }}" write
          by users read

        - |-
          to dn.subtree="ou=People,{{ slapd__basedn }}"
             attrs="shadowLastChange"
          by self write
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor,           ou=Roles,{{ slapd__basedn }}" write
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" write
          by group/organizationalRole/roleOccupant.exact="cn=Password Reset Agent,  ou=Roles,{{ slapd__basedn }}" =w
          by group/groupOfNames/member.exact="cn=LDAP Editors,           ou=System Groups,{{ slapd__basedn }}" write
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" write
          by group/groupOfNames/member.exact="cn=Password Reset Agents,  ou=System Groups,{{ slapd__basedn }}" =w
          by users read

        - |-
          to dn.subtree="ou=People,{{ slapd__basedn }}"
             attrs="userPassword"
          by self =wx
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor,           ou=Roles,{{ slapd__basedn }}" =w
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" =w
          by group/organizationalRole/roleOccupant.exact="cn=Password Reset Agent,  ou=Roles,{{ slapd__basedn }}" =w
          by group/groupOfNames/member.exact="cn=LDAP Editors,           ou=System Groups,{{ slapd__basedn }}" =w
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" =w
          by group/groupOfNames/member.exact="cn=Password Reset Agents,  ou=System Groups,{{ slapd__basedn }}" =w
          by anonymous auth
          by * none

        - |-
          to attrs="userPassword"
          by self      =wx
          by anonymous auth
          by *         none

        - |-
          to dn.regex="^cn=(LDAP Administrator|LDAP Replicator), ou=Roles,{{ slapd__basedn }}$"
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor,           ou=Roles,{{ slapd__basedn }}" read
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=LDAP Editors,           ou=System Groups,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" read
          by * break

        - |-
          to dn.subtree="cn=UNIX Administrators, ou=Groups,{{ slapd__basedn }}"
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor,           ou=Roles,{{ slapd__basedn }}" read
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=LDAP Editors,           ou=System Groups,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" read
          by * break

        - |-
          to dn.subtree="ou=System Groups,{{ slapd__basedn }}"
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor, ou=Roles,{{ slapd__basedn }}" read
          by group/groupOfNames/member.exact="cn=LDAP Editors, ou=System Groups,{{ slapd__basedn }}" read
          by * break

        - |-
          to dn.subtree="{{ slapd__basedn }}"
          by group/organizationalRole/roleOccupant.exact="cn=LDAP Editor, ou=Roles,{{ slapd__basedn }}" write
          by group/groupOfNames/member.exact="cn=LDAP Editors, ou=System Groups,{{ slapd__basedn }}" write
          by * break

        - |-
          to dn.regex="^cn=[^,]+,ou=(System Groups|Groups),{{ slapd__basedn }}$"
             attrs="member"
          by dnattr="owner" write
          by * break

        - |-
          to dn.regex="^([^,]+,)?ou=(People|Groups|Machines),{{ slapd__basedn }}$"
             attrs="children,entry"
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" write
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" write
          by * break

        - |-
          to dn.regex="^[^,]+,ou=(People|Groups|Machines),{{ slapd__basedn }}$"
          by group/organizationalRole/roleOccupant.exact="cn=Account Administrator, ou=Roles,{{ slapd__basedn }}" write
          by group/groupOfNames/member.exact="cn=Account Administrators, ou=System Groups,{{ slapd__basedn }}" write
          by * break

        - |-
          to attrs="carLicense,homePhone,homePostalAddress"
          by self write
          by * none

        - |-
          to attrs="mobile"
          by self write
          by group/organizationalRole/roleOccupant.exact="cn=SMS Gateway, ou=Roles,{{ slapd__basedn }}" read
          by * none

        - |-
          to *
          by users read
          by * none

    state: 'exact'
slapd__cluster_tasks

Separate list of LDAP tasks meant to be used to configure OpenLDAP clustering on multiple hosts in an Ansible inventory group.

slapd__cluster_tasks: []
slapd__structure_tasks

List of the tasks performed on the OpenLDAP server which create the basic structure of the directory itself.

slapd__structure_tasks:

  - name: 'Remove the default cn=admin object'
    dn: '{{ [ "cn=admin" ] + slapd__base_dn }}'
    state: 'absent'
    entry_state: 'absent'

  - name: 'Create the ou=Groups object'
    dn: '{{ [ "ou=Groups" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=Machines object'
    dn: '{{ [ "ou=Machines" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=Hosts object'
    dn: '{{ [ "ou=Hosts" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=People object'
    dn: '{{ [ "ou=People" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=Roles object'
    dn: '{{ [ "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=Services object'
    dn: '{{ [ "ou=Services" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=Password Policies object'
    dn: '{{ [ "ou=Password Policies" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

  - name: 'Create the ou=System object'
    dn: '{{ [ "ou=System" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'

    # Refer to slapo-ppolicy(5) for details
  - name: 'Create the cn=Default Password Policy object'
    dn: '{{ [ "cn=Default Password Policy", "ou=Password Policies" ] + slapd__base_dn }}'
    objectClass: [ 'namedObject', 'pwdPolicy' ]
    attributes:
      cn: 'Default Password Policy'
      pwdAttribute: 'userPassword'
      pwdMaxAge: '0'
      pwdInHistory: '5'
      pwdCheckQuality: '1'
      pwdMinLength: '10'
      pwdExpireWarning: '1209600'
      pwdGraceAuthNLimit: '5'
      pwdLockout: 'FALSE'
      pwdLockoutDuration: '300'
      pwdMaxFailure: '5'
      pwdFailureCountInterval: '0'
      pwdMustChange: 'FALSE'
      pwdAllowUserChange: 'TRUE'
      pwdSafeModify: 'FALSE'

  - name: 'Create cn=LDAP Administrator role'
    dn: '{{ [ "cn=LDAP Administrator", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'LDAP Administrator'
      description: 'People responsible for LDAP infrastructure'

  - name: 'Create cn=LDAP Replicator role'
    dn: '{{ [ "cn=LDAP Replicator", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'LDAP Replicator'
      description: 'Service accounts used for LDAP replication'

  - name: 'Create cn=LDAP Monitor role'
    dn: '{{ [ "cn=LDAP Monitor", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'LDAP Monitor'
      description: 'Accounts which can read cn=Monitor information'

  - name: 'Create cn=LDAP Editor role'
    dn: '{{ [ "cn=LDAP Editor", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'LDAP Editor'
      description: 'People responsible for LDAP contents'

  - name: 'Create cn=UNIX Administrators group'
    dn: '{{ [ "cn=UNIX Administrators", "ou=Groups" ] + slapd__base_dn }}'
    objectClass: [ 'groupOfEntries', 'posixGroup', 'posixGroupId',
                   'authorizedServiceObject', 'hostObject' ]
    attributes:
      cn: 'UNIX Administrators'
      gid: 'admins'
      gidNumber: '{{ slapd__groupid_min }}'
      description: 'People responsible for UNIX-like infrastructure'
      host: 'posix:all'

  - name: 'Create cn=Account Administrator role'
    dn: '{{ [ "cn=Account Administrator", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'Account Administrator'
      description: 'People responsible for personal accounts'

  - name: 'Create cn=Password Reset Agent role'
    dn: '{{ [ "cn=Password Reset Agent", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'Password Reset Agent'
      description: 'Services that can perform password changes on behalf of users'

  - name: 'Create cn=SMS Gateway role'
    dn: '{{ [ "cn=SMS Gateway", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'SMS Gateway'
      description: 'Devices which send SMS messages to mobile numbers'

  - name: 'Create cn=Hidden Object Viewer role'
    dn: '{{ [ "cn=Hidden Object Viewer", "ou=Roles" ] + slapd__base_dn }}'
    objectClass: 'organizationalRole'
    attributes:
      cn: 'Hidden Object Viewer'
      memberOf: '{{ ([ "cn=Hidden Objects", "ou=Groups" ] + slapd__base_dn) | join(",") }}'
      description: 'LDAP objects which can see hidden objects'

  - name: 'Create cn=Hidden Objects group'
    dn: '{{ [ "cn=Hidden Objects", "ou=Groups" ] + slapd__base_dn }}'
    objectClass: 'groupOfNames'
    attributes:
      cn: 'Hidden Objects'
      member:
        - '{{ ([ "cn=Hidden Objects", "ou=Groups" ] + slapd__base_dn) | join(",") }}'
        - '{{ ([ "cn=Hidden Object Viewer", "ou=Roles" ] + slapd__base_dn) | join(",") }}'
      memberOf: '{{ ([ "cn=Hidden Objects", "ou=Groups" ] + slapd__base_dn) | join(",") }}'
      description: 'LDAP objects which are accessible only by privileged accounts'

  - name: 'Create cn=UNIX SSH users group'
    dn: '{{ [ "cn=UNIX SSH users", "ou=Groups" ] + slapd__base_dn }}'
    objectClass: [ 'groupOfEntries', 'posixGroup', 'posixGroupId',
                   'authorizedServiceObject', 'hostObject' ]
    attributes:
      cn: 'UNIX SSH users'
      gid: 'sshusers'
      gidNumber: '{{ slapd__groupid_min|int + 1 }}'
      description: 'People who can connect to UNIX-like infrastructure via SSH'
      host: 'posix:all'

  - name: 'Create cn=Next POSIX UID object'
    dn: '{{ [ "cn=Next POSIX UID", "ou=System" ] + slapd__base_dn }}'
    objectClass: 'uidNext'
    attributes:
      cn: 'Next POSIX UID'
      uidNumber: '{{ slapd__groupid_max|int + 2 }}'
      description: 'The next available uidNumber value'

  - name: 'Create cn=Next POSIX GID object'
    dn: '{{ [ "cn=Next POSIX GID", "ou=System" ] + slapd__base_dn }}'
    objectClass: 'gidNext'
    attributes:
      cn: 'Next POSIX GID'
      gidNumber: '{{ slapd__groupid_min|int + 2 }}'
      description: 'The next available gidNumber value'

  - name: 'Create SUDOers container'
    dn: '{{ [ "ou=SUDOers" ] + slapd__base_dn }}'
    objectClass: 'organizationalStructure'
    attributes:
      ou: 'SUDOers'
      description: 'Container for sudoers.ldap(5) configuration'

  - name: 'Create sudoer defaults LDAP entry'
    dn: '{{ [ "cn=defaults", "ou=SUDOers" ] + slapd__base_dn }}'
    objectClass: 'sudoRole'
    attributes:
      cn: 'defaults'
      description: 'Object which contains default options for all sudo roles'

  - name: 'Allow admins to gain root privileges via sudo'
    dn: '{{ [ "cn=%admins", "ou=SUDOers" ] + slapd__base_dn }}'
    objectClass: 'sudoRole'
    attributes:
      cn: '%admins'
      description: 'Grant privileged access to UNIX accounts in the "admins" UNIX group'
      sudoUser: '%admins'
      sudoRunAsUser: 'ALL'
      sudoRunAsGroup: 'ALL'
      sudoHost: 'ALL'
      sudoCommand: 'ALL'
      sudoOption:
        - '!authenticate'
        - '!requiretty'
        - 'env_check+=SSH_CLIENT'
slapd__tasks

List of the tasks performed on the OpenLDAP server, defined on all hosts in the Ansible inventory.

slapd__tasks: []
slapd__group_tasks

List of the tasks performed on the OpenLDAP server, defined on hosts in a specific Ansible inventory group.

slapd__group_tasks: []
slapd__host_tasks

List of the tasks performed on the OpenLDAP server, defined on specific hosts in the Ansible inventory.

slapd__host_tasks: []
slapd__combined_tasks

Variable which combines all of the OpenLDAP task variables and is used in the role tasks and templates.

slapd__combined_tasks: '{{ slapd__default_tasks
                           + slapd__acl_tasks
                           + slapd__cluster_tasks
                           + slapd__structure_tasks
                           + slapd__tasks
                           + slapd__group_tasks
                           + slapd__host_tasks }}'

Backup snapshots

These variables configure periodic backup snapshots of the OpenLDAP databases. See Backup and restore procedures for more details.

slapd__snapshot_deploy_state

If present, the snapshot cron jobs will be configured to run the slapd-snapshot script periodically to create snapshots of known OpenLDAP databases. If absent, the cron jobs will be removed.

slapd__snapshot_deploy_state: 'present'
slapd__snapshot_cron_jobs

List of cron periods during which the slapd-snapshot script should be executed to create OpenLDAP snapshots.

slapd__snapshot_cron_jobs: [ 'daily', 'weekly', 'monthly' ]

Network access to OpenLDAP server

slapd__services

List of the service URLs on which OpenLDAP should listen for new connections. Network access is controlled using the firewall rules defined below.

slapd__services:

  # Listen for plaintext and StartTLS connections
  - 'ldap:///'

  # Listen for encrypted SSL connections (deprecated)
  - '{{ "ldaps:///" if slapd__pki|bool else [] }}'

  # Listen for connections on local UNIX domain socket
  - 'ldapi:///'
slapd__ports

List of TCP service names of the ports on which OpenLDAP listens for network connections. These ports will be opened in the firewall so that other hosts can contact the LDAP service.

slapd__ports:

  # Plaintext and StartTLS connections on port 389/tcp
  - 'ldap'

  # Encrypted SSL connections on port 636/tcp (deprecated)
  - '{{ "ldaps" if slapd__pki|bool else [] }}'
slapd__accept_any

If True, the role will configure the firewall and TCP Wrappers to accept connections to the OpenLDAP service from any network, specific IP addresses or subnets can be blocked using the slapd__*_deny variables.

If False, the role will block connections to the OpenLDAP via the system firewall and TCP Wrappers from any host; hosts that can connect must be specified via the slapd__*_allow variables.

slapd__accept_any: False
slapd__deny

List of IP addresses or CIDR subnets which should be blocked from access to the OpenLDAP server, defined on all hosts in the Ansible inventory.

slapd__deny: []
slapd__group_deny

List of IP addresses or CIDR subnets which should be blocked from access to the OpenLDAP server, defined on hosts in a specific Ansible inventory group.

slapd__group_deny: []
slapd__host_deny

List of IP addresses or CIDR subnets which should be blocked from access to the OpenLDAP server, defined on specific hosts in the Ansible inventory.

slapd__host_deny: []
slapd__allow

List of IP addresses or CIDR subnets which should have access to the OpenLDAP server, defined on all hosts in the Ansible inventory.

slapd__allow: []
slapd__group_allow

List of IP addresses or CIDR subnets which should have access to the OpenLDAP server, defined on hosts in a specific Ansible inventory group.

slapd__group_allow: []
slapd__host_allow

List of IP addresses or CIDR subnets which should have access to the OpenLDAP server, defined on specific hosts in the Ansible inventory.

slapd__host_allow: []

LDAP Access Control List tests

These variables control the ACL rule testing using a generated bash script. See Access Control List tests and validation for more details about the ACL testing, and the slapd__slapacl_tests for details about test definition.

slapd__slapacl_deploy_state

If present, the slapacl test suite script will be generated on the host. If absent, the script will be removed.

slapd__slapacl_deploy_state: 'present'
slapd__slapacl_test_objects_state

This variable controls if the role should add or remove various LDAP objects used for more extensive ACL tests. By default they are not added to avoid issues with production data; they can be very useful in development environments to properly check and verify that the defined ACL rules are consistent with the defined access policy. The supported values are present or absent.

slapd__slapacl_test_objects_state: 'absent'
slapd__slapacl_run_tests

When enabled, the slapacl test suite will be run on each debops.slapd role execution to test any changes in the ACL rules. You can use this variable to temporarily disable the ACL tests using the --extra-vars Ansible option, or permanently via the Ansible inventory. The script still will be generated and can be used independently on the OpenLDAP servers to test the ACLs.

slapd__slapacl_run_tests: True
slapd__slapacl_script

Absolute path of the slapacl test suite script generated by the role.

slapd__slapacl_script: '/etc/ldap/slapacl-test-suite'
slapd__slapacl_default_tasks

Some of the slapacl tests require existing LDAP objects to work correctly. The slapd__*slapacl_*_tasks variables define list of LDAP objects which will be created or removed, depending on the value of the slapd__slapacl_test_objects_state variable. The syntax of these lists is the same as the slapd__tasks variables. You can refer to the created LDAP objects in the slapacl tests defined elsewhere to test ACL rules.

This variable defines the default set of test objects to manage.

slapd__slapacl_default_tasks:

  - name: 'Manage LDAP Administrator object for ACL tests'
    dn: 'uid=slapacl-test-ldap-admin,ou=People,{{ slapd__basedn }}'
    objectClass: [ 'inetOrgPerson' ]
    attributes:
      uid: 'slapacl-test-ldap-admin'
      cn: 'LDAP Administrator'
      surname: 'Administrator'
    state: '{{ slapd__slapacl_test_objects_state }}'

  - name: 'Manage cn=LDAP Administrator role'
    dn: 'cn=LDAP Administrator,ou=Roles,{{ slapd__basedn }}'
    attributes:
      roleOccupant: 'uid=slapacl-test-ldap-admin,ou=People,{{ slapd__basedn }}'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "ignore" }}'


  - name: 'Manage LDAP Editor object for ACL tests'
    dn: 'uid=slapacl-test-ldap-editor,ou=People,{{ slapd__basedn }}'
    objectClass: [ 'inetOrgPerson' ]
    attributes:
      uid: 'slapacl-test-ldap-editor'
      cn: 'LDAP Editor'
      surname: 'Editor'
    state: '{{ slapd__slapacl_test_objects_state }}'

  - name: 'Manage cn=LDAP Editor role'
    dn: 'cn=LDAP Editor,ou=Roles,{{ slapd__basedn }}'
    attributes:
      roleOccupant: 'uid=slapacl-test-ldap-editor,ou=People,{{ slapd__basedn }}'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "ignore" }}'


  - name: 'Manage UNIX Administrator object for ACL tests'
    dn: 'uid=slapacl-test-unix-admin,ou=People,{{ slapd__basedn }}'
    objectClass: [ 'inetOrgPerson' ]
    attributes:
      uid: 'slapacl-test-unix-admin'
      cn: 'UNIX Administrator'
      surname: 'Administrator'
    state: '{{ slapd__slapacl_test_objects_state }}'

  - name: 'Manage cn=UNIX Administrator group'
    dn: 'cn=UNIX Administrators,ou=Groups,{{ slapd__basedn }}'
    attributes:
      member: 'uid=slapacl-test-unix-admin,ou=People,{{ slapd__basedn }}'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "ignore" }}'


  - name: 'Manage Account Administrator object for ACL tests'
    dn: 'uid=slapacl-test-account-admin,ou=People,{{ slapd__basedn }}'
    objectClass: [ 'inetOrgPerson' ]
    attributes:
      uid: 'slapacl-test-account-admin'
      cn: 'Account Administrator'
      surname: 'Administrator'
    state: '{{ slapd__slapacl_test_objects_state }}'

  - name: 'Manage cn=Account Administrator role'
    dn: 'cn=Account Administrator,ou=Roles,{{ slapd__basedn }}'
    attributes:
      roleOccupant: 'uid=slapacl-test-account-admin,ou=People,{{ slapd__basedn }}'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "ignore" }}'


  - name: 'Manage unprivileged user object for ACL tests'
    dn: 'uid=slapacl-test-unpriv-user,ou=People,{{ slapd__basedn }}'
    objectClass: [ 'inetOrgPerson' ]
    attributes:
      uid: 'slapacl-test-unpriv-user'
      cn: 'Unprivileged User'
      surname: 'User'
    state: '{{ slapd__slapacl_test_objects_state }}'
slapd__slapacl_tasks

This variable defines a list of test objects to manage on all hosts in the Ansible inventory. See slapd__tasks for syntax details.

slapd__slapacl_tasks: []
slapd__slapacl_group_tasks

This variable defines a list of test objects to manage on hosts in a specific Ansible inventory group. See slapd__tasks for syntax details.

slapd__slapacl_group_tasks: []
slapd__slapacl_host_tasks

This variable defines a list of test objects to manage on specific hosts in the Ansible inventory. See slapd__tasks for syntax details.

slapd__slapacl_host_tasks: []
slapd__slapacl_combined_tasks

This variable combines all lists of slapacl test objects and is used in the role tasks and templates.

slapd__slapacl_combined_tasks: '{{ slapd__slapacl_default_tasks
                                   + slapd__slapacl_tasks
                                   + slapd__slapacl_group_tasks
                                   + slapd__slapacl_host_tasks }}'
slapd__slapacl_default_tests

The list of the OpenLDAP ACL test rules for the slapacl(8) command defined by the role. See slapd__slapacl_tests for more details.

slapd__slapacl_default_tests:

  - name: 'Deny anonymous access to cn=config'
    dn: 'cn=config'
    authdn: ''
    policy: '=0'
    dry_run: True

  - name: 'Allow administrator access to cn=config'
    dn: 'cn=config'
    authdn: 'cn=admin,cn=config'
    policy: 'manage(=mwrscxd)'
    dry_run: True

  - name: 'Deny regular user access to cn=config'
    dn: 'cn=config'
    authdn: 'uid=slapacl-test-unpriv-user,ou=People,{{ slapd__basedn }}'
    policy: '=0'
    dry_run: True
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: 'Deny direct admin access to cn=config'
    dn: 'cn=config'
    authdn: 'uid=slapacl-test-ldap-admin,ou=People,{{ slapd__basedn }}'
    policy: '=0'
    dry_run: True
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: 'Deny anonymous access to cn=Monitor'
    dn: 'cn=Monitor'
    authdn: ''
    query: 'entry'
    policy: 'none(=0)'
    dry_run: True

  - name: 'Deny anonymous access to base DN'
    dn: '{{ slapd__basedn }}'
    authdn: ''
    policy: 'none(=0)'

  - name: "Allow authentication by anonymous users"
    dn: 'uid=slapacl-test-unpriv-user,ou=People,{{ slapd__basedn }}'
    authdn: ''
    query: 'userPassword'
    policy: 'auth(=xd)'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: "Deny password read access by anonymous users"
    dn: 'uid=slapacl-test-unpriv-user,ou=People,{{ slapd__basedn }}'
    authdn: ''
    query: 'userPassword/read'
    policy: 'denied'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: 'Deny anonymous access to ou=People'
    dn: 'ou=People,{{ slapd__basedn }}'
    authdn: ''
    queries:

      - name: 'entry'
        result: 'entry: none(=0)'

      - name: 'children'
        result: 'children: none(=0)'

    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: 'Deny write access to ou=People by unprivileged users'
    dn: 'ou=People,{{ slapd__basedn }}'
    authdn: 'uid=slapacl-test-unpriv-user,ou=People,{{ slapd__basedn }}'
    query: 'entry/write'
    policy: 'denied'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'

  - name: 'Allow write access to ou=People by administrators'
    dn: 'ou=People,{{ slapd__basedn }}'
    authdn: 'uid=slapacl-test-ldap-admin,ou=People,{{ slapd__basedn }}'
    query: 'entry/write'
    policy: 'allowed'
    state: '{{ "present"
               if (slapd__slapacl_test_objects_state == "present")
               else "init" }}'
slapd__slapacl_tests

The list of the OpenLDAP ACL test rules for the slapacl(8) command defined on all hosts in the Ansible inventory. See slapd__slapacl_tests for more details.

slapd__slapacl_tests: []
slapd__slapacl_group_tests

The list of the OpenLDAP ACL test rules for the slapacl(8) command defined on hosts in a specific Ansible inventory group. See slapd__slapacl_tests for more details.

slapd__slapacl_group_tests: []
slapd__slapacl_host_tests

The list of the OpenLDAP ACL test rules for the slapacl(8) command defined on specific hosts in the Ansible inventory. See slapd__slapacl_tests for more details.

slapd__slapacl_host_tests: []
slapd__slapacl_combined_tests

The variable which combines all of the ACL test rule lists and is used in role tasks and templates.

slapd__slapacl_combined_tests: '{{ slapd__slapacl_default_tests
                                   + slapd__slapacl_tests
                                   + slapd__slapacl_group_tests
                                   + slapd__slapacl_host_tests }}'

Configuration variables for other Ansible roles

slapd__logrotate__dependent_config

Configuration for the debops.logrotate Ansible role.

slapd__logrotate__dependent_config:

  - filename: 'slapd'
    sections:

      - logs: '{{ slapd__log_dir + "/*.log" }}'
        options: |
          notifempty
          missingok
          weekly
          maxsize 256M
          rotate 120
          compress
        comment: 'OpenLDAP server logs'

      - logs: '{{ slapd__log_dir + "/*.ldif" }}'
        options: |
          notifempty
          missingok
          monthly
          maxsize 256M
          rotate 120
          compress
        comment: 'OpenLDAP audit logs'
slapd__python__dependent_packages3

Configuration for the debops.python Ansible role.

slapd__python__dependent_packages3:

  - '{{ []
        if (ansible_distribution_release in
            ([ "wheezy", "jessie", "stretch",
               "precise", "trusty", "xenial" ]))
        else "python3-ldap" }}'
slapd__python__dependent_packages2

Configuration for the debops.python Ansible role.

slapd__python__dependent_packages2:

  - 'python-ldap'
slapd__ferm__dependent_rules

Firewall configuration managed by the debops.ferm Ansible role.

slapd__ferm__dependent_rules:

  - name: 'reject_slapd'
    type: 'accept'
    protocol: 'tcp'
    dport: '{{ q("flattened", slapd__ports) }}'
    multiport: True
    saddr: '{{ slapd__deny + slapd__group_deny + slapd__host_deny }}'
    weight: '45'
    by_role: 'debops.slapd'
    target: 'REJECT'
    rule_state: '{{ "present"
                    if (slapd__deny + slapd__group_deny + slapd__host_deny)
                    else "absent" }}'

  - name: 'accept_slapd'
    type: 'accept'
    protocol: 'tcp'
    dport: '{{ q("flattened", slapd__ports) }}'
    multiport: True
    saddr: '{{ slapd__allow + slapd__group_allow + slapd__host_allow }}'
    accept_any: '{{ slapd__accept_any }}'
    weight: '50'
    by_role: 'debops.slapd'
slapd__tcpwrappers__dependent_allow

Configuration of TCP Wrappers through the debops.tcpwrappers Ansible role.

slapd__tcpwrappers__dependent_allow:

  - daemon: 'slapd'
    client: '{{ slapd__allow + slapd__group_allow + slapd__host_allow }}'
    default: 'ALL'
    accept_any: '{{ slapd__accept_any }}'
    weight: '50'
    filename: 'slapd_dependent_allow'
    comment: 'Allow connections to OpenLDAP service'
slapd__saslauthd__dependent_instances

Configuration for the debops.saslauthd Ansible role.

slapd__saslauthd__dependent_instances:

  - name: 'slapd'
    group: '{{ slapd__group }}'
    description: 'OpenLDAP SASL Authentication Daemon'
    config_path: '/etc/ldap/sasl2/slapd.conf'
    config_group: '{{ slapd__group }}'
    config_raw: |
      pwcheck_method: saslauthd
      mech_list: PLAIN LOGIN EXTERNAL
      saslauthd_path: /var/lib/slapd/saslauthd/mux
    socket_path: '/var/lib/slapd/saslauthd'
    socket_group: '{{ slapd__group }}'
    ldap_profile: 'slapd'