summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorPeter Simons <simons@cryp.to>2015-12-17 14:32:19 +0100
committerPeter Simons <simons@cryp.to>2015-12-17 14:32:19 +0100
commit8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85 (patch)
tree9c8c9b1129bc5bd28d6cdccc3793cb00c1f93eb1 /nixos
parent263a17f90c0f7d8d06591bb149104ad341984c78 (diff)
parent3f4276369e92a4d60a48add0a89bc727b66dc5e2 (diff)
downloadnixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar.gz
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar.bz2
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar.lz
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar.xz
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.tar.zst
nixlib-8f575eb0bfe9b383db3f50ec6ec5cf1234dd2b85.zip
Merge pull request #11573 from hrdinka/refactor/dovecot
dovecot service: refactor module
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/mail/dovecot.nix262
1 files changed, 157 insertions, 105 deletions
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index fca0d2a7f616..7ca4faae5d4f 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -3,137 +3,178 @@
 with lib;
 
 let
-
   cfg = config.services.dovecot2;
+  dovecotPkg = cfg.package;
 
-  dovecotConf =
-    ''
-      base_dir = /var/run/dovecot2/
+  baseDir = "/run/dovecot2";
+  stateDir = "/var/lib/dovecot";
 
-      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"}
+  protocols = concatStrings [
+    (optionalString cfg.enableImap "imap")
+    (optionalString cfg.enablePop3 "pop3")
+    (optionalString cfg.enableLmtp "lmtp")
+  ];
+
+  dovecotConf = concatStrings [
     ''
-    + (if cfg.sslServerCert!="" then
+      base_dir = ${baseDir}
+      protocols = ${protocols}
     ''
+
+    (if isNull cfg.sslServerCert then ''
+      ssl = no
+      disable_plaintext_auth = no
+    '' else ''
       ssl_cert = <${cfg.sslServerCert}
       ssl_key = <${cfg.sslServerKey}
-      ssl_ca = <${cfg.sslCACert}
+      ${optionalString (!(isNull cfg.sslCACert)) ("ssl_ca = <" + cfg.sslCACert)}
       disable_plaintext_auth = yes
-    '' else ''
-      ssl = no
-      disable_plaintext_auth = no
     '')
 
-    + ''
+    ''
       default_internal_user = ${cfg.user}
 
       mail_location = ${cfg.mailLocation}
 
       maildir_copy_with_hardlinks = yes
+      pop3_uidl_format = %08Xv%08Xu
 
       auth_mechanisms = plain login
+
       service auth {
         user = root
       }
+    ''
+
+    (optionalString cfg.enablePAM ''
       userdb {
         driver = passwd
       }
+
       passdb {
         driver = pam
         args = ${optionalString cfg.showPAMFailure "failure_show_msg=yes"} dovecot2
       }
+    '')
 
-      pop3_uidl_format = %08Xv%08Xu
-    '' + cfg.extraConfig;
+    cfg.extraConfig
+  ];
 
-in
+  modulesDir = pkgs.symlinkJoin "dovecot-modules"
+    (map (module: "${module}/lib/dovecot") cfg.modules);
 
+in
 {
 
-  ###### interface
-
-  options = {
+  options.services.dovecot2 = {
+    enable = mkEnableOption "Dovecot 2.x POP3/IMAP server";
 
-    services.dovecot2 = {
+    enablePop3 = mkOption {
+      type = types.bool;
+      default = true;
+      description = "Start the POP3 listener (when Dovecot is enabled).";
+    };
 
-      enable = mkOption {
-        default = false;
-        description = "Whether to enable the Dovecot 2.x POP3/IMAP server.";
-      };
+    enableImap = mkOption {
+      type = types.bool;
+      default = true;
+      description = "Start the IMAP listener (when Dovecot is enabled).";
+    };
 
-      enablePop3 = mkOption {
-        default = true;
-        description = "Start the POP3 listener (when Dovecot is enabled).";
-      };
+    enableLmtp = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Start the LMTP listener (when Dovecot is enabled).";
+    };
 
-      enableImap = mkOption {
-        default = true;
-        description = "Start the IMAP listener (when Dovecot is enabled).";
-      };
+    package = mkOption {
+      type = types.package;
+      default = pkgs.dovecot22;
+      description = "Dovecot package to use.";
+    };
 
-      enableLmtp = mkOption {
-        default = false;
-        description = "Start the LMTP listener (when Dovecot is enabled).";
-      };
+    user = mkOption {
+      type = types.str;
+      default = "dovecot2";
+      description = "Dovecot user name.";
+    };
 
-      user = mkOption {
-        default = "dovecot2";
-        description = "Dovecot user name.";
-      };
+    group = mkOption {
+      type = types.str;
+      default = "dovecot2";
+      description = "Dovecot group name.";
+    };
 
-      group = mkOption {
-        default = "dovecot2";
-        description = "Dovecot group name.";
-      };
+    extraConfig = mkOption {
+      type = types.str;
+      default = "";
+      example = "mail_debug = yes";
+      description = "Additional entries to put verbatim into Dovecot's config file.";
+    };
 
-      extraConfig = mkOption {
-        default = "";
-        example = "mail_debug = yes";
-        description = "Additional entries to put verbatim into Dovecot's config file.";
-      };
+    configFile = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = "Config file used for the whole dovecot configuration.";
+      apply = v: if v != null then v else pkgs.writeText "dovecot.conf" dovecotConf;
+    };
 
-      configFile = mkOption {
-        default = null;
-        description = "Config file used for the whole dovecot configuration.";
-        apply = v: if v != null then v else pkgs.writeText "dovecot.conf" dovecotConf;
-      };
+    mailLocation = mkOption {
+      type = types.str;
+      default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */
+      example = "maildir:~/mail:INBOX=/var/spool/mail/%u";
+      description = ''
+        Location that dovecot will use for mail folders. Dovecot mail_location option.
+      '';
+    };
 
-      mailLocation = mkOption {
-        default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */
-        example = "maildir:~/mail:INBOX=/var/spool/mail/%u";
-        description = ''
-          Location that dovecot will use for mail folders. Dovecot mail_location option.
-        '';
-      };
+    modules = mkOption {
+      type = types.listOf types.package;
+      default = [];
+      example = [ pkgs.dovecot_pigeonhole ];
+      description = ''
+        Symlinks the contents of lib/dovecot of every given package into
+        /var/lib/dovecot/modules. This will make the given modules available
+        if a dovecot package with the module_dir patch applied (like
+        pkgs.dovecot22, the default) is being used.
+      '';
+    };
 
-      sslServerCert = mkOption {
-        default = "";
-        description = "Server certificate";
-      };
+    sslCACert = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = "Path to the server's CA certificate key.";
+    };
 
-      sslCACert = mkOption {
-        default = "";
-        description = "CA certificate used by the server certificate.";
-      };
+    sslServerCert = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = "Path to the server's public key.";
+    };
 
-      sslServerKey = mkOption {
-        default = "";
-        description = "Server key.";
-      };
+    sslServerKey = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = "Path to the server's private key.";
+    };
 
-      showPAMFailure = mkOption {
-        default = false;
-        description = "Show the PAM failure message on authentication error (useful for OTPW).";
-      };
+    enablePAM = mkOption {
+      type = types.bool;
+      default = true;
+      description = "Wether to create a own Dovecot PAM service and configure PAM user logins.";
     };
 
+    showPAMFailure = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Show the PAM failure message on authentication error (useful for OTPW).";
+    };
   };
 
 
-  ###### implementation
-
-  config = mkIf config.services.dovecot2.enable {
+  config = mkIf cfg.enable {
 
-    security.pam.services.dovecot2 = {};
+    security.pam.services.dovecot2 = mkIf cfg.enablePAM {};
 
     users.extraUsers = [
       { name = cfg.user;
@@ -148,36 +189,47 @@ in
       }
     ];
 
-    users.extraGroups = singleton
-      { name = cfg.group;
-        gid = config.ids.gids.dovecot2;
-      };
-
-    systemd.services.dovecot2 =
-      { description = "Dovecot IMAP/POP3 server";
-
-        after = [ "network.target" ];
-        wantedBy = [ "multi-user.target" ];
-
-        preStart =
-          ''
-            ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot2 /var/run/dovecot2/login
-            ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2
-          '';
-
-        serviceConfig = {
-          ExecStart = "${pkgs.dovecot}/sbin/dovecot -F -c ${cfg.configFile}";
-          Restart = "on-failure";
-          RestartSec = "1s";
-          StartLimitInterval = "1min";
-        };
+    users.extraGroups = singleton {
+      name = cfg.group;
+      gid = config.ids.gids.dovecot2;
+    };
 
+    systemd.services.dovecot2 = {
+      description = "Dovecot IMAP/POP3 server";
+
+      after = [ "keys.target" "network.target" ];
+      wants = [ "keys.target" ];
+      wantedBy = [ "multi-user.target" ];
+
+      preStart = ''
+        mkdir -p "${baseDir}/login"
+        chown -R ${cfg.user}:${cfg.group} "${baseDir}"
+        rm -f "${stateDir}/modules"
+        ln -s "${modulesDir}" "${stateDir}/modules"
+      '';
+
+      serviceConfig = {
+        ExecStart = "${dovecotPkg}/sbin/dovecot -F -c ${cfg.configFile}";
+        Restart = "on-failure";
+        RestartSec = "1s";
+        StartLimitInterval = "1min";
       };
+    };
 
-    environment.systemPackages = [ pkgs.dovecot ];
+    environment.systemPackages = [ dovecotPkg ];
 
-    assertions = [{ assertion = cfg.enablePop3 || cfg.enableImap;
-                    message = "dovecot needs at least one of the IMAP or POP3 listeners enabled";}];
+    assertions = [
+      { assertion = cfg.enablePop3 || cfg.enableImap;
+        message = "dovecot needs at least one of the IMAP or POP3 listeners enabled";
+      }
+      { assertion = isNull cfg.sslServerCert == isNull cfg.sslServerKey
+          && (!(isNull cfg.sslCACert) -> !(isNull cfg.sslServerCert || isNull cfg.sslServerKey));
+        message = "dovecot needs both sslServerCert and sslServerKey defined for working crypto";
+      }
+      { assertion = cfg.showPAMFailure -> cfg.enablePAM;
+        message = "dovecot is configured with showPAMFailure while enablePAM is disabled";
+      }
+    ];
 
   };