Files @ 3d1e72c4cbaf
Branch filter:

Location: majic-ansible-roles/roles/ldap_server/molecule/default/tests/test_default.py

branko
MAR-192: Drop rsyslog/logrotate configuration for ldap_server role under Debian 12 Bookworm:

- Default installations of Debian 12 Bookworm no longer come with
rsyslog pre-installed (and it is considered to be deprecated as
default system logger under Debian 12 Bookworm).
import os

import testinfra.utils.ansible_runner

from helpers import parse_ldif


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-*')


def test_installed_packages(host):
    """
    Tests if all the necessary packages have been installed.
    """

    assert host.package('slapd').is_installed
    assert host.package('python3-pyldap').is_installed


def test_ldap_user_group(host):
    """
    Tests if LDAP server user is part of group that allows it to traverse TLS
    private keys directory.
    """

    assert "ssl-cert" in host.user('openldap').groups


def test_ldap_server_service_sockets_and_ports(host):
    """
    Tests if LDAP server has been configured to listen on correct sockets.
    """

    assert host.socket('tcp://389').is_listening
    assert host.socket('tcp://636').is_listening
    assert host.socket('unix:///var/run/slapd/ldapi').is_listening


def test_ldap_server_service(host):
    """
    Tests if the LDAP service is enabled and running.
    """

    service = host.service('slapd')

    assert service.is_enabled
    assert service.is_running


def test_misc_schema_presence(host):
    """
    Tests if the misc LDAP schema has been imported.
    """

    with host.sudo():

        misc_schema = host.run('ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b cn=config dn')
        assert misc_schema.rc == 0
        assert 'dn: cn={4}misc,cn=schema,cn=config' in misc_schema.stdout


def test_memberof_module(host):
    """
    Tests if the memberof overlay has been enabled for the main database.
    """

    with host.sudo():
        memberof = host.run('ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b cn=config dn')

        assert memberof.rc == 0
        assert 'dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config' in memberof.stdout


def test_basic_directory_structure(host):
    """
    Tests if the base LDAP directory structure has been set-up correctly.
    """

    expected_entries = parse_ldif("""
dn: ou=people,dc=local
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=local
objectClass: organizationalUnit
ou: groups

dn: ou=services,dc=local
objectClass: organizationalUnit
ou: services
""")

    entry = host.run("ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b dc=local "
                     "'(|(entrydn=ou=people,dc=local)(entrydn=ou=groups,dc=local)(entrydn=ou=services,dc=local))'")

    assert entry.rc == 0
    assert parse_ldif(entry.stdout) == expected_entries


def test_mail_service_entries(host):
    """
    Tests if the mail service entries have been set-up correctly.
    """

    with host.sudo():

        expected_entries = parse_ldif("""
dn: ou=mail,ou=services,dc=local
objectClass: organizationalUnit
ou: mail

dn: ou=aliases,ou=mail,ou=services,dc=local
objectClass: organizationalUnit
ou: aliases

dn: ou=domains,ou=mail,ou=services,dc=local
objectClass: organizationalUnit
ou: domains
""")

        entry = host.run('ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b ou=mail,ou=services,dc=local')
        assert entry.rc == 0
        assert parse_ldif(entry.stdout) == expected_entries


def test_firewall_configuration_file(host):
    """
    Tests if firewall configuration file has been deployed correctly.
    """

    with host.sudo():

        config = host.file('/etc/ferm/conf.d/10-ldap.conf')

        assert config.is_file
        assert config.user == 'root'
        assert config.group == 'root'
        assert config.mode == 0o640


def test_admin_password(host):
    """
    Tests if administrator password has been set correctly.
    """

    login = host.run("ldapwhoami -H ldapi:/// -x -w adminpassword -D cn=admin,dc=local")

    assert login.rc == 0
    assert login.stdout == "dn:cn=admin,dc=local\n"


def test_temporary_admin_password_file_not_present(host):
    """
    Tests if the file that temporarily contains the LDAP adminstrator password
    has been removed.
    """

    with host.sudo():
        assert not host.file('/root/.ldap_admin_password').exists


def test_ldap_tls_private_key_file(host):
    """
    Tests if the TLS private key has been deployed correctly.
    """

    with host.sudo():

        inventory_hostname = host.ansible.get_variables()['inventory_hostname']

        key = host.file('/etc/ssl/private/%s_ldap.key' % inventory_hostname)

        assert key.is_file
        assert key.user == 'root'
        assert key.group == 'openldap'
        assert key.mode == 0o640
        assert key.content_string == open('tests/data/x509/server/%s_ldap.key.pem' % inventory_hostname).read()


def test_ldap_tls_certificate_file(host):
    """
    Tests if the TLS certificate has been deployed correctly.
    """

    with host.sudo():

        inventory_hostname = host.ansible.get_variables()['inventory_hostname']

        cert = host.file('/etc/ssl/certs/%s_ldap.pem' % inventory_hostname)

        assert cert.is_file
        assert cert.user == 'root'
        assert cert.group == 'root'
        assert cert.mode == 0o644
        assert cert.content_string == open('tests/data/x509/server/%s_ldap.cert.pem' % inventory_hostname).read()


def test_ldap_server_dh_parameter_file(host):
    """
    Tests if the Diffie-Hellman parameter file has been generated
    correctly.
    """

    hostname = host.run('hostname').stdout.strip()
    dhparam_file_path = '/etc/ssl/private/%s_ldap.dh.pem' % hostname

    with host.sudo():
        dhparam_file = host.file(dhparam_file_path)
        assert dhparam_file.is_file
        assert dhparam_file.user == 'root'
        assert dhparam_file.group == 'openldap'
        assert dhparam_file.mode == 0o640

        dhparam_info = host.run("openssl dhparam -noout -text -in %s", dhparam_file_path)

        assert "DH Parameters: (2048 bit)" in dhparam_info.stdout


def test_ldap_server_uses_correct_dh_parameters(host):
    """
    Tests if the LDAP server uses the generated Diffie-Hellman
    parameter.
    """

    # Technically we should be testing here against deployed DH
    # parameters file, however... When linked against GnuTLS, slapd
    # seems to only take into account the size of pointed-to DH
    # parameters, and then picks one of the parameters from the
    # RFC-7919 (https://www.ietf.org/rfc/rfc7919.txt)
    # instead. Therefore we list here the 2048-bit DH parameter from
    # the RFC instead.
    expected_dhparam = """-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----"""

    connection = host.run("gnutls-cli --no-ca-verification --starttls-proto=ldap --port 389 "
                          "--priority 'NONE:+VERS-TLS1.2:+CTYPE-X509:+COMP-NULL:+SIGN-RSA-SHA384:+DHE-RSA:+SHA384:+AEAD:+AES-256-GCM' --verbose localhost")

    output = connection.stdout
    begin_marker = "-----BEGIN DH PARAMETERS-----"
    end_marker = "-----END DH PARAMETERS-----"
    used_dhparam = output[output.find(begin_marker):output.find(end_marker) + len(end_marker)]

    assert used_dhparam == expected_dhparam