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