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