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