diff options
author | Martin Weinelt <hexa@darmstadt.ccc.de> | 2022-08-12 18:54:49 +0200 |
---|---|---|
committer | lewo <lewo@abesis.fr> | 2023-07-11 19:31:20 +0000 |
commit | 8b03ae5701a672186c704be70bff8390b662c323 (patch) | |
tree | 90cfc28246b373107c20dbc6b17eeef784752994 | |
parent | 42e245b06909d63acc2310c14ba04ec700346a84 (diff) |
Create LDAP test
Sets up a declaratively configured OpenLDAP instance with users alice
and bob. They each own one email address,
First we test that postfix can communicate with LDAP and do the expected
lookups using the defined maps.
Then we use doveadm to make sure it can look up the two accounts.
Next we check the binding between account and mail address, by logging
in as alice and trying to send from bob@example.com, which alice is not
allowed to do. We expect postfix to reject the sender address here.
Finally we check mail delivery between alice and bob. Alice tries to
send a mail from alice@example.com to bob@example.com and bob then
checks whether it arrived in their mailbox.
-rw-r--r-- | flake.nix | 1 | ||||
-rw-r--r-- | tests/ldap.nix | 172 |
2 files changed, 173 insertions, 0 deletions
@@ -35,6 +35,7 @@ "external" "clamav" "multiple" + "ldap" ]; genTest = testName: release: { "name"= "${testName}-${builtins.replaceStrings ["."] ["_"] release.name}"; diff --git a/tests/ldap.nix b/tests/ldap.nix new file mode 100644 index 0000000..6077543 --- /dev/null +++ b/tests/ldap.nix @@ -0,0 +1,172 @@ +{ pkgs ? import <nixpkgs> {} +, ... +}: + +let + bindPassword = "unsafegibberish"; + alicePassword = "testalice"; + bobPassword = "testbob"; +in +pkgs.nixosTest { + name = "ldap"; + nodes = { + machine = { config, pkgs, ... }: { + imports = [ + ./../default.nix + ./lib/config.nix + ]; + + virtualisation.memorySize = 1024; + + environment.systemPackages = [ + (pkgs.writeScriptBin "mail-check" '' + ${pkgs.python3}/bin/python ${../scripts/mail-check.py} $@ + '')]; + + services.openldap = { + enable = true; + settings = { + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + "${pkgs.openldap}/etc/schema/nis.ldif" + ]; + "olcDatabase={1}mdb" = { + attrs = { + objectClass = [ + "olcDatabaseConfig" + "olcMdbConfig" + ]; + olcDatabase = "{1}mdb"; + olcDbDirectory = "/var/lib/openldap"; + olcSuffix = "dc=example"; + }; + }; + }; + }; + declarativeContents."dc=example" = '' + dn: dc=example + objectClass: domain + dc: example + + dn: cn=mail,dc=example + objectClass: organizationalRole + objectClass: simpleSecurityObject + objectClass: top + cn: mail + userPassword: ${bindPassword} + + dn: ou=users,dc=example + objectClass: organizationalUnit + ou: users + + dn: cn=alice,ou=users,dc=example + objectClass: inetOrgPerson + cn: alice + sn: Foo + mail: alice@example.com + userPassword: ${alicePassword} + + dn: cn=bob,ou=users,dc=example + objectClass: inetOrgPerson + cn: bob + sn: Bar + mail: bob@example.com + userPassword: ${bobPassword} + ''; + }; + + mailserver = { + enable = true; + fqdn = "mail.example.com"; + domains = [ "example.com" ]; + localDnsResolver = false; + + ldap = { + enable = true; + uris = [ + "ldap://" + ]; + bind = { + dn = "cn=mail,dc=example"; + password = bindPassword; + }; + searchBase = "ou=users,dc=example"; + searchScope = "sub"; + }; + + vmailGroupName = "vmail"; + vmailUID = 5000; + + enableImap = false; + }; + }; + }; + testScript = '' + import sys + + from glob import glob + + machine.start() + machine.wait_for_unit("multi-user.target") + + def test_lookup(map, key, expected): + path = glob(f"/nix/store/*-{map}")[0] + value = machine.succeed(f"postmap -q alice@example.com ldap:{path}").rstrip() + try: + assert value == expected + except AssertionError: + print(f"Expected {map} lookup for key '{key}' to return '{expected}, but got '{value}'", file=sys.stderr) + raise + + + with subtest("Test postmap lookups"): + test_lookup("ldap-virtual-mailbox-map.cf", "alice@example.com", "alice") + test_lookup("ldap-sender-login-map.cf", "alice", "alice") + + test_lookup("ldap-virtual-mailbox-map.cf", "bob@example.com", "alice") + test_lookup("ldap-sender-login-map.cf", "bob", "alice") + + with subtest("Test doveadm lookups"): + out = machine.succeed("doveadm user -u alice") + machine.log(out) + + out = machine.succeed("doveadm user -u bob") + machine.log(out) + + with subtest("Test account/mail address binding"): + machine.fail(" ".join([ + "mail-check send-and-read", + "--smtp-port 587", + "--smtp-starttls", + "--smtp-host localhost", + "--smtp-username alice", + "--imap-host localhost", + "--imap-username bob", + "--from-addr bob@example.com", + "--to-addr aliceb@example.com", + "--src-password-file <(echo '${alicePassword}')", + "--dst-password-file <(echo '${bobPassword}')", + "--ignore-dkim-spf" + ])) + machine.succeed("journalctl -u postfix | grep -q 'Sender address rejected: not owned by user alice'") + + with subtest("Test mail delivery"): + machine.succeed(" ".join([ + "mail-check send-and-read", + "--smtp-port 587", + "--smtp-starttls", + "--smtp-host localhost", + "--smtp-username alice", + "--imap-host localhost", + "--imap-username bob", + "--from-addr alice@example.com", + "--to-addr bob@example.com", + "--src-password-file <(echo '${alicePassword}')", + "--dst-password-file <(echo '${bobPassword}')", + "--ignore-dkim-spf" + ])) + ''; +} |