{ pkgs, lib, config, ... }: let inherit (builtins) hasAttr; inherit (builtins.extraBuiltins) pass-chomp; inherit (config) networking; inherit (config.services) openldap postfix dovecot2; inherit (config.users) users groups; inherit (pkgs.lib) unlines; domain = "autogeree.net"; domainGroup = "autogeree"; domainOrg = "autogeree"; domainSuffix = "dc=" + lib.concatStringsSep ",dc=" (lib.splitString "." domain); posixAccount = pkgs.callPackage (import ./posixAccount.nix) { inherit domain domainSuffix domainGroup; }; in { services.openldap.databases."${domainSuffix}" = { # WARNING: newlines matter conf = '' dn: olcDatabase=mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig # Checkpoint the database periodically in case of system failure # and to speed up slapd shutdown. olcDbCheckpoint: 512 30 # Database max size is 1G olcDbMaxSize: 1073741824 olcLastMod: TRUE # Database superuser. Needed for syncrepl. olcRootDN: cn=admin,${domainSuffix} # Superuser password, generated with slappasswd -h "{SSHA}" # Commented-out because SASL EXTERNAL mechanism is used. #olcRootPW: {SSHA}COkATGNe7rs/g8vWcYP5rqt4u5sWdMgP # olcDbIndex: objectClass eq olcDbIndex: cn,uid eq olcDbIndex: uidNumber,gidNumber eq olcDbIndex: member,memberUid eq olcDbIndex: mail eq olcDbIndex: mailAlias eq olcDbIndex: mailEnabled eq # olcAccess: to attrs=userPassword by self write by anonymous auth by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write by * none olcAccess: to attrs=shadowLastChange by self write by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write by * none olcAccess: to dn.sub="ou=posix,${domainSuffix}" by self read ${lib.optionalString (hasAttr postfix.user users) ''by dn="gidNumber=${toString groups.postfix.gid}+uidNumber=${toString users.postfix.uid},cn=peercred,cn=external,cn=auth" read''} ${lib.optionalString (hasAttr dovecot2.user users) ''by dn="gidNumber=${toString groups.dovecot2.gid}+uidNumber=${toString users.dovecot2.uid},cn=peercred,cn=external,cn=auth" read''} by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read olcAccess: to * by self read by * none ''; data = '' dn: ${domainSuffix} objectClass: top objectClass: dcObject objectClass: organization o: ${domainOrg} dn: cn=admin,${domainSuffix} objectClass: simpleSecurityObject objectClass: organizationalRole description: ${domainOrg} LDAP administrator roleOccupant: ${domainSuffix} userPassword: dn: ou=posix,${domainSuffix} objectClass: top objectClass: organizationalUnit dn: ou=accounts,ou=posix,${domainSuffix} objectClass: top objectClass: organizationalUnit dn: ou=groups,ou=posix,${domainSuffix} objectClass: top objectClass: organizationalUnit dn: cn=${domainGroup},ou=groups,ou=posix,${domainSuffix} objectClass: top objectClass: posixGroup gidNumber: 20000 memberUid: julm '' + lib.concatMapStrings posixAccount [ rec { uid = "julm"; cn = "Julien Moutinho"; sn = uid; uidNumber = users.julm.uid; gidNumber = groups.julm.gid; mailAlias = [ "julien.moutinho" ]; userPassword = pass-chomp "members/julm/mail/hashedPassword"; mailStorageDirectory = let stateDir = "/var/lib/dovecot"; d=domain; in # I'm personnaly using "maildir:" instead of "sdbox:" to be able to use a local (neo)mutt on it, # bypassing IMAP because (neo)mutt support of IMAP is very bad # (can't even have a decent $folder_format (with %n or %m) working, # neither sorting them by date). "maildir:${stateDir}/mail/${d}/${uid}/mail.d:LAYOUT=maildir++:UTF-8:CONTROL=${stateDir}/control/${d}/${uid}:INDEX=${stateDir}/index/${d}/${uid}"; } ]; }; }