services: dovecot: Serialize global settings first.
[jackhill/guix/guix.git] / gnu / services / mail.scm
CommitLineData
d8c18af8
AW
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
8d9bb4b4 3;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
82ccc499 4;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
c3f146e7 5;;; Copyright © 2017, 2020 Tobias Geerinckx-Rice <me@tobias.gr>
ace8e269 6;;; Copyright © 2019 Kristofer Buffington <kristoferbuffington@gmail.com>
d8c18af8
AW
7;;;
8;;; This file is part of GNU Guix.
9;;;
10;;; GNU Guix is free software; you can redistribute it and/or modify it
11;;; under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 3 of the License, or (at
13;;; your option) any later version.
14;;;
15;;; GNU Guix is distributed in the hope that it will be useful, but
16;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU General Public License
21;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22;;;
23;;; Some of the help text was taken from the default dovecot.conf files.
24
25(define-module (gnu services mail)
26 #:use-module (gnu services)
27 #:use-module (gnu services base)
5305ed20 28 #:use-module (gnu services configuration)
0190c1c0 29 #:use-module (gnu services shepherd)
d8c18af8
AW
30 #:use-module (gnu system pam)
31 #:use-module (gnu system shadow)
32 #:use-module (gnu packages mail)
33 #:use-module (gnu packages admin)
34 #:use-module (gnu packages tls)
35 #:use-module (guix records)
36 #:use-module (guix packages)
37 #:use-module (guix gexp)
d8c18af8 38 #:use-module (ice-9 match)
82ccc499 39 #:use-module (ice-9 format)
8d17cf1c 40 #:use-module (srfi srfi-1)
5305ed20 41 #:export (dovecot-service
24e96431 42 dovecot-service-type
d8c18af8
AW
43 dovecot-configuration
44 opaque-dovecot-configuration
45
46 dict-configuration
47 passdb-configuration
48 userdb-configuration
49 unix-listener-configuration
50 fifo-listener-configuration
51 inet-listener-configuration
52 service-configuration
53 protocol-configuration
54 plugin-configuration
55 mailbox-configuration
f88371e8
SB
56 namespace-configuration
57
58 opensmtpd-configuration
59 opensmtpd-configuration?
60 opensmtpd-service-type
82ccc499
CZ
61 %default-opensmtpd-config-file
62
8d17cf1c
CZ
63 mail-aliases-service-type
64
82ccc499
CZ
65 exim-configuration
66 exim-configuration?
67 exim-service-type
412e6396
SB
68 %default-exim-config-file
69
70 imap4d-configuration
71 imap4d-configuration?
72 imap4d-service-type
f7dbf186 73 %default-imap4d-config-file))
d8c18af8
AW
74
75;;; Commentary:
76;;;
77;;; This module provides service definitions for the Dovecot POP3 and IMAP
78;;; mail server.
79;;;
80;;; Code:
81
56aef188
CL
82(define (uglify-field-name field-name)
83 (let ((str (symbol->string field-name)))
84 (string-join (string-split (if (string-suffix? "?" str)
85 (substring str 0 (1- (string-length str)))
86 str)
87 #\-)
88 "_")))
89
90(define (serialize-field field-name val)
91 (format #t "~a=~a\n" (uglify-field-name field-name) val))
92
93(define (serialize-string field-name val)
94 (serialize-field field-name val))
95
96(define (space-separated-string-list? val)
97 (and (list? val)
98 (and-map (lambda (x)
99 (and (string? x) (not (string-index x #\space))))
100 val)))
101(define (serialize-space-separated-string-list field-name val)
102 (serialize-field field-name (string-join val " ")))
d8c18af8
AW
103
104(define (comma-separated-string-list? val)
105 (and (list? val)
106 (and-map (lambda (x)
107 (and (string? x) (not (string-index x #\,))))
108 val)))
109(define (serialize-comma-separated-string-list field-name val)
110 (serialize-field field-name (string-join val ",")))
111
56aef188
CL
112(define (file-name? val)
113 (and (string? val)
114 (string-prefix? "/" val)))
115(define (serialize-file-name field-name val)
116 (serialize-string field-name val))
117
d8c18af8
AW
118(define (colon-separated-file-name-list? val)
119 (and (list? val)
120 ;; Trailing slashes not needed and not
121 (and-map file-name? val)))
122(define (serialize-colon-separated-file-name-list field-name val)
123 (serialize-field field-name (string-join val ":")))
124
56aef188
CL
125(define (serialize-boolean field-name val)
126 (serialize-string field-name (if val "yes" "no")))
127
d8c18af8
AW
128(define (non-negative-integer? val)
129 (and (exact-integer? val) (not (negative? val))))
130(define (serialize-non-negative-integer field-name val)
131 (serialize-field field-name val))
132
133(define (hours? val) (non-negative-integer? val))
134(define (serialize-hours field-name val)
135 (serialize-field field-name (format #f "~a hours" val)))
136
137(define (free-form-fields? val)
138 (match val
139 (() #t)
ad34409e 140 ((((? symbol?) . (? string?)) . val) (free-form-fields? val))
d8c18af8
AW
141 (_ #f)))
142(define (serialize-free-form-fields field-name val)
143 (for-each (match-lambda ((k . v) (serialize-field k v))) val))
144
145(define (free-form-args? val)
146 (match val
147 (() #t)
ad34409e 148 ((((? symbol?) . (? string?)) . val) (free-form-args? val))
d8c18af8
AW
149 (_ #f)))
150(define (serialize-free-form-args field-name val)
151 (serialize-field field-name
152 (string-join
153 (map (match-lambda ((k . v) (format #t "~a=~a" k v))) val)
154 " ")))
155
156(define-configuration dict-configuration
157 (entries
158 (free-form-fields '())
159 "A list of key-value pairs that this dict should hold."))
160
161(define (serialize-dict-configuration field-name val)
162 (format #t "dict {\n")
163 (serialize-configuration val dict-configuration-fields)
164 (format #t "}\n"))
165
166(define-configuration passdb-configuration
167 (driver
168 (string "pam")
169 "The driver that the passdb should use. Valid values include
170@samp{pam}, @samp{passwd}, @samp{shadow}, @samp{bsdauth}, and
171@samp{static}.")
172 (args
deb36188
CL
173 (space-separated-string-list '())
174 "Space separated list of arguments to the passdb driver."))
d8c18af8
AW
175
176(define (serialize-passdb-configuration field-name val)
177 (format #t "passdb {\n")
178 (serialize-configuration val passdb-configuration-fields)
179 (format #t "}\n"))
180(define (passdb-configuration-list? val)
181 (and (list? val) (and-map passdb-configuration? val)))
182(define (serialize-passdb-configuration-list field-name val)
183 (for-each (lambda (val) (serialize-passdb-configuration field-name val)) val))
184
185(define-configuration userdb-configuration
186 (driver
187 (string "passwd")
188 "The driver that the userdb should use. Valid values include
189@samp{passwd} and @samp{static}.")
190 (args
deb36188
CL
191 (space-separated-string-list '())
192 "Space separated list of arguments to the userdb driver.")
d8c18af8
AW
193 (override-fields
194 (free-form-args '())
195 "Override fields from passwd."))
196
197(define (serialize-userdb-configuration field-name val)
198 (format #t "userdb {\n")
199 (serialize-configuration val userdb-configuration-fields)
200 (format #t "}\n"))
201(define (userdb-configuration-list? val)
202 (and (list? val) (and-map userdb-configuration? val)))
203(define (serialize-userdb-configuration-list field-name val)
204 (for-each (lambda (val) (serialize-userdb-configuration field-name val)) val))
205
206(define-configuration unix-listener-configuration
207 (path
eba56076
CL
208 (string (configuration-missing-field 'unix-listener 'path))
209 "Path to the file, relative to @code{base-dir} field. This is also used as
210the section name.")
d8c18af8
AW
211 (mode
212 (string "0600")
213 "The access mode for the socket.")
214 (user
215 (string "")
216 "The user to own the the socket.")
217 (group
218 (string "")
219 "The group to own the socket."))
220
221(define (serialize-unix-listener-configuration field-name val)
222 (format #t "unix_listener ~a {\n" (unix-listener-configuration-path val))
223 (serialize-configuration val (cdr unix-listener-configuration-fields))
224 (format #t "}\n"))
225
226(define-configuration fifo-listener-configuration
227 (path
eba56076
CL
228 (string (configuration-missing-field 'fifo-listener 'path))
229 "Path to the file, relative to @code{base-dir} field. This is also used as
230the section name.")
d8c18af8
AW
231 (mode
232 (string "0600")
233 "The access mode for the socket.")
234 (user
235 (string "")
236 "The user to own the the socket.")
237 (group
238 (string "")
239 "The group to own the socket."))
240
241(define (serialize-fifo-listener-configuration field-name val)
242 (format #t "fifo_listener ~a {\n" (fifo-listener-configuration-path val))
243 (serialize-configuration val (cdr fifo-listener-configuration-fields))
244 (format #t "}\n"))
245
246(define-configuration inet-listener-configuration
247 (protocol
5305ed20 248 (string (configuration-missing-field 'inet-listener 'protocol))
d8c18af8
AW
249 "The protocol to listen for.")
250 (address
251 (string "")
252 "The address on which to listen, or empty for all addresses.")
253 (port
254 (non-negative-integer
5305ed20 255 (configuration-missing-field 'inet-listener 'port))
d8c18af8
AW
256 "The port on which to listen.")
257 (ssl?
258 (boolean #t)
259 "Whether to use SSL for this service; @samp{yes}, @samp{no}, or
260@samp{required}."))
261
262(define (serialize-inet-listener-configuration field-name val)
263 (format #t "inet_listener ~a {\n" (inet-listener-configuration-protocol val))
264 (serialize-configuration val (cdr inet-listener-configuration-fields))
265 (format #t "}\n"))
266
267(define (listener-configuration? val)
268 (or (unix-listener-configuration? val)
269 (fifo-listener-configuration? val)
270 (inet-listener-configuration? val)))
271(define (serialize-listener-configuration field-name val)
272 (cond
273 ((unix-listener-configuration? val)
274 (serialize-unix-listener-configuration field-name val))
275 ((fifo-listener-configuration? val)
276 (serialize-fifo-listener-configuration field-name val))
277 ((inet-listener-configuration? val)
278 (serialize-inet-listener-configuration field-name val))
5305ed20 279 (else (configuration-field-error field-name val))))
d8c18af8
AW
280(define (listener-configuration-list? val)
281 (and (list? val) (and-map listener-configuration? val)))
282(define (serialize-listener-configuration-list field-name val)
283 (for-each (lambda (val)
284 (serialize-listener-configuration field-name val))
285 val))
286
287(define-configuration service-configuration
288 (kind
5305ed20 289 (string (configuration-missing-field 'service 'kind))
d8c18af8
AW
290 "The service kind. Valid values include @code{director},
291@code{imap-login}, @code{pop3-login}, @code{lmtp}, @code{imap},
292@code{pop3}, @code{auth}, @code{auth-worker}, @code{dict},
293@code{tcpwrap}, @code{quota-warning}, or anything else.")
294 (listeners
295 (listener-configuration-list '())
296 "Listeners for the service. A listener is either an
297@code{unix-listener-configuration}, a @code{fifo-listener-configuration}, or
298an @code{inet-listener-configuration}.")
8d9bb4b4
CL
299 (client-limit
300 (non-negative-integer 0)
301 "Maximum number of simultaneous client connections per process. Once this
302number of connections is received, the next incoming connection will prompt
303Dovecot to spawn another process. If set to 0, @code{default-client-limit} is
304used instead.")
d8c18af8
AW
305 (service-count
306 (non-negative-integer 1)
307 "Number of connections to handle before starting a new process.
308Typically the only useful values are 0 (unlimited) or 1. 1 is more
309secure, but 0 is faster. <doc/wiki/LoginProcess.txt>.")
be8dd4a5
CL
310 (process-limit
311 (non-negative-integer 0)
312 "Maximum number of processes that can exist for this service. If set to 0,
313@code{default-process-limit} is used instead.")
d8c18af8
AW
314 (process-min-avail
315 (non-negative-integer 0)
316 "Number of processes to always keep waiting for more connections.")
317 ;; FIXME: Need to be able to take the default for this value from other
318 ;; parts of the config.
319 (vsz-limit
320 (non-negative-integer #e256e6)
321 "If you set @samp{service-count 0}, you probably need to grow
322this."))
323
324(define (serialize-service-configuration field-name val)
325 (format #t "service ~a {\n" (service-configuration-kind val))
326 (serialize-configuration val (cdr service-configuration-fields))
327 (format #t "}\n"))
328(define (service-configuration-list? val)
329 (and (list? val) (and-map service-configuration? val)))
330(define (serialize-service-configuration-list field-name val)
331 (for-each (lambda (val)
332 (serialize-service-configuration field-name val))
333 val))
334
335(define-configuration protocol-configuration
336 (name
5305ed20 337 (string (configuration-missing-field 'protocol 'name))
d8c18af8
AW
338 "The name of the protocol.")
339 (auth-socket-path
340 (string "/var/run/dovecot/auth-userdb")
341 "UNIX socket path to master authentication server to find users.
342This is used by imap (for shared users) and lda.")
343 (mail-plugins
344 (space-separated-string-list '("$mail_plugins"))
345 "Space separated list of plugins to load.")
346 (mail-max-userip-connections
347 (non-negative-integer 10)
348 "Maximum number of IMAP connections allowed for a user from each IP
349address. NOTE: The username is compared case-sensitively."))
350
351(define (serialize-protocol-configuration field-name val)
352 (format #t "protocol ~a {\n" (protocol-configuration-name val))
353 (serialize-configuration val (cdr protocol-configuration-fields))
354 (format #t "}\n"))
355(define (protocol-configuration-list? val)
356 (and (list? val) (and-map protocol-configuration? val)))
357(define (serialize-protocol-configuration-list field-name val)
358 (serialize-field 'protocols
359 (string-join (map protocol-configuration-name val) " "))
360 (for-each (lambda (val)
361 (serialize-protocol-configuration field-name val))
362 val))
363
364(define-configuration plugin-configuration
365 (entries
366 (free-form-fields '())
367 "A list of key-value pairs that this dict should hold."))
368
369(define (serialize-plugin-configuration field-name val)
370 (format #t "plugin {\n")
371 (serialize-configuration val plugin-configuration-fields)
372 (format #t "}\n"))
373
374(define-configuration mailbox-configuration
375 (name
376 (string (error "mailbox name is required"))
377 "Name for this mailbox.")
378
379 (auto
380 (string "no")
381 "@samp{create} will automatically create this mailbox.
382@samp{subscribe} will both create and subscribe to the mailbox.")
383
384 (special-use
385 (space-separated-string-list '())
386 "List of IMAP @code{SPECIAL-USE} attributes as specified by RFC 6154.
387Valid values are @code{\\All}, @code{\\Archive}, @code{\\Drafts},
388@code{\\Flagged}, @code{\\Junk}, @code{\\Sent}, and @code{\\Trash}."))
389
390(define (serialize-mailbox-configuration field-name val)
391 (format #t "mailbox \"~a\" {\n" (mailbox-configuration-name val))
392 (serialize-configuration val (cdr mailbox-configuration-fields))
393 (format #t "}\n"))
394(define (mailbox-configuration-list? val)
395 (and (list? val) (and-map mailbox-configuration? val)))
396(define (serialize-mailbox-configuration-list field-name val)
397 (for-each (lambda (val)
398 (serialize-mailbox-configuration field-name val))
399 val))
400
401(define-configuration namespace-configuration
402 (name
403 (string (error "namespace name is required"))
404 "Name for this namespace.")
405
406 (type
407 (string "private")
408 "Namespace type: @samp{private}, @samp{shared} or @samp{public}.")
409
410 (separator
411 (string "")
412 "Hierarchy separator to use. You should use the same separator for
413all namespaces or some clients get confused. @samp{/} is usually a good
414one. The default however depends on the underlying mail storage
415format.")
416
417 (prefix
418 (string "")
419 "Prefix required to access this namespace. This needs to be
420different for all namespaces. For example @samp{Public/}.")
421
422 (location
423 (string "")
424 "Physical location of the mailbox. This is in same format as
425mail_location, which is also the default for it.")
426
427 (inbox?
428 (boolean #f)
429 "There can be only one INBOX, and this setting defines which
430namespace has it.")
431
432 (hidden?
433 (boolean #f)
434 "If namespace is hidden, it's not advertised to clients via NAMESPACE
435extension. You'll most likely also want to set @samp{list? #f}. This is mostly
436useful when converting from another server with different namespaces
437which you want to deprecate but still keep working. For example you can
438create hidden namespaces with prefixes @samp{~/mail/}, @samp{~%u/mail/}
439and @samp{mail/}.")
440
441 (list?
442 (boolean #t)
443 "Show the mailboxes under this namespace with LIST command. This
444makes the namespace visible for clients that don't support NAMESPACE
445extension. The special @code{children} value lists child mailboxes, but
446hides the namespace prefix.")
447
448 (subscriptions?
449 (boolean #t)
450 "Namespace handles its own subscriptions. If set to @code{#f}, the
451parent namespace handles them. The empty prefix should always have this
452as @code{#t}.)")
453
454 (mailboxes
455 (mailbox-configuration-list '())
456 "List of predefined mailboxes in this namespace."))
457
458(define (serialize-namespace-configuration field-name val)
459 (format #t "namespace ~a {\n" (namespace-configuration-name val))
460 (serialize-configuration val (cdr namespace-configuration-fields))
461 (format #t "}\n"))
462(define (list-of-namespace-configuration? val)
463 (and (list? val) (and-map namespace-configuration? val)))
464(define (serialize-list-of-namespace-configuration field-name val)
465 (for-each (lambda (val)
466 (serialize-namespace-configuration field-name val))
467 val))
468
469(define-configuration dovecot-configuration
470 (dovecot
471 (package dovecot)
472 "The dovecot package.")
473
474 (listen
475 (comma-separated-string-list '("*" "::"))
476 "A list of IPs or hosts where to listen in for connections. @samp{*}
477listens in all IPv4 interfaces, @samp{::} listens in all IPv6
478interfaces. If you want to specify non-default ports or anything more
479complex, customize the address and port fields of the
480@samp{inet-listener} of the specific services you are interested in.")
481
d8c18af8
AW
482 (dict
483 (dict-configuration (dict-configuration))
484 "Dict configuration, as created by the @code{dict-configuration}
485constructor.")
486
487 (passdbs
488 (passdb-configuration-list (list (passdb-configuration (driver "pam"))))
489 "List of passdb configurations, each one created by the
490@code{passdb-configuration} constructor.")
491
492 (userdbs
493 (userdb-configuration-list (list (userdb-configuration (driver "passwd"))))
494 "List of userdb configurations, each one created by the
495@code{userdb-configuration} constructor.")
496
497 (plugin-configuration
498 (plugin-configuration (plugin-configuration))
499 "Plug-in configuration, created by the @code{plugin-configuration}
500constructor.")
501
502 (namespaces
503 (list-of-namespace-configuration
504 (list
505 (namespace-configuration
506 (name "inbox")
507 (prefix "")
508 (inbox? #t)
509 (mailboxes
510 (list
511 (mailbox-configuration (name "Drafts") (special-use '("\\Drafts")))
512 (mailbox-configuration (name "Junk") (special-use '("\\Junk")))
513 (mailbox-configuration (name "Trash") (special-use '("\\Trash")))
514 (mailbox-configuration (name "Sent") (special-use '("\\Sent")))
515 (mailbox-configuration (name "Sent Messages") (special-use '("\\Sent")))
516 (mailbox-configuration (name "Drafts") (special-use '("\\Drafts"))))))))
517 "List of namespaces. Each item in the list is created by the
518@code{namespace-configuration} constructor.")
519
520 (base-dir
521 (file-name "/var/run/dovecot/")
522 "Base directory where to store runtime data.")
523
524 (login-greeting
525 (string "Dovecot ready.")
526 "Greeting message for clients.")
527
528 (login-trusted-networks
529 (space-separated-string-list '())
530 "List of trusted network ranges. Connections from these IPs are
531allowed to override their IP addresses and ports (for logging and for
532authentication checks). @samp{disable-plaintext-auth} is also ignored
533for these networks. Typically you'd specify your IMAP proxy servers
534here.")
535
536 (login-access-sockets
537 (space-separated-string-list '())
538 "List of login access check sockets (e.g. tcpwrap).")
539
540 (verbose-proctitle?
541 (boolean #f)
542 "Show more verbose process titles (in ps). Currently shows user name
543and IP address. Useful for seeing who are actually using the IMAP
544processes (e.g. shared mailboxes or if same uid is used for multiple
545accounts).")
546
547 (shutdown-clients?
548 (boolean #t)
549 "Should all processes be killed when Dovecot master process shuts down.
550Setting this to @code{#f} means that Dovecot can be upgraded without
551forcing existing client connections to close (although that could also
552be a problem if the upgrade is e.g. because of a security fix).")
553
554 (doveadm-worker-count
555 (non-negative-integer 0)
556 "If non-zero, run mail commands via this many connections to doveadm
557server, instead of running them directly in the same process.")
558
559 (doveadm-socket-path
560 (string "doveadm-server")
561 "UNIX socket or host:port used for connecting to doveadm server.")
562
563 (import-environment
564 (space-separated-string-list '("TZ"))
565 "List of environment variables that are preserved on Dovecot startup
566and passed down to all of its child processes. You can also give
567key=value pairs to always set specific settings.")
568
569;;; Authentication processes
570
571 (disable-plaintext-auth?
572 (boolean #t)
573 "Disable LOGIN command and all other plaintext authentications unless
574SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
575matches the local IP (i.e. you're connecting from the same computer),
576the connection is considered secure and plaintext authentication is
577allowed. See also ssl=required setting.")
578
579 (auth-cache-size
580 (non-negative-integer 0)
581 "Authentication cache size (e.g. @samp{#e10e6}). 0 means it's disabled.
582Note that bsdauth, PAM and vpopmail require @samp{cache-key} to be set
583for caching to be used.")
584
585 (auth-cache-ttl
586 (string "1 hour")
587 "Time to live for cached data. After TTL expires the cached record
588is no longer used, *except* if the main database lookup returns internal
589failure. We also try to handle password changes automatically: If
590user's previous authentication was successful, but this one wasn't, the
591cache isn't used. For now this works only with plaintext
592authentication.")
593
594 (auth-cache-negative-ttl
595 (string "1 hour")
596 "TTL for negative hits (user not found, password mismatch).
5970 disables caching them completely.")
598
599 (auth-realms
600 (space-separated-string-list '())
601 "List of realms for SASL authentication mechanisms that need them.
602You can leave it empty if you don't want to support multiple realms.
603Many clients simply use the first one listed here, so keep the default
604realm first.")
605
606 (auth-default-realm
607 (string "")
608 "Default realm/domain to use if none was specified. This is used for
609both SASL realms and appending @@domain to username in plaintext
610logins.")
611
612 (auth-username-chars
613 (string
614 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@")
615 "List of allowed characters in username. If the user-given username
616contains a character not listed in here, the login automatically fails.
617This is just an extra check to make sure user can't exploit any
618potential quote escaping vulnerabilities with SQL/LDAP databases. If
619you want to allow all characters, set this value to empty.")
620
621 (auth-username-translation
622 (string "")
623 "Username character translations before it's looked up from
624databases. The value contains series of from -> to characters. For
625example @samp{#@@/@@} means that @samp{#} and @samp{/} characters are
626translated to @samp{@@}.")
627
628 (auth-username-format
629 (string "%Lu")
630 "Username formatting before it's looked up from databases. You can
631use the standard variables here, e.g. %Lu would lowercase the username,
632%n would drop away the domain if it was given, or @samp{%n-AT-%d} would
633change the @samp{@@} into @samp{-AT-}. This translation is done after
634@samp{auth-username-translation} changes.")
635
636 (auth-master-user-separator
637 (string "")
638 "If you want to allow master users to log in by specifying the master
639username within the normal username string (i.e. not using SASL
640mechanism's support for it), you can specify the separator character
641here. The format is then <username><separator><master username>.
642UW-IMAP uses @samp{*} as the separator, so that could be a good
643choice.")
644
645 (auth-anonymous-username
646 (string "anonymous")
647 "Username to use for users logging in with ANONYMOUS SASL
648mechanism.")
649
650 (auth-worker-max-count
651 (non-negative-integer 30)
652 "Maximum number of dovecot-auth worker processes. They're used to
653execute blocking passdb and userdb queries (e.g. MySQL and PAM).
654They're automatically created and destroyed as needed.")
655
656 (auth-gssapi-hostname
657 (string "")
658 "Host name to use in GSSAPI principal names. The default is to use
659the name returned by gethostname(). Use @samp{$ALL} (with quotes) to
660allow all keytab entries.")
661
662 (auth-krb5-keytab
663 (string "")
664 "Kerberos keytab to use for the GSSAPI mechanism. Will use the
665system default (usually /etc/krb5.keytab) if not specified. You may
666need to change the auth service to run as root to be able to read this
667file.")
668
669 (auth-use-winbind?
670 (boolean #f)
671 "Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon
672and @samp{ntlm-auth} helper.
673<doc/wiki/Authentication/Mechanisms/Winbind.txt>.")
674
675 (auth-winbind-helper-path
676 (file-name "/usr/bin/ntlm_auth")
677 "Path for Samba's @samp{ntlm-auth} helper binary.")
678
679 (auth-failure-delay
680 (string "2 secs")
681 "Time to delay before replying to failed authentications.")
682
683 (auth-ssl-require-client-cert?
684 (boolean #f)
685 "Require a valid SSL client certificate or the authentication
686fails.")
687
688 (auth-ssl-username-from-cert?
689 (boolean #f)
690 "Take the username from client's SSL certificate, using
691@code{X509_NAME_get_text_by_NID()} which returns the subject's DN's
692CommonName.")
693
694 (auth-mechanisms
695 (space-separated-string-list '("plain"))
696 "List of wanted authentication mechanisms. Supported mechanisms are:
697@samp{plain}, @samp{login}, @samp{digest-md5}, @samp{cram-md5},
698@samp{ntlm}, @samp{rpa}, @samp{apop}, @samp{anonymous}, @samp{gssapi},
699@samp{otp}, @samp{skey}, and @samp{gss-spnego}. NOTE: See also
700@samp{disable-plaintext-auth} setting.")
701
702 (director-servers
703 (space-separated-string-list '())
704 "List of IPs or hostnames to all director servers, including ourself.
705Ports can be specified as ip:port. The default port is the same as what
706director service's @samp{inet-listener} is using.")
707
708 (director-mail-servers
709 (space-separated-string-list '())
710 "List of IPs or hostnames to all backend mail servers. Ranges are
711allowed too, like 10.0.0.10-10.0.0.30.")
712
713 (director-user-expire
714 (string "15 min")
715 "How long to redirect users to a specific server after it no longer
716has any connections.")
717
d8c18af8
AW
718 (director-username-hash
719 (string "%Lu")
720 "How the username is translated before being hashed. Useful values
721include %Ln if user can log in with or without @@domain, %Ld if mailboxes
722are shared within domain.")
723
724;;; Log destination.
725
726 (log-path
727 (string "syslog")
728 "Log file to use for error messages. @samp{syslog} logs to syslog,
729@samp{/dev/stderr} logs to stderr.")
730
731 (info-log-path
732 (string "")
733 "Log file to use for informational messages. Defaults to
734@samp{log-path}.")
735
736 (debug-log-path
737 (string "")
738 "Log file to use for debug messages. Defaults to
739@samp{info-log-path}.")
740
741 (syslog-facility
742 (string "mail")
743 "Syslog facility to use if you're logging to syslog. Usually if you
744don't want to use @samp{mail}, you'll use local0..local7. Also other
745standard facilities are supported.")
746
747 (auth-verbose?
748 (boolean #f)
749 "Log unsuccessful authentication attempts and the reasons why they
750failed.")
751
5b3d3cf7
CB
752 (auth-verbose-passwords
753 (string "no")
d8c18af8
AW
754 "In case of password mismatches, log the attempted password. Valid
755values are no, plain and sha1. sha1 can be useful for detecting brute
756force password attempts vs. user simply trying the same password over
757and over again. You can also truncate the value to n chars by appending
758\":n\" (e.g. sha1:6).")
759
760 (auth-debug?
761 (boolean #f)
762 "Even more verbose logging for debugging purposes. Shows for example
763SQL queries.")
764
765 (auth-debug-passwords?
766 (boolean #f)
767 "In case of password mismatches, log the passwords and used scheme so
768the problem can be debugged. Enabling this also enables
769@samp{auth-debug}.")
770
771 (mail-debug?
772 (boolean #f)
773 "Enable mail process debugging. This can help you figure out why
774Dovecot isn't finding your mails.")
775
776 (verbose-ssl?
777 (boolean #f)
778 "Show protocol level SSL errors.")
779
780 (log-timestamp
781 (string "\"%b %d %H:%M:%S \"")
782 "Prefix for each line written to log file. % codes are in
783strftime(3) format.")
784
785 (login-log-format-elements
786 (space-separated-string-list
787 '("user=<%u>" "method=%m" "rip=%r" "lip=%l" "mpid=%e" "%c"))
788 "List of elements we want to log. The elements which have a
789non-empty variable value are joined together to form a comma-separated
790string.")
791
792 (login-log-format
793 (string "%$: %s")
794 "Login log format. %s contains @samp{login-log-format-elements}
795string, %$ contains the data we want to log.")
796
797 (mail-log-prefix
28c03b45 798 (string "\"%s(%u)<%{pid}><%{session}>: \"")
d8c18af8
AW
799 "Log prefix for mail processes. See doc/wiki/Variables.txt for list
800of possible variables you can use.")
801
802 (deliver-log-format
803 (string "msgid=%m: %$")
804 "Format to use for logging mail deliveries. You can use variables:
805@table @code
806@item %$
807Delivery status message (e.g. @samp{saved to INBOX})
808@item %m
809Message-ID
810@item %s
811Subject
812@item %f
813From address
814@item %p
815Physical size
816@item %w
817Virtual size.
818@end table")
819
820;;; Mailbox locations and namespaces
821
822 (mail-location
823 (string "")
824 "Location for users' mailboxes. The default is empty, which means
825that Dovecot tries to find the mailboxes automatically. This won't work
826if the user doesn't yet have any mail, so you should explicitly tell
827Dovecot the full location.
828
829If you're using mbox, giving a path to the INBOX
830file (e.g. /var/mail/%u) isn't enough. You'll also need to tell Dovecot
831where the other mailboxes are kept. This is called the \"root mail
832directory\", and it must be the first path given in the
833@samp{mail-location} setting.
834
835There are a few special variables you can use, eg.:
836
837@table @samp
838@item %u
839username
840@item %n
841user part in user@@domain, same as %u if there's no domain
842@item %d
843domain part in user@@domain, empty if there's no domain
844@item %h
845home director
846@end table
847
848See doc/wiki/Variables.txt for full list. Some examples:
849@table @samp
850@item maildir:~/Maildir
851@item mbox:~/mail:INBOX=/var/mail/%u
852@item mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%
853@end table")
854
855 (mail-uid
856 (string "")
857 "System user and group used to access mails. If you use multiple,
858userdb can override these by returning uid or gid fields. You can use
859either numbers or names. <doc/wiki/UserIds.txt>.")
860
861 (mail-gid
862 (string "")
863 "")
864
865 (mail-privileged-group
866 (string "")
867 "Group to enable temporarily for privileged operations. Currently
868this is used only with INBOX when either its initial creation or
869dotlocking fails. Typically this is set to \"mail\" to give access to
870/var/mail.")
871
872 (mail-access-groups
873 (string "")
874 "Grant access to these supplementary groups for mail processes.
875Typically these are used to set up access to shared mailboxes. Note
876that it may be dangerous to set these if users can create
877symlinks (e.g. if \"mail\" group is set here, ln -s /var/mail ~/mail/var
878could allow a user to delete others' mailboxes, or ln -s
879/secret/shared/box ~/mail/mybox would allow reading it).")
880
881 (mail-full-filesystem-access?
882 (boolean #f)
8f65585b 883 "Allow full file system access to clients. There's no access checks
d8c18af8
AW
884other than what the operating system does for the active UID/GID. It
885works with both maildir and mboxes, allowing you to prefix mailboxes
886names with e.g. /path/ or ~user/.")
887
888;;; Mail processes
889
890 (mmap-disable?
891 (boolean #f)
892 "Don't use mmap() at all. This is required if you store indexes to
8f65585b 893shared file systems (NFS or clustered file system).")
d8c18af8
AW
894
895 (dotlock-use-excl?
896 (boolean #t)
897 "Rely on @samp{O_EXCL} to work when creating dotlock files. NFS
898supports @samp{O_EXCL} since version 3, so this should be safe to use
899nowadays by default.")
900
901 (mail-fsync
902 (string "optimized")
903 "When to use fsync() or fdatasync() calls:
904@table @code
905@item optimized
906Whenever necessary to avoid losing important data
907@item always
908Useful with e.g. NFS when write()s are delayed
909@item never
910Never use it (best performance, but crashes can lose data).
911@end table")
912
913 (mail-nfs-storage?
914 (boolean #f)
915 "Mail storage exists in NFS. Set this to yes to make Dovecot flush
916NFS caches whenever needed. If you're using only a single mail server
917this isn't needed.")
918
919 (mail-nfs-index?
920 (boolean #f)
921 "Mail index files also exist in NFS. Setting this to yes requires
922@samp{mmap-disable? #t} and @samp{fsync-disable? #f}.")
923
924 (lock-method
925 (string "fcntl")
926 "Locking method for index files. Alternatives are fcntl, flock and
927dotlock. Dotlocking uses some tricks which may create more disk I/O
928than other locking methods. NFS users: flock doesn't work, remember to
929change @samp{mmap-disable}.")
930
931 (mail-temp-dir
932 (file-name "/tmp")
933 "Directory in which LDA/LMTP temporarily stores incoming mails >128
934kB.")
935
936 (first-valid-uid
937 (non-negative-integer 500)
938 "Valid UID range for users. This is mostly to make sure that users can't
939log in as daemons or other system users. Note that denying root logins is
940hardcoded to dovecot binary and can't be done even if @samp{first-valid-uid}
941is set to 0.")
942
943 (last-valid-uid
944 (non-negative-integer 0)
945 "")
946
947 (first-valid-gid
948 (non-negative-integer 1)
949 "Valid GID range for users. Users having non-valid GID as primary group ID
950aren't allowed to log in. If user belongs to supplementary groups with
951non-valid GIDs, those groups are not set.")
952
953 (last-valid-gid
954 (non-negative-integer 0)
955 "")
956
957 (mail-max-keyword-length
958 (non-negative-integer 50)
959 "Maximum allowed length for mail keyword name. It's only forced when
960trying to create new keywords.")
961
962 (valid-chroot-dirs
963 (colon-separated-file-name-list '())
964 "List of directories under which chrooting is allowed for mail
965processes (i.e. /var/mail will allow chrooting to /var/mail/foo/bar
966too). This setting doesn't affect @samp{login-chroot}
967@samp{mail-chroot} or auth chroot settings. If this setting is empty,
968\"/./\" in home dirs are ignored. WARNING: Never add directories here
969which local users can modify, that may lead to root exploit. Usually
970this should be done only if you don't allow shell access for users.
971<doc/wiki/Chrooting.txt>.")
972
973 (mail-chroot
974 (string "")
975 "Default chroot directory for mail processes. This can be overridden
976for specific users in user database by giving /./ in user's home
977directory (e.g. /home/./user chroots into /home). Note that usually
978there is no real need to do chrooting, Dovecot doesn't allow users to
979access files outside their mail directory anyway. If your home
980directories are prefixed with the chroot directory, append \"/.\" to
981@samp{mail-chroot}. <doc/wiki/Chrooting.txt>.")
982
983 (auth-socket-path
984 (file-name "/var/run/dovecot/auth-userdb")
985 "UNIX socket path to master authentication server to find users.
986This is used by imap (for shared users) and lda.")
987
988 (mail-plugin-dir
bcfe0f0c
AA
989 (file-name "/etc/dovecot/modules")
990 "Directory where to look up mail plugins.
991Defaults to @samp{\"/etc/dovecot/modules\"}, a union of all enabled mail
992plugins.")
d8c18af8
AW
993
994 (mail-plugins
995 (space-separated-string-list '())
996 "List of plugins to load for all services. Plugins specific to IMAP,
997LDA, etc. are added to this list in their own .conf files.")
998
999
1000 (mail-cache-min-mail-count
1001 (non-negative-integer 0)
1002 "The minimum number of mails in a mailbox before updates are done to
1003cache file. This allows optimizing Dovecot's behavior to do less disk
1004writes at the cost of more disk reads.")
1005
1006 (mailbox-idle-check-interval
1007 (string "30 secs")
1008 "When IDLE command is running, mailbox is checked once in a while to
1009see if there are any new mails or other changes. This setting defines
1010the minimum time to wait between those checks. Dovecot can also use
1011dnotify, inotify and kqueue to find out immediately when changes
1012occur.")
1013
1014 (mail-save-crlf?
1015 (boolean #f)
1016 "Save mails with CR+LF instead of plain LF. This makes sending those
1017mails take less CPU, especially with sendfile() syscall with Linux and
1018FreeBSD. But it also creates a bit more disk I/O which may just make it
1019slower. Also note that if other software reads the mboxes/maildirs,
1020they may handle the extra CRs wrong and cause problems.")
1021
1022 (maildir-stat-dirs?
1023 (boolean #f)
1024 "By default LIST command returns all entries in maildir beginning
1025with a dot. Enabling this option makes Dovecot return only entries
1026which are directories. This is done by stat()ing each entry, so it
1027causes more disk I/O.
1028 (For systems setting struct @samp{dirent->d_type} this check is free
1029and it's done always regardless of this setting).")
1030
1031 (maildir-copy-with-hardlinks?
1032 (boolean #t)
1033 "When copying a message, do it with hard links whenever possible.
1034This makes the performance much better, and it's unlikely to have any
1035side effects.")
1036
1037 (maildir-very-dirty-syncs?
1038 (boolean #f)
1039 "Assume Dovecot is the only MUA accessing Maildir: Scan cur/
1040directory only when its mtime changes unexpectedly or when we can't find
1041the mail otherwise.")
1042
1043 (mbox-read-locks
1044 (space-separated-string-list '("fcntl"))
1045 "Which locking methods to use for locking mbox. There are four
1046available:
1047
1048@table @code
1049@item dotlock
1050Create <mailbox>.lock file. This is the oldest and most NFS-safe
1051solution. If you want to use /var/mail/ like directory, the users will
1052need write access to that directory.
1053@item dotlock-try
1054Same as dotlock, but if it fails because of permissions or because there
1055isn't enough disk space, just skip it.
1056@item fcntl
1057Use this if possible. Works with NFS too if lockd is used.
1058@item flock
1059May not exist in all systems. Doesn't work with NFS.
1060@item lockf
1061May not exist in all systems. Doesn't work with NFS.
1062@end table
1063
1064You can use multiple locking methods; if you do the order they're declared
1065in is important to avoid deadlocks if other MTAs/MUAs are using multiple
1066locking methods as well. Some operating systems don't allow using some of
1067them simultaneously.")
1068
1069 (mbox-write-locks
1070 (space-separated-string-list '("dotlock" "fcntl"))
1071 "")
1072
1073 (mbox-lock-timeout
1074 (string "5 mins")
1075 "Maximum time to wait for lock (all of them) before aborting.")
1076
1077 (mbox-dotlock-change-timeout
1078 (string "2 mins")
1079 "If dotlock exists but the mailbox isn't modified in any way,
1080override the lock file after this much time.")
1081
1082 (mbox-dirty-syncs?
1083 (boolean #t)
1084 "When mbox changes unexpectedly we have to fully read it to find out
1085what changed. If the mbox is large this can take a long time. Since
1086the change is usually just a newly appended mail, it'd be faster to
1087simply read the new mails. If this setting is enabled, Dovecot does
1088this but still safely fallbacks to re-reading the whole mbox file
1089whenever something in mbox isn't how it's expected to be. The only real
1090downside to this setting is that if some other MUA changes message
1091flags, Dovecot doesn't notice it immediately. Note that a full sync is
1092done with SELECT, EXAMINE, EXPUNGE and CHECK commands.")
1093
1094 (mbox-very-dirty-syncs?
1095 (boolean #f)
1096 "Like @samp{mbox-dirty-syncs}, but don't do full syncs even with SELECT,
1097EXAMINE, EXPUNGE or CHECK commands. If this is set,
1098@samp{mbox-dirty-syncs} is ignored.")
1099
1100 (mbox-lazy-writes?
1101 (boolean #t)
1102 "Delay writing mbox headers until doing a full write sync (EXPUNGE
1103and CHECK commands and when closing the mailbox). This is especially
1104useful for POP3 where clients often delete all mails. The downside is
1105that our changes aren't immediately visible to other MUAs.")
1106
1107 (mbox-min-index-size
1108 (non-negative-integer 0)
1109 "If mbox size is smaller than this (e.g. 100k), don't write index
1110files. If an index file already exists it's still read, just not
1111updated.")
1112
1113 (mdbox-rotate-size
28c03b45 1114 (non-negative-integer #e10e6)
d8c18af8
AW
1115 "Maximum dbox file size until it's rotated.")
1116
1117 (mdbox-rotate-interval
1118 (string "1d")
1119 "Maximum dbox file age until it's rotated. Typically in days. Day
1120begins from midnight, so 1d = today, 2d = yesterday, etc. 0 = check
1121disabled.")
1122
1123 (mdbox-preallocate-space?
1124 (boolean #f)
1125 "When creating new mdbox files, immediately preallocate their size to
1126@samp{mdbox-rotate-size}. This setting currently works only in Linux
8f65585b 1127with some file systems (ext4, xfs).")
d8c18af8
AW
1128
1129 (mail-attachment-dir
1130 (string "")
1131 "sdbox and mdbox support saving mail attachments to external files,
1132which also allows single instance storage for them. Other backends
1133don't support this for now.
1134
1135WARNING: This feature hasn't been tested much yet. Use at your own risk.
1136
1137Directory root where to store mail attachments. Disabled, if empty.")
1138
1139 (mail-attachment-min-size
1140 (non-negative-integer #e128e3)
1141 "Attachments smaller than this aren't saved externally. It's also
1142possible to write a plugin to disable saving specific attachments
1143externally.")
1144
1145 (mail-attachment-fs
1146 (string "sis posix")
8f65585b 1147 "File system backend to use for saving attachments:
d8c18af8
AW
1148@table @code
1149@item posix
1150No SiS done by Dovecot (but this might help FS's own deduplication)
1151@item sis posix
1152SiS with immediate byte-by-byte comparison during saving
1153@item sis-queue posix
1154SiS with delayed comparison and deduplication.
1155@end table")
1156
1157 (mail-attachment-hash
1158 (string "%{sha1}")
1159 "Hash format to use in attachment filenames. You can add any text and
1160variables: @code{%@{md4@}}, @code{%@{md5@}}, @code{%@{sha1@}},
1161@code{%@{sha256@}}, @code{%@{sha512@}}, @code{%@{size@}}. Variables can be
1162truncated, e.g. @code{%@{sha256:80@}} returns only first 80 bits.")
1163
1164 (default-process-limit
1165 (non-negative-integer 100)
1166 "")
1167
1168 (default-client-limit
1169 (non-negative-integer 1000)
1170 "")
1171
1172 (default-vsz-limit
1173 (non-negative-integer #e256e6)
1174 "Default VSZ (virtual memory size) limit for service processes.
1175This is mainly intended to catch and kill processes that leak memory
1176before they eat up everything.")
1177
1178 (default-login-user
1179 (string "dovenull")
1180 "Login user is internally used by login processes. This is the most
1181untrusted user in Dovecot system. It shouldn't have access to anything
1182at all.")
1183
1184 (default-internal-user
1185 (string "dovecot")
1186 "Internal user is used by unprivileged processes. It should be
1187separate from login user, so that login processes can't disturb other
1188processes.")
1189
1190 (ssl?
1191 (string "required")
1192 "SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>.")
1193
1194 (ssl-cert
1195 (string "</etc/dovecot/default.pem")
1196 "PEM encoded X.509 SSL/TLS certificate (public key).")
1197
1198 (ssl-key
1199 (string "</etc/dovecot/private/default.pem")
1200 "PEM encoded SSL/TLS private key. The key is opened before
1201dropping root privileges, so keep the key file unreadable by anyone but
1202root.")
1203
1204 (ssl-key-password
1205 (string "")
1206 "If key file is password protected, give the password here.
1207Alternatively give it when starting dovecot with -p parameter. Since
1208this file is often world-readable, you may want to place this setting
1209instead to a different.")
1210
1211 (ssl-ca
1212 (string "")
1213 "PEM encoded trusted certificate authority. Set this only if you
1214intend to use @samp{ssl-verify-client-cert? #t}. The file should
1215contain the CA certificate(s) followed by the matching
1216CRL(s). (e.g. @samp{ssl-ca </etc/ssl/certs/ca.pem}).")
1217 (ssl-require-crl?
1218 (boolean #t)
1219 "Require that CRL check succeeds for client certificates.")
1220 (ssl-verify-client-cert?
1221 (boolean #f)
1222 "Request client to send a certificate. If you also want to require
1223it, set @samp{auth-ssl-require-client-cert? #t} in auth section.")
1224
1225 (ssl-cert-username-field
1226 (string "commonName")
1227 "Which field from certificate to use for username. commonName and
1228x500UniqueIdentifier are the usual choices. You'll also need to set
1229@samp{auth-ssl-username-from-cert? #t}.")
1230
28c03b45
TGR
1231 (ssl-min-protocol
1232 (string "TLSv1")
1233 "Minimum SSL protocol version to accept.")
d8c18af8
AW
1234
1235 (ssl-cipher-list
28c03b45 1236 (string "ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH")
d8c18af8
AW
1237 "SSL ciphers to use.")
1238
1239 (ssl-crypto-device
1240 (string "")
1241 "SSL crypto device to use, for valid values run \"openssl engine\".")
1242
1243 (postmaster-address
66329c23 1244 (string "postmaster@%d")
d8c18af8
AW
1245 "Address to use when sending rejection mails.
1246Default is postmaster@@<your domain>. %d expands to recipient domain.")
1247
1248 (hostname
1249 (string "")
1250 "Hostname to use in various parts of sent mails (e.g. in Message-Id)
1251and in LMTP replies. Default is the system's real hostname@@domain.")
1252
1253 (quota-full-tempfail?
1254 (boolean #f)
1255 "If user is over quota, return with temporary failure instead of
1256bouncing the mail.")
1257
1258 (sendmail-path
1259 (file-name "/usr/sbin/sendmail")
1260 "Binary to use for sending mails.")
1261
1262 (submission-host
1263 (string "")
1264 "If non-empty, send mails via this SMTP host[:port] instead of
1265sendmail.")
1266
1267 (rejection-subject
1268 (string "Rejected: %s")
1269 "Subject: header to use for rejection mails. You can use the same
1270variables as for @samp{rejection-reason} below.")
1271
1272 (rejection-reason
1273 (string "Your message to <%t> was automatically rejected:%n%r")
1274 "Human readable error message for rejection mails. You can use
1275variables:
1276
1277@table @code
1278@item %n
1279CRLF
1280@item %r
1281reason
1282@item %s
1283original subject
1284@item %t
1285recipient
1286@end table")
1287
1288 (recipient-delimiter
1289 (string "+")
1290 "Delimiter character between local-part and detail in email
1291address.")
1292
1293 (lda-original-recipient-header
1294 (string "")
1295 "Header where the original recipient address (SMTP's RCPT TO:
1296address) is taken from if not available elsewhere. With dovecot-lda -a
1297parameter overrides this. A commonly used header for this is
1298X-Original-To.")
1299
1300 (lda-mailbox-autocreate?
1301 (boolean #f)
1302 "Should saving a mail to a nonexistent mailbox automatically create
1303it?.")
1304
1305 (lda-mailbox-autosubscribe?
1306 (boolean #f)
1307 "Should automatically created mailboxes be also automatically
1308subscribed?.")
1309
1310
1311 (imap-max-line-length
1312 (non-negative-integer #e64e3)
1313 "Maximum IMAP command line length. Some clients generate very long
1314command lines with huge mailboxes, so you may need to raise this if you
1315get \"Too long argument\" or \"IMAP command line too large\" errors
1316often.")
1317
1318 (imap-logout-format
28c03b45 1319 (string "in=%i out=%o deleted=%{deleted} expunged=%{expunged} trashed=%{trashed} hdr_count=%{fetch_hdr_count} hdr_bytes=%{fetch_hdr_bytes} body_count=%{fetch_body_count} body_bytes=%{fetch_body_bytes}")
d8c18af8
AW
1320 "IMAP logout format string:
1321@table @code
1322@item %i
1323total number of bytes read from client
1324@item %o
1325total number of bytes sent to client.
28c03b45
TGR
1326@end table
1327See @file{doc/wiki/Variables.txt} for a list of all the variables you can use.")
d8c18af8
AW
1328
1329 (imap-capability
1330 (string "")
1331 "Override the IMAP CAPABILITY response. If the value begins with '+',
1332add the given capabilities on top of the defaults (e.g. +XFOO XBAR).")
1333
1334 (imap-idle-notify-interval
1335 (string "2 mins")
1336 "How long to wait between \"OK Still here\" notifications when client
1337is IDLEing.")
1338
1339 (imap-id-send
1340 (string "")
1341 "ID field names and values to send to clients. Using * as the value
1342makes Dovecot use the default value. The following fields have default
1343values currently: name, version, os, os-version, support-url,
1344support-email.")
1345
1346 (imap-id-log
1347 (string "")
1348 "ID fields sent by client to log. * means everything.")
1349
1350 (imap-client-workarounds
1351 (space-separated-string-list '())
1352 "Workarounds for various client bugs:
1353
1354@table @code
1355@item delay-newmail
1356Send EXISTS/RECENT new mail notifications only when replying to NOOP and
1357CHECK commands. Some clients ignore them otherwise, for example OSX
1358Mail (<v2.1). Outlook Express breaks more badly though, without this it
1359may show user \"Message no longer in server\" errors. Note that OE6
1360still breaks even with this workaround if synchronization is set to
1361\"Headers Only\".
1362
1363@item tb-extra-mailbox-sep
1364Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and
1365adds extra @samp{/} suffixes to mailbox names. This option causes Dovecot to
1366ignore the extra @samp{/} instead of treating it as invalid mailbox name.
1367
1368@item tb-lsub-flags
1369Show \\Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox).
1370This makes Thunderbird realize they aren't selectable and show them
1371greyed out, instead of only later giving \"not selectable\" popup error.
1372@end table
1373")
1374
1375 (imap-urlauth-host
1376 (string "")
22470c88
AA
1377 "Host allowed in URLAUTH URLs sent by client. \"*\" allows all.")
1378
1379 (protocols
1380 (protocol-configuration-list
1381 (list (protocol-configuration
1382 (name "imap"))))
1383 "List of protocols we want to serve. Available protocols include
1384@samp{imap}, @samp{pop3}, and @samp{lmtp}.")
1385
1386 (services
1387 (service-configuration-list
1388 (list
1389 (service-configuration
1390 (kind "imap-login")
1391 (client-limit 0)
1392 (process-limit 0)
1393 (listeners
1394 (list
1395 (inet-listener-configuration (protocol "imap") (port 143) (ssl? #f))
1396 (inet-listener-configuration (protocol "imaps") (port 993) (ssl? #t)))))
1397 (service-configuration
1398 (kind "pop3-login")
1399 (listeners
1400 (list
1401 (inet-listener-configuration (protocol "pop3") (port 110) (ssl? #f))
1402 (inet-listener-configuration (protocol "pop3s") (port 995) (ssl? #t)))))
1403 (service-configuration
1404 (kind "lmtp")
1405 (client-limit 1)
1406 (process-limit 0)
1407 (listeners
1408 (list (unix-listener-configuration (path "lmtp") (mode "0666")))))
1409 (service-configuration
1410 (kind "imap")
1411 (client-limit 1)
1412 (process-limit 1024))
1413 (service-configuration
1414 (kind "pop3")
1415 (client-limit 1)
1416 (process-limit 1024))
1417 (service-configuration
1418 (kind "auth")
1419 (service-count 0)
1420 (client-limit 0)
1421 (process-limit 1)
1422 (listeners
1423 (list (unix-listener-configuration (path "auth-userdb")))))
1424 (service-configuration
1425 (kind "auth-worker")
1426 (client-limit 1)
1427 (process-limit 0))
1428 (service-configuration
1429 (kind "dict")
1430 (client-limit 1)
1431 (process-limit 0)
1432 (listeners (list (unix-listener-configuration (path "dict")))))))
1433 "List of services to enable. Available services include @samp{imap},
1434@samp{imap-login}, @samp{pop3}, @samp{pop3-login}, @samp{auth}, and
1435@samp{lmtp}."))
d8c18af8
AW
1436
1437(define-configuration opaque-dovecot-configuration
1438 (dovecot
1439 (package dovecot)
1440 "The dovecot package.")
1441
1442 (string
5305ed20
JL
1443 (string (configuration-missing-field 'opaque-dovecot-configuration
1444 'string))
d8c18af8
AW
1445 "The contents of the @code{dovecot.conf} to use."))
1446
1447(define %dovecot-accounts
1448 ;; Account and group for the Dovecot daemon.
1449 (list (user-group (name "dovecot") (system? #t))
1450 (user-account
1451 (name "dovecot")
1452 (group "dovecot")
1453 (system? #t)
1454 (comment "Dovecot daemon user")
1455 (home-directory "/var/empty")
9e41130b 1456 (shell (file-append shadow "/sbin/nologin")))
d8c18af8
AW
1457
1458 (user-group (name "dovenull") (system? #t))
1459 (user-account
1460 (name "dovenull")
1461 (group "dovenull")
1462 (system? #t)
1463 (comment "Dovecot daemon login user")
1464 (home-directory "/var/empty")
9e41130b 1465 (shell (file-append shadow "/sbin/nologin")))))
d8c18af8 1466
6310dff1 1467(define (%dovecot-activation config)
d8c18af8 1468 ;; Activation gexp.
6310dff1
OP
1469 (let ((config-str
1470 (cond
1471 ((opaque-dovecot-configuration? config)
1472 (opaque-dovecot-configuration-string config))
1473 (else
1474 (with-output-to-string
1475 (lambda ()
1476 (serialize-configuration config
1477 dovecot-configuration-fields)))))))
1478 #~(begin
1479 (use-modules (guix build utils))
1480 (define (mkdir-p/perms directory owner perms)
1481 (mkdir-p directory)
1482 (chown "/var/run/dovecot" (passwd:uid owner) (passwd:gid owner))
1483 (chmod directory perms))
1484 (define (build-subject parameters)
1485 (string-concatenate
1486 (map (lambda (pair)
1487 (let ((k (car pair)) (v (cdr pair)))
1488 (define (escape-char str chr)
1489 (string-join (string-split str chr) (string #\\ chr)))
1490 (string-append "/" k "="
1491 (escape-char (escape-char v #\=) #\/))))
1492 (filter (lambda (pair) (cdr pair)) parameters))))
1493 (define* (create-self-signed-certificate-if-absent
1494 #:key private-key public-key (owner (getpwnam "root"))
1495 (common-name (gethostname))
59e80445 1496 (organization-name "Guix")
6310dff1
OP
1497 (organization-unit-name "Default Self-Signed Certificate")
1498 (subject-parameters `(("CN" . ,common-name)
1499 ("O" . ,organization-name)
1500 ("OU" . ,organization-unit-name)))
1501 (subject (build-subject subject-parameters)))
1502 ;; Note that by default, OpenSSL outputs keys in PEM format. This
1503 ;; is what we want.
1504 (unless (file-exists? private-key)
1505 (cond
1506 ((zero? (system* (string-append #$openssl "/bin/openssl")
1507 "genrsa" "-out" private-key "2048"))
1508 (chown private-key (passwd:uid owner) (passwd:gid owner))
1509 (chmod private-key #o400))
1510 (else
1511 (format (current-error-port)
1512 "Failed to create private key at ~a.\n" private-key))))
1513 (unless (file-exists? public-key)
1514 (cond
1515 ((zero? (system* (string-append #$openssl "/bin/openssl")
1516 "req" "-new" "-x509" "-key" private-key
1517 "-out" public-key "-days" "3650"
1518 "-batch" "-subj" subject))
1519 (chown public-key (passwd:uid owner) (passwd:gid owner))
1520 (chmod public-key #o444))
1521 (else
1522 (format (current-error-port)
1523 "Failed to create public key at ~a.\n" public-key)))))
bcfe0f0c
AA
1524 (let ((user (getpwnam "dovecot"))
1525 ;; This is Dovecot's term for the base directory for
1526 ;; dynamically loadable modules. It supports only one.
1527 (moduledir "/etc/dovecot/modules"))
6310dff1
OP
1528 (mkdir-p/perms "/var/run/dovecot" user #o755)
1529 (mkdir-p/perms "/var/lib/dovecot" user #o755)
1530 (mkdir-p/perms "/etc/dovecot" user #o755)
1531 (copy-file #$(plain-file "dovecot.conf" config-str)
1532 "/etc/dovecot/dovecot.conf")
1533 (mkdir-p/perms "/etc/dovecot/private" user #o700)
bcfe0f0c
AA
1534 (unless (file-exists? moduledir)
1535 (symlink "/run/current-system/profile/lib/dovecot" moduledir))
6310dff1
OP
1536 (create-self-signed-certificate-if-absent
1537 #:private-key "/etc/dovecot/private/default.pem"
1538 #:public-key "/etc/dovecot/default.pem"
1539 #:owner (getpwnam "root")
1540 #:common-name (format #f "Dovecot service on ~a" (gethostname)))))))
d8c18af8 1541
d4053c71
AK
1542(define (dovecot-shepherd-service config)
1543 "Return a list of <shepherd-service> for CONFIG."
6310dff1
OP
1544 (let ((dovecot (if (opaque-dovecot-configuration? config)
1545 (opaque-dovecot-configuration-dovecot config)
1546 (dovecot-configuration-dovecot config))))
d4053c71 1547 (list (shepherd-service
d8c18af8
AW
1548 (documentation "Run the Dovecot POP3/IMAP mail server.")
1549 (provision '(dovecot))
1550 (requirement '(networking))
1551 (start #~(make-forkexec-constructor
1552 (list (string-append #$dovecot "/sbin/dovecot")
6310dff1 1553 "-F")))
b25ecfa2
LC
1554 (stop #~(lambda _
1555 (invoke #$(file-append dovecot "/sbin/dovecot")
1556 "stop")
1557 #f))))))
d8c18af8
AW
1558
1559(define %dovecot-pam-services
1560 (list (unix-pam-service "dovecot")))
1561
1562(define dovecot-service-type
1563 (service-type (name 'dovecot)
1564 (extensions
d4053c71
AK
1565 (list (service-extension shepherd-root-service-type
1566 dovecot-shepherd-service)
d8c18af8
AW
1567 (service-extension account-service-type
1568 (const %dovecot-accounts))
1569 (service-extension pam-root-service-type
1570 (const %dovecot-pam-services))
1571 (service-extension activation-service-type
6310dff1 1572 %dovecot-activation)))))
d8c18af8
AW
1573
1574(define* (dovecot-service #:key (config (dovecot-configuration)))
1575 "Return a service that runs @command{dovecot}, a mail server that can run
1576POP3, IMAP, and LMTP. @var{config} should be a configuration object created
1577by @code{dovecot-configuration}. @var{config} may also be created by
1578@code{opaque-dovecot-configuration}, which allows specification of the
1579@code{dovecot.conf} as a string."
1580 (validate-configuration config
1581 (if (opaque-dovecot-configuration? config)
1582 opaque-dovecot-configuration-fields
1583 dovecot-configuration-fields))
1584 (service dovecot-service-type config))
1585
1586;; A little helper to make it easier to document all those fields.
5305ed20
JL
1587(define (generate-dovecot-documentation)
1588 (generate-documentation
d8c18af8
AW
1589 `((dovecot-configuration
1590 ,dovecot-configuration-fields
1591 (dict dict-configuration)
1592 (namespaces namespace-configuration)
1593 (plugin plugin-configuration)
1594 (passdbs passdb-configuration)
1595 (userdbs userdb-configuration)
1596 (services service-configuration)
1597 (protocols protocol-configuration))
1598 (dict-configuration ,dict-configuration-fields)
1599 (plugin-configuration ,plugin-configuration-fields)
1600 (passdb-configuration ,passdb-configuration-fields)
1601 (userdb-configuration ,userdb-configuration-fields)
1602 (unix-listener-configuration ,unix-listener-configuration-fields)
1603 (fifo-listener-configuration ,fifo-listener-configuration-fields)
1604 (inet-listener-configuration ,inet-listener-configuration-fields)
1605 (namespace-configuration
1606 ,namespace-configuration-fields
1607 (mailboxes mailbox-configuration))
1608 (mailbox-configuration ,mailbox-configuration-fields)
1609 (service-configuration
1610 ,service-configuration-fields
1611 (listeners unix-listener-configuration fifo-listener-configuration
1612 inet-listener-configuration))
5305ed20
JL
1613 (protocol-configuration ,protocol-configuration-fields))
1614 'dovecot-configuration))
f88371e8
SB
1615
1616\f
1617;;;
1618;;; OpenSMTPD.
1619;;;
1620
1621(define-record-type* <opensmtpd-configuration>
1622 opensmtpd-configuration make-opensmtpd-configuration
1623 opensmtpd-configuration?
1624 (package opensmtpd-configuration-package
1625 (default opensmtpd))
1626 (config-file opensmtpd-configuration-config-file
1627 (default %default-opensmtpd-config-file)))
1628
1629(define %default-opensmtpd-config-file
1630 (plain-file "smtpd.conf" "
1631listen on lo
c3f146e7
TGR
1632
1633action inbound mbox
1634match for local action inbound
1635
1636action outbound relay
1637match from local for any action outbound
f88371e8
SB
1638"))
1639
1640(define opensmtpd-shepherd-service
1641 (match-lambda
1642 (($ <opensmtpd-configuration> package config-file)
1643 (list (shepherd-service
1644 (provision '(smtpd))
1645 (requirement '(loopback))
1646 (documentation "Run the OpenSMTPD daemon.")
1647 (start (let ((smtpd (file-append package "/sbin/smtpd")))
1648 #~(make-forkexec-constructor
1649 (list #$smtpd "-f" #$config-file)
1650 #:pid-file "/var/run/smtpd.pid")))
1651 (stop #~(make-kill-destructor)))))))
1652
1653(define %opensmtpd-accounts
1654 (list (user-group
1655 (name "smtpq")
1656 (system? #t))
1657 (user-account
1658 (name "smtpd")
1659 (group "nogroup")
1660 (system? #t)
1661 (comment "SMTP Daemon")
1662 (home-directory "/var/empty")
1663 (shell (file-append shadow "/sbin/nologin")))
1664 (user-account
1665 (name "smtpq")
1666 (group "smtpq")
1667 (system? #t)
1668 (comment "SMTPD Queue")
1669 (home-directory "/var/empty")
1670 (shell (file-append shadow "/sbin/nologin")))))
1671
1672(define opensmtpd-activation
1673 (match-lambda
1674 (($ <opensmtpd-configuration> package config-file)
1675 (let ((smtpd (file-append package "/sbin/smtpd")))
1676 #~(begin
e57bd0be 1677 (use-modules (guix build utils))
f88371e8
SB
1678 ;; Create mbox and spool directories.
1679 (mkdir-p "/var/mail")
1680 (mkdir-p "/var/spool/smtpd")
a37e03d6
LC
1681 (chmod "/var/spool/smtpd" #o711)
1682 (mkdir-p "/var/spool/mail")
1683 (chmod "/var/spool/mail" #o711))))))
f88371e8 1684
ace8e269
KB
1685(define %opensmtpd-pam-services
1686 (list (unix-pam-service "smtpd")))
1687
f88371e8
SB
1688(define opensmtpd-service-type
1689 (service-type
1690 (name 'opensmtpd)
1691 (extensions
1692 (list (service-extension account-service-type
1693 (const %opensmtpd-accounts))
1694 (service-extension activation-service-type
1695 opensmtpd-activation)
ace8e269
KB
1696 (service-extension pam-root-service-type
1697 (const %opensmtpd-pam-services))
f88371e8
SB
1698 (service-extension profile-service-type
1699 (compose list opensmtpd-configuration-package))
1700 (service-extension shepherd-root-service-type
1701 opensmtpd-shepherd-service)))))
82ccc499
CZ
1702
1703\f
8d17cf1c
CZ
1704;;;
1705;;; mail aliases.
1706;;;
1707
1708(define (mail-aliases-etc aliases)
1709 `(("aliases" ,(plain-file "aliases"
1710 ;; Ideally we'd use a format string like
1711 ;; "~:{~a: ~{~a~^,~}\n~}", but it gives a
1712 ;; warning that I can't figure out how to fix,
1713 ;; so we'll just use string-join below instead.
1714 (format #f "~:{~a: ~a\n~}"
1715 (map (match-lambda
1716 ((alias addresses ...)
1717 (list alias (string-join addresses ","))))
1718 aliases))))))
1719
1720(define mail-aliases-service-type
1721 (service-type
1722 (name 'mail-aliases)
1723 (extensions
1724 (list (service-extension etc-service-type mail-aliases-etc)))
1725 (compose concatenate)
1726 (extend append)))
1727
1728\f
82ccc499
CZ
1729;;;
1730;;; Exim.
1731;;;
1732
1733(define-record-type* <exim-configuration> exim-configuration
1734 make-exim-configuration
1735 exim-configuration?
1736 (package exim-configuration-package ;<package>
1737 (default exim))
1738 (config-file exim-configuration-config-file ;file-like
b065f78e 1739 (default #f)))
82ccc499
CZ
1740
1741(define %exim-accounts
1742 (list (user-group
1743 (name "exim")
1744 (system? #t))
1745 (user-account
1746 (name "exim")
1747 (group "exim")
1748 (system? #t)
1749 (comment "Exim Daemon")
1750 (home-directory "/var/empty")
1751 (shell (file-append shadow "/sbin/nologin")))))
1752
1753(define (exim-computed-config-file package config-file)
1754 (computed-file "exim.conf"
1755 #~(call-with-output-file #$output
1756 (lambda (port)
1757 (format port "
1758exim_user = exim
1759exim_group = exim
1760.include ~a"
1761 #$(or config-file
1762 (file-append package "/etc/exim.conf")))))))
1763
1764(define exim-shepherd-service
1765 (match-lambda
b065f78e 1766 (($ <exim-configuration> package config-file)
82ccc499
CZ
1767 (list (shepherd-service
1768 (provision '(exim mta))
1769 (documentation "Run the exim daemon.")
1770 (requirement '(networking))
1771 (start #~(make-forkexec-constructor
1772 '(#$(file-append package "/bin/exim")
1773 "-bd" "-v" "-C"
1774 #$(exim-computed-config-file package config-file))))
1775 (stop #~(make-kill-destructor)))))))
1776
1777(define exim-activation
1778 (match-lambda
b065f78e 1779 (($ <exim-configuration> package config-file)
82ccc499
CZ
1780 (with-imported-modules '((guix build utils))
1781 #~(begin
1782 (use-modules (guix build utils))
1783
1784 (let ((uid (passwd:uid (getpw "exim")))
1785 (gid (group:gid (getgr "exim"))))
1786 (mkdir-p "/var/spool/exim")
1787 (chown "/var/spool/exim" uid gid))
1788
1789 (zero? (system* #$(file-append package "/bin/exim")
1790 "-bV" "-C" #$(exim-computed-config-file package config-file))))))))
1791
82ccc499
CZ
1792(define exim-profile
1793 (compose list exim-configuration-package))
1794
1795(define exim-service-type
1796 (service-type
1797 (name 'exim)
1798 (extensions
1799 (list (service-extension shepherd-root-service-type exim-shepherd-service)
1800 (service-extension account-service-type (const %exim-accounts))
1801 (service-extension activation-service-type exim-activation)
1802 (service-extension profile-service-type exim-profile)
b065f78e 1803 (service-extension mail-aliases-service-type (const '()))))))
412e6396
SB
1804
1805\f
1806;;;
1807;;; GNU Mailutils IMAP4 Daemon.
1808;;;
1809
1810(define %default-imap4d-config-file
1811 (plain-file "imap4d.conf" "server localhost {};\n"))
1812
1813(define-record-type* <imap4d-configuration>
1814 imap4d-configuration make-imap4d-configuration imap4d-configuration?
1815 (package imap4d-configuration-package
1816 (default mailutils))
1817 (config-file imap4d-configuration-config-file
1818 (default %default-imap4d-config-file)))
1819
1820(define imap4d-shepherd-service
1821 (match-lambda
1822 (($ <imap4d-configuration> package config-file)
1823 (list (shepherd-service
1824 (provision '(imap4d))
1825 (requirement '(networking syslogd))
1826 (documentation "Run the imap4d daemon.")
1827 (start (let ((imap4d (file-append package "/sbin/imap4d")))
1828 #~(make-forkexec-constructor
1829 (list #$imap4d "--daemon" "--foreground"
1830 "--config-file" #$config-file))))
1831 (stop #~(make-kill-destructor)))))))
1832
1833(define imap4d-service-type
1834 (service-type
1835 (name 'imap4d)
1836 (description
1837 "Run the GNU @command{imap4d} to serve e-mail messages through IMAP.")
1838 (extensions
1839 (list (service-extension
1840 shepherd-root-service-type imap4d-shepherd-service)))
1841 (default-value (imap4d-configuration))))