gnu: Fix typo in description of xfce-desktop-service.
[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>
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)
0190c1c0 24 #:use-module (gnu services shepherd)
d8c18af8
AW
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
24e96431 40 dovecot-service-type
d8c18af8
AW
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
362an @code{inet-listener-configuration}.")
363 (service-count
364 (non-negative-integer 1)
365 "Number of connections to handle before starting a new process.
366Typically the only useful values are 0 (unlimited) or 1. 1 is more
367secure, 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
376this."))
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.
396This 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
403address. 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.
441Valid 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
467all namespaces or some clients get confused. @samp{/} is usually a good
468one. The default however depends on the underlying mail storage
469format.")
470
471 (prefix
472 (string "")
473 "Prefix required to access this namespace. This needs to be
474different for all namespaces. For example @samp{Public/}.")
475
476 (location
477 (string "")
478 "Physical location of the mailbox. This is in same format as
479mail_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
484namespace has it.")
485
486 (hidden?
487 (boolean #f)
488 "If namespace is hidden, it's not advertised to clients via NAMESPACE
489extension. You'll most likely also want to set @samp{list? #f}. This is mostly
490useful when converting from another server with different namespaces
491which you want to deprecate but still keep working. For example you can
492create hidden namespaces with prefixes @samp{~/mail/}, @samp{~%u/mail/}
493and @samp{mail/}.")
494
495 (list?
496 (boolean #t)
497 "Show the mailboxes under this namespace with LIST command. This
498makes the namespace visible for clients that don't support NAMESPACE
499extension. The special @code{children} value lists child mailboxes, but
500hides the namespace prefix.")
501
502 (subscriptions?
503 (boolean #t)
504 "Namespace handles its own subscriptions. If set to @code{#f}, the
505parent namespace handles them. The empty prefix should always have this
506as @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{*}
531listens in all IPv4 interfaces, @samp{::} listens in all IPv6
532interfaces. If you want to specify non-default ports or anything more
533complex, 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}
586constructor.")
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}
601constructor.")
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
632allowed to override their IP addresses and ports (for logging and for
633authentication checks). @samp{disable-plaintext-auth} is also ignored
634for these networks. Typically you'd specify your IMAP proxy servers
635here.")
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
644and IP address. Useful for seeing who are actually using the IMAP
645processes (e.g. shared mailboxes or if same uid is used for multiple
646accounts).")
647
648 (shutdown-clients?
649 (boolean #t)
650 "Should all processes be killed when Dovecot master process shuts down.
651Setting this to @code{#f} means that Dovecot can be upgraded without
652forcing existing client connections to close (although that could also
653be 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
658server, 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
667and passed down to all of its child processes. You can also give
668key=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
675SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
676matches the local IP (i.e. you're connecting from the same computer),
677the connection is considered secure and plaintext authentication is
678allowed. 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.
683Note that bsdauth, PAM and vpopmail require @samp{cache-key} to be set
684for 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
689is no longer used, *except* if the main database lookup returns internal
690failure. We also try to handle password changes automatically: If
691user's previous authentication was successful, but this one wasn't, the
692cache isn't used. For now this works only with plaintext
693authentication.")
694
695 (auth-cache-negative-ttl
696 (string "1 hour")
697 "TTL for negative hits (user not found, password mismatch).
6980 disables caching them completely.")
699
700 (auth-realms
701 (space-separated-string-list '())
702 "List of realms for SASL authentication mechanisms that need them.
703You can leave it empty if you don't want to support multiple realms.
704Many clients simply use the first one listed here, so keep the default
705realm first.")
706
707 (auth-default-realm
708 (string "")
709 "Default realm/domain to use if none was specified. This is used for
710both SASL realms and appending @@domain to username in plaintext
711logins.")
712
713 (auth-username-chars
714 (string
715 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@")
716 "List of allowed characters in username. If the user-given username
717contains a character not listed in here, the login automatically fails.
718This is just an extra check to make sure user can't exploit any
719potential quote escaping vulnerabilities with SQL/LDAP databases. If
720you 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
725databases. The value contains series of from -> to characters. For
726example @samp{#@@/@@} means that @samp{#} and @samp{/} characters are
727translated to @samp{@@}.")
728
729 (auth-username-format
730 (string "%Lu")
731 "Username formatting before it's looked up from databases. You can
732use 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
734change 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
740username within the normal username string (i.e. not using SASL
741mechanism's support for it), you can specify the separator character
742here. The format is then <username><separator><master username>.
743UW-IMAP uses @samp{*} as the separator, so that could be a good
744choice.")
745
746 (auth-anonymous-username
747 (string "anonymous")
748 "Username to use for users logging in with ANONYMOUS SASL
749mechanism.")
750
751 (auth-worker-max-count
752 (non-negative-integer 30)
753 "Maximum number of dovecot-auth worker processes. They're used to
754execute blocking passdb and userdb queries (e.g. MySQL and PAM).
755They'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
760the name returned by gethostname(). Use @samp{$ALL} (with quotes) to
761allow all keytab entries.")
762
763 (auth-krb5-keytab
764 (string "")
765 "Kerberos keytab to use for the GSSAPI mechanism. Will use the
766system default (usually /etc/krb5.keytab) if not specified. You may
767need to change the auth service to run as root to be able to read this
768file.")
769
770 (auth-use-winbind?
771 (boolean #f)
772 "Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon
773and @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
787fails.")
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
793CommonName.")
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.
806Ports can be specified as ip:port. The default port is the same as what
807director 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
812allowed 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
817has any connections.")
818
819 (director-doveadm-port
820 (non-negative-integer 0)
821 "TCP/IP port that accepts doveadm connections (instead of director
822connections) 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
828include %Ln if user can log in with or without @@domain, %Ld if mailboxes
829are 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
851don't want to use @samp{mail}, you'll use local0..local7. Also other
852standard facilities are supported.")
853
854 (auth-verbose?
855 (boolean #f)
856 "Log unsuccessful authentication attempts and the reasons why they
857failed.")
858
859 (auth-verbose-passwords?
860 (boolean #f)
861 "In case of password mismatches, log the attempted password. Valid
862values are no, plain and sha1. sha1 can be useful for detecting brute
863force password attempts vs. user simply trying the same password over
864and 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
870SQL queries.")
871
872 (auth-debug-passwords?
873 (boolean #f)
874 "In case of password mismatches, log the passwords and used scheme so
875the 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
881Dovecot 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
890strftime(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
896non-empty variable value are joined together to form a comma-separated
897string.")
898
899 (login-log-format
900 (string "%$: %s")
901 "Login log format. %s contains @samp{login-log-format-elements}
902string, %$ 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
907of 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 %$
914Delivery status message (e.g. @samp{saved to INBOX})
915@item %m
916Message-ID
917@item %s
918Subject
919@item %f
920From address
921@item %p
922Physical size
923@item %w
924Virtual 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
932that Dovecot tries to find the mailboxes automatically. This won't work
933if the user doesn't yet have any mail, so you should explicitly tell
934Dovecot the full location.
935
936If you're using mbox, giving a path to the INBOX
937file (e.g. /var/mail/%u) isn't enough. You'll also need to tell Dovecot
938where the other mailboxes are kept. This is called the \"root mail
939directory\", and it must be the first path given in the
940@samp{mail-location} setting.
941
942There are a few special variables you can use, eg.:
943
944@table @samp
945@item %u
946username
947@item %n
948user part in user@@domain, same as %u if there's no domain
949@item %d
950domain part in user@@domain, empty if there's no domain
951@item %h
952home director
953@end table
954
955See 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,
965userdb can override these by returning uid or gid fields. You can use
966either 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
975this is used only with INBOX when either its initial creation or
976dotlocking 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.
982Typically these are used to set up access to shared mailboxes. Note
983that it may be dangerous to set these if users can create
984symlinks (e.g. if \"mail\" group is set here, ln -s /var/mail ~/mail/var
985could 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 filesystem access to clients. There's no access checks
991other than what the operating system does for the active UID/GID. It
992works with both maildir and mboxes, allowing you to prefix mailboxes
993names 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
1000shared filesystems (NFS or clustered filesystem).")
1001
1002 (dotlock-use-excl?
1003 (boolean #t)
1004 "Rely on @samp{O_EXCL} to work when creating dotlock files. NFS
1005supports @samp{O_EXCL} since version 3, so this should be safe to use
1006nowadays by default.")
1007
1008 (mail-fsync
1009 (string "optimized")
1010 "When to use fsync() or fdatasync() calls:
1011@table @code
1012@item optimized
1013Whenever necessary to avoid losing important data
1014@item always
1015Useful with e.g. NFS when write()s are delayed
1016@item never
1017Never 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
1023NFS caches whenever needed. If you're using only a single mail server
1024this 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
1034dotlock. Dotlocking uses some tricks which may create more disk I/O
1035than other locking methods. NFS users: flock doesn't work, remember to
1036change @samp{mmap-disable}.")
1037
1038 (mail-temp-dir
1039 (file-name "/tmp")
1040 "Directory in which LDA/LMTP temporarily stores incoming mails >128
1041kB.")
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
1046log in as daemons or other system users. Note that denying root logins is
1047hardcoded to dovecot binary and can't be done even if @samp{first-valid-uid}
1048is 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
1057aren't allowed to log in. If user belongs to supplementary groups with
1058non-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
1067trying 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
1072processes (i.e. /var/mail will allow chrooting to /var/mail/foo/bar
1073too). 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
1076which local users can modify, that may lead to root exploit. Usually
1077this 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
1083for specific users in user database by giving /./ in user's home
1084directory (e.g. /home/./user chroots into /home). Note that usually
1085there is no real need to do chrooting, Dovecot doesn't allow users to
1086access files outside their mail directory anyway. If your home
1087directories 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.
1093This 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,
1102LDA, 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
1108cache file. This allows optimizing Dovecot's behavior to do less disk
1109writes 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
1114see if there are any new mails or other changes. This setting defines
1115the minimum time to wait between those checks. Dovecot can also use
1116dnotify, inotify and kqueue to find out immediately when changes
1117occur.")
1118
1119 (mail-save-crlf?
1120 (boolean #f)
1121 "Save mails with CR+LF instead of plain LF. This makes sending those
1122mails take less CPU, especially with sendfile() syscall with Linux and
1123FreeBSD. But it also creates a bit more disk I/O which may just make it
1124slower. Also note that if other software reads the mboxes/maildirs,
1125they 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
1130with a dot. Enabling this option makes Dovecot return only entries
1131which are directories. This is done by stat()ing each entry, so it
1132causes more disk I/O.
1133 (For systems setting struct @samp{dirent->d_type} this check is free
1134and 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.
1139This makes the performance much better, and it's unlikely to have any
1140side effects.")
1141
1142 (maildir-very-dirty-syncs?
1143 (boolean #f)
1144 "Assume Dovecot is the only MUA accessing Maildir: Scan cur/
1145directory only when its mtime changes unexpectedly or when we can't find
1146the 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
1151available:
1152
1153@table @code
1154@item dotlock
1155Create <mailbox>.lock file. This is the oldest and most NFS-safe
1156solution. If you want to use /var/mail/ like directory, the users will
1157need write access to that directory.
1158@item dotlock-try
1159Same as dotlock, but if it fails because of permissions or because there
1160isn't enough disk space, just skip it.
1161@item fcntl
1162Use this if possible. Works with NFS too if lockd is used.
1163@item flock
1164May not exist in all systems. Doesn't work with NFS.
1165@item lockf
1166May not exist in all systems. Doesn't work with NFS.
1167@end table
1168
1169You can use multiple locking methods; if you do the order they're declared
1170in is important to avoid deadlocks if other MTAs/MUAs are using multiple
1171locking methods as well. Some operating systems don't allow using some of
1172them 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,
1185override 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
1190what changed. If the mbox is large this can take a long time. Since
1191the change is usually just a newly appended mail, it'd be faster to
1192simply read the new mails. If this setting is enabled, Dovecot does
1193this but still safely fallbacks to re-reading the whole mbox file
1194whenever something in mbox isn't how it's expected to be. The only real
1195downside to this setting is that if some other MUA changes message
1196flags, Dovecot doesn't notice it immediately. Note that a full sync is
1197done 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,
1202EXAMINE, 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
1208and CHECK commands and when closing the mailbox). This is especially
1209useful for POP3 where clients often delete all mails. The downside is
1210that 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
1215files. If an index file already exists it's still read, just not
1216updated.")
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
1225begins from midnight, so 1d = today, 2d = yesterday, etc. 0 = check
1226disabled.")
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
1232with some filesystems (ext4, xfs).")
1233
1234 (mail-attachment-dir
1235 (string "")
1236 "sdbox and mdbox support saving mail attachments to external files,
1237which also allows single instance storage for them. Other backends
1238don't support this for now.
1239
1240WARNING: This feature hasn't been tested much yet. Use at your own risk.
1241
1242Directory 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
1247possible to write a plugin to disable saving specific attachments
1248externally.")
1249
1250 (mail-attachment-fs
1251 (string "sis posix")
1252 "Filesystem backend to use for saving attachments:
1253@table @code
1254@item posix
1255No SiS done by Dovecot (but this might help FS's own deduplication)
1256@item sis posix
1257SiS with immediate byte-by-byte comparison during saving
1258@item sis-queue posix
1259SiS 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
1265variables: @code{%@{md4@}}, @code{%@{md5@}}, @code{%@{sha1@}},
1266@code{%@{sha256@}}, @code{%@{sha512@}}, @code{%@{size@}}. Variables can be
1267truncated, 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.
1280This is mainly intended to catch and kill processes that leak memory
1281before 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
1286untrusted user in Dovecot system. It shouldn't have access to anything
1287at all.")
1288
1289 (default-internal-user
1290 (string "dovecot")
1291 "Internal user is used by unprivileged processes. It should be
1292separate from login user, so that login processes can't disturb other
1293processes.")
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
1306dropping root privileges, so keep the key file unreadable by anyone but
1307root.")
1308
1309 (ssl-key-password
1310 (string "")
1311 "If key file is password protected, give the password here.
1312Alternatively give it when starting dovecot with -p parameter. Since
1313this file is often world-readable, you may want to place this setting
1314instead to a different.")
1315
1316 (ssl-ca
1317 (string "")
1318 "PEM encoded trusted certificate authority. Set this only if you
1319intend to use @samp{ssl-verify-client-cert? #t}. The file should
1320contain the CA certificate(s) followed by the matching
1321CRL(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
1328it, 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
1333x500UniqueIdentifier 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
1339quite CPU intensive operation. The value is in hours, 0 disables
1340regeneration 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 "")
1356 "Address to use when sending rejection mails.
1357Default 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)
1362and 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
1367bouncing 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
1376sendmail.")
1377
1378 (rejection-subject
1379 (string "Rejected: %s")
1380 "Subject: header to use for rejection mails. You can use the same
1381variables 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
1386variables:
1387
1388@table @code
1389@item %n
1390CRLF
1391@item %r
1392reason
1393@item %s
1394original subject
1395@item %t
1396recipient
1397@end table")
1398
1399 (recipient-delimiter
1400 (string "+")
1401 "Delimiter character between local-part and detail in email
1402address.")
1403
1404 (lda-original-recipient-header
1405 (string "")
1406 "Header where the original recipient address (SMTP's RCPT TO:
1407address) is taken from if not available elsewhere. With dovecot-lda -a
1408parameter overrides this. A commonly used header for this is
1409X-Original-To.")
1410
1411 (lda-mailbox-autocreate?
1412 (boolean #f)
1413 "Should saving a mail to a nonexistent mailbox automatically create
1414it?.")
1415
1416 (lda-mailbox-autosubscribe?
1417 (boolean #f)
1418 "Should automatically created mailboxes be also automatically
1419subscribed?.")
1420
1421
1422 (imap-max-line-length
1423 (non-negative-integer #e64e3)
1424 "Maximum IMAP command line length. Some clients generate very long
1425command lines with huge mailboxes, so you may need to raise this if you
1426get \"Too long argument\" or \"IMAP command line too large\" errors
1427often.")
1428
1429 (imap-logout-format
1430 (string "in=%i out=%o")
1431 "IMAP logout format string:
1432@table @code
1433@item %i
1434total number of bytes read from client
1435@item %o
1436total 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 '+',
1442add 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
1447is IDLEing.")
1448
1449 (imap-id-send
1450 (string "")
1451 "ID field names and values to send to clients. Using * as the value
1452makes Dovecot use the default value. The following fields have default
1453values currently: name, version, os, os-version, support-url,
1454support-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
1466Send EXISTS/RECENT new mail notifications only when replying to NOOP and
1467CHECK commands. Some clients ignore them otherwise, for example OSX
1468Mail (<v2.1). Outlook Express breaks more badly though, without this it
1469may show user \"Message no longer in server\" errors. Note that OE6
1470still breaks even with this workaround if synchronization is set to
1471\"Headers Only\".
1472
1473@item tb-extra-mailbox-sep
1474Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and
1475adds extra @samp{/} suffixes to mailbox names. This option causes Dovecot to
1476ignore the extra @samp{/} instead of treating it as invalid mailbox name.
1477
1478@item tb-lsub-flags
1479Show \\Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox).
1480This makes Thunderbird realize they aren't selectable and show them
1481greyed 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 #~(string-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 #~(string-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
d4053c71
AK
1578(define (dovecot-shepherd-service config)
1579 "Return a list of <shepherd-service> for CONFIG."
d8c18af8
AW
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))))
d4053c71 1593 (list (shepherd-service
d8c18af8
AW
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
d4053c71
AK
1610 (list (service-extension shepherd-root-service-type
1611 dovecot-shepherd-service)
d8c18af8
AW
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
1621POP3, IMAP, and LMTP. @var{config} should be a configuration object created
1622by @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))