{ pkgs, lib, config, ... }:
let
- inherit (builtins) toString toFile attrNames;
- inherit (lib) types;
- inherit (pkgs.lib) unlinesAttrs unlinesValues unwords;
- inherit (config.services) dovecot2 openldap;
- inherit (config) networking;
- stateDir = "/var/lib/dovecot";
- mailDir = "${stateDir}/mail";
- sieveDir = "${stateDir}/sieve";
- authDir = "${stateDir}/auth";
- escapeGroup = lib.stringAsChars (c: if "a"<=c && c<="z"
- || "0"<=c && c<="9"
- || c=="-"
- then c else "_");
- domainGroup = escapeGroup "${networking.domainBase}";
+ inherit (pkgs.lib) unlinesValues;
+ inherit (config.services) dovecot2;
+ stateDir = "/var/lib/dovecot";
in
{
-options.services.dovecot2 = {
- domains = lib.mkOption {
- default = {};
- type = types.attrsOf (types.submodule ({domain, ...}: {
- #config.domain = lib.mkDefault domain;
- options = {
- accounts = lib.mkOption {
- type = types.attrsOf (types.submodule ({account, ...}: {
- options = {
- password = lib.mkOption {
- type = types.str;
- example = "{SSHA512}uyjL1KYx4z7HpfNvnKzuVxpMLD2KVueGGBvOcj7AF1EZCTVhT++IIKUVOC4xpZtWdqVD0OVmZqgYr2qpn/3t3Aj4oU0=";
- description = ''Password.
- Use: `doveadm pw -s SSHA512 -p "$password"`
- '';
- };
- aliases = lib.mkOption {
- type = with types; listOf types.str;
- example = [ "abuse@${config.networking.domain}" ];
- default = [];
- description = ''Aliases of this account.'';
- };
- quota = lib.mkOption {
- type = with types; nullOr types.str;
- default = null;
- example = "2G";
- description = ''
- Per user quota rules. Accepted sizes are `xx k/M/G/T` with the
- obvious meaning. Leave blank for the standard quota `100G`.
- '';
- };
- sieves = lib.mkOption {
- type = with types; attrsOf str;
- default = { main = ''
- require ["include"];
-
- #include :personal "roundcube";
- include :global "spam";
- include :global "list";
- include :global "extension";
- '';
- };
- };
- groups = lib.mkOption {
- type = with types; listOf str;
- default = [];
- };
- };
- }));
- };
- };
- }));
- };
- sieves = {
- global = lib.mkOption {
- description = "global scripts.";
- type = types.attrsOf types.str;
- default = {};
- };
- before = lib.mkOption {
- description = "before scripts.";
- type = types.attrsOf types.str;
- default = {};
- };
- after = lib.mkOption {
- description = "after scripts.";
- type = types.attrsOf types.str;
- default = {};
- };
- };
-};
-
config = lib.mkIf dovecot2.enable {
systemd.services.dovecot2 = {
preStart = unlinesValues {
- installMailDir = ''
+ installDomains = ''
# SEE: http://wiki2.dovecot.org/SharedMailboxes/Permissions
install -D -d -m 0771 \
- -o ${dovecot2.mailUser} \
- -g ${dovecot2.mailGroup} \
- ${mailDir}
- '';
-
- installSieve = ''
- rm -rf "${sieveDir}"
- install -D -d -m 0755 -o root -g root \
- "${sieveDir}/bin"
- '' + unlinesAttrs (dir: sieves: ''
- install -D -d -m 0755 -o root -g root \
- ${sieveDir} ${sieveDir}/${dir}.d
- '' + unlinesAttrs (name: text: ''
- src=${pkgs.writeText "${name}.sieve" text}
- dst="${sieveDir}/${dir}.d/${name}.sieve"
- ln -fns "$src" "$dst"
- ${pkgs.dovecot_pigeonhole}/bin/sievec "$dst"
- '') sieves
- ) dovecot2.sieves;
-
- installDomains =
- lib.optionalString openldap.enable ''
- # NOTE: make sure nslcd cache is in sync with the LDAP data
- systemctl restart nslcd
- '' + ''
- install -D -d -m 1770 \
- -o ${dovecot2.mailUser} \
- -g ${domainGroup} \
- ${mailDir}/${networking.domain} \
- ${stateDir}/control/${networking.domain} \
- ${stateDir}/index/${networking.domain}
-
- # NOTE: do not set the sticky bit (+t)
- # on acl/<domain>/, to let dovecot
- # rename acl.db.lock (own by new user)
- # to acl.db (own by old user)
- install -D -d -m 0770 \
- -o ${dovecot2.mailUser} \
- -g ${domainGroup} \
- ${stateDir}/acl/${networking.domain}
-
- # NOTE: domainAliases point to the very same mailboxes as domain's.
- for domainAlias in ${unwords networking.domainAliases}
- do
- ln -fns ${networking.domain} ${mailDir}/$domainAlias
- ln -fns ${networking.domain} ${stateDir}/control/$domainAlias
- ln -fns ${networking.domain} ${stateDir}/index/$domainAlias
- ln -fns ${networking.domain} ${stateDir}/acl/$domainAlias
- done
+ -o "${dovecot2.user}" \
+ -g "${dovecot2.group}" \
+ ${stateDir}/mail
'';
};
};