1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 inherit (lib)
10 literalExpression
11 mkIf
12 mkOption
13 singleton
14 types
15 mkPackageOption
16 ;
17 inherit (pkgs) coreutils;
18 cfg = config.services.exim;
19in
20
21{
22
23 ###### interface
24
25 options = {
26
27 services.exim = {
28
29 enable = mkOption {
30 type = types.bool;
31 default = false;
32 description = "Whether to enable the Exim mail transfer agent.";
33 };
34
35 config = mkOption {
36 type = types.lines;
37 default = "";
38 description = ''
39 Verbatim Exim configuration. This should not contain exim_user,
40 exim_group, exim_path, or spool_directory.
41 '';
42 };
43
44 user = mkOption {
45 type = types.str;
46 default = "exim";
47 description = ''
48 User to use when no root privileges are required.
49 In particular, this applies when receiving messages and when doing
50 remote deliveries. (Local deliveries run as various non-root users,
51 typically as the owner of a local mailbox.) Specifying this value
52 as root is not supported.
53 '';
54 };
55
56 group = mkOption {
57 type = types.str;
58 default = "exim";
59 description = ''
60 Group to use when no root privileges are required.
61 '';
62 };
63
64 spoolDir = mkOption {
65 type = types.path;
66 default = "/var/spool/exim";
67 description = ''
68 Location of the spool directory of exim.
69 '';
70 };
71
72 package = mkPackageOption pkgs "exim" {
73 extraDescription = ''
74 This can be used to enable features such as LDAP or PAM support.
75 '';
76 };
77
78 queueRunnerInterval = mkOption {
79 type = types.str;
80 default = "5m";
81 description = ''
82 How often to spawn a new queue runner.
83 '';
84 };
85 };
86
87 };
88
89 ###### implementation
90
91 config = mkIf cfg.enable {
92
93 environment = {
94 etc."exim.conf".text = ''
95 exim_user = ${cfg.user}
96 exim_group = ${cfg.group}
97 exim_path = /run/wrappers/bin/exim
98 spool_directory = ${cfg.spoolDir}
99 ${cfg.config}
100 '';
101 systemPackages = [ cfg.package ];
102 };
103
104 users.users.${cfg.user} = {
105 description = "Exim mail transfer agent user";
106 uid = config.ids.uids.exim;
107 group = cfg.group;
108 };
109
110 users.groups.${cfg.group} = {
111 gid = config.ids.gids.exim;
112 };
113
114 security.wrappers.exim = {
115 setuid = true;
116 owner = "root";
117 group = "root";
118 source = "${cfg.package}/bin/exim";
119 };
120
121 systemd.services.exim = {
122 description = "Exim Mail Daemon";
123 wantedBy = [ "multi-user.target" ];
124 restartTriggers = [ config.environment.etc."exim.conf".source ];
125 serviceConfig = {
126 ExecStart = "!${cfg.package}/bin/exim -bdf -q${cfg.queueRunnerInterval}";
127 ExecReload = "!${coreutils}/bin/kill -HUP $MAINPID";
128 User = cfg.user;
129 };
130 preStart = ''
131 if ! test -d ${cfg.spoolDir}; then
132 ${coreutils}/bin/mkdir -p ${cfg.spoolDir}
133 ${coreutils}/bin/chown ${cfg.user}:${cfg.group} ${cfg.spoolDir}
134 fi
135 '';
136 };
137
138 };
139
140}