From 622c7c2204c1b475a9fc4ae38152ae1aa328e771 Mon Sep 17 00:00:00 2001 From: Leon Schuermann Date: Fri, 6 May 2022 19:05:21 +0200 Subject: [PATCH] Support customized maildir type and location per virtual user This adds the option to add a customized userdb_mail parameter to the Dovecot userdb, overriding the global mail_location setting. This change applies to both mail delivery (handled via LMTP from postfix to Dovecot), as well as Maildir access via IMAP etc. Furthermore, the UID and GID can be customized to reflect the desired permissions. Finally, the Dovecot virtual user home, holding the user's private state, can be set. These changes allow for great flexibility in the mail server setup. For instance, users can selectively have their mail accessible through a Maildir in their home directory, or via a purely virtual user maintained under /var/vmail. --- default.nix | 54 +++++++++++++++++++++++++++++++++++++++++ mail-server/dovecot.nix | 34 +++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/default.nix b/default.nix index 3f46610..c0d3a03 100644 --- a/default.nix +++ b/default.nix @@ -140,6 +140,60 @@ in ''; }; + customMaildir = mkOption { + type = types.nullOr (types.submodule ({ name, ...}: { + options = { + uid = mkOption { + type = types.int; + example = 1000; + description = '' + User ID for files and directories in the maildir. Files and + directories created by Dovecot will be assigned this UID. + ''; + }; + + gid = mkOption { + type = types.int; + example = 1000; + description = '' + Group ID for files and directories in the maildir. Files and + directories created by Dovecot will be assigned this GID. + ''; + }; + + dovecotHome = mkOption { + type = types.str; + example = "/home/myusername"; + description = '' + Home directory for Dovecot virtual user. This is used to + maintain mail user's private state. This MUST be different + for each Dovecot virtual user and MUST be an absolute path. + Refer to the Dovecot documentation for further information + on this configuration option: + https://wiki.dovecot.org/VirtualUsers/Home + ''; + }; + + mailDirectorySpec = mkOption { + type = types.str; + example = "maildir:~/mail"; + description = '' + Dovecot mail location specification. Refer to the Dovecot + documentation for further information on this configuration + option: + https://doc.dovecot.org/configuration_manual/mail_location/ + ''; + }; + }; + })); + default = null; + description = '' + Configuration options for a custom Maildir location. For instance, + this can be used to implement home-directory Maildirs for specific + users only. If null, a Maildir under /var/vmail will be assigned. + ''; + }; + sieveScript = mkOption { type = with types; nullOr lines; default = null; diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix index c75aff2..d41a202 100644 --- a/mail-server/dovecot.nix +++ b/mail-server/dovecot.nix @@ -123,10 +123,36 @@ let EOF cat < ${userdbFile} - ${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: - "${name}:::::::" - + lib.optionalString (value.quota != null) "userdb_quota_rule=*:storage=${value.quota}" - ) cfg.loginAccounts)} + ${lib.concatStringsSep "\n" ( + lib.mapAttrsToList (name: value: let + # Space-separated "extra fields" options, appended as the 8-th element + # in a userdb entry tuple in passwd format: + # $user:$passwd:$uid:$gid:$uidinfo:$home:$shell:$extraFields + extraFieldsStr = lib.concatStringsSep " " ( + # Custom Maildir location option: + (lib.optional + (value.customMaildir != null) + "userdb_mail=${value.customMaildir.mailDirectorySpec}") + ++ + # Quota option: + (lib.optional + (value.quota != null) + "userdb_quota_rule=*:storage=${value.quota}") + ); + in ( + if value.customMaildir == null then + "${name}:::::::${extraFieldsStr}" + else + "${name}" + + ":" + + ":${builtins.toString value.customMaildir.uid}" + + ":${builtins.toString value.customMaildir.gid}" + + ":" + + ":${value.customMaildir.dovecotHome}" + + ":/run/current-system/sw/bin/nologin" + + ":${extraFieldsStr}" + )) cfg.loginAccounts + )} EOF '';