{ pkgs, lib, config, ... }: let inherit (builtins) hasAttr; inherit (config.services) openldap postfix dovecot2; inherit (config.users) users groups; domain = "sourcephile.fr"; domainGroup = "sourcephile"; domainOrg = "sourcephile"; domainSuffix = "dc=" + lib.concatStringsSep ",dc=" (lib.splitString "." domain); posixAccount = pkgs.callPackage (import ./posixAccount.nix) { inherit domain domainSuffix domainGroup; }; in { users.groups.${domainGroup} = { gid = 20000; members = [ users."julm".name ]; }; services.openldap = { # sudo ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b 'olcDatabase={1}mdb,cn=config' -s sub settings.children."olcDatabase={1}mdb".attrs = { objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; olcDatabase = "{1}mdb"; olcSuffix = domainSuffix; olcDbDirectory = "/var/lib/openldap/${domainSuffix}"; olcDbIndex = [ "objectClass eq" "cn,uid eq" "uidNumber,gidNumber eq" "member,memberUid eq" "mail eq" "mailAlias eq" "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 '' ''to attrs=shadowLastChange by self write by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write by * none '' ''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 '' ''to * by self read by * none '' ]; # 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"; }; # sudo ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b 'ou=posix,dc=sourcephile,dc=fr' -s sub declarativeContents."${domainSuffix}" = '' 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 dn: cn=autogeree,ou=groups,ou=posix,${domainSuffix} objectClass: top objectClass: posixGroup gidNumber: 20001 memberUid: julm */ + lib.concatMapStrings posixAccount [ rec { uid = "julm"; cn = "Julien Moutinho"; sn = uid; uidNumber = users."julm".uid; gidNumber = groups."users".gid; mailAlias = [ "julien.moutinho" ]; userPassword = builtins.readFile (./. + "/${domain}/${uid}/hashedPassword.clear"); mailHomeDirectory = "/home/${uid}/mail/${domain}"; mailQuota = "3G"; mailStorageDirectory = let stateDir = "/var/lib/dovecot"; 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). # WARNING: regarding the atomicity of backuping, # it's not a good idea to put the mails # and the index/control on different ZFS datasets like here. "maildir:/home/${uid}/mail/${domain}/mail:LAYOUT=maildir++:UTF-8:CONTROL=${stateDir}/control/${domain}/${uid}:INDEX=${stateDir}/index/${domain}/${uid}"; } rec { uid = "testbox"; cn = "Test Box"; sn = uid; uidNumber = 21000; gidNumber = groups.${domainGroup}.gid; mailAlias = [ "test.box" ]; userPassword = builtins.readFile (./. + "/${domain}/${uid}/hashedPassword.clear"); #mailHomeDirectory = "/home/${uid}/mail/${domain}"; mailQuota = "1G"; } ]; }; }