?¡ëPNG
IHDR ? f ??C1 sRGB ??¨¦ gAMA ¡À?¨¹a pHYs ? ??o¡§d GIDATx^¨ª¨¹L¡±¡Âe¡ÂY?a?("Bh?_¨°???¡é¡ì?q5k?*:t0A-o??£¤]VkJ¡éM??f?¡À8\k2¨ªll¡ê1]q?¨´???T
Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/user1137782/www/china1.by/classwithtostring.php on line 86
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 213
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 214
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 215
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 216
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 217
Warning: Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 218
wiki/BasicConfiguration.txt 0000666 00000012331 15050120373 0012021 0 ustar 00 Basic Configuration
===================
This page tells you the basics that you'll need to get a working Dovecot
installation.
Find Dovecot configuration file location using:
---%<-------------------------------------------------------------------------
doveconf -n | head -1
---%<-------------------------------------------------------------------------
Your configuration file doesn't exist if you installed Dovecot from sources.
You can copy example configuration from the location printed by doveconf. For
example:
---%<-------------------------------------------------------------------------
cp -r /usr/local/share/doc/dovecot/example-config/* /usr/local/etc/dovecot/
---%<-------------------------------------------------------------------------
Authentication
--------------
Here we're going to create a simple passwd-like file to make sure that the
authentication will work. Later when you know Dovecot is working, you can do it
differently:
* If you're going to use system users, see [PasswordDatabase.PAM.txt].
* If you're going to use virtual users, see .
Run as your own non-root user:
---%<-------------------------------------------------------------------------
echo "$USER:{PLAIN}password:$UID:$GID::$HOME" > users
sudo mv users /etc/dovecot/
---%<-------------------------------------------------------------------------
You can (and should) replace the "password" with whatever password you wish to
use, but don't use any important password here as we'll be logging in with
insecure plaintext authentication until is configured.
If you used the example configuration files, switch to passwd-file by modifying
'conf.d/10-auth.conf':
---%<-------------------------------------------------------------------------
!include auth-passwdfile.conf.ext
---%<-------------------------------------------------------------------------
In auth-passwdfile.conf.ext you should have:
---%<-------------------------------------------------------------------------
passdb {
driver = passwd-file
args = scheme=CRYPT username_format=%u /etc/dovecot/users
}
---%<-------------------------------------------------------------------------
Verify with 'doveconf -n passdb userdb' that the output looks like this (and
there are no other passdbs or userdbs):
---%<-------------------------------------------------------------------------
passdb {
args = scheme=CRYPT username_format=%u /etc/dovecot/passwd
driver = passwd-file
}
userdb {
args = username_format=%u /etc/dovecot/passwd
driver = passwd-file
}
---%<-------------------------------------------------------------------------
Plaintext Authentication
------------------------
Until SSL is configured, allow plaintext authentication. You probably want to
switch this back to "yes" afterwards.
If you didn't use the temporary passwd-file created above, don't do this if you
don't want your password to be sent in clear to network. Instead get SSL
configuration working and connect to Dovecot only using SSL.
---%<-------------------------------------------------------------------------
disable_plaintext_auth = no
---%<-------------------------------------------------------------------------
Mail Location
-------------
Set the 'mail_location' as instructed by .
('default_mail_env' in older Dovecot versions)
mbox
----
If you're using mboxes, it's important to have locking configuration correct.
See for more information.
If you're using '/var/mail/' or '/var/spool/mail/' directory for INBOXes, you
may need to give Dovecot additional permissions so it can create dotlock files
there. A failure to do so will result in errors like these:
---%<-------------------------------------------------------------------------
open(/var/mail/.temp.host.1234.abcdefg) failed: Permission denied
file_lock_dotlock() failed with mbox file /var/mail/user: Permission denied
---%<-------------------------------------------------------------------------
From here on I'm assuming the INBOX directory is '/var/mail'.
First check what the permissions of '/var/mail' are:
---%<-------------------------------------------------------------------------
# ls -ld /var/mail
drwxrwxrwt 2 root mail 47 2006-01-07 20:44 /var/mail/
---%<-------------------------------------------------------------------------
In this case everyone has write access there and the directory is marked
sticky. This allows Dovecot to create the dotlock files, so you don't need to
do anything.
---%<-------------------------------------------------------------------------
# ls -ld /var/mail
drwxrwxr-- 2 root mail 47 2006-01-07 20:44 /var/mail/
---%<-------------------------------------------------------------------------
In this case only the root and the 'mail' group has write permission to the
directory. You'll need to give Dovecot's mail processes ability to use this
group by changing 'dovecot.conf':
---%<-------------------------------------------------------------------------
mail_privileged_group = mail
---%<-------------------------------------------------------------------------
Note: Specifying the privileged user must be done as shown. Simply adding
'dovecot' user to the 'mail' group does /*not*/ grant write permission.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Upgrading.1.0.txt 0000666 00000010352 15050120373 0010466 0 ustar 00 Upgrading Dovecot v0.99.x to v1.0
=================================
Contents
1. Upgrading Dovecot v0.99.x to v1.0
1. Configuration file
2. PAM
3. SQL Configuration
4. Subscriptions
5. Keywords
6. POP3 UIDLs
7. mbox errors
8. Port Changes
9. Log Changes for POP before SMTP
The upgrade from Dovecot v0.99.x to v1.0 isn't just a drop-in upgrade, but also
requires the administrator to adjust the configuration in several places, as
detailed in the chapters below.
Configuration file
------------------
The configuration file has had a lot of changes, so it's better to just modify
the included 'dovecot-example.conf' file manually. The easiest way to remember
what you had changed in the old file is with grep:
---%<-------------------------------------------------------------------------
egrep -v '^ *(#|$)'|less
---%<-------------------------------------------------------------------------
PAM
---
Dovecot v0.99.x defaulted to using "imap" or "pop3" PAM service identifiers,
ie.'/etc/pam.d/imap' or '/etc/pam.d/pop3' files. With v1.0, the default is to
use "dovecot" service identifier, i.e.'/etc/pam.d/dovecot'. Either change the
passdb pam args to use the "*" parameter or set up the '/etc/pam.d/' files
properly.
SQL Configuration
-----------------
The SQL configuration has changed. 'password_query' in the new dovecot-sql.conf
must return a field named 'password'.
Subscriptions
-------------
*Maildir only*: The filename that stores user subscriptions has changed from
'.subscriptions' to 'subscriptions'. (It is still called '.subscriptions' for
mbox.). Since v1.0.rc2 the renaming is done automatically.
Keywords
--------
*Maildir-only*: The former '.customflags' file has been renamed to
*dovecot-keywords*, which is incompatible with v0.99.x's format. Since v1.0.rc2
Dovecot can convert the file automatically. (This conversion does not happen
when going directly from v0.99 to v1.1, though. The files must be renamed
manually.)
POP3 UIDLs
----------
UIDLs are used by POP3 clients to keep track of what messages they've
downloaded, typically only if you've enabled "keep messages in server" option.
If the UIDL changes, the existing messages are re-downloaded as new messages,
which you should try to avoid.
For compatibility with Dovecot v0.99.x, use:
---%<-------------------------------------------------------------------------
pop3_uidl_format = %v.%u
---%<-------------------------------------------------------------------------
However this doesn't work well for Outlook 2003 users (as it didn't with
v0.99.x either), which is the reason this isn't the default anymore. See
[POP3Server.txt] for alternative (and better) UIDL formats.
mbox errors
-----------
The first time a user opens a mailbox after upgrading it may log some errors
such as:
---%<-------------------------------------------------------------------------
mbox sync: UID inserted in the middle of mailbox /var/mail/**** (4409 > 4237)
---%<-------------------------------------------------------------------------
The user may need to log out and log in again to see all of the messages in the
affected mailboxes. Note that this shouldn't happen unless the mbox already had
some errors. The new mbox parsing code just does better error checking.
Port Changes
------------
The port settings are different. The new settings are:
---%<-------------------------------------------------------------------------
# if you wish to just change IP address, change:
listen = 1.2.3.4
ssl_listen = 1.2.3.4
# if you wish to change ports also, use instead:
protocol imap {
listen = *:143
ssl_listen = *:993
}
protocol pop3 {
listen = *:110
ssl_listen = *:995
}
---%<-------------------------------------------------------------------------
Log Changes for POP before SMTP
-------------------------------
If you used [PopBSMTPAndDovecot.txt], the log strings are
different. This should work with new versions:
---%<-------------------------------------------------------------------------
$s =~ s/^... .. ..:..:.. .* dovecot: (pop3|imap)-login: Login: .+
rip=(\d+\.\d+\.\d+\.\d+),.*$/$2/i;
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/MailLocation.dbox.txt 0000666 00000006273 15050120373 0011566 0 ustar 00 dbox configuration
==================
See for a description of the dbox mailbox format.
Mail location
-------------
dbox can be used in two ways:
1. One message per file (*single-dbox*), similar to
[MailboxFormat.Maildir.txt].
2. Multiple messages per file (*multi-dbox*), but unlike
[MailboxFormat.mbox.txt] multiple files per mailbox.
To use *single-dbox*, use the tag 'sdbox' in the
[MailLocation.txt], for example:
---%<-------------------------------------------------------------------------
# single-dbox
mail_location = sdbox:~/dbox
---%<-------------------------------------------------------------------------
For backwards compatibility, 'dbox' is an alias to 'sdbox' in the mail
location.
To use *multi-dbox*, use the tag 'mdbox' in the
[MailLocation.txt], for example:
---%<-------------------------------------------------------------------------
# multi-dbox
mail_location = mdbox:~/mdbox
---%<-------------------------------------------------------------------------
Alternate storage
-----------------
dbox has a feature for transparently moving message data to an [MailboxFormat.dbox.txt] area.
To specify an alternate storage area, use the 'ALT' parameter in the mail
location. For example, specifying the mail location as:
---%<-------------------------------------------------------------------------
mail_location = mdbox:/var/vmail/%d/%n:ALT=/altstorage/vmail/%d/%n
---%<-------------------------------------------------------------------------
will make Dovecot look for message data first under '/var/vmail/%d/%n', and if
it is not found there it will look under '/altstorage/vmail/%d/%n' instead.
Mailbox directory name
----------------------
When using the default hierarchical layout, there is a potential for naming
collisions between dbox's 'dbox-Mails/' subdirectory and mail folders of the
same name. For example, consider a mail folder "foo/bar". Under the default
hierarchical layout, data about this mail folder would be stored at
'~/mdbox/mailboxes/foo/bar/dbox-Mails/'.
If the user then tried to create a mail folder "foo/bar/dbox-Mails", this would
then imply that data would be stored at
'~/mdbox/mailboxes/foo/bar/dbox-Mails/dbox-Mails/'. But this would overlap the
'dbox-Mails/' subdirectory of mail folder "foo/bar".
This may not be a problem in many installations, but if a risk of collisions
with the default name "dbox-Mails" is perceived, then the 'DIRNAME' parameter
can be used. For example, if we specify mail location as:
---%<-------------------------------------------------------------------------
mail_location = mdbox:~/mdbox:DIRNAME=DbOx-mAiLs
---%<-------------------------------------------------------------------------
then this will make data for mail folders be stored in a subdirectory
'DbOx-mAiLs/' instead of the default 'dbox-Mails/', so a mail folder "foo/bar"
would have data stored at '~/mdbox/mailboxes/foo/bar/DbOx-mAiLs/'.
The value for 'DIRNAME' should be chosen carefully so as to minimise the
chances of clashing with mail folder names. In the example here, unusual
upper/lower casing has been used.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/PasswordDatabase.ExtraFields.Host.txt 0000666 00000004005 15050120373 0014623 0 ustar 00 Login referrals
===============
Login referrals are an IMAP extension specified by RFC 2221
[http://www.apps.ietf.org/rfc/rfc2221.html]. They're not supported by many
clients, so you probably don't want to use them normally.
Login referrals can be used in two ways:
1. Tell the client to log into another server without allowing to log in
locally.
2. Suggest the client to log into another server, but log it in anyway.
The following fields can be used to configure login referrals:
* 'host=s': The destination server's hostname. This field is required for
login referrals to be used.
* 'port=s': The destination server's port. The default is 143.
* 'destuser=s': Tell client to use a different username when logging in.
* 'reason=s': Optional reason to use as the reply to the login command. The
default is "Logged in, but you should use this server instead."
Using the above settings you can suggest client to log in elsewhere. To require
it, you'll also have to return:
* 'nologin': User is not allowed to log in.
* 'reason=s': Optional reason. The default is "Try this server instead.".
Client support
--------------
The following clients are known to support login referrals:
* Pine
* Outlook (but not Outlook Express)
Examples
--------
Forward user to another server after successful authentication:
---%<-------------------------------------------------------------------------
password_query = SELECT password, host, 'Y' as nologin FROM users WHERE userid
= '%u'
---%<-------------------------------------------------------------------------
Forward all users to another server without authentication:
---%<-------------------------------------------------------------------------
password_query = \
SELECT NULL AS password, 'Y' AS nopassword \
'imap2.example.com' AS host, \
'This server is down, try another one.' AS reason, \
'Y' AS nologin, \
'Y' AS nodelay
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.txt 0000666 00000005151 15050120373 0007673 0 ustar 00 Plugins
=======
Distributed with Dovecot:
* [ACL.txt]: Access Control Lists for mailboxes
* [Plugins.Autocreate.txt]: Automatically create/subscribe
mailboxes when user logs in
* [Plugins.Expire.txt]: Delete mails from specified mailboxes after a
designated number of days
* [Plugins.FTS.txt]: Full text search indexing
* [Plugins.Lazyexpunge.txt]: Make EXPUNGE and DELETE commands
just rename the mails elsewhere
* [Plugins.Listescape.txt]: Allow using characters in mailbox
names that would otherwise be illegal
* [Plugins.MailLog.txt]: Log several mail actions
* [Plugins.Snarf.txt]: UW-IMAP style (mbox) snarfing, i.e. keeps
moving all mails from one mailbox to INBOX
* [Quota.txt]: Quota tracking and enforcing
* imap_quota: IMAP commands for requesting current quota
* [Plugins.Trash.txt]: Delete mails from Trash when user would go over
quota
* [Plugins.Virtual.txt]: Virtual mailboxes
* [Plugins.Zlib.txt]: Access compressed mails
* [Plugins.Compress.txt]: Enable IMAP COMPRESS
[http://www.ietf.org/rfc/rfc4978.txt] extension
External:
* [Plugins.Antispam.txt]: Integrates spam learning into Dovecot
* drac [http://dovecot.org/patches/1.1/drac.c]: Pop-before-SMTP plugin using
DRAC
* whoson [ftp://ftp.ufanet.ru/pub/boco/dovecot/whoson-plugin/]:
Pop-before-SMTP plugin using WHOSON protocol [http://whoson.sourceforge.net]
* alert [http://dovecot.org/patches/1.0/imap-alert-plugin.c]: Send IMAP ALERT
message from '/etc/dovecot.alert'.
* [Pigeonhole.Sieve.txt]: Use the Sieve
[http://sieve.info/] language for filtering upon message delivery
* Fetchmail wakeup [http://github.com/marschap/fetchmail_wakeup]: Wakes
fetchmail when Dovecot looks for new mail. This is a heavily extended and
updated version that works with Dovecot 1.1.x and 1.2.x
* Fetchmail wake [http://guichaz.free.fr/misc/]: Wakes fetchmail when Dovecot
looks for new mail. This is the original version that only works with
dovecot 1.0.x
* [Plugins.deleted-to-trash.txt]: Automatically move
deleted item to trash folder, if client side doesn't do it, such as outlook
and evolution.
Experimental Plugins:
* [Plugins.xexec.txt]: Execute any server side application and
communicate with it through plugins over IMAP
To enable / disable plugins per user you can make your userdb return
'mail_plugins' extra field. See for examples.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Pigeonhole.Sieve.Examples.txt 0000666 00000024141 15050120373 0013172 0 ustar 00 Pigeonhole Sieve examples
=========================
Contents
1. Pigeonhole Sieve examples
1. Mail filtering by various headers
2. Flagging or Highlighting your mail
3. Spam/Virus rules
1. Direct filtering using message header
2. Filtering using the spamtest and virustest extensions
4. Plus Addressed mail filtering
5. Vacation auto-reply
6. Include scripts
7. Translation from Procmail
Below are some simple Sieve code examples, more can be found from
http://libsieve.sourceforge.net/script1.php and
http://wiki.fastmail.fm/index.php?title=SieveExamples.
Mail filtering by various headers
---------------------------------
Use if/elsif/else to store messages into various folders/subfolders:
* ---%<----------------------------------------------------------------------
require ["fileinto", "envelope"];
if address :is "to" "dovecot@dovecot.org" {
fileinto "Dovecot-list";
} elsif envelope :is "from" "owner-cipe-l@inka.de" {
fileinto "lists.cipe";
} elsif anyof (header :contains "X-listname" "lugog@cip.rz.fh-offenburg.de",
header :contains "List-Id" "Linux User Group Offenburg") {
fileinto "ml.lugog";
} else {
# The rest goes into INBOX
# default is "implicit keep", we do it explicitly here
keep;
}
---%<----------------------------------------------------------------------
"anyof" means logical OR, "allof" is AND.
Forward mails with "order" or "buy" in their subject to another address:
* ---%<----------------------------------------------------------------------
if header :contains "subject" ["order", "buy"] {
redirect "orders@company.dom";
}
---%<----------------------------------------------------------------------
Message-ID and recipient of forwarded message are stored in a
'.dovecot.lda-dupes' at users home directory to prevent mail loops.
Flagging or Highlighting your mail
----------------------------------
Some mail readers use these flags:
---%<-------------------------------------------------------------------------
require "imap4flags";
require "regex";
if anyof (exists "X-Cron-Env",
header :regex ["subject"] [".* security run output",
".* monthly run output",
".* daily run output",
".* weekly run output"]) {
addflag "$label1"; # ie 'Important'/red label within Thunderbird
# Other flags:
# addflag "$label1"; # Important: #ff0000 => red
# addflag "$label2"; # Work: #ff9900 => orange
# addflag "$label3"; # personal: #009900 => green
# addflag "$label4"; # todo: #3333ff => blue
# addflag "$label5"; # later: #993399 => violet
#
}
---%<-------------------------------------------------------------------------
Local copy of your emails:
---%<-------------------------------------------------------------------------
require "envelope";
if envelope "from" "my_address@my_domain.com"
{
setflag "\\seen";
}
---%<-------------------------------------------------------------------------
/Useful, when you want sieve to manage your incoming *and* outgoing email (you
must ask your mail reader to Bcc your mail to your dovecot in this case)./
Spam/Virus rules
----------------
Most spam and virus scanners add a special header to mail messages, so that
users can apply filtering accordingly. Depending on how the Sieve interpreter
is configured, filtering can either be performed by evaluating these headers
directly, or using the spamtest and virustest extensions.
Direct filtering using message header
-------------------------------------
Evaluating the headers directly is always possible as long as the headers are
actually added to the messages by the scanner software. For example, to
fileSpamAssassin-tagged mails into a folder called "Spam":
---%<-------------------------------------------------------------------------
require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
fileinto "Spam";
}
---%<-------------------------------------------------------------------------
The following example discards SpamAssassin-tagged mails with level higher than
or equal to 10:
---%<-------------------------------------------------------------------------
if header :contains "X-Spam-Level" "**********" {
discard;
}
---%<-------------------------------------------------------------------------
Filtering using the spamtest and virustest extensions
-----------------------------------------------------
When the spamtest [http://tools.ietf.org/html/rfc5235#section-3.2] and
virustest [http://tools.ietf.org/html/rfc5235#section-3.3] extensions are
configured on the server, users (and GUIs) can have a much easier way to filter
spam and virus messages respectively. To filter spam, the spamtest extension
can for example be used as follows:
---%<-------------------------------------------------------------------------
require "spamtestplus";
require "fileinto";
require "relational";
require "comparator-i;ascii-numeric";
/* If the spamtest fails for some reason, e.g. spam header is missing, file
* file it in a special folder.
*/
if spamtest :value "eq" :comparator "i;ascii-numeric" "0" {
fileinto "Unclassified";
/* If the spamtest score (in the range 1-10) is larger than or equal to 3,
* file it into the spam folder:
*/
} elsif spamtest :value "ge" :comparator "i;ascii-numeric" "3" {
fileinto "Spam";
/* For more fine-grained score evaluation, the :percent tag can be used. The
* following rule discards all messages with a percent score
* (relative to maximum) of more than 85 %:
*/
} elsif spamtest :value "gt" :comparator "i;ascii-numeric" :percent "85" {
discard;
}
/* Other messages get filed into INBOX */
---%<-------------------------------------------------------------------------
The virustest extension can be used in a similar manner:
---%<-------------------------------------------------------------------------
require "virustest";
require "fileinto";
require "relational";
require "comparator-i;ascii-numeric";
/* Not scanned ? */
if virustest :value "eq" :comparator "i;ascii-numeric" "0" {
fileinto "Unscanned";
/* Infected with high probability (value range in 1-5) */
} if virustest :value "eq" :comparator "i;ascii-numeric" "4" {
/* Quarantine it in special folder (still somewhat dangerous) */
fileinto "Quarantine";
/* Definitely infected */
} elsif virustest :value "eq" :comparator "i;ascii-numeric" "5" {
/* Just get rid of it */
discard;
}
---%<-------------------------------------------------------------------------
Plus Addressed mail filtering
-----------------------------
This is useful when you don't want just any +tag to create a directory, but you
want to use tagged addresses such as with amavisd-new. This example would
place email addressed to user+spam@example.com into user's Spam folder.
---%<-------------------------------------------------------------------------
require ["fileinto", "envelope", "subaddress"];
if envelope :detail "to" "spam"{
fileinto "Spam";
}
---%<-------------------------------------------------------------------------
To work with Postfix, this requires that the envelope "to" still contains the
full address, so pass it with the -a flag.
---%<-------------------------------------------------------------------------
dovecot unix - n n - - pipe
flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/dovecot-lda
-f ${sender} -d ${user}@${nexthop} -a ${recipient}
---%<-------------------------------------------------------------------------
or
---%<-------------------------------------------------------------------------
mailbox_command = /usr/lib/dovecot/dovecot-lda -a "$RECIPIENT"
---%<-------------------------------------------------------------------------
Vacation auto-reply
-------------------
---%<-------------------------------------------------------------------------
require ["fileinto", "vacation"];
# Move spam to spam folder
if header :contains "X-Spam-Flag" "YES" {
fileinto "spam";
# Stop here so that we do not reply on spams
stop;
}
vacation
# Reply at most once a day to a same sender
:days 1
:subject "Out of office reply"
# List of additional recipient addresses which are included in the auto
replying.
# If a mail's recipient is not the envelope recipient and it's not on this
list,
# no vacation reply is sent for it.
:addresses ["j.doe@company.dom", "john.doe@company.dom"]
"I'm out of office, please contact Joan Doe instead.
Best regards
John Doe";
---%<-------------------------------------------------------------------------
Include scripts
---------------
It's possible to include other Sieve scripts in your script:
---%<-------------------------------------------------------------------------
require ["include"];
include :global "global-spam";
include :personal "my-own-spam";
---%<-------------------------------------------------------------------------
The lookup directories can be specified with:
---%<-------------------------------------------------------------------------
plugin {
# Directory for :personal include scripts. The default is to use home
directory.
sieve_dir = %h/sieve
# Directory for :global include scripts (not to be confused with
sieve_global_path).
# If unset, the include fails.
sieve_global_dir = /etc/dovecot/sieve/
}
---%<-------------------------------------------------------------------------
Both 'sieve_dir' and 'sieve_global_dir' may also be overridden by [UserDatabase.ExtraFields.txt].
It's not currently possible to use subdirectories for the scripts. Having a '/'
character in the script name always fails the include. This is just an extra
check to avoid potential problems with including scripts within mail
directories.
Translation from Procmail
-------------------------
There exists a script which attempts to translate simple Procmail rules into
Sieve rules:http://www.earth.ox.ac.uk/~steve/sieve/procmail2sieve.pl
(dovecot.org mirror [http://dovecot.org/tools/procmail2sieve.pl])
Here's the original post announcing it:
http://dovecot.org/list/dovecot/2007-March/020895.html
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Authentication.Mechanisms.NTLM.txt 0000666 00000002335 15050120373 0014071 0 ustar 00 NTLM
====
There are four authentication submethods inside the NTLM:
1. LM: server nonce only, highly vulnerable to MITM and rogue server attacks.
2. NTLM: different algorithm, almost equally vulnerable as LM today.
3. NTLM2: server and client nonce, but MITM can force downgrade to NTLM/LM.
4. NTLMv2: server and client nonce, MITM can't force downgrade.
NTLM [Authentication.PasswordSchemes.txt] is required for
NTLM, NTLM2 and NTLMv2.
NTLMv2 can not be negotiated. It must be explicitly enabled on the client side
by setting registry key below to at least 3:
* Win9x:
'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA\LMCompatibility'
* WinNT:
'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA\LMCompatibilityLevel'
Dovecot's NTLM logic is:
1. If we have only LM password scheme, try LM authentication;
2. If client sends LM response only (some very old clients do it), try LM too;
3. If NTLMv2 is guessed (using client response length), try NTLMv2;
4. If NTLM2 was negotiated, try it;
5. Otherwise try NTLM.
For more information about NTLM internals, see http://ubiqx.org/cifs/ and
http://davenport.sourceforge.net/ntlm.html
(This file was created from the wiki on 2011-01-13 04:52)
wiki/HowTo.txt 0000666 00000007376 15050120373 0007325 0 ustar 00 HOWTOs / Examples / Tutorials
=============================
[VirtualUsers.txt] with
[AuthDatabase.PasswdFile.txt]:
* [HowTo.SimpleVirtualInstall.txt]
* [HowTo.VirtualhostingWithExim.txt]
* [HowTo.VirtualUserFlatFilesPostfix.txt]
[VirtualUsers.txt] with [AuthDatabase.LDAP.txt]:
* [HowTo.DovecotOpenLdap.txt] (
[HowTo.DoveLdapCheatSheet.txt])
* Postfix and Active Directory or OpenLDAP [http://www.linuxmail.info]
* Samba LDAP PDC / Mail / DNS / DHCP server
[http://wiki.nutum.es/linux/samba/samba_ldap_mds/inicio], using Debian,
Samba, OpenLDAP, Postfix, Dovecot, Bind, Horde (fully integrated with Ingo
for Sieve scripts management) and MDS as administration interface (in
Spanish)
[SystemUsers.txt] and/or [VirtualUsers.txt] with
[AuthDatabase.LDAP.txt]:
* Dovecot, ManageSieve, Exim, OpenLDAP and getmail
[http://www.effinger.org/blog/2009/03/22/dovecot-exim-openldap-und-getmail-unter-ubuntu-1-openldap/]
(Instructions in German) - LDAP users (can be both
[SystemUsers.txt] and [VirtualUsers.txt] depending on how
you use [AuthDatabase.LDAP.txt]) with the possibility to add
subaccounts for each user. For example if you have a LDAP user named peter,
you can add a separate subordinate mailbox to retrieve mail from an external
mail account like peter[at]gmail.com
[VirtualUsers.txt] with [AuthDatabase.SQL.txt]:
* MySQL
* [HowTo.DovecotXAMS.txt]
*
[HowTo.DovecotLDAPostfixAdminMySQL.txt]
* MySQL, Postfix and CCC [http://postfix.pentachron.net/]
* MySQL, Exim, SpamAssassin and ClamAV
[http://struction.de/projects/HOWTO_VirtualMail_Exim-MySQL-Spamassassin-ClamAV-Dovecot/]
* Postfix and Dovecot with MySQL and TLS/SSL, Postgrey and DSPAM
[http://johnny.chadda.se/2007/04/15/mail-server-howto-postfix-and-dovecot-with-mysql-and-tlsssl-postgrey-and-dspam/]
* ISP-style Email Server with Debian-Etch and Postfix (MySQL, Dovecot,
Postfix etc.) [http://workaround.org/ispmail]
* PostgreSQL
* [HowTo.DovecotPostgresql.txt]
* Mailserver virtual configuration (Postfix, Dovecot, SMTP Auth, PostgreSQL
backend) German
[http://www.tuxj0b.de/HOWTO_Mailserver_mit_Postfix_Dovecot_Antispam_und_PostgreSQL_Backend]
* PostgreSQL, Postfix (Dovecot LDA and Dovecot SASL), Dovecot and vmm
(command line tool) [http://vmm.localdomain.org/] (also available in
German [http://de.vmm.localdomain.org/])
Others:
* SMTP AUTH
* [HowTo.PostfixAndDovecotSASL.txt]
* [HowTo.EximAndDovecotSASL.txt]
*
[HowTo.DebianStable.txt]
* [HowTo.ImapProxy.txt]
* [HowTo.CRAM-MD5.txt]
* [HowTo.Rootless.txt]
* [HowTo.PopBSMTPAndDovecot.txt]
* [HowTo.PopRelay.txt]
* [HowTo.RefilterMail.txt]
* [HowTo.BynariConnector.txt]
* [HowTo.Fail2Ban.txt]
* [HowTo.VMailMgr.txt]
*
[HowTo.ActiveDirectoryNtlm.txt]
* [HowTo.PostfixDovecotLMTP.txt]
(This file was created from the wiki on 2011-01-13 04:52)
wiki/TestInstallation.txt 0000666 00000015355 15050120373 0011562 0 ustar 00 Contents
1. Check that it's running
2. Check that it's listening
3. Check that it's allowing logins
4. Check that it's allowing remote logins
5. Check that it finds INBOX
6. Check that it finds other mailboxes
7. Check that real mail clients work
For testing POP3 installation, see .
Check that it's running
-----------------------
First check with 'ps' that 'dovecot' process is actually running. If it's not,
you had an error in 'dovecot.conf' and the error message was written to log. Go
back to and if you can't find it.
Check that it's listening
-------------------------
Next check that Dovecot is listening for connections:
---%<-------------------------------------------------------------------------
# telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS
AUTH=PLAIN] Dovecot ready.
---%<-------------------------------------------------------------------------
If you got "connection refused", check that 'imap' is included in 'protocols'
setting in 'dovecot.conf'. Also check that 'listen' setting is '*'.
Next check that it also works from remote host:
---%<-------------------------------------------------------------------------
# telnet your.host.org 143
Trying 1.2.3.4...
Connected to your.host.org.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS
AUTH=PLAIN] Dovecot ready.
---%<-------------------------------------------------------------------------
If that didn't work, check all possible firewalls in between, and check that
'listen' setting is '*' in 'dovecot.conf'.
If you have only imaps enabled, see "remote login" section below for how to
test using openssl s_client.
Check that it's allowing logins
-------------------------------
---%<-------------------------------------------------------------------------
# telnet localhost 143
a login username password
---%<-------------------------------------------------------------------------
Replace the username and password with the ones you added to 'passwd.dovecot'
in . Note that all IMAP commands begin with a tag,
which is basically any string you want, but it must be there. So don't leave
out the "a" in the above example.
You should get an "a OK Logged in." reply. If you get "Authentication failed"
error, set 'auth_verbose = yes' and 'auth_debug = yes' in 'dovecot.conf',
restart Dovecot and try again. The log file should now show enough information
to help you fix the problem.
Check that it's allowing remote logins
--------------------------------------
You'll need to try this from another computer, since all local IPs are treated
as secure:
---%<-------------------------------------------------------------------------
# telnet your.host.org 143
a login username password
---%<-------------------------------------------------------------------------
If the connection is hanging instead of giving '* Dovecot ready', you have a
firewall that's preventing the connections.
Otherwise, the only difference here compared to step above is that you might
get:
---%<-------------------------------------------------------------------------
* BAD [ALERT] Plaintext authentication is disabled, but your client sent
password in plaintext anyway. If anyone was listening, the password was
exposed.
a NO Plaintext authentication disabled.
---%<-------------------------------------------------------------------------
If this is the case, you didn't set 'disable_plaintext_auth = no'. You could
alternatively use OpenSSL to test that the server works with SSL:
* Test using imaps port (assuming you haven't disabled imaps port):
---%<----------------------------------------------------------------------
# openssl s_client -connect your.host.org:993
* OK Dovecot ready.
---%<----------------------------------------------------------------------
* Test using imap port and STARTTLS command (works also with imap port):
---%<----------------------------------------------------------------------
# openssl s_client -connect your.host.org:143 -starttls imap
* OK Dovecot ready.
---%<----------------------------------------------------------------------
Check that it finds INBOX
-------------------------
After logging in, check that the INBOX is found:
---%<-------------------------------------------------------------------------
b select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags
permitted.
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1106186941] UIDs valid
* OK [UIDNEXT 2] Predicted next UID
b OK [READ-WRITE] Select completed.
---%<-------------------------------------------------------------------------
It should contain the mail that you sent to yourself in
step.
If anything goes wrong, set 'mail_debug = yes' and try again. The log file
should now contain debugging information of where Dovecot is trying to find the
mails. Fix 'mail_location' setting and try again.
Check that it finds other mailboxes
-----------------------------------
If you already have other mailboxes created, you can check that Dovecot finds
them:
---%<-------------------------------------------------------------------------
c list "" *
* LIST (\NoInferiors) "/" "test"
* LIST (\NoInferiors) "/" "INBOX"
c OK List completed.
---%<-------------------------------------------------------------------------
If they weren't found, set 'mail_debug = yes' and look at the debugging
information. Fix 'mail_location' setting and try again.
Check that real mail clients work
---------------------------------
Since mail clients can be configured in various ways, please check first if the
problem is with Dovecot configuration or with the client's configuration. You
can rule out it being Dovecot's problem with the "telnet" methods described
above.
If you can't log in,
* Make sure SSL/TLS settings are correct.
* Make sure the client uses plaintext authentication method, unless you've
specifically configured Dovecot to accept others.
If you can see only INBOX,
* Clear out any "IMAP namespace prefix" or similar settings from clients.
* Check if client is configured to show only "subscribed mailboxes". If so,
you'll have to subscribe to the mailboxes you wish to see. You can see a
list of subscribed mailboxes with:
---%<----------------------------------------------------------------------
d lsub "" *
* LSUB () "/" "INBOX"
d OK Lsub completed.
---%<----------------------------------------------------------------------
Most IMAP clients have been tested with Dovecot and they work.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.Listescape.txt 0000666 00000003265 15050120373 0011772 0 ustar 00 Listescape plugin
=================
The Listescape plugin allows users to use characters in mailboxes names that
would otherwise be illegal, for example:
* Maildir++ layout disallows using the '.' character, since it's used
internally as the hierarchy separator.
* The '~' character at the beginning of the mailbox name is disallowed,
because of the possibility that it gets expanded to user's home directory.
* The '/' character is disallowed with all layouts (if it's not the hierarchy
separator).
The Listescape plugin allows you to use all of these characters, as long as the
virtual separator is changed to something else. The characters are escaped to
the mailbox name as \NN hex codes.
Examples
--------
Allow '.' characters with Maildir++ layout when virtual hierarchy separator is
changed to '/':
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins listescape
namespace private {
separator = /
inbox = yes
}
plugin {
# The default escape character is '\', but you can change it.
# Note that even here the expansion of % takes place, thus you need to
# use "%%" if you want to have the % sign as the escape character.
#listescape_char = "\\"
}
---%<-------------------------------------------------------------------------
Allow both '.' and '/' characters when virtual hierarchy separator is changed
to '^':
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins listescape
namespace private {
separator = ^
inbox = yes
}
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.Virtual.txt 0000666 00000017077 15050120373 0011332 0 ustar 00 Virtual mailboxes
=================
First, you'll have to load the plugin:
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins virtual
---%<-------------------------------------------------------------------------
Namespace configuration
-----------------------
Then, you'll have to create a [Namespaces.txt] for the virtual
mailboxes, for example:
---%<-------------------------------------------------------------------------
namespace {
prefix = virtual/
separator = /
location = virtual:~/Maildir/virtual
}
---%<-------------------------------------------------------------------------
After this you can create virtual mailboxes under '~/Maildir/virtual'. By
default it uses the "fs" layout, so you can create directories such as:
* INBOX: '~/Maildir/virtual/INBOX/'
* Sub/mailbox: '~/Maildir/virtual/Sub/mailbox/'
If you prefer to use Maildir++ layout instead, you can simply append
':LAYOUT=maildir++' to the location.
Virtual mailbox configuration
-----------------------------
For each virtual directory you need to create a 'dovecot-virtual' file. Its
syntax is like:
---%<-------------------------------------------------------------------------
<1+ mailbox patterns>
[
[etc..]]
---%<-------------------------------------------------------------------------
Mailbox patterns can contain IMAP LIST-compatible
[http://tools.ietf.org/html/rfc3501#section-6.3.8] "*" and "%" wildcards. They
are currently evaluated only when the virtual mailbox is being selected, so if
more mailboxes are created during that they aren't noticed.
"*" wildcard matches only one namespace at a time based on the namespace
prefix. For example if you have namespaces with an empty prefix and a prefix
"mail/":
* '*' matches only mailboxes from the namespace with empty prefix
* 'mail*' matches mailboxes beginning with name "mail" from the namespace with
empty prefix
* 'mail/*' matches only mailboxes from the mail/ namespace
It's possible to give negative matches for mailbox names by prefixing the
mailbox name with '-' character.
Search program is compatible with IMAP SEARCH command
[http://tools.ietf.org/html/rfc3501#section-6.4.4]. Besides the standard SEARCH
key you may want to use X-MAILBOX key which matches the message's original
mailbox. Note the leading whitespace in front of search specifications.
Saving mails to virtual mailboxes
---------------------------------
It's possible to configure virtual mailbox so that it's possible to save/copy
messages there. This is done by specifying a single physical mailbox where the
message is really saved by prefixing it with '!', e.g.:
---%<-------------------------------------------------------------------------
!INBOX
work/*
unseen
---%<-------------------------------------------------------------------------
Note however that nothing guarantees that the saved mail will actually show up
in the virtual mailbox. If a message was saved with \Seen flag to the above
virtual mailbox, it wouldn't show up there. This also means it's problematic to
support IMAP UIDPLUS extension for virtual mailboxes, and currently Dovecot
doesn't even try (no [APPENDUID] or [COPYUID] is sent to client).
The !-prefixed virtual mailbox is also selected from; you don't need to list it
again without an ! or you'll get two copies of your messages in the virtual
mailbox.
Examples
--------
List all messages with \Deleted flag in all mailboxes:
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/Trash/dovecot-virtual
*
deleted
---%<-------------------------------------------------------------------------
List all unseen INBOX and work/* messages:
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/unseen/dovecot-virtual
INBOX
work/*
unseen
---%<-------------------------------------------------------------------------
Create a GMail-style "conversation view" for INBOX which shows all threads that
have messages in INBOX, but shows all messages in the thread regardless of in
what mailbox they physically exist in:
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/all/dovecot-virtual
*
all
---%<-------------------------------------------------------------------------
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/INBOX/dovecot-virtual
virtual/all
inthread refs x-mailbox INBOX
---%<-------------------------------------------------------------------------
Create a mailbox containing messages from all mailboxes except Trash and its
children:
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/all/dovecot-virtual
*
-Trash
-Trash/*
all
---%<-------------------------------------------------------------------------
Create a virtual Sentmail folder that includes Sent*:
---%<-------------------------------------------------------------------------
# ~/Maildir/virtual/Sentmail/dovecot-virtual
Sent*
all
---%<-------------------------------------------------------------------------
Virtual POP3 INBOX
------------------
If you want POP3 INBOX to contain some or all mailboxes, you can do this in the
following way:
Namespace configuration:
---%<-------------------------------------------------------------------------
# The default namespace that is visible to IMAP clients
namespace default {
prefix =
separator = /
list = yes
}
# Virtual namespace for the virtual INBOX. Use a global directory for
dovecot-virtual files.
namespace virtual {
prefix = virtual/
separator = /
location = virtual:/etc/dovecot/virtual:INDEX=~/Maildir/virtual
list = no
hidden = yes
}
# Copy of the default namespace. We'll use this in dovecot-virtual file.
namespace real {
prefix = RealMails/
separator = /
list = no
hidden = yes
}
---%<-------------------------------------------------------------------------
Note that none of the namespaces have inbox=yes. This is because for IMAP users
you want the default namespace to have inbox=yes, but for POP3 users you want
the virtual namespace to have inbox=yes. This requires setting the inbox=yes in
[UserDatabase.ExtraFields.txt]. For example with MySQL
you can can do this like:
---%<-------------------------------------------------------------------------
user_query = SELECT ..., \
CASE '%s' WHEN 'pop3' THEN NULL ELSE 'yes' END AS 'namespace/default/inbox',
\
CASE '%s' WHEN 'pop3' THEN 'yes' ELSE NULL END AS 'namespace/virtual/inbox' \
WHERE ...
---%<-------------------------------------------------------------------------
Finally specify what the virtual INBOX looks like for POP3 users:
'/etc/dovecot/virtual/INBOX/dovecot-virtual' :
---%<-------------------------------------------------------------------------
RealMails/*
-RealMails/Trash
-RealMails/Trash/*
-RealMails/Spam
all
---%<-------------------------------------------------------------------------
You'll have to use the RealMails/ prefix if you want to use "*" wildcard,
otherwise it would match INBOX, which in turn would again lead to the virtual
INBOX and that would create a loop.
Also to avoid accidental POP3 UIDL changes, you shouldn't base the UIDLs on
IMAP UIDs. Instead use for GUIDs (with maildir the same as base filename):
---%<-------------------------------------------------------------------------
pop3_uidl_format = %g
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/MboxChildFolders.txt 0000666 00000022307 15050120373 0011444 0 ustar 00 Mail folders containing both messages and sub-folders
-----------------------------------------------------
Under mbox, it is not normally possible to have a mail folder which contains
both messages and sub-folders. This is because there would be a filesystem name
collision between the name of the mbox file containing the messages and the
name of the directory containing the sub-folders, for example:
* Mail folder "foo" containing messages would be stored in a file at
'~/mail/foo'.
* Mail folder "foo/bar" containing messages would be stored in a file at
'~/mail/foo/bar', but this cannot happen because this relies on the
existence of a directory '~/mail/foo/' which can't exist because there is
already a file with that name.
If however there is a requirement to be able to have a mail folder which
contains both messages and sub-folders, then there are a couple of ways to do
it:
1. Maildir++ layout
2. Messages in named file
These approaches are described in more detail below.
Maildir++ layout
----------------
Under mbox, Dovecot normally stores mail folders in "filesystem" layout. In
this layout, mail folders are stored in mbox files (potentially under
subdirectories) with the same relative path as the mail folder path, for
example:
* '~/mail/foo' - mbox file containing mail for mail folder "foo"; can not
create any mail sub-folders of "foo"
* '~/mail/bar/baz' - mbox file containing mail for mail folder "bar/baz"; can
not create any mail sub-folders of "bar/baz"
* ('~/mail/inbox' - mbox file containing mail for INBOX)
However, Dovecot can be configured to keep mbox mail in a Maildir++-like
layout. This makes Dovecot keep mail in mbox files where all the mailbox folder
naming levels are separated with dots (with a leading dot), for example:
* '~/mail/.foo' - mbox file containing mail for mail folder "foo"
* '~/mail/.foo.bar' - mbox file containing mail for mail folder "foo/bar". We
can now do this.
* '~/mail/.bar.baz' - mbox file containing mail for mail folder "bar/baz"
* ('~/mail/inbox' - mbox file containing mail for INBOX)
This can be enabled by adding ':LAYOUT=maildir++' to the mail location, for
example:
---%<-------------------------------------------------------------------------
# Incomplete example. Do not use!
mail_location = mbox:~/mail:LAYOUT=maildir++
---%<-------------------------------------------------------------------------
However there is a problem. Under mbox, setting 'LAYOUT=maildir++' alone leaves
Dovecot unable to place index files, which would likely result in performance
issues. So when using 'LAYOUT=maildir++' with mbox, it is advisable to also
configure 'INDEX'. Now, mail files (other than 'inbox') all have names
beginning with a dot, so if we like we can store other things in the '~/mail'
directory by using names which do not begin with a dot. So we could think to
use 'INDEX' to indexes at '~/mail/index/', for example:
---%<-------------------------------------------------------------------------
# Incomplete example. Do not use!
mail_location = mbox:~/mail:LAYOUT=maildir++:INDEX=~/mail/index
---%<-------------------------------------------------------------------------
If we do this, then indexes will be kept at '~/mail/index/' and this will not
clash with any names used for mail folders. There is one more thing we may want
to consider though. By default Dovecot will maintain a list of subscribed
folders in a file '.subscriptions' under the mail location root. In this case
that means it would end up at '~/mail/.subscriptions'. This would then mean
that it would be impossible to create a mail folder called "subscriptions". We
can get around this by using the 'CONTROL' parameter to move the
'.subscriptions' file somewhere else, for example into the directory
'~/mail/control' (again choosing a name which doesn't begin with a dot so we
don't collide with the names of mbox files storing mail folders). That gives
us:
---%<-------------------------------------------------------------------------
# Trick mbox configuration which allows a mail folder which contains both
# messages and sub-folders
mail_location =
mbox:~/mail:LAYOUT=maildir++:INDEX=~/mail/index:CONTROL=~/mail/control
---%<-------------------------------------------------------------------------
This then allows mail folders which contains both messages and sub-folders
without possibility of naming collisions between mail folders and other data.
There is one further wrinkle. Specifying ':LAYOUT=maildir++' for mbox changes
the default hierarchy separator from a slash to a dot. This should not be a
problem for IMAP clients as the hierarchy separator is exposed through IMAP.
However anything which expects to just "know" that the hierarchy separator is a
slash may get confused. This can be worked around by using a
[Namespaces.txt] to set the folder separator back to a slash again.
Messages in named file
----------------------
Under mbox, Dovecot normally stores mail folders in "filesystem" layout. In
this layout, mail folders are stored in mbox files (potentially under
subdirectories) with the same relative path as the mail folder path, for
example:
* '~/mail/foo' - mbox file containing mail for mail folder "foo"; can not
create any mail sub-folders of "foo"
* '~/mail/bar/baz' - mbox file containing mail for mail folder "bar/baz"; can
not create any mail sub-folders of "bar/baz"
* ('~/mail/inbox' - mbox file containing mail for INBOX)
In the example above, we can't create any sub-folders of "foo" because there is
a file 'foo' in the way. So we could think to get rid of that file and put a
directory there instead. But if we do that then we need somewhere to put the
messages for folder "foo". We could think to put them in a specially-named file
in the directory 'foo/'. Then if we wanted to create a sub-folder of "foo" we
would be fine because we could then do that. The rule would then be that
messages go into the specially-named file in the directory corresponding to the
mail folder name. We want want to choose a special name which would be unlikely
to collide with a folder name. We could think to use something like
'mBoX-MeSsAgEs'. Now, it turns out that you can configure Dovecot to do this
using the 'DIRNAME' parameter. For example, using a configuration of:
---%<-------------------------------------------------------------------------
# Incomplete example. Do not use!
mail_location = mbox:~/mail:DIRNAME=mBoX-MeSsAgEs
---%<-------------------------------------------------------------------------
we would get a layout like this:
* '~/mail/inbox' - mbox file containing mail for INBOX
* '~/mail/foo/mBoX-MeSsAgEs' - mbox file containing mail for mail folder "foo"
* '~/mail/foo/bar/mBoX-MeSsAgEs' - mbox file containing mail for mail folder
"foo/bar"
However there is a problem. Under mbox, setting 'DIRNAME' alone leaves Dovecot
unable to place index files, which would likely result in performance issues,
or worse, if the index directory gets created first, this will obstruct the
creation of the mbox file. So when using 'DIRNAME' with mbox, it is also
necessary to configure 'INDEX'. The question then arises where to put index
files.
Any directory under the '~/mail' directory could be considered as a mail
folder. We could think to use a name beginning with a dot, for example
'~/mail/.index' but that would then mean that it would not be possible to
create a mail folder called ".index"; unlikely, but it would be nice to have as
few implementation-specific restrictions as possible.
In addition, by default, Dovecot will create a file '.subscriptions' at the
mail location root to hold a list of mailbox subscriptions. This would make it
impossible to create a mail folder called ".subscriptions". But we can move the
'.subscriptions' file to another directory by using the 'CONTROL' parameter. To
get round these issues, we can add another directory layer which separates
these purposes. For example, using the configuration:
---%<-------------------------------------------------------------------------
# Trick mbox configuration which allows a mail folder which contains both
# messages and sub-folders
mail_location =
mbox:~/mail/mailboxes:DIRNAME=mBoX-MeSsAgEs:INDEX=~/mail/index:CONTROL=~/mail/control
---%<-------------------------------------------------------------------------
would result in the following layout:
* '~/mail/mailboxes/foo/mBoX-MeSsAgEs' - mbox file containing messages for
mail folder "foo"
* '~/mail/mailboxes/foo/bar/mBoX-MeSsAgEs' - mbox file containing messages for
mail folder "foo/bar"
* '~/mail/mailboxes/inbox' - mbox file containing messages for INBOX
* '~/mail/control/.subscriptions' - file containg list of subscribed mailboxes
* '~/mail/index/INBOX/dovecot.index.*' - index files for INBOX
* '~/mail/index/foo/dovecot.index.*' - index files for mail folder "foo"
* '~/mail/index/foo/bar/dovecot.index.*' - index files for mail folder
"foo/bar"
* '~/mail/index/dovecot.mailbox.log' - other index files
Restrictions on mail folder names are then minimised; we can't have mail
folders with the names "mBoX-M ''eSsAgEs", "dovecot.index.*, or
"dovecot.mailbox.log".
Unlike the Maildir++ layout approach above, because we are still using
"filesystem" layout, the hierarchy separator remains as a slash.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Indexes.txt 0000666 00000005767 15050120373 0011076 0 ustar 00 Dovecot's index files
=====================
Dovecot's index files consist of three different files:
* [Design.Indexes.MainIndex.txt] ('dovecot.index')
* [Design.Indexes.TransactionLog.txt] ('dovecot.index.log'
and 'dovecot.index.log.2')
* [Design.Indexes.Cache.txt] ('dovecot.index.cache')
See for more generic information about what they contain and
why.
The index files can be accessed using
[Design.Indexes.MailIndexApi.txt].
Locking
-------
The index files are designed so that readers cannot block a writer, and write
locks are always short enough not to cause other processes to wait too long.
Dovecot v0.99's index files didn't do this, and it was common to get lock
timeouts when using multiple connections to the same large mailbox.
The main index file is the only file which has read locks. They can however
block the writer only for two seconds (and even this could be changed to not
block at all). The writes are locked only for the duration of the mailbox
synchronization.
Transaction logs don't require read locks. The writing is locked for the
duration of the mailbox synchronization, and also for single transaction
appends.
Cache files doesn't require read locks. They're locked for writing only for the
duration of allocating space inside the file. The actual writing inside the
allocated space is done without any locks being held.
In future these could be improved even further. For example there's no need to
keep any index files locked while synchronizing, as long the mailbox backend
takes care of the locking issues. Also writing to transaction log could work in
a similar way to cache files: Lock, allocate space, unlock, write.
Lockless integers
-----------------
Dovecot uses several different techniques to allow reading files without
locking them. One of them uses fields in a "lockless integer" format. Initially
these fields have "unset" value. They can be set to a wanted value in range
0..2^28 (with 32bit fields) once, but they cannot be changed. It would be
possible to set them back to "unset", but setting them the second time isn't
safe anymore, so Dovecot never does this.
The lockless integers work by allocating one bit from each byte of the value to
"this value is set" flag. The reader then verifies that the flag is set for the
value's all bytes. If all of them aren't set, the value is still "unset".
Dovecot uses the highest bit for this flag. So for example:
* 0x00000000: The value is unset
* 0xFFFF7FFF: The value is unset, because one of the bytes didn't have the
highest bit set
* 0xFFFFFFFF: The value is 2^28-1
* 0x80808080: The value is 0
* 0x80808180: The value is 0x80
Dovecot contains 'mail_index_uint32_to_offset()' and
'mail_index_offset_to_uint32()' functions to translate values between integers
and lockless integers. The "unset" value is returned as 0, so it's not possible
to differentiate between "unset" and "set" 0 values.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Quota.Configuration.txt 0000666 00000025043 15050120373 0012153 0 ustar 00 Quota Configuration
===================
The configuration is split into multiple settings:
First you have the quota root backend configuration. Quota root is a concept
from IMAP Quota specifications [http://www.rfc-editor.org/rfc/rfc2087.txt].
Normally you'll have only one quota root, but in theory there could be e.g.
"user quota" and "domain quota" roots. It's unspecified how the quota roots
interact with each others (if at all). In some systems for example INBOX could
have a completely different quota root from the rest of the mailboxes (e.g.
INBOX in '/var/mail/' partition and others in '/home/' partition).
Quota root configuration includes the backend name, quota root name and its
parameters, if there are any:
---%<-------------------------------------------------------------------------
quota = [:[:]]
---%<-------------------------------------------------------------------------
The quota root name is just an arbitrary string that is sent to IMAP clients,
which in turn may show it to the user. The name has no meaning. By default an
empty string is used, but you may want to change that since some clients (Apple
Mail) break and don't show quota at all then.
You can define multiple quota roots by appending an increasing number, for
example:
---%<-------------------------------------------------------------------------
plugin {
quota = maildir:User quota
quota2 = fs:Disk quota
#quota3 = ...
}
---%<-------------------------------------------------------------------------
Quota rules
-----------
Quota rules configure the actual quota limits. The syntax is:
---%<-------------------------------------------------------------------------
quota_rule = :
#quota_rule2 = ...
#quota_rule3 = ..etc..
---%<-------------------------------------------------------------------------
"*" as the mailbox name configures the default limit, which is applied on top
of a mailbox-specific limit if found. So for example:
---%<-------------------------------------------------------------------------
quota_rule = *:storage=1G
quota_rule2 = Trash:storage=100M
quota_rule3 = SPAM:ignore
---%<-------------------------------------------------------------------------
This means that the user has 1GB quota, but when saving messages to Trash
mailbox it's possible to use up to 1,1GB of quota. The quota isn't specifically
assigned to Trash, so if you had 1GB of mails in Trash you could still save
100MB of mails to Trash, but nothing to other mailboxes. The idea of this is
mostly to allow the clients' move-to-Trash feature work while user is deleting
messages to get under quota. Additionally, any messages in the SPAM folder are
ignored per the 'ignore' directive and would not count against the quota.
"?" as the mailbox name works almost like "*". The difference is that "?" is
used only if quota backend doesn't override the limit. For example with
Maildir++ [http://www.inter7.com/courierimap/README.maildirquota.html] quota if
'maildirsize' file exists the limits are taken from it, but if it doesn't exist
the "?" limits are used.
"*" can't be used as a generic wildcard in mailbox names, so for example "box*"
wouldn't match "boxes". As shown in the above example, the first quota rule is
named 'quota_rule' while the following rules have an increasing digit in them.
You can have as many quota rules as you want.
Limit configuration
-------------------
The following limit names are supported:
* *storage*: Quota limit in kilobytes, 0 means unlimited.
* *bytes*: Quota limit in bytes, 0 means unlimited.
* *messages*: Quota limit in number of messages, 0 means unlimited. This
probably isn't very useful.
* *backend*: Quota backend-specific limit configuration.
* *ignore*: Don't include the specified mailbox in quota at all.
All of these support also b/k/M/G/T/% suffixes. So storage=100M and bytes=100M
both mean the exact same thing. messages=1k also means 1024 messages (not
1000).
Percents are relative to the default rule. For example:
---%<-------------------------------------------------------------------------
plugin {
quota = maildir:User quota
quota_rule = *:storage=1GB
# 10% of 1GB = 100MB
quota_rule2 = Trash:storage=10%%
# 20% of 1GB = 200MB
quota_rule3 = Spam:storage=20%%
}
---%<-------------------------------------------------------------------------
Note that % is written twice to escape it, because <%variables> [Variables.txt]
are expanded in plugin section. [UserDatabase.txt] configuration may
or may not require this escaping.
Backend-specific configuration currently is used only with Maildir++ quota
backend. It means you can have the quota in Maildir++ format (e.g.
"10000000S").
Per-user quota
--------------
You can override quota rules in your [UserDatabase.txt]'s [UserDatabase.ExtraFields.txt]. Keep all the global settings in plugin
section and override only those settings you need to in your userdb. For
example:
---%<-------------------------------------------------------------------------
plugin {
quota = maildir:User quota
quota_rule = *:storage=1G
quota_rule2 = Trash:storage=100M
}
---%<-------------------------------------------------------------------------
Next override the default 1GB quota for users:
---%<-------------------------------------------------------------------------
# LDAP:
user_attrs = homeDirectory=home,quotaBytes=quota_rule=*:bytes=%$
# MySQL:
user_query = select uid, gid, home, \
concat('*:bytes=', quota_bytes) as quota_rule \
from users where userid = '%u'
# MySQL with userdb prefetch: Remember to prefix quota_rule with userdb_
# (just like all other userdb extra fields):
password_query = select userid as user, password, \
uid as userdb_uid, gid as userdb_gid, \
concat('*:bytes=', quota_bytes) as userdb_quota_rule \
from users where userid = '%u'
# Example passwd-file entries:
user:{plain}pass:1000:1000::/home/user::userdb_quota_rule=*:bytes=100M
user2:{plain}pass2:1001:1001::/home/user2::userdb_quota_rule=*:bytes=200M
---%<-------------------------------------------------------------------------
Quota for public namespaces
---------------------------
You can create a separate namespace-specific quota that's shared between all
users. This is done simply by adding ':ns=' parameter to
quota setting. For example you could have something like:
---%<-------------------------------------------------------------------------
namespace {
type = public
prefix = Public/
#location = ..
}
plugin {
quota = maildir:User quota
quota2 = maildir:Shared quota:ns=Public/
#quota_rules and quota2_rules..
}
---%<-------------------------------------------------------------------------
Custom Quota Exceeded Message
-----------------------------
You can configure Dovecot to send a custom string instead of the default quota
exceeded message. You could have something like:
---%<-------------------------------------------------------------------------
plugin {
quota_exceeded_message = Quota exceeded, please go to
http://www.example.com/over_quota_help for instructions on how to fix this.
}
---%<-------------------------------------------------------------------------
Quota warnings
--------------
You can configure Dovecot to run an external command when user's quota exceeds
a specified limit. Note that the warning is ONLY executed at the exact time
when the limit is being crossed, so when you're testing it you have to do it by
crossing the limit by saving a new mail. If something else besides Dovecot
updates quota so that the limit is crossed, the warning is never executed. The
syntax is:
---%<-------------------------------------------------------------------------
quota_warning =
#quota_warning2 = ...
#quota_warning3 = ..etc..
---%<-------------------------------------------------------------------------
Limit configuration is the exact same as for rules. Usually you want to use
percents instead of absolute limits. Only the command for the first exceeded
limit is executed, so configure the highest limit first. The actual commands
that are run need to be created as services.
An example configuration:
---%<-------------------------------------------------------------------------
plugin {
quota_warning = storage=95%% quota-warning 95 %u
quota_warning2 = storage=80%% quota-warning 80 %u
}
service quota-warning {
executable = script /usr/local/bin/quota-warning.sh
# use some unprivileged user for executing the quota warnings
user = vmail
unix_listener quota-warning {
}
}
---%<-------------------------------------------------------------------------
With the above example when user's quota exceeds 80%, 'quota-warning.sh' is
executed with parameter 80. The same goes for when quota exceeds 95%. If user
suddenly receives a huge mail and the quota jumps from 70% to 99%, only the 95
script is executed.
You have to create the 'quota-warning.sh' script yourself. Here is an example
that sends a mail to the user:
---%<-------------------------------------------------------------------------
#!/bin/sh
PERCENT=$1
USER=$2
cat << EOF | /usr/local/libexec/dovecot/dovecot-lda -d $USER -o
"plugin/quota=maildir:User quota:noenforcing"
From: postmaster@domain.com
Subject: quota warning
Your mailbox is now $PERCENT% full.
EOF
---%<-------------------------------------------------------------------------
The quota enforcing is disabled to avoid looping. You'll of course need to
change the 'plugin/quota' value to match the quota backend and other
configuration you use. Basically preserve your original "quota" setting and
just insert ":noenforcing" to proper location in it. For example with dict
quota, you can use something like:'-o "plugin/quota=dict:User
quota::noenforcing:proxy::quota"'
Per-user quota limit configuration examples
-------------------------------------------
SQL
---
---%<-------------------------------------------------------------------------
# MySQL, quota in bytes:
user_query = SELECT home, uid, gid, concat('*:bytes=', quota_bytes) AS
quota_rule FROM users WHERE userid = '%u'
# PostgreSQL, SQLite, quota in bytes:
user_query = SELECT home, uid, gid, '*:bytes=' || quota_bytes AS quota_rule
FROM users WHERE userid = '%u'
---%<-------------------------------------------------------------------------
LDAP
----
---%<-------------------------------------------------------------------------
user_attrs = homeDirectory=home, uidNumber=uid, gidNumber=gid,
quotaBytes=quota_rule=*:bytes=%$
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/AuthDatabase.LDAP.AuthBinds.txt 0000666 00000006324 15050120373 0013202 0 ustar 00 Passdb LDAP with authentication binds
=====================================
Advantages over [AuthDatabase.LDAP.PasswordLookups.txt]:
* LDAP server verifies the password, so Dovecot doesn't need to know what
format the password is stored in.
* A bit more secure, as a security hole in Dovecot doesn't give attacker
access to all the users' passwords.
You can enable authentication binds by setting 'auth_bind=yes'. Next Dovecot
needs to know what DN to use in the binding. There are two ways to configure
this: lookup or template.
DN lookup
---------
DN is looked up by sending a 'pass_filter' LDAP request and getting the DN from
the reply. This is very similar to doing a
[AuthDatabase.LDAP.PasswordLookups.txt]. The only difference is that
userPassword attribute isn't returned. Just as with password lookups, the
'pass_attrs' may contain special
[PasswordDatabase.ExtraFields.txt].
Example:
---%<-------------------------------------------------------------------------
auth_bind = yes
pass_attrs = uid=user
pass_filter = (&(objectClass=posixAccount)(uid=%u))
---%<-------------------------------------------------------------------------
DN template
-----------
The main reason to use DN template is to avoid doing the DN lookup, so that the
authentication consists only of one LDAP request. With IMAP and POP3 logins the
same optimization can be done by using
[UserDatabase.Prefetch.txt] and returning userdb info in the DN lookup (a total
of two LDAP requests per login in both cases). If you're also using Dovecot for
SMTP AUTH, it doesn't do a userdb lookup so the prefetch optimization doesn't
help.
If you're using DN template, 'pass_attrs' and 'pass_filter' settings are
completely ignored. That means you can't make passdb return any
[PasswordDatabase.ExtraFields.txt]. You should also set 'auth_username_format =
%Lu' in 'dovecot.conf' to normalize the username by lowercasing it.
Example:
---%<-------------------------------------------------------------------------
auth_bind = yes
auth_bind_userdn = cn=%u,ou=people,o=org
---%<-------------------------------------------------------------------------
Connection optimization
-----------------------
When using
* auth binds and
* userdb ldap lookups,
the userdb lookups should use a separate connection to the LDAP server. That
way it can send LDAP requests asynchronously to the server, which improves the
performance. This can be done by specifying different filenames in the LDAP
passdb and userdb args. The second file could be a symlink to the first one.
For example:
---%<-------------------------------------------------------------------------
passdb {
driver = ldap
args = /etc/dovecot/dovecot-ldap.conf.ext
}
userdb {
driver = ldap
args = /etc/dovecot/dovecot-ldap-userdb.conf.ext
}
---%<-------------------------------------------------------------------------
And create the symlink:
---%<-------------------------------------------------------------------------
ln -s /etc/dovecot/dovecot-ldap.conf.ext
/etc/dovecot/dovecot-ldap-userdb.conf.ext
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/SSL.DovecotConfiguration.txt 0000666 00000020736 15050120373 0013053 0 ustar 00 Dovecot SSL configuration
=========================
The most important SSL settings are:
---%<-------------------------------------------------------------------------
ssl = yes
# Preferred permissions: root:root 0444
ssl_cert =
[Authentication.Mechanisms.txt] only when SSL/TLS is used first.
* 'ssl = required' requires SSL/TLS also for
[Authentication.Mechanisms.txt].
* If you have only plaintext mechanisms enabled ('auth { mechanisms = plain
login }'), you can use either (or both) of the above settings. They behave
exactly the same way then.
Multiple SSL certificates
-------------------------
TLS SNI (Server Name Indication) support required
-------------------------------------------------
/It is important to note that having multiple SSL certificates per IP will not
be compatible with all clients, especially mobile ones. It is a TLS SNI
limitation./
---%<-------------------------------------------------------------------------
local_name imap.example.org {
ssl_cert = /var/lib/dovecot/ssl-parameters.ssl'. After the initial creation
they're by default regenerated every week. With newer computers the generation
shouldn't take more than a few seconds, but with older computers it can take as
long as half an hour. The extra security gained by the regeneration is quite
small, so with slower computers you might want to disable it:
---%<-------------------------------------------------------------------------
ssl_parameters_regenerate = 0
---%<-------------------------------------------------------------------------
By default Dovecot's allowed ciphers list contains:
---%<-------------------------------------------------------------------------
ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
---%<-------------------------------------------------------------------------
Disallowing more won't really gain any security for those using better ciphers,
but it does prevent people from accidentally using insecure ciphers. See
http://www.openssl.org/docs/apps/ciphers.html for a list of the ciphers.
SSL verbosity
-------------
---%<-------------------------------------------------------------------------
verbose_ssl = yes
---%<-------------------------------------------------------------------------
This will make Dovecot log all the problems it sees with SSL connections. Some
errors might be caused by dropped connections, so it could be quite noisy.
Client certificate verification/authentication
----------------------------------------------
If you want to require clients to present a valid SSL certificate, you'll need
these settings:
---%<-------------------------------------------------------------------------
ssl_ca = class3-revoke.pem
---%<-------------------------------------------------------------------------
With the above settings if a client connects which doesn't present a
certificate signed by one of the CAs in the 'ssl_ca' file, Dovecot won't let
the user log in.
You may also force the username to be taken from the certificate by setting
'ssl_username_from_cert = yes'.
* The text is looked up from subject DN's specified field using OpenSSL's
'X509_NAME_get_text_by_NID()' function.
* By default the 'CommonName' field is used.
* You can change the field with 'ssl_cert_username_field = name' setting
(parsed using OpenSSL's 'OBJ_txt2nid()' function). 'x500UniqueIdentifier' is
a common choice.
You may also want to disable the password checking completely. Doing this
currently circumvents Dovecot's security model so it's not recommended to use
it, but it is possible by making the [PasswordDatabase.txt] allow
logins using any password (typically requiring <"nopassword" extra field>
[PasswordDatabase.ExtraFields.txt] to be returned).
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.Autocreate.txt 0000666 00000001376 15050120373 0011773 0 ustar 00 Autocreate plugin
=================
This plugin allows administrator to specify mailboxes that must always exist
for all users. They can optionally also be subscribed. The mailboxes are
created and subscribed always after user logs in. Namespaces are fully
supported, so namespace prefixes need to be used where necessary.
Example:
---%<-------------------------------------------------------------------------
protocol imap {
mail_plugins = $mail_plugins autocreate
}
plugin {
autocreate = Trash
autocreate2 = Spam
#autocreate3 = ..etc..
autosubscribe = Trash
autosubscribe2 = Spam
#autosubscribe3 = ..etc..
}
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Arrays.txt 0000666 00000007510 15050120373 0010724 0 ustar 00 Dynamic Arrays
==============
'lib/array.h' and 'lib/array-decl.h' describes Dovecot's type-safe dynamic
arrays. Trying to add wrong typed elements gives a compiler warning.
Declaring
---------
Arrays can be declared in two ways:
1. Directly: 'ARRAY_DEFINE(array_name, array_type);'. For example:
'ARRAY_DEFINE(numbers, int);' or 'ARRAY_DEFINE(foos, struct foo);'
2. Via predefined type: 'ARRAY_DEFINE_TYPE(foo, struct foo); ...
ARRAY_TYPE(foo) foos;'
The main reason to define a type for an array is to be able to pass the array
as a function parameter, like:
---%<-------------------------------------------------------------------------
void func(ARRAY_TYPE(foo) *foos) { .. }
---%<-------------------------------------------------------------------------
Trying to do the same with 'ARRAY_DEFINE()' will generate a compiler warning.
'lib/array-decl.h' defines several commonly used types.
Initializing
------------
Arrays are typically initialized by calling 'i_array_init()', 'p_array_init()'
or 't_array_init()' depending on where you want to allocate the memory from.
Arrays are internally handled as [Design.Buffers.txt], so the initial
size is just multiplied by element size and passed to
'buffer_create_dynamic()'.
Example:
---%<-------------------------------------------------------------------------
ARRAY_DEFINE(foo, struct foo *);
i_array_init(&foo, 32); /* initialize array with 32 elements until it needs to
be grown */
---%<-------------------------------------------------------------------------
Arrays can be freed with 'array_free()', but this isn't necessary if the memory
gets freed by other means (i.e. it was allocated from alloconly-pool or data
stack).
Writing
-------
* 'array_append(array, data, count)' is the most common way to add data to
arrays
* 'array_append_array(dest, src)'
* 'array_insert(array, idx, data, count)'
* 'array_delete(array, idx, count)'
* 'array_idx_set(array, idx, data)' replaces (or adds) data to given index
* 'array_idx_clear(array, idx)' clears given index by writing NULs to it
* 'array_append_space(array, count)'
Reading
-------
'array_idx(array, idx)' returns pointer to given index in array. The index must
already exist, otherwise the call assert-crashes. This call adds extra overhead
for accessing arrays though, so usually it's better to just get list of all
elements and access them directly:
---%<-------------------------------------------------------------------------
data = array_get(&array, &count);
---%<-------------------------------------------------------------------------
You can also iterate through the whole array easily:
---%<-------------------------------------------------------------------------
const char *str;
array_foreach(&string_array, str) {
/* str changes in each iteration */
}
---%<-------------------------------------------------------------------------
There's also 'array_foreach_modifiable()' to get the data without const.
Unsafe Read/Write
-----------------
Functions below have similar problems to [[Design/Buffer|buffer]'s '*_unsafe()'
functions. Memory returned by them must not be accessed after calls to other
'array_*()' modifying functions, because they may reallocate the array
elsewhere in memory.
* 'array_append_space(array)'
* 'array_insert_space(array, idx)'
* 'array_get_modifiable(array, &count)'
* 'array_idx_modifiable(array, idx)'
Others
------
* 'array_cmp(array1, array2)' compares two arrays
* 'array_reverse(array)' reverses all elements in an array
* 'array_sort(array, cmp_func)' is a wrapper for 'qsort()' adding also type
safety. The parameters in cmp_func should be the same type as the array,
instead of 'const void *'.
* 'array_bsearch(array, key, cmp_func)' is a wrapper for 'bsearch()' also
adding type safety, just like 'array_sort()'.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/UserDatabase.Static.txt 0000666 00000002777 15050120373 0012056 0 ustar 00 Static User Database
====================
Static user database can be used when you want to use only single UID and GID
values for all users, and their home directories can be specified with a simple
template. The syntax is:
---%<-------------------------------------------------------------------------
userdb {
driver = static
args = uid= gid= home=
}
---%<-------------------------------------------------------------------------
The home is optional. You can also return other
[UserDatabase.ExtraFields.txt]. You can use the standard
[Variables.txt] everywhere.
Deliver
-------
Unless your MTA already verifies that the user exists before calling deliver,
you'll most likely want deliver itself to verify the user's existence. Since
deliver looks up the user only from the userdb, it of course doesn't work with
static userdb because there is no list of users. Normally static userdb handles
this by doing a passdb lookup instead. This works with most passdbs, with
[PasswordDatabase.PAM.txt] being the most notable exception. If you want to
avoid this user verification, you can add 'allow_all_users=yes' to the args in
which case the passdb lookup is skipped.
Example
-------
---%<-------------------------------------------------------------------------
userdb {
driver = static
args = uid=500 gid=500 home=/home/%u
}
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.Compress.txt 0000666 00000000776 15050120373 0011475 0 ustar 00 IMAP COMPRESS plugin
====================
The goal of the extension is to reduce the bandwidth usage of IMAP.
The [Plugins.Zlib.txt] has to be enabled for imap_zlib to work
Configuration:
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins zlib
protocol imap {
mail_plugins = $mail_plugins imap_zlib
}
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Indexes.MailIndexApi.txt 0000666 00000004106 15050120373 0013363 0 ustar 00 Mail Index API
==============
'lib-index/mail-index.h' contains the functions to access the index files.
'mail-cache.h' contains the functions to access the cache file.
The purpose of the main structures are:
* 'struct mail_index': Global state of the index.
* 'struct mail_index_view': You can have multiple views to the index. The
views see new messages come and expunged messages go only when it's being
explicitly synchronized. With mmaped indexes you can't really trust the
record data (flags, keywords, extensions) not to change. This doesn't matter
with IMAP.
* 'struct mail_index_map': Index file is accessed via maps. Views can point to
one or more maps. Maps can be shared by different views. Maps can contain
either mmap()ed memory areas pointing to the index file, or a in-memory copy
of it.
* 'struct mail_index_transaction': In-memory list of changes to be written to
the transaction log. The writing is done only when the transaction is
committed.
Views and maps
--------------
In general you access all the data in the index files via views. The mails are
accessed using sequence numbers, which change only when the view is
synchronized.
For accessing messages with their UIDs, you'll first need to convert them to
sequences with either 'mail_index_lookup_uid()' or
'mail_index_lookup_uid_range()'.
'mail_index_lookup()' can be used to look up a single record's UID and flags.
The returned record points to the latest map, so that it contains the latest
flag changes. If the message was already expunged from the latest map, it
returns 0.
'mail_index_lookup_full()' can be used to get also the map where the message
was found. This can be important with extensions. If extension record's state
depends on the extension header, they must be looked up from the same map. For
this reason there exists 'mail_index_map_get_header_ext()' and
'mail_index_lookup_ext_full()' functions which take the map as parameter. The
non-map versions return the data from the latest map if the message hasn't been
expunged.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Storage.Mailbox.Transaction.txt 0000666 00000005525 15050120373 0014751 0 ustar 00 Mailbox Transactions
====================
Before you can read any mails or do any changes to mails, you need to create a
transaction with 'mailbox_transaction_begin()'. It has a few flags:
* 'MAILBOX_TRANSACTION_FLAG_HIDE': Mark the changes in a way that when later
[Design.Storage.Mailbox.Sync.txt] the mailbox in this session,
'mailbox_sync_next()' won't return sync records for the changes done by this
transaction. This is primarily meant for flag and keyword changes, you can't
hide expunges. For example IMAP's 'STORE FLAGS.SILENT' command is
implemented by setting this flag for the transaction.
* 'MAILBOX_TRANSACTION_FLAG_EXTERNAL': Changes done by this transaction should
be marked as external changes. Internal changes can be thought of as "change
requests" that syncing later finishes, while external changes are done
immediately and syncing ignores them. Normally you would use this flag when
you want to save or copy messages, nothing else.
* 'MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS': Require assigning UIDs to
saved/copied messages immediately. Normally this is done only when it's easy
(maildir: if dovecot-uidlist can be locked without waiting, mbox: if mbox is
already fully synced).
* 'MAILBOX_TRANSACTION_FLAG_REFRESH': Do a quick index refresh, so any recent
flag/modseq changes done by other Dovecot sessions will be visible. You
shouldn't usually need this, because usually you should have recently done a
mailbox sync.
Changes for a transaction are kept in memory until the transaction is
committed. If you want to cancel the changes, you can call
'mailbox_transaction_rollback()'. Transaction can be commited with
'mailbox_transaction_commit()'. If you want to know a bit more about the
results of the transaction, use 'mailbox_transaction_commit_get_changes()'
instead. It returns a change structure:
* uid_validity: UIDVALIDITY used by returned UIDs
* saved_uids: UIDs assigned to saved/copied mails. Typically they're in an
ascending order, unless you explicitly requested some specific UIDs for
mails while saving them (e.g. dsync does this).
* ignored_uid_changes: Number of UIDs that couldn't be changed by
'mail_update_uid()' calls, because the UIDs were less than next_uid's value.
* ignored_modseq_changes: Number of modseqs that couldn't be changed by
'mail_update_modseq()' calls, because they would have lowered the modseq.
Once you're done with reading the change structure, be sure to free the memory
used by it with 'pool_unref(&changes->pool)'.
'mailbox_transaction_set_max_modseq()' can be used to implement atomic
conditional flag changes. If message's modseq is higher than the given
max_modseq while transaction is being committed, the change isn't done and the
message's sequence number is added to the given array.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Storage.Plugins.txt 0000666 00000012362 15050120373 0012510 0 ustar 00 Mail Plugins
============
Typically plugins add hooks in their init() function by calling
'mail_storage_hooks_add()', and remove the hooks at deinit() with
'mail_storage_hooks_remove()'. Hooks that are currently supported:
* mail_user_created: A new mail user was created. It doesn't yet have any
namespaces.
* mail_storage_created: A new mail storage was created. It's not connected to
any namespaces/mailbox lists yet.
* mailbox_list_created: A new mailbox list was created. It's not connected to
any storages yet. Because of this, some internal virtual methods haven't
been overridden by the storage yet, so plugins rarely want to use this hook.
Instead they should use:
* mail_namespace_storage_added: Storage was connected to its first
namespace/mailbox list. This hook should usually be used if plugin wants to
override mailbox_list's methods.
* mail_namespaces_created: User's all namespaces have been created. This hook
is called only per user at startup. More internal namespaces may be created
later when using shared mailboxes.
* mailbox_allocated: 'mailbox_alloc()' was called.
* mailbox_opened: Mailbox (and its index) was actually opened, either
explicitly with 'mailbox_open()' or implicitly by some other function.
Overriding methods
------------------
When the hook gets called, you usually want to override some method of the
created object. This is the easy part, for example:
---%<-------------------------------------------------------------------------
static void plugin_mailbox_allocated(struct mailbox *box)
..
box->v.transaction_begin = plugin_transaction_begin;
---%<-------------------------------------------------------------------------
The problem is that once 'plugin_transaction_begin()' is called, it should call
the original 'transaction_begin()'. There may also be multiple plugins that
want to override the same method, so the idea is to just have each plugin call
the previous 'transaction_begin()'. The next problem is where do you save the
previous value? Most objects have a 'module_contexts' array for storing
per-plugin pointers for this purpose. There are several helper functions to
make setting and accessing them in a quite safe way.
Easiest way to set up the module context is to just copy&paste code from an
existing plugin that sets the same context. Here's some documentation about it
anyway:
First you start by creating register for the plugin. There are different
registers for different types of objects:
* mail_user_module_register: For mail_user.
* mailbox_list_module_register: For mailbox_list.
* mail_storage_module_register: For mail_storage, mailbox, mailbox_transaction
and mail_search.
* mail_module_register: For mail.
We'll assume you want to use mail_storage_module_register:
---%<-------------------------------------------------------------------------
static MODULE_CONTEXT_DEFINE_INIT(plugin_storage_module,
&mail_storage_module_register);
---%<-------------------------------------------------------------------------
If you need to make it external, use:
---%<-------------------------------------------------------------------------
extern MODULE_CONTEXT_DEFINE(plugin_storage_module,
&mail_storage_module_register);
struct plugin_storage_module plugin_storage_module =
MODULE_CONTEXT_INIT(&mail_storage_module_register);
---%<-------------------------------------------------------------------------
Next you'll need to allocate memory for the structure you want to place in the
context. If you only want to override some methods, you can use:
---%<-------------------------------------------------------------------------
union mailbox_module_context *mbox;
struct mailbox_vfuncs *v = box->vlast;
mbox = p_new(box->pool, union mailbox_module_context, 1);
mbox->super = *v;
box->vlast = &mbox->super;
v->transaction_begin = plugin_transaction_begin;
MODULE_CONTEXT_SET_SELF(box, plugin_storage_module, mbox);
---%<-------------------------------------------------------------------------
If you want to store some more plugin-specific data to the object instead of
just the super methods, you can do:
---%<-------------------------------------------------------------------------
struct plugin_mailbox {
/* must be called module_ctx */
union mailbox_module_context module_ctx;
};
/* .. */
struct plugin_mailbox *mbox;
struct mailbox_vfuncs *v = box->vlast;
mbox = p_new(box->pool, struct plugin_mailbox, 1);
mbox->module_ctx.super = *v;
box->vlast = &mbox->super;
v->transaction_begin = plugin_transaction_begin;
MODULE_CONTEXT_SET(box, plugin_storage_module, mbox);
---%<-------------------------------------------------------------------------
Note that when using union directly you use 'MODULE_CONTEXT_SET_SELF()', while
when it's inside a struct you use 'MODULE_CONTEXT_SET()'.
Once all this initialization is done, you can look up the module context with:
---%<-------------------------------------------------------------------------
#define PLUGIN_CONTEXT(obj) MODULE_CONTEXT(obj, plugin_storage_module)
/* .. */
struct plugin_mailbox *mbox = PLUGIN_CONTEXT(box);
---%<-------------------------------------------------------------------------
(Yes, this API seems a bit too difficult to use and could use a redesign.)
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Director.txt 0000666 00000012512 15050120373 0010024 0 ustar 00 Director
========
Director can be used by
[PasswordDatabase.ExtraFields.Proxy.txt] to keep a temporary user -> mail
server mapping. As long as user has simultaneous connections, the user is
always redirected to the same server. Each proxy server is running its own
director process, and the directors are communicating the state to each others.
Directors are mainly useful for setups where all of the mail storage is seen by
all servers, such as with NFS or a cluster filesystem.
First test non-director proxying
--------------------------------
The director is simply a small add-on for Dovecot proxy. Before configuring
director, you should test that a simple proxying setup with static destination
server works. See the [PasswordDatabase.ExtraFields.Proxy.txt] page for
more information about how to configure it. If you have a simple setup, you can
test this easily using a static passdb:
---%<-------------------------------------------------------------------------
passdb {
driver = static
args = proxy=y host=10.2.0.20 nopassword=y
}
---%<-------------------------------------------------------------------------
Once finished testing, remember to remove the "host" field.
Servers
-------
You need one or more servers assigned for Dovecot proxies. The same servers
could also act as backends handling the mails, but you need to run [RunningDovecot.txt] in different ports. This
may get a bit confusing, so it's not recommended.
The directors are going to connect to each others in a ring. For example if you
have servers called A, B and C, director will create connections A->B, B->C and
C->A.
Director configuration
----------------------
In example configuration you can configure director from
'conf.d/10-director.conf'.
Listeners
---------
Configure the listeners that director requires:
---%<-------------------------------------------------------------------------
service director {
unix_listener login/director {
mode = 0666
}
fifo_listener login/proxy-notify {
mode = 0666
}
unix_listener director-userdb {
mode = 0600
}
inet_listener {
port = 9090
}
}
---%<-------------------------------------------------------------------------
The port 9090 will be used for listening and connecting to other directors.
You're free to use any port number you want.
Configuring list of director servers
------------------------------------
List all of your directors in 'director_servers' setting separated by spaces.
You can use:
* IP addresses
* hostnames
* hostnames that expand to multiple IPs (e.g. you could have a "directors-all"
DNS entry that expands to all directors' IPs)
You can also add :port after the IP/host. The default port is the same as what
director service's inet_listener is using (the port 9090 above).
For example if you have 3 directors, you could set:
---%<-------------------------------------------------------------------------
director_servers = 10.1.0.2 10.1.0.3 10.1.0.4
---%<-------------------------------------------------------------------------
Configuring list of mail servers
--------------------------------
List all of your backend mail servers in 'director_mail_servers' setting
separated by spaces. You can use:
* IP addresses
* IP ranges (e.g. 10.2.0.10-10.2.0.30)
* hostnames
* hostnames that expand to multiple IPs
For example if you had 20 mail servers with consecutive IPs:
---%<-------------------------------------------------------------------------
director_mail_servers = 10.2.0.11-10.2.0.30
---%<-------------------------------------------------------------------------
Enabling director
-----------------
Enable director for the wanted login services by telling them to connect to
director socket instead of the default login socket:
---%<-------------------------------------------------------------------------
service imap-login {
executable = imap-login director
}
service pop3-login {
executable = pop3-login director
}
---%<-------------------------------------------------------------------------
If you want to enable director for LMTP, also set:
---%<-------------------------------------------------------------------------
lmtp_proxy = yes
protocol lmtp {
auth_socket_path = director-userdb
}
---%<-------------------------------------------------------------------------
Passdb configuration
--------------------
Your passdb must return "proxy"
[PasswordDatabase.ExtraFields.txt], otherwise director doesn't do anything.
Director works by adding a "host" extra field to the auth reply, which contains
the temporary destination mail server. This "host" field isn't added if the
passdb lookup already returns "host". This allows configuring some users to be
always proxied to a specific server.
If the backend servers verify password, you can use static passdb for director:
---%<-------------------------------------------------------------------------
passdb {
driver = static
args = proxy=y nopassword=y
}
---%<-------------------------------------------------------------------------
Health monitoring of backend servers
------------------------------------
Brad Davidson has written a small daemon for monitoring backend servers, and
disable/enable them on demand.
Ref:http://www.dovecot.org/list/dovecot/2010-August/051946.html
(This file was created from the wiki on 2011-01-13 04:52)
wiki/SharedMailboxes.Shared.txt 0000666 00000023156 15050120373 0012536 0 ustar 00 Mailbox sharing between users
=============================
To enable mailbox sharing, you'll need to create a shared namespace. See
for more information about ACL-specific settings.
---%<-------------------------------------------------------------------------
# User's private mail location.
mail_location = maildir:~/Maildir
# When creating any namespaces, you must also have a private namespace:
namespace {
type = private
separator = /
prefix =
#location defaults to mail_location.
inbox = yes
}
namespace {
type = shared
separator = /
prefix = shared/%%u/
location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u
subscriptions = no
list = children
}
mail_plugins = acl
protocol imap {
mail_plugins = $mail_plugins imap_acl
}
plugin {
acl = vfile
}
---%<-------------------------------------------------------------------------
This creates a shared/ namespace under which each user's mailboxes are. If you
have multiple domains and allow sharing between them, you might want to set
'prefix=shared/%%d/%%n/' instead (although %%u works just fine too). If you
don't, you might want to drop the domain part and instead use
'prefix=shared/%%n/'.
'list=children' specifies that if no one has shared mailboxes to the user, the
"shared" directory isn't listed by the LIST command. If you wish it to be
visible always, you can set 'list=yes'.
The 'location' setting specifies how to access other users' mailboxes. If you
use %%h, the user's home directory is asked from auth process via auth-userdb
socket. See for how to configure the socket. If the users' mailboxes
can be found using a template, it's faster not to use the %%h. For example:
---%<-------------------------------------------------------------------------
location = maildir:/var/mail/%%d/%%n/Maildir:INDEX=~/Maildir/shared/%%u
---%<-------------------------------------------------------------------------
% vs %%
-------
%var expands to the logged in user's variable, while %%var expands to the other
users' variables. For example if your name is "myself" and "someone1" and
"someone2" have shared mailboxes to you, the variables could be expanded like:
* %u expands to "myself"
* %%u expands to "someone1" or "someone2"
* %h might expand to "/home/myself"
* %%h might expand to "/home/someone1" or "/home/someone2"
* ~/ equals %h/
Note that in e.g. mail_location setting you might need both. For example in:
---%<-------------------------------------------------------------------------
mail_location = maildir:%%h/Maildir:INDEX=%h/Maildir/shared/%%u
---%<-------------------------------------------------------------------------
What it means is:
* %%h/Maildir points to the other user's Maildir, e.g. "/home/someone1".
* :INDEX=%h/Maildir/shared/%%u points to a per-user directory under your own
Maildir, e.g. "/home/myself/Maildir/someone1" or
"/home/myself/Maildir/someone2". This is necessary to keep a local copy of
the other users' index files.
dbox
----
With dbox the index files are a very important part of the mailboxes. You must
not try to :INDEX= to have copies of index files. This will only result in
mailbox corruption. This also means that with dbox there's currently no way to
have private \Seen flags.
Filesystem permissions
----------------------
Dovecot assumes that it can access the other users' mailboxes. If you use
multiple UNIX UIDs, you may have problems setting up the permissions so that
the mailbox sharing works. Dovecot never modifies existing files' permissions.
See for more information.
Shared mailbox listing
----------------------
With the above configuration it's possible to open shared mailboxes if you know
their name, but they won't be visible in the mailbox list. This is because
Dovecot has no way of knowing what users have shared mailboxes to whom.
Iterating through all users and looking inside their mail directories would be
horribly inefficient for more than a couple users.
To overcome this problem Dovecot needs a dictionary, which contains the list of
users who have shared mailboxes and to whom they have shared. If the users
aren't properly listed in this dictionary, their shared mailboxes won't be
visible. Currently there's no way to automatically rebuild this dictionary, so
make sure it doesn't get lost. If it does, each user having shared mailboxes
must use the IMAP SETACL command (see below) to get the dictionary updated for
themselves.
You could use any dictionary backend, including SQL, but a simple flat file
should work pretty well too:
---%<-------------------------------------------------------------------------
plugin {
acl_shared_dict = file:/var/lib/dovecot/shared-mailboxes.db
}
---%<-------------------------------------------------------------------------
If you use multiple domains and don't wish users to share their mailboxes to
users in other domains, you can use separate dict files for each domain:
---%<-------------------------------------------------------------------------
plugin {
# assumes mailboxes are in /var/mail/%d/%n:
acl_shared_dict = file:/var/mail/%d/shared-mailboxes.db
}
---%<-------------------------------------------------------------------------
Using SQL dictionary
--------------------
'dovecot.conf':
---%<-------------------------------------------------------------------------
plugin {
acl_shared_dict = proxy::acl
}
dict {
acl = pgsql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
---%<-------------------------------------------------------------------------
See for more information, especially about permission issues.
Database tables:
---%<-------------------------------------------------------------------------
CREATE TABLE user_shares (
from_user varchar(100) not null,
to_user varchar(100) not null,
dummy char(1) DEFAULT '1', -- always '1' currently
primary key (from_user, to_user)
);
COMMENT ON TABLE user_shares IS 'User from_user shares folders to user
to_user.';
CREATE TABLE anyone_shares (
from_user varchar(100) not null,
dummy char(1) DEFAULT '1', -- always '1' currently
primary key (from_user)
);
COMMENT ON TABLE anyone_shares IS 'User from_user shares folders to anyone.';
---%<-------------------------------------------------------------------------
'/etc/dovecot/dovecot-dict-sql.conf.ext':
---%<-------------------------------------------------------------------------
connect = host=localhost dbname=mails user=sqluser password=sqlpass
map {
pattern = shared/shared-boxes/user/$to/$from
table = user_shares
value_field = dummy
fields {
from_user = $from
to_user = $to
}
}
map {
pattern = shared/shared-boxes/anyone/$from
table = anyone_shares
value_field = dummy
fields {
from_user = $from
}
}
---%<-------------------------------------------------------------------------
IMAP ACL commands
-----------------
Mailbox sharing is expected to be done using IMAP SETACL command. It is the
only way to update the shared mailbox list dictionary.
Below is a quick introduction to IMAP ACL commands. See RFC 4314
[http://www.ietf.org/rfc/rfc4314.txt] for more details.
* MYRIGHTS : Returns the user's current rights to the mailbox.
* GETACL : Returns the mailbox's all ACLs.
* SETACL [+|-]: Give the specified rights to the
mailbox.
* DELETEACL [-]: Delete 's ACL from the mailbox.
is one of:
* anyone: Matches all users, including anonymous users.
* authenticated: Like "anyone", but doesn't match anonymous users.
* $group: Matches all users belonging to the group ($ is not part of the group
name).
* $!group: See group-override in (Dovecot-specific feature).
* user: Matches the given user.
The $group syntax is not a standard, but it is mentioned in RFC 4314 examples
and is also understood by at least Cyrus IMAP. Having '-' before the identifier
specifies negative rights.
See for list of .
Sharing mailboxes to everyone
-----------------------------
By default Dovecot doesn't allow using the IMAP "anyone" or "authenticated"
identifier, because it would be an easy way to spam other users in the system.
If you wish to allow it, set:
---%<-------------------------------------------------------------------------
plugin {
acl_anyone = allow
}
---%<-------------------------------------------------------------------------
Note that you can also do this only for some users by using the second table
"anyone_shares". Every user listed in this table shares his folders with
everyone. See also [UserDatabase.ExtraFields.txt].
IMAP ACL examples
-----------------
Let's begin with some simple example that first gives "read" and "lookup"
rights, and later adds "write-seen" right:
---%<-------------------------------------------------------------------------
1 SETACL Work user@domain rl
1 OK Setacl complete.
2 SETACL Work user@domain +s
2 OK Setacl complete.
3 GETACL Work
* ACL "Work" "user@domain" lrs "myself" lrwstipekxacd
3 OK Getacl completed.
---%<-------------------------------------------------------------------------
Let's see how negative rights work by testing it on ourself. See how we
initially have "lookup" right, but later we don't:
---%<-------------------------------------------------------------------------
1 MYRIGHTS Work
* MYRIGHTS "Work" lrwstipekxacd
1 OK Myrights completed.
2 SETACL Work -myself l
2 OK Setacl complete.
3 GETACL Work
* ACL "Work" "-myself" l "user@domain" lr "myself" lrwstipekxacd
3 OK Getacl completed.
4 myrights Work
* MYRIGHTS "Work" rwstipekxacd
4 OK Myrights completed.
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Plugins.FTS.Lucene.txt 0000666 00000001451 15050120373 0011537 0 ustar 00 Lucene Full Text Search Indexing
================================
The current Lucene implementation is a bit ugly and simultaneous access may
give some errors. Use [Plugins.FTS.Solr.txt] instead if possible.
Dovecot builds only a single Lucene index for all mailboxes. In future this
would allow support for searching messages quickly from all mailboxes. The
Lucene indexes are stored in 'lucene-indexes/' directory under the root index
directory (e.g.'~/Maildir/lucene-indexes/').
Configuration
-------------
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins fts fts_lucene
plugin {
fts = lucene
}
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/WhyDoesItNotWork.txt 0000666 00000004761 15050120373 0011463 0 ustar 00 Why doesn't Dovecot work?
=========================
* *Dovecot always logs an error message* if anything goes wrong, so make sure
you're looking at the correct log files. Debug messages may be written to a
different log file than error messages. See .
* Try logging in manually by sending IMAP commands. If you're trying with an
IMAP client you can't be sure if the problem is with the client's
configuration or Dovecot's configuration. Many IMAP clients handle all
errors simply by showing you the login password dialog, even if the problem
has nothing to do with authentication. See (or
).
* Are you using an older version than v1.0? RHEL 5.0 and Debian Etch
distribute v1.0.rc15, and there have been a LOT of fixes since then. If you
have a problem, see if NEWS [http://dovecot.org/doc/NEWS] file mentions
anything related to it. There are also
[PrebuiltBinaries.txt] available for newer versions.
It says "Authentication failed"
-------------------------------
First of all enable 'auth_debug_passwords=yes' and see if the logs show what
the problem is. For non-PAM setups it should contain all the information needed
to solve the problem. If it's trying to use a wrong password scheme, you can
change that. See .
If the client isn't even attempting to log in, you most likely have
'disable_plaintext_auth=yes' (default) and the client isn't configured to use
SSL/TLS (or you've also set 'ssl=no').
If you're using [PasswordDatabase.PAM.txt]:
* Make sure that dovecot-auth is running as root (assuming it's using
'/etc/shadow').
* PAM errors aren't written to Dovecot's own logs. Usually they go to
'/var/log/auth.log' or something similar.
* Unfortunately PAM's error messages aren't always all that helpful in
figuring out what exactly the problem is.
* You could (temporarily) try to use
[PasswordDatabase.Shadow.txt] instead to see if it logs something more
understandable.
* Usually the problem is that you don't have a correctly named file in
'/etc/pam.d/'. See .
It's not finding my emails
--------------------------
'mail_debug=yes' makes Dovecot log where it's really looking for mails. Also
'auth_debug=yes' may be helpful in debugging. See for how to
configure where the mails are looked up from.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/LDA.txt 0000666 00000030243 15050120373 0006652 0 ustar 00 Dovecot LDA
===========
The Dovecot LDA is a [MDA.txt], which takes mail from an
and delivers it to a user's mailbox, while keeping Dovecot index
files up to date. An alternative is to use [LMTP.txt], but most
of the configuration between them is identical.
This page describes the common settings required to make LDA work. You should
read it first, and then the MTA specific pages:
*
*
*
*
*
Main features of Dovecot LDA
----------------------------
* [LDA.Indexing.txt], providing faster
mailbox access later
* [Quota.txt]
* [Pigeonhole.Sieve.txt]
* Mail filtering
* Mail forwarding
* Vacation auto-reply
Common configuration
--------------------
The configuration is done in the /protocol lda/ section in 'dovecot.conf'. The
important settings are:
* 'postmaster_address' is used as the From: header address in bounce mails
* 'hostname' is used in generated Message-IDs and in Reporting-UA: header in
bounce mails
* 'sendmail_path' is used to send mails. Note that the default is
'/usr/lib/sendmail', which doesn't necessarily work the same as
'/usr/sbin/sendmail'.
* 'auth_socket_path' specifies the UNIX socket to auth-userdb where LDA can
lookup userdb information when '-d' parameter is used. See below how to
configure Dovecot to configure the socket.
Note that 'dovecot.conf' file must be world readable to enable dovecot-lda
process read it, while running with user privileges.
Parameters
----------
Parameters accepted by dovecot-lda:
* '-d ': Destination username. If given, the user information is
looked up from dovecot-auth. Typically used with virtual users, but not
necessarily with system users.
* '-a ': Original envelope recipient address (e.g. user+ext@domain),
typically same as SMTP's RCPT TO: value. If not specified, it's taken from
header specified by 'lda_original_recipient_header' setting (v2.0.3+). If
the header doesn't exist either, defaults to same as username.
* '-r ': Final envelope recipient address. Defaults to -a address,
but may differ if e.g. aliases are used or when dropping the +ext part.
(v2.0.3+)
* '-f ': Envelope sender address. If not specified and message data
begins with a valid mbox-style "From " line, the address is taken from it.
* '-c ': Alternative configuration file path.
* '-m ': Destination mailbox (default is INBOX). If the mailbox
doesn't exist, it will not be created (unless the lda_mailbox_autocreate
setting is set to yes). If message couldn't be saved to the mailbox for any
reason, it's delivered to INBOX instead.
* If Sieve plugin is used, this mailbox is used as the "keep" action's
mailbox. It's also used if there is no Sieve script or if the script
fails for some reason.
* Deliveries to namespace prefix will result in saving the mail to INBOX
instead. For example if you have "Mail/" namespace, this allows you to
specify 'dovecot-lda -m Mail/$mailbox' where mail is stored to
Mail/$mailbox or to INBOX if $mailbox is empty.
* The mailbox name is specified the same as it's visible in IMAP client.
For example if you've a Maildir with '.box.sub/' directory and your
namespace configuration is 'prefix=INBOX/', 'separator=/', the correct
way to deliver mail there is to use '-m INBOX/box/sub'
* '-e': If mail gets rejected, write the rejection reason to stderr and exit
with EX_NOPERM. The default is to send a rejection mail ourself.
* '-k': Don't clear all environment at startup.
* '-p ': Path to the mail to be delivered instead of reading from stdin.
If using maildir the file is hard linked to the destination if possible.
This allows a single mail to be delivered to multiple users using hard
links, but currently it also prevents dovecot-lda from updating cache file
so it shouldn't be used unless really necessary.
Return values
-------------
dovecot-lda will exit with one of the following values:
* 0 (EX_OK): Delivery was successful
* 64 (EX_USAGE): Invalid parameter given.
* 77 (EX_NOPERM): -e parameter was used and mail was rejected. Typically this
happens when user is over quota and 'quota_full_tempfail=no'.
* 75 (EX_TEMPFAIL): A temporary failure. This is returned for almost all
failures. See the log file for details.
System users
------------
You can use LDA with a few selected system users (ie. user is found from
'/etc/passwd' / NSS) by calling dovecot-lda in the user's '~/.forward' file:
---%<-------------------------------------------------------------------------
| "/usr/local/libexec/dovecot/dovecot-lda"
---%<-------------------------------------------------------------------------
This should work with any MTA which supports per-user '.forward' files. For
qmail's per-user setup, see .
This method doesn't require the authentication socket explained below since
it's executed as the user itself.
Virtual users
-------------
With a lookup
-------------
Give the destination username to dovecot-lda with '-d' parameter, for example:
---%<-------------------------------------------------------------------------
dovecot-lda -f $FROM_ENVELOPE -d $DEST_USERNAME
---%<-------------------------------------------------------------------------
You'll need to set up a auth-userdb socket for dovecot-lda so it knows where to
find mailboxes for the users:
---%<-------------------------------------------------------------------------
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail # User running dovecot-lda
#group = vmail # Or alternatively mode 0660 + dovecot-lda user in this
group
}
}
---%<-------------------------------------------------------------------------
The auth-userdb socket can be used to do [UserDatabase.txt] lookups
for given usernames or get a list of all users. Typically the result will
contain the user's UID, GID and home directory, but depending on your
configuration it may return other information as well. So the information is
similar to what can be found from eg.'/etc/passwd' for system users. This means
that it's probably not a problem to use mode=0666 for the socket, but you
should try to restrict it more just to be safe.
Without a lookup
----------------
If you have already looked up the user's home directory and you don't need a
userdb lookup for any other reason either (such as overriding settings for
specific users), you can run dovecot-lda similar to how it's run for system
users:
---%<-------------------------------------------------------------------------
HOME=/path/to/user/homedir dovecot-lda -f $FROM_ENVELOPE
---%<-------------------------------------------------------------------------
This way you don't need to have a master listener socket. Note that you should
verify the user's existence prior to running dovecot-lda, otherwise you'll end
up having mail delivered to nonexistent users as well.
You must have set the proper UID (and GID) before running dovecot-lda. It's not
possible to run dovecot-lda as root without '-d' parameter.
Multiple UIDs
-------------
If you're using more than one UID for users, you're going to have problems
running dovecot-lda, as most MTAs won't let you run dovecot-lda as root. Best
solution is to use instead, but if you can't do that, there are two
ways to work around this problem:
1. Make dovecot-lda setuid-root.
2. Use sudo to wrap the invocation of dovecot-lda.
Making dovecot-lda setuid-root:
-------------------------------
Beware: *it's insecure to make dovecot-lda setuid-root*, especially if you have
untrusted users in your system.*Setuid-root dovecot-lda can be used to gain
root privileges*. You should take extra steps to make sure that untrusted users
can't run it and potentially gain root privileges. You can do this by making
sure only your MTA has execution access to it. For example:
---%<-------------------------------------------------------------------------
# chgrp secmail /usr/local/libexec/dovecot/dovecot-lda
# chmod 04750 /usr/local/libexec/dovecot/dovecot-lda
# ls -l /usr/local/libexec/dovecot/dovecot-lda
-rwsr-x--- 1 root secmail 4023932 2010-06-15 16:23 dovecot-lda
---%<-------------------------------------------------------------------------
Then start dovecot-lda as a user that belongs to secmail group. Note that you
have to recreate these rights after each update of dovecot.
Using sudo:
-----------
Alternatively, you can use sudo to wrap the invocation of dovecot-lda. This has
the advantage that updates will not clobber the setuid bit, but note that *it
is just as insecure being able to run dovecot-lda via sudo as setuid-root*.
Make sure you only give your MTA the ability to invoke dovecot-lda via sudo.
First configure sudo to allow 'dovelda' user to invoke dovecot-lda by adding
the following to your '/etc/sudoers':
---%<-------------------------------------------------------------------------
Defaults:dovelda !syslog
dovelda ALL=NOPASSWD:/usr/local/libexec/dovecot/dovecot-lda
---%<-------------------------------------------------------------------------
Then configure your MTA to invoke dovecot-lda as user 'dovelda' and via sudo:
---%<-------------------------------------------------------------------------
/usr/bin/sudo /usr/local/libexec/dovecot/dovecot-lda
---%<-------------------------------------------------------------------------
instead of just plain '/usr/local/libexec/dovecot/dovecot-lda'.
Problems with dovecot-lda
-------------------------
* If you are using [UserDatabase.Prefetch.txt], keep in mind
that 'dovecot-lda' does not make a password query and thus will not work if
'-d' parameter is used. The page explains how to
fix this.
* See [PasswordDatabase.CheckPassword.txt] for how to make
dovecot-lda work with checkpassword.
Logging
-------
* Normally Dovecot logs everything through its log process, which is running
as root. dovecot-lda doesn't, which means that you might need some special
configuration for it to log anything at all.
* If dovecot-lda fails to write to log files it exits with temporary failure.
* If you have trouble finding where Dovecot logs by default, see
.
* Note that Postfix's 'mailbox_size_limit' setting applies to all files that
are written to. So if you have a limit of 50 MB, dovecot-lda can't write to
log files larger than 50 MB and you'll start getting temporary failures.
If you want dovecot-lda to keep using Dovecot's the default log files:
* If you're logging to syslog, make sure the syslog socket (usually
'/dev/log') has enough write permissions for dovecot-lda. For example set it
world-read/writable:'chmod a+rw /dev/log'.
* If you're logging to Dovecot's default log files again you'll need to give
enough write permissions to the log files for dovecot-lda.
You can also specify different log files for dovecot-lda. This way you don't
have to give any extra write permissions to other log files or the syslog
socket. You can do this by overriding the 'log_path' and 'info_log_path'
settings:
---%<-------------------------------------------------------------------------
protocol lda {
..
# remember to give proper permissions for these files as well
log_path = /var/log/dovecot-lda-errors.log
info_log_path = /var/log/dovecot-lda.log
}
---%<-------------------------------------------------------------------------
For using syslog with dovecot-lda, set the paths empty:
---%<-------------------------------------------------------------------------
protocol lda {
..
log_path =
info_log_path =
# You can also override the default syslog_facility:
#syslog_facility = mail
}
---%<-------------------------------------------------------------------------
Plugins
-------
* Most of the [Plugins.txt] work with dovecot-lda.
* Virtual quota can be enforced using [Quota.txt].
* Sieve language support can be added with the
[Pigeonhole.Sieve.txt].
(This file was created from the wiki on 2011-01-13 04:52)
wiki/SharedMailboxes.txt 0000666 00000001242 15050120373 0011321 0 ustar 00 Shared mailboxes
================
Dovecot can support mailbox sharing in several different ways:
* [SharedMailboxes.Public.txt]: Shared mailboxes created by
administrators (ACLs can still restrict who sees them)
* [SharedMailboxes.Shared.txt]: Users sharing their
mailboxes to other users (using IMAP ACL commands) (v1.2+)
* [SharedMailboxes.Symlinks.txt]: Quick and dirty way
of sharing a few mailboxes.
See for common filesystem related permission
problems that are common with all the sharing methods.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/HowTo.EximAndDovecotSASL.txt 0000666 00000002064 15050120373 0012645 0 ustar 00 Exim and Dovecot SASL
=====================
Exim v4.64+ users can use Dovecot SASL instead of Cyrus SASL for authenticating
SMTP clients.
conf.d/10-master.conf
---------------------
---%<-------------------------------------------------------------------------
service auth {
...
#SASL
unix_listener auth-client {
mode = 0660
user = mail
}
...
}
---%<-------------------------------------------------------------------------
exim.conf
---------
Create authenticators for Dovecot:
---%<-------------------------------------------------------------------------
dovecot_login:
driver = dovecot
public_name = LOGIN
server_socket = /var/run/dovecot/auth-client
# setting server_set_id might break several headers in mails sent by
authenticated smtp. So be careful.
server_set_id = $auth1
dovecot_plain:
driver = dovecot
public_name = PLAIN
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
---%<-------------------------------------------------------------------------
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Quota.Maildir.txt 0000666 00000004473 15050120373 0010731 0 ustar 00 Maildir++ quota
===============
Maildir++ is the most commonly used quota backend with Maildir format. Note
that *Maildir++ quota works only with Maildir format*. With other mailbox
formats you should use [Quota.Dict.txt]. Dovecot
implements the standard Maildir++ specification
[http://www.inter7.com/courierimap/README.maildirquota.html], so it's
compatible with Courier [http://www.courier-mta.org/], maildrop
[http://www.courier-mta.org/maildrop/], Exim [http://www.exim.org], etc.
There are two ways to configure Maildir++ quota limits:
1. Configure the limits in Dovecot. You most likely want to do this. See
[Quota.txt] for how to do this configuration.
2. Make Dovecot get the limits from existing 'maildirsize' files.
Only Maildir++-specific settings are described below. See for more
generic configuration.
Maildir++ quota relies on 'maildirsize' file having correct information, so if
your users can modify the file in some way (e.g. shell access), you're relying
on the goodwill of your users for the quota to work.
You can't rely on Dovecot noticing external changes to Maildir and updating
maildirsize accordingly. This happens eventually when quota is being
recalculated, but it may take a while. Quota recalculation also currently
doesn't trigger quota warning executions.
Maildirsize file
----------------
The 'maildirsize' file in the Maildir root directory contains both the quota
limit information and the current quota status. It contains a header in format:
---%<-------------------------------------------------------------------------
S,C
---%<-------------------------------------------------------------------------
If you don't configure any quota limits in Dovecot ('quota=maildir' with no
other settings), Dovecot takes the limits from the header. If the file does not
exist, quota isn't enforced.
If you configure quota limits in Dovecot, Dovecot makes sure that this header
is kept up to date. If the file does not exist, it's simply rebuilt.
Once the 'maildirsize' reaches 5120 bytes, the quota is recalculated and the
file is recreated. This makes sure that if quota happens to be broken (e.g.
externally deleted files) it won't stay that way forever.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/PasswordDatabase.ExtraFields.AllowNets.txt 0000666 00000001107 15050120373 0015616 0 ustar 00 Allow_nets extra field
----------------------
This is a comma separated list of IPs and/or networks where the user is allowed
to log in from. If the user tries to log in elsewhere, the authentication will
fail the same way as if a wrong password was given.
Example: 'allow_nets=127.0.0.0/8,192.168.0.0/16,1.2.3.4,4.5.6.7'.
IPv6 addresses are also allowed. IPv6 mapped IPv4 addresses (eg.
'::ffff:1.2.3.4') are converted to standard IPv4 addresses before matching.
Example:'allow_nets=::1,2001:abcd:abcd::0:0/80,1.2.3.4'
(This file was created from the wiki on 2011-01-13 04:52)
wiki/OSCompatibility.txt 0000666 00000003140 15050120373 0011321 0 ustar 00 Operating System Compatibility
==============================
Dovecot is commonly used with Linux, Solaris, FreeBSD, OpenBSD, NetBSD and Mac
OS X. The following operating systems have also worked at least at some point
in Dovecot's existence:
* BSD/OS 4.2
* AIX 4.3
* HP-UX 11i (Dovecot v1.1+)
* Tru64 ?.?
* 7.1.4
* IRIX 6.5 compiles, but SCM_RIGHTS seems to be broken.
* Cygwin apparently doesn't work nowadays.
* MidnightBSD (ports)
If there are compiling problems with any OS, please send a bug report that
includes the error messages.
SCM_RIGHTS
----------
There is one slightly problematic feature that Dovecot requires for
implementing privilege separation:*SCM_RIGHTS*. If it doesn't work correctly,
you'll get errors on 'fd_send()' or 'fd_read()' such as:
---%<-------------------------------------------------------------------------
imap-login: fd_send(X) failed: Bad file number
---%<-------------------------------------------------------------------------
If this happens, you can still use inetd and mailfront
[http://untroubled.org/mailfront/], which executes Dovecot's post-login IMAP or
POP3 binary. You can also try defining 'BUGGY_CMSG_MACROS' in
'src/lib/fdpass.c' to see if it helps.
Compilers
---------
Dovecot should compile with any ANSI-C99 compiler. Dovecot has been known to
compile (at least once in its lifetime) with the following compilers:
* GCC
* Intel CC [http://www.intel.com/software/products/compilers/clin/]
* Tiny CC [http://www.tinycc.org]
* Sun Studio 11
* Sun Studio 12
* AIX xlC
* HP-UX cc
(This file was created from the wiki on 2011-01-13 04:52)
wiki/SharedMailboxes.Permissions.txt 0000666 00000014371 15050120373 0013642 0 ustar 00 Filesystem permissions in shared mailboxes
==========================================
IMAP processes need filesystem level permissions to access shared/public
mailboxes. This means that:
* If you use more than one [UserIds.txt] for your mail users (e.g.
you use system users), you'll need to make sure that all users can access
the mailboxes on filesystem level. ( [ACL.txt] won't help you
with this.)
* You can remove write permissions on purpose from public namespace root
directory to prevent users from creating new mailboxes under it.
Dovecot never modifies permissions for existing mail files or directories. When
users share mailboxes between each others, the system must have been set up in
a way that filesystem permissions don't get in the way. The easiest way to do
that is to use only a single UID. Another possibility would be to use one or
more groups for all the mail files that may be shared to other users belonging
to the same group. For example if you host multiple domains, you might create a
group for each domain and allow mailbox sharing (only) between users in the
same domain.
System user UNIX groups
-----------------------
There's no requirement to use UNIX groups (i.e. typically defined in
'/etc/group') for anything. If you don't care about them, you can safely ignore
this section.
If you use [AuthDatabase.Passwd.txt] userdb, the IMAP process has
access to all the UNIX groups defined for that user. You may use these groups
when granting filesystem permissions. If you wish to use UNIX groups defined in
'/etc/group' but don't use passwd userdb, you can still do this by returning
'system_groups_user' [UserDatabase.ExtraFields.txt], which
contains the UNIX user name whose groups are read from the group file.
You can also set up extra UNIX groups by listing them in 'mail_access_groups'
setting. To have per-user UNIX groups, return 'mail_access_groups' as userdb
extra field. The advantage of using this method is that only Dovecot mail
processes have access to the group, but nothing else, such as user's SSH
session. For example a simple way to set up shared mailbox access for all
system users is to make all mail dirs/files 0770/0660 mode and owned by group
"sharedmail" and then set 'mail_access_groups=sharedmail'. Using more fine
grained groups of course leaks less mail data in case there's a security hole
in Dovecot.
Permissions for new mailboxes
-----------------------------
When creating a new mailbox, Dovecot copies the permissions from the mailbox
root directory. For example with mboxes if you have directories:
---%<-------------------------------------------------------------------------
drwx--xr-x 8 user group 4096 2009-02-21 18:31 /home/user/mail/
drwxrwxrwx 2 user group 4096 2009-02-21 18:32 /home/user/mail/foo/
---%<-------------------------------------------------------------------------
When creating a new foo/bar/ directory, Dovecot gives it permissions:
---%<-------------------------------------------------------------------------
drwx--xr-x 2 user group 4096 2009-02-21 18:33 /home/usermail/foo/bar/
---%<-------------------------------------------------------------------------
As you can see, the file mode was copied from mail/ directory, not mail/foo/.
The group is also preserved. If this causes problems (e.g. different users
having different groups create mailboxes, causing permission denied errors when
trying to preserve the group) you can set the setgid bit for the root
directory:
---%<-------------------------------------------------------------------------
chmod g+s /home/user/mail
---%<-------------------------------------------------------------------------
This will cause the group to be automatically copied by the OS for all created
files/directories under it, even if the user doesn't belong to the group.
Permissions for new files in mailboxes
--------------------------------------
When creating new files inside a mailbox, Dovecot copies the read/write
permissions from the mailbox's directory. For example if you have:
---%<-------------------------------------------------------------------------
drwx--xr-x 5 user group 4096 2009-02-21 18:53 /home/user/Maildir/.foo/
---%<-------------------------------------------------------------------------
Dovecot creates files under it with modes:
---%<-------------------------------------------------------------------------
drwx--xr-x 2 user group 4096 2009-02-21 18:54 cur/
drwx--xr-x 2 user group 4096 2009-02-21 18:54 new/
drwx--xr-x 2 user group 4096 2009-02-21 18:54 tmp/
-rw----r-- 1 user group 156 2009-02-21 18:54 dovecot.index.log
-rw----r-- 1 user group 17 2009-02-21 18:54 dovecot-uidlist
---%<-------------------------------------------------------------------------
Note how the g+x gets copied to directories, but for files it's simply ignored.
The group is copied the same way as explained in the previous section.
When mails are copied between Maildirs, it's usually done by hard linking. If
the source and destination directory permissions are different, Dovecot create
a new file and copies data the slow way so that it can assign the wanted
destination permissions. The source and destination permission lookups are done
only by looking at the mailbox root directories' permissions, not individual
mail files. This may become a problem if the mail files' permissions aren't as
Dovecot expects.
Mail Delivery Agent permissions
-------------------------------
When using Dovecot , it uses all the same configuration files as
IMAP/POP3, so you don't need to worry about it.
When using an external MDA to deliver to a shared mailbox, you need to make
sure that the resulting files have proper permissions. For example with
Procmail + Maildir, set 'UMASK=007' in '.procmailrc' to make the delivered mail
files group-readable. To get the file to use the proper group, set the group to
the Maildir's 'tmp/' directory and also set its setgid bit ('chmod g+s').
Dictionary files
----------------
Created dictionary files (e.g. 'acl_shared_dict = file:...') also base their
initial permissions on parent directory's permissions. After the initial
creation, the permissions are permanently preserved. So if you want to use
different permissions, just chown/chmod the file.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Quota.txt 0000666 00000006120 15050120373 0007340 0 ustar 00 Quota
=====
Quota backend specifies the method how Dovecot keeps track of the current quota
usage. They don't (usually) specify users' quota limits, that's done by
returning extra fields from userdb. There are different quota backends that
Dovecot can use:
* [Quota.FS.txt]: Filesystem quota.
* [Quota.Dirsize.txt]: The simplest and slowest quota backend, but
it works quite well with mboxes.
* [Quota.Dict.txt]: Store quota usage in a dictionary (e.g. SQL).
* [Quota.Maildir.txt]: Store quota usage in Maildir++ maildirsize
files. This is the most commonly used quota for virtual users.
Enabling quota plugins
----------------------
There are two quota related plugins:
* quota: Implements the actual quota handling and includes also all the quota
backends.
* imap_quota: For reporting quota information via IMAP.
Enable them in configuration files, e.g.:
conf.d/10-mail.conf:
---%<-------------------------------------------------------------------------
# Space separated list of plugins to load for all services. Plugins specific to
# IMAP, LDA, etc. are added to this list in their own .conf files.
mail_plugins = $mail_plugins quota
---%<-------------------------------------------------------------------------
conf.d/20-imap.conf:
---%<-------------------------------------------------------------------------
protocol imap {
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins imap_quota
}
---%<-------------------------------------------------------------------------
Configuration
-------------
See for backend-independent quota configuration.
Quota recalculation
-------------------
If your quotas are out of sync, you can use 'doveadm quota recalc' command to
recalculate them.
Quota and Trash mailbox
-----------------------
Standard way to expunge messages with IMAP works by:
1. Marking message with \Deleted flag
2. Actually expunging the message using EXPUNGE command
Both of these commands can be successfully used while user's quota is full.
However many clients use a "move-to-Trash" feature, which works by:
1. COPY the message to Trash mailbox
2. Mark the message with \Deleted
3. Expunge the message from the original mailbox.
4. (Maybe later expunge the message from Trash when "clean trash" feature is
used)
If user is over quota (or just under it), the first COPY command will fail and
user may get an unintuitive message about not being able to delete messages
because user is over quota. The possible solutions for this are:
* Disable move-to-trash feature from client
* You can create a separate quota rule ignoring Trash mailbox's quota. Note
that this would allow users to store messages infinitely to the mailbox.
* You can create a separate quota rule giving Trash mailbox somewhat higher
quota limit (but not unlimited).
To make sure users don't start keeping messages permanently in Trash you can
use a nightly [Plugins.Expire.txt] to expunge old messages from Trash
mailbox.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Storage.MailboxList.txt 0000666 00000017240 15050120373 0013316 0 ustar 00 Mailbox List
============
'src/lib-storage/mailbox-list.h' and 'mailbox-list-private.h' describes mailbox
list. The purpose of mailbox list is to manage mailbox storage name<-> physical
directory path mapping. Its most important functions are:
* listing existing mailboxes,
* creating directories for new mailboxes (but not the mailboxes themselves,
that's storage's job),
* deleting mailboxes,
* renaming mailboxes and
* managing mailbox subscriptions.
Mailbox list code also internally creates and updates mailbox changelog (in
'dovecot.mailbox.log' file), which keeps track of mailbox deletions, renames
and subscription changes. This is primarily useful for dsync utility.
Mailbox list is configured by [MailLocation.txt] setting, which
fills 'struct mailbox_list_settings':
* root_dir: The root mail directory (e.g. with
'mail_location=maildir:~/Maildir' it would be the '~/Maildir').
* index_dir: Directory under which index files are written to. Empty string
means in-memory indexes. Defaults to root_dir.
* control_dir: Directory under which control files are written to. Control
files are files that contain some important metadata information about
mailbox so (unlike index files) they should never be deleted. For example
subscriptions file is a control file. Defaults to root_dir.
* alt_dir: This is currently [MailboxFormat.dbox.txt]-specific setting.
* inbox_path: Path to INBOX mailbox. This exists mainly because with mbox
format INBOX is often in a different location than other mailboxes.
* subscription_fname: Filename used by subscriptions file.
* dir_guid_fname: Filename used to store directories' (not mailboxes') global
UIDs. Directory GUIDs are mainly useful for dsync.
* maildir_name: Directory name under which the actual mailboxes are stored in,
such as dbox-Mails/ with dbox. See the .h file for more detailed
description.
* mailbox_dir_name: If non-empty, store all mailboxes under
root_dir/mailbox_dir_name/.
Listing mailboxes
-----------------
First the list operation is initialized with one of the init functions:
* 'mailbox_list_iter_init()' lists mailboxes that match the given pattern.
* 'mailbox_list_iter_init_multiple()' lists mailboxes that match any of the
given patterns list.
* 'mailbox_list_iter_init_namespaces()' lists matching mailboxes from all
namespaces.
* 'MAILBOX_LIST_ITER_SKIP_ALIASES' flag skips namespaces that have
'alias_for' set. You usually want to set this flag to avoid processing
the same mailbox multiple times.
The patterns are IMAP-style patterns with '%' and '*' wildcards as described by
RFC 3501: '%' matches only up to next hierarchy separator, while '*' matches
the rest of the string.
These flags control what mailboxes are returned:
* 'MAILBOX_LIST_ITER_NO_AUTO_INBOX' doesn't list INBOX unless it physically
exists. Normally INBOX is listed, because INBOX doesn't need to be (and
cannot be) explicitly created. It can always be opened and messages can be
saved to it, it's just automatically created when it doesn't exist.
* 'MAILBOX_LIST_ITER_SELECT_SUBSCRIBED' lists only subscribed mailboxes.
* 'MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH' is currently only useful when
combined with '_SELECT_SUBSCRIBED' flag. Then it adds
'MAILBOX_CHILD_SUBSCRIBED' flags for mailboxes whose children are
subscribed. It also lists mailboxes that aren't themselves subscribed, but
have children that do.
These flags control what is returned for matching mailboxes:
* 'MAILBOX_LIST_ITER_RETURN_NO_FLAGS' can be set when you don't care about
mailbox flags. They're then set only if it can be done without any
additional disk I/O.
* 'MAILBOX_LIST_ITER_RETURN_SUBSCRIBED' returns mailbox's subscription state.
* 'MAILBOX_LIST_ITER_RETURN_CHILDREN' sets "has child mailboxes" or "doesn't
have child mailboxes" flag.
Other flags:
* 'MAILBOX_LIST_ITER_RAW_LIST' should usually be avoided. It ignores ACLs and
just returns everything.
* 'MAILBOX_LIST_ITER_VIRTUAL_NAMES' enables listing to use virtual names
instead of storage names in patterns and returned mailbox names.
Once listing is initialized, 'mailbox_list_iter_next()' can be called until it
returns NULL. The returned mailbox_info struct contains:
* 'name': Mailbox's name, either virtual or storage name depending on
'_VIRTUAL_NAMES' flag.
* 'ns': Mailbox's namespace. This is useful only when mailboxes are listed
using 'mailbox_list_iter_init_namespaces()'.
* 'flags': Mailbox flags:
* 'MAILBOX_NOSELECT': Mailbox exists, but can't be selected. It's possible
that it can be created and then it becomes selectable. For example with
mbox and FS layout the directories aren't selectable mailboxes.
* 'MAILBOX_NONEXISTENT': Mailbox doesn't exist. It's listed only because it
has child mailboxes that do exist but don't match the pattern.
* Example: "foo/bar" exists, but "foo" doesn't. "%", "foo" or "*o"
pattern would list "foo", because it matches the pattern but its child
doesn't. Then again "*", "*bar" or "%/%" wouldn't list "foo", because
"foo/bar" matches the pattern (and is also listed). Something like
"*asd*" wouldn't match either "foo" or "foo/bar" so neither is
returned.
* 'MAILBOX_CHILDREN' and 'MAILBOX_NOCHILDREN': Mailbox has or doesn't have
children. If neither of these flags are set, it's not known if mailbox
has children.
* 'MAILBOX_NOINFERIORS': Mailbox doesn't have children and none can ever be
created. For example with mbox and FS layout the mailboxes have this flag
set, because files can't be created under files.
* 'MAILBOX_MARKED' and 'MAILBOX_UNMARKED': Mailbox has or doesn't have
messages with \Recent flags. If neither is set, the state is unknown.
Because this check is done in a very cheap way, having 'MAILBOX_MARKED'
doesn't always mean that there are \Recent flags. However, if
'MAILBOX_UNMARKED' is returned it is guaranteed to be correct. (False
positives are ok, false negatives are not ok.)
* 'MAILBOX_SUBSCRIBED': Mailbox is subscribed.
* 'MAILBOX_CHILD_SUBSCRIBED': Mailbox has a child that is subscribed (and
'_SELECT_RECURSIVEMATCH' flag was set).
Finally the listing is deinitalized with 'mailbox_list_iter_deinit()'. If it
returns -1, it means that some mailboxes perhaps weren't listed due to some
internal error.
If you wish to get mailbox_info flags only for a single mailbox, you can use
'mailbox_list_mailbox()'.
Directory permissions
---------------------
'mailbox_list_get_permissions()' and 'mailbox_list_get_dir_permissions()' can
be used to get wanted permissions for newly created files and directories.
* For global files, give NULL as the mailbox name. The permissions are then
based on the root_dir. If root_dir doesn't exist, it returns 0700/0600 mode.
* For per-mailbox files, give the mailbox name. The permissions are then based
on the mailbox's directory.
The returned permissions are:
* mode: Creation mode, like 0600.
* gid: Group that should be set, unless it's '(gid_t)-1'. There are 3 reasons
why it could be that:
* directory has g+s bit set, so the wanted group is set automatically
* group is the same as process's effective GID, so it gets set
automatically
* mode's group permissions are the same as world permissions, so group
doesn't matter.
* gid_origin: This string points to the directory where the group (and
permissions in general) was based on, or "defaults" for internal defaults.
If changing the group fails with EPERM, 'eperm_error_get_chgrp()' can be used
to log a nice and understandable error message.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/LDA.Postfix.txt 0000666 00000022702 15050120373 0010306 0 ustar 00 Dovecot LDA with Postfix
========================
This page contains only information specific to using LDA with Postfix, see
for more information about using the LDA itself.
System users
------------
If you wish you use 'dovecot-lda' for all system users on a single domain mail
host you can do it by editing 'mailbox_command' parameter in
'/etc/postfix/main.cf' (postconf(5) [http://www.postfix.org/postconf.5.html]):
---%<-------------------------------------------------------------------------
mailbox_command = /usr/local/libexec/dovecot/dovecot-lda
# or
mailbox_command = /usr/libexec/dovecot/dovecot-lda
# or
mailbox_command = /usr/lib/dovecot/dovecot-lda
# or wherever it was installed in your system.
---%<-------------------------------------------------------------------------
Then run 'postfix reload'.
* Be sure that /var/mail or wherever you deliver mail is writable by the
dovecot-lda process, which does not run as root.
* Postfix's 'mailbox_size_limit' setting applies to all files that are written
via dovecot-lda. The default is 50 MB, so dovecot-lda can't write *any*
files larger than that, including mbox files or log files. This shows up
only in Dovecot's logs:
---%<----------------------------------------------------------------------
dovecot-lda(user): write() failed with mbox file /home/user/mail/foo: File
too large (process was started with ulimit -f limit)
---%<----------------------------------------------------------------------
* If you have trouble seeing anything in Dovecot's logs, see
[LDA.txt].
Some detailed config files and examples at
http://heinous.org/wiki/Virtual_Domains%2C_Postfix%2C_Dovecot_LDA%2C_and_LDAP
[http://heinous.org/wiki/Virtual_Domains,_Postfix,_Dovecot_LDA,_and_LDAP]
Virtual users
-------------
Dovecot LDA is very easy to use on large scale installations with Postfix
virtual domains support, just add a 'dovecot' service in
'/etc/postfix/master.cf' (master(5) [http://www.postfix.org/master.5.html]):
---%<-------------------------------------------------------------------------
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/dovecot-lda -f
${sender} -d ${recipient}
---%<-------------------------------------------------------------------------
An example using address extensions (ie user+extension@domain.com (don't forget
to define the proper recipient_delimiter in Postfix's main.cf)) to deliver to
the folder 'extension' in your maildir (If you wish to preserve the case of
${extension}, remove the 'hu'flags [http://www.postfix.org/pipe.8.html], and be
sure to utilize [Variables.txt] in your dovecot.conf for mail
locations and other configuration parameters that are expecting lower case):
---%<-------------------------------------------------------------------------
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/dovecot-lda -f
${sender} -d ${user}@${nexthop} -m ${extension}
# or if you have a INBOX/ namespace prefix:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/dovecot-lda -f
${sender} -d ${user}@${nexthop} -m INBOX/${extension}
---%<-------------------------------------------------------------------------
This example ignores address extensions (ie user+extension@domain.com delivers
just like user@domain.com ), but still shows the original address for Sieve:
---%<-------------------------------------------------------------------------
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -a
${recipient} -d ${user}@${nexthop}
---%<-------------------------------------------------------------------------
Replace 'vmail' above with your virtual mail user account.
Then set 'virtual_transport' to 'dovecot' in '/etc/postfix/main.cf':
---%<-------------------------------------------------------------------------
dovecot_destination_recipient_limit = 1
virtual_mailbox_domains = your.domain.here
virtual_transport = dovecot
---%<-------------------------------------------------------------------------
And remember to run
---%<-------------------------------------------------------------------------
postfix reload
---%<-------------------------------------------------------------------------
Virtual users with multiple uids/gids
-------------------------------------
If you need multiple uids/gids you'll need to set dovecot-lda setuid root or
invoke it through sudo. See [LDA.txt] for how to do this
securely.
Postfix with a NFS mail store
-----------------------------
If you are experiencing problems with dovecot-lda processes hanging when
delivering to an NFS mail store, it's likely that the dovecot-lda process is
hanging while waiting for free locks. The occurrence of this can be greatly
reduced, if not eradicated, by forcing Postfix to only deliver to the same
recipient one at a time.
---%<-------------------------------------------------------------------------
dovecot_destination_concurrency_limit = 1
---%<-------------------------------------------------------------------------
Prevent backscatter
-------------------
To prevent backscatter you should configure Postfix to reject mail for non
existent recipients.
This is the default behaviour (smtpd_reject_unlisted_recipient = yes) so
there's no need to set "reject_unlisted_recipient" in any of your restriction.
But: Postfix must know if a recipient exists. Depending on how you've
configured Dovecot and Postfix this can be done several ways.
System users
------------
If you only use local system users this is no problem - all valid recipients
can be found in the local password or alias database.
Virtual users (static)
----------------------
When you use virtual users and domains you should maintain a list of valid
recipients. The relevant settings settings are:
*virtual_alias_maps, virtual_mailbox_maps*
For static verification you can maintain the content of the files yourself. For
every recipient or alias you need one entry. Example:
*virtual_alias_maps*
---%<-------------------------------------------------------------------------
name_recipient@example.com external@example.net
---%<-------------------------------------------------------------------------
*virtual_mailbox_maps*
---%<-------------------------------------------------------------------------
name@example.com OK
recipient@example.com available
---%<-------------------------------------------------------------------------
Don't forget to run "postmap" afterwards.
*Info:* if you use the Dovecot LDA or LMTP it doesn't matter what you use
behind the recipient address. Use "OK", the full name of the user or else.
Virtual users (dynamic)
-----------------------
Do you already use a database (MySQL, PostgreSQL) for Dovecot? Use the same
source for Postfix. You only have to to define a valid sql query for Postfix.
Example:
---%<-------------------------------------------------------------------------
virtual_mailbox_maps = proxy:mysql:/etc/postfix/virtual_mailbox_maps.cf
---%<-------------------------------------------------------------------------
*virtual_mailbox_maps.cf*
---%<-------------------------------------------------------------------------
user = mysql-user
password = mysql-password
hosts = unix:/var/run/mysql/mysqld.sock
dbname = mailserver
query = SELECT name FROM mailbox WHERE email='%s'
---%<-------------------------------------------------------------------------
This query will return the value of the filed "name" from table "mailbox" if
the email address of the recipient matches the email from the field "email".
This is enough for Postfix because Postfix must only know if the recipient
exists. The value doesn't matter. When you use a database (or LDAP) there's no
need to manually maintain a file with valid recipients.
*Info:* If you use "relay_domains" instead of "virtual_mailbox_domains" you
have to use "relay_recipient_maps" instead of "virtual_mailbox_maps".
Dynamic address verfication with LMTP
-------------------------------------
With Dovecot 2.0 you can also use LMTP and the Postfix setting
"reject_unverified_recipient" for dynamic address verification. It's really
nice because Postfix doesn't need to query an external datasource (MySQL,
LDAP...). Postfix maintain a local database with existing/non existing
addresses (you can configure how long positive/negative results should be
cached).
To use LMTP and dynamic address verification you must first get Dovecot
working. Then you can configure Postfix to use LMTP and set
"reject_unverified_recipient" in the smtpd_recipient_restrictions.
On every incoming email Postfix will probe if the recipient address exists. You
will see similar entries in your logfile:
---%<-------------------------------------------------------------------------
Recipient address rejected: undeliverable address: host
tux.example.com[private/dovecot-lmtp] said: 550 5.1.1 < tzknvtr@example.com >
User doesn't exist: tzknvtr@example.com (in reply to RCPT TO command); from=<
cnrilrgfclra@spammer.org > to=< tzknvtr@example.com >
---%<-------------------------------------------------------------------------
If the recipient address exists (status=deliverable) Postfix accepts the mail.
*Info:* you can not use "reject_unverified_recipient" with "pipe" so this
doesn't work with the Dovecot LDA "deliver".
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Indexes.Cache.txt 0000666 00000014156 15050120373 0012070 0 ustar 00 Cache file
==========
Cache file is used for storing immutable data. It supports several different
kinds of fields:
MAIL_CACHE_FIELD_FIXED_SIZE:
The field size doesn't need to be stored in the cache file. It's always the
same.
MAIL_CACHE_FIELD_BITMASK:
A fixed size bitmask field. It's possible to add new bits by updating this
field. All the added fields are ORed together.
MAIL_CACHE_FIELD_VARIABLE_SIZE:
Variable sized binary data.
MAIL_CACHE_FIELD_STRING:
Variable sized string.
MAIL_CACHE_FIELD_HEADER:
Variable sized message header. The data begins with a 0-terminated 'uint32_t
line_numbers[]'. The line number exists only for each header, header
continuation lines in multiline headers don't get listed. After the line
numbers comes the list of headers, including the "header-name: " prefix for
each line, LFs and the TABs or spaces for continued lines.
The last 3 variable sized fields are treated identically by the cache file
code. Their main purpose is to make it easier for "dump cache file's contents"
programs ('src/util/idxview') to do their job.
Locking
-------
Because cache file is typically used in potentially long-running operations,
such as with IMAP command 'FETCH 1:* (BODY.PEEK[] ENVELOPE BODYSTRUCTURE)' it's
important that updating the cache file doesn't block out any other readers.
Also because the readers are often also writers (if something isn't cached,
it's added there), it's important that they don't block writers either.
Reading cache files requires no locking. Writing is done by first locking the
file, reserving some space to write to, and immediately after that unlocking
the file. This way the transaction can keep writing to the cache file as long
as it wants to without blocking other writers. When the transaction is
committed, the updated cache offsets are written to the transaction log which
makes them visible to other processes.
This also means that it's possible for two processes to write the same cached
fields twice to the cache file. Because the data written to the cache file are
really just cached data, the fields' contents are identical. Having the data
exist twice (or even more times) means wasting some disk space, but otherwise
it isn't a problem. The duplicates are dropped the next time the file is
compressed.
Cache decisions
---------------
Dovecot tries to be smart about what it keeps in the cache file. If the client
never fetches the cached data, it's just waste of disk space and disk I/O.
The caching decisions are:
MAIL_CACHE_DECISION_NO:
This field isn't cached currently.
MAIL_CACHE_DECISION_TEMP:
This field is cached for new mails.
MAIL_CACHE_DECISION_YES:
This field is cached for all mails.
Normally Dovecot changes the decisions based on what fields are fetched and for
what messages. A specific decision can be forced by ORing it with
'MAIL_CACHE_DECISION_FORCED'.
'mail-cache-decisions.c' file contains the rules how Dovecot changes the
decisions. The following is copied from the file:
Users can be divided to three groups:
1. Most users will use only a single IMAP client which caches everything
locally. For these users it's quite pointless to do any kind of caching as
it only wastes disk space. That might also mean more disk I/O.
2. Some users use multiple IMAP clients which cache everything locally. These
could benefit from caching until all clients have fetched the data. After
that it's useless.
3. Some clients don't do permanent local caching at all. For example Pine and
webmails. These clients would benefit from caching everything. Some locally
caching clients might also access some data from server again, such as when
searching messages. They could benefit from caching only these fields.
After thinking about these a while, I figured out that people who care about
performance most will be using Dovecot optimized LDA anyway which updates the
indexes/cache immediately. In that case even the first user group would benefit
from caching the same way as second group. LDA reads the mail anyway, so it
might as well extract some information about it and store them into cache.
So, group 1. and 2. could be optimally implemented by keeping things cached
only for a while. I thought a week would be good. When cache file is
compressed, everything older than week will be dropped.
But how to figure out if user is in group 3? One quite easy rule would be to
see if client is accessing messages older than a week. But with only that rule
we might have already dropped useful cached data. It's not very nice if we have
to read and cache it twice.
Most locally caching clients always fetch new messages (all but body) when they
see them. They fetch them in ascending order. Noncaching clients might fetch
messages in pretty much any order, as they usually don't fetch everything they
can, only what's visible in screen. Some will use server side sorting/threading
which also makes messages to be fetched in random order. Second rule would then
be that if a session doesn't fetch messages in ascending order, the fetched
field type will be permanently cached.
So, we have three caching decisions:
1. Don't cache: Clients have never wanted the field
2. Cache temporarily: Clients want this only once
3. Cache permanently: Clients want this more than once
Different mailboxes have different decisions. Different fields have different
decisions.
There are some problems, such as if a client accesses message older than a
week, we can't know if user just started using a new client which is just
filling its local cache for the first time. Or it might be a client user hasn't
just used for over a week. In these cases we shouldn't have marked the field to
be permanently cached. User might also switch clients from non-caching to
caching.
So we should re-evaluate our caching decisions from time to time. This is done
by checking the above rules constantly and marking when was the last time the
decision was right. If decision hasn't matched for two months, it's changed. I
picked two months because people go to at least one month vacations where they
might still be reading mails, but with different clients.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Design.Dsync.txt 0000666 00000011550 15050120373 0010542 0 ustar 00 Dsync Design
============
Two-way synchronization
-----------------------
dsync attempts to preserve all changes done by both sides of the synced
mailboxes.
Mailbox list
------------
Mailboxes have 128 bit globally unique IDs, which are used for figuring out
when two mailboxes should actually be synchronized. This solves two major
problems:
* If mailbox has been renamed in one side, dsync finds it because its GUID
hasn't changed.
* If mailbox has been deleted and recreated, dsync doesn't attempt to sync it
because it's a different mailbox.
Then there's the problem of how to correctly sync mailbox renames and
deletions. How do you know which side of the sync has the most recent name for
the mailbox? How do you know if one side had deleted mailbox, or if the other
side had created it? To solve these problems, Dovecot v2.0 created a "mailbox
log", which adds a record with mailbox GUID and timestamp whenever mailbox is
renamed or deleted. So:
* If mailbox has different names on two sides, its "last renamed" timestamp is
looked up from the mailbox list index. The side with the most recent
timestamp is assumed to contain the newer name and the other side's mailbox
is renamed to it.
* If neither side has a "last renamed" timestamp, one side is picked. This
shouldn't happen, except when mailbox log is deleted for some reason or
if the renaming is done outside Dovecot.
* If mailbox exists only on one side, the other side checks if mailbox log
contains a delete record for its GUID. If there is one, the mailbox is
deleted from the other side. If there's not, the mailbox is created and
synced.
* Subscriptions and unsubscriptions are synced in a similar way. But because
it's possible to be subscribed to nonexistent mailboxes, mailbox log can't
contain mailbox GUIDs for them. Instead the first 128 bits of SHA1 of
mailbox name are used. Collisions for mailbox names are highly unlikely, but
even if one happens, the worst that can happen is that user gets
unsubscribed from wrong mailbox.
dsync writes timestamps to changelog using the original timestamps, so that
dsync's changes won't override changes done by user during sync.
Mailbox
-------
When saving new mails, dsync preserves all of their immutable state:
* GUID
* Received date
* Save date
* Message contents
It also attempts preserve IMAP UID. This works as long as the other side hasn't
already used the UID for another mail. If it has, dsync doesn't attempt to
preserve the UID, because an IMAP client might have already seen the UID and
cached another mail's contents for it. IMAP requires that message's contents
must never change, so UIDs can't be reused. So whenever an UID conflict
happens, dsync gives messages in both sides a new UID, because it can't know
which message the client had seen, or perhaps user used two clients and both
saw a different message. (This assumes a master/slave replication use case for
dsync.)
The mutable metadata that dsync preserves is:
* Message flags and keywords
* Modification sequences (modseqs)
Flags and keywords are synced based on modseqs. Whichever side has a higher
modseq for the message, its flags and keywords are synced to the other side.
Currently there's no per-flag or per-keyword synchronization, so that if one
side had added \Seen flag and other side had added \Answered flag, one of them
would be dropped.
Finding what to sync
--------------------
dsync can run in full mode or fast mode. Full mode means it goes through all
messages in all mailboxes, making sure everything is fully synchronized. In
fast mode it relies on uidvalidity, uid-next and highest-modseq values to find
out changes. If any of the values changed, the mailbox is included in sync.
FIXME: A superfast mode should still be implemented, where once a mailbox is
selected for syncing, it should sync only mails whose modseq is higher than a
given one. This would improve performance and network traffic with large
mailboxes.
Copy optimizations
------------------
Before dsync actually starts syncing anything, it first fetched a list of all
to-be-synced messages and adds them to a GUID -> message hash table. Whenever
dsync needs to sync a new message to the other side, it first checks if the
message's GUID already exists on the other side. If it does, it starts a
message copy operation instead of a full save. It's possible that this copy
operation fails if the message just gets expunged from the other side, so there
needs to be fallback handling for this. If the message exists in multiple
mailboxes, a copy from the next mailbox is attempted. If all of them fail,
dsync fallbacks to saving the message.
FIXME: This optimization currently works only in full sync mode. If this were
to work in fast sync mode, the full mailbox list would have to be looked up
from local side. And this would slow it down..
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Authentication.Kerberos.txt 0000666 00000012654 15050120373 0013012 0 ustar 00 Kerberos
========
Dovecot supports Kerberos 5 using GSSAPI. The Kerberos authentication mechanism
doesn't require having a [PasswordDatabase.txt], but you do need a
[UserDatabase.txt] so Dovecot can lookup user-specific information,
such as where their mailboxes are stored.
*Note:* If you only wish to authenticate clients using their Kerberos
/passphrase/ (as opposed to ticket authentication), you will probably want to
use [PasswordDatabase.PAM.txt] authentication with 'pam_krb5.so' instead.
Pre-requisites
--------------
This document assumes that you already have a Kerberos Realm up and functioning
correctly at your site, and that each host in your realm also has a host
/keytab/ installed in the appropriate location.
For Dovecot, you will need to install the appropriate /service/ keys on your
server. By default, Dovecot will look for these in the host's keytab file,
typically '/etc/krb5.keytab', but you can specify an alternate path using the
'auth_krb5_keytab' configuration entry in dovecot.conf. If you wish to provide
an IMAP service, you will need to install a service ticket of the form
'imap/hostname@REALM'. For POP3, you will need a service ticket of the form
'pop/hostname@REALM'. When using Dovecot's [Sasl.txt] with MTA, you
will need to install service ticket of the form 'smtp/hostname@REALM'.
Example dovecot.conf configurations
-----------------------------------
If you only want to use Kerberos ticket-based authentication:
---%<-------------------------------------------------------------------------
auth_mechanisms = gssapi
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/vmail/%u
}
---%<-------------------------------------------------------------------------
(In this virtual-hosting example, all mail is stored in /var/vmail/$username
with uid and gid set to 'vmail')
If you also want to support plaintext authentication in addition to
ticket-based authentication, you will need something like:
---%<-------------------------------------------------------------------------
auth_mechanisms = plain gssapi
passdb {
driver = pam
}
userdb {
driver = passwd
}
---%<-------------------------------------------------------------------------
(Note that in this example, you will also need to configure PAM to use
whichever authentication backends are appropriate for your site.)
Enable plaintext authentication to use Kerberos
-----------------------------------------------
This is needed when some of your clients don't support GSSAPI and you still
want them to authenticate against Kerberos.
Install pam_krb5 module for PAM, and create '/etc/pam.d/dovecot':
---%<-------------------------------------------------------------------------
auth sufficient pam_krb5.so
account sufficient pam_krb5.so
---%<-------------------------------------------------------------------------
Then enable PAM passdb:
---%<-------------------------------------------------------------------------
passdb {
driver = pam
}
---%<-------------------------------------------------------------------------
Check '/var/log/auth.log' if you have any problems logging in. The problem
could be that PAM is still trying to use pam_unix.so rather than pam_krb5.so.
Make sure pam_krb5.so is the first module for account or just change
pam_unix.so to sufficient.
Client support
--------------
Mail clients that support Kerberos GSSAPI authentication include:
* Evolution
* Mozilla Thunderbird
* SeaMonkey
* Mutt
* UW Pine
* Apple Mail
Testing
-------
*FIXME*: This section requires cleanup.
Test that the server can access the keytab
------------------------------------------
This test demonstrates that the server can acquire its private credentials.
First telnet directly to the server
---%<-------------------------------------------------------------------------
$ telnet localhost 143
* OK Dovecot ready.
---%<-------------------------------------------------------------------------
or, if you are using IMAPS then use openssl instead of telnet to connect:
---%<-------------------------------------------------------------------------
$ openssl s_client -connect localhost:993
CONNECTED(00000003)
...
* OK Dovecot ready.
---%<-------------------------------------------------------------------------
Check that GSSAPI appears in the authentication capabilities:
---%<-------------------------------------------------------------------------
a capability
* CAPABILITY ... AUTH=GSSAPI
---%<-------------------------------------------------------------------------
Attempt the first round of GSS communication. The '+' indicates that the server
is ready
---%<-------------------------------------------------------------------------
a authenticate GSSAPI
+
---%<-------------------------------------------------------------------------
Abort the telnet session by typing control-] and then 'close'
---%<-------------------------------------------------------------------------
^]
telnet> close
---%<-------------------------------------------------------------------------
The test:
* Setup mutt in /etc/Muttrc to use kerberos using gssapi and imap
configuration
* this is done with 'set imap_authenticators="gssapi"'
* run kinit (type in password for kerb)
* run command mutt
* If you get error No Authentication Method
* run command klist (list all kerberos keys) should show imap/HOSTNAME
* /etc/hosts has to be set properly so that kerberos can find server.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Variables.txt 0000666 00000020757 15050120373 0010173 0 ustar 00 Variables
=========
You can use special variables in several places:
* [MailLocation.txt] setting and [Namespaces.txt]
locations
* [UserDatabase.Static.txt] and
[AuthDatabase.PasswdFile.txt] template strings
* [AuthDatabase.LDAP.txt] and [AuthDatabase.SQL.txt] userdb query
strings
* log prefix for imap/pop3 process
* [Plugins.txt] settings
The variables that work everywhere are:
*
+------------+----------+-----------------------------------------------------+
| *Variable* | *Long | *Description* |
| | name* | |
+------------+----------+-----------------------------------------------------+
| %% | | '%' character. See for |
| | | further information about %% variables |
+------------+----------+-----------------------------------------------------+
| %u | user | full username (e.g. user@domain) |
+------------+----------+-----------------------------------------------------+
| %n | username | user part in user@domain, same as %u if there's no |
| | | domain |
+------------+----------+-----------------------------------------------------+
| %d | domain | domain part in user@domain, empty if user there's no|
| | | domain |
+------------+----------+-----------------------------------------------------+
| %s | service | imap, pop3, smtp, lda (and doveadm, dsync, etc.) |
+------------+----------+-----------------------------------------------------+
| %p | pid | PID of the current process (login or imap/pop3 |
| | | process) |
+------------+----------+-----------------------------------------------------+
| %l | lip | local IP address |
+------------+----------+-----------------------------------------------------+
| %r | rip | remote IP address |
+------------+----------+-----------------------------------------------------+
These variables work almost everywhere else except in Dovecot-auth (userdb
queries/templates):
*
+------------+----------+-----------------------------------------------------+
| *Variable* | *Long | *Description* |
| | name* | |
+------------+----------+-----------------------------------------------------+
| %h | home | home directory. Use of ~/ is better whenever |
| | | possible. |
+------------+----------+-----------------------------------------------------+
| %i | uid | UNIX UID of the user |
+------------+----------+-----------------------------------------------------+
These variables work only in Dovecot-auth:
*
+------------+----------+-----------------------------------------------------+
| *Variable* | *Long | *Description* |
| | name* | |
+------------+----------+-----------------------------------------------------+
| %w | password | plaintext password from plaintext authentication |
| | | mechanism |
+------------+----------+-----------------------------------------------------+
| %m | mech | |
| | | [Authentication.Mechanisms.txt], e.g. PLAIN |
+------------+----------+-----------------------------------------------------+
| %a | lport | Local port |
+------------+----------+-----------------------------------------------------+
| %b | rport | Remote port |
+------------+----------+-----------------------------------------------------+
| %c | secured | "secured" string with SSL, TLS and localhost |
| | | connections. Otherwise empty. |
+------------+----------+-----------------------------------------------------+
| %k | cert | "valid" if client had sent a valid client |
| | | certificate, otherwise empty. |
+------------+----------+-----------------------------------------------------+
These variables work only in 'login_log_format_elements' setting:
*
+------------+--------------+-------------------------------------------------+
| *Variable* | *Long name* | *Description* |
+------------+--------------+-------------------------------------------------+
| %m | mech | |
| | | [Authentication.Mechanisms.txt], e.g. PLAIN |
+------------+--------------+-------------------------------------------------+
| %a | lport | Local port |
+------------+--------------+-------------------------------------------------+
| %b | rport | Remote port |
+------------+--------------+-------------------------------------------------+
| %c | secured | SSL, TLS or empty |
+------------+--------------+-------------------------------------------------+
| %k | ssl_security | SSL protocol and cipher information, e.g. "TLSv1|
| | | with cipher DHE-RSA-AES256-SHA (256/256 bits)" |
+------------+--------------+-------------------------------------------------+
| %e | mail_pid | Mail process (imap/pop3) PID that handles the |
| | | post-login connection |
+------------+--------------+-------------------------------------------------+
Long variable names can be used like '%{long_name} ' or with L modifier:
'%L{long_name}'. Environment variables can be accessed with
'%{env:ENVIRONMENT_VARIABLE}'. Additionally, the (self-explanatory) variables
'%{pid}' and '%{hostname} ' are available.
Modifiers
---------
You can apply a modifiers for each variable (e.g. %Us = POP3):
* %L - lowercase
* %U - uppercase
* %E - escape '"', "'" and '\' characters by inserting '\' before them. Note
that variables in SQL queries are automatically escaped, you don't need to
use this modifier for them.
* %X - parse the variable as a base-10 number, and convert it to base-16
(hexadecimal)
* %R - reverse the string
* %H - take a 32bit hash of the variable and return it as hex. You can also
limit the hash value. For example %256Hu gives values 0..ff. You might want
padding also, so %2.256Hu gives 00..ff. This can be useful for example in
dividing users automatically to multiple partitions.
* %H hash function is a bit bad if all the strings end with the same text,
so if you're hashing usernames being in user@domain form, you probably
want to reverse the username to get better hash value variety, e.g.
%3RHu.
* %M - return the string's MD5 sum as hex.
* %D - return "sub.domain.org" as "sub,dc=domain,dc=org" (for LDAP queries)
* %T - Trim trailing whitespace
You can take a substring of the variable by giving optional offset followed by
'.' and width after the '%' character. For example %2u gives first two
characters of the username. %2.1u gives third character of the username.
If the offset is negative, it counts from the end, for example %-2.2i gives the
UID mod 100 (last two characters of the UID printed in a string). If a positive
offset points outside the value, empty string is returned, if a negative offset
does then the string is taken from the start.
If the width is prefixed with zero, the string isn't truncated, but only padded
with '0' character if the string is shorter. For example %04i may return
"0001", "1000" and "12345". %1.04i for the same string would return "001",
"000" and "2345".
The modifiers are applied from left-to-right order, except the substring is
always taken from the final string.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Migration.MailFormat.txt 0000666 00000025562 15050120373 0012245 0 ustar 00 Converting between mailbox formats
==================================
If you want a transparent migration, the biggest problem is preserving message
UIDs. See for the problems this may cause. If you do the
conversion with dsync, it preserves the UIDs.
dsync
-----
With dsync you can convert between any two mailbox formats that Dovecot
supports. As much of the mailbox state is preserved as possible. Typically it's
everything. See for full documentation, here are only a
couple of examples:
* mbox -> maildir migration. Set 'mail_location=maildir:~/Maildir' and run
'doveadm mirror -u username mbox:~/mail:INBOX=/var/mail/username'
* maildir -> mdbox migration. Set 'mail_location=mdbox:~/mdbox' and run
'doveadm mirror -u username maildir:~/Maildir'
If you can successfully use dsync, you can skip the rest of this page.
Converting from mbox to Maildir
-------------------------------
* mb2md.pl with Dovecot modifications [http://dovecot.org/tools/mb2md.pl] can
convert mails, preserving UIDs and keywords.
* See also [attachment:migrateuser.sh script to drive the full migration
for a user].
* This script requires patched 'mailutil' that supports Maildir. One
working 'mailutil' binary is RHEL4 PINE RPM
[http://dag.wieers.com/rpm/packages/pine/pine-4.64-3.el4.rf.i386.rpm]
from the DAG RPM Repository [http://dag.wieers.com/rpm/]. You could
also patch any version of pine/c-client and patch it with the Maildir
patches from
http://staff.washington.edu/chappa/pine/info/maildir.html.
* mb2md.py [http://dovecot.org/list/dovecot/2008-March/029736.html] can
convert also message UIDs.
* Yet another way to fix the UIDL migration problem. If you can generate an
uildlist ("messagenumber uidl" pairs), use my new -U uidllist option to
inject X-UILD: headers in the converted Maildir-file. The modified mb2md
script is avalable here:mb2md.xuidl.pl.gz
[http://www.chaos.dk/~sch/mb2md.xuidl/mb2md.xuidl.pl.gz]. I used this to
convert a cucipop installation to dovecot. pop3_reuse_xuidl=yes will do the
rest./-- 2009-02-13/
Check also the *User-Contributed Maildir Support* section on the qmail
community site [http://www.qmail.org/top.html#usersoft] for more choices.
Example (user's mail in '~someuser/mail' and INBOX in '/var/mail/someuser'):
---%<-------------------------------------------------------------------------
cd ~someuser
mb2md-3.20.pl -s mail -R
mb2md-3.20.pl -m -s /var/mail/someuser
mv mail mail.old
---%<-------------------------------------------------------------------------
Now the mail will be in '~someuser/Maildir'. Do not forget to migrate the
subscriptions as well, otherwise the new maildir will seem to have only an
inbox when viewed through a mail client that supports them. This can be as
simple as copying the old '~someuser/mail/.subscriptions' file to
'~someuser/Maildir/subscriptions' (warning: I have not tested this extensively,
my subscription list and folder hierarchy was very simplistic).
Hierarchy separator change
--------------------------
The default hierarchy separator with Maildir is '.' instead of '/' which is
common with mboxes. To keep the migration transparent to users, you can keep
the '/' separator by using [Namespaces.txt]. In any case you need
to replace the '/' with '.' in the subscriptions file:
* ---%<----------------------------------------------------------------------
sed 's:/:.:g' subscriptions > subscriptions.new
mv subscriptions.new subscriptions
---%<----------------------------------------------------------------------
UW-IMAP's subscriptions file is in '~/.mailboxlist'. Dovecot's mbox
subscriptions is in '/.subscriptions'. Dovecot's Maildir
subscriptions is in '/subscriptions'.
Also if you're migrating from UW-IMAP, you probably had "mail/" prefixes in the
mailbox names. You can again use [Namespaces.txt] to let clients
use the prefix, or you can tell your users to remove the namespace prefix from
their clients and change the subscriptions file:
---%<-------------------------------------------------------------------------
sed 's/^mail\.//' subscriptions > subscriptions.new
mv subscriptions.new subscriptions
---%<-------------------------------------------------------------------------
Note that because Maildir uses '.' as the hierarchy separator in filesystem,
it's not possible to have mailbox names containing '.' characters, even if you
changed the separator in namespaces. If you really want to have dots, the only
way to do this is by modifying the filesystem separator in 'MAILDIR_FS_SEP' and
'MAILDIR_FS_SEP_S' defines in 'src/lib-storage/index/maildir/maildir-storage.h'
file in the sources. Do not be tempted to change 'MAILDIR_FS_SEP' et al to
'/'; it won't work.
Converting from Maildir to mbox
-------------------------------
This is especially helpful if you want to archive your mail to a single file
for storage on a CD, a PC, etc. But it can also be helpful if you want to use
[MailboxFormat.mbox.txt] with Dovecot.
Use the reformail program that comes with maildrop
[http://www.courier-mta.org/maildrop/]. You can also use the formail program
that comes with procmail [http://www.procmail.org/]. Here is a simple script
showing how this works.
To use it, adjust the script to invoke the right command according to your
system.
Then 'cd' to the user's home directory (one level above 'Maildir') and run the
script with two arguments: the mailbox name (You can use "." for the top-level
folder), and the output mbox filename, for example:
---%<-------------------------------------------------------------------------
cd ~hans
perl dw-maildirtombox.pl . >/tmp/hans-inbox
perl dw-maildirtombox.pl Sent >/tmp/hans-sent
---%<-------------------------------------------------------------------------
---%<-------------------------------------------------------------------------
#!/usr/bin/env perl
# dw-maildirtombox.pl
# dw = Dovecot Wiki :-)
# NOTE! The output file must not contain single quotes (')!
# figure out which program to run
$cmd="reformail -f1";
system("$cmd /dev/null 2>/dev/null") == 0 or $cmd="formail";
system("$cmd /dev/null 2>/dev/null") == 0
or die "cannot find reformail or formail on your \$PATH!\nAborting";
$dir=$ARGV[0];
$outputfile=$ARGV[1];
if (($outputfile eq '') || ($dir eq ''))
{ die "Usage: ./archivemail.pl mailbox outputfile\nAborting"; }
if (!stat("Maildir/$dir/cur") || !stat("Maildir/$dir/new"))
{ die "Maildir/$dir is not a maildir.\nAborting"; }
@files = (,);
foreach $file (@files) {
next unless -f $file; # skip non-regular files
next unless -s $file; # skip empty files
next unless -r $file; # skip unreadable files
$file =~ s/'/'"'"'/; # escape ' (single quote)
$run = "cat '$file' | $cmd >>'$outputfile'";
system($run) == 0 or warn "cannot run \"$run\".";
}
---%<-------------------------------------------------------------------------
Converting from MBX to Maildir
------------------------------
See the uw2dovecot.pl
[http://wiki.dovecot.org/Migration/UW?action=AttachFile&do=view&target=uw2dovecot.pl]
as mentioned on the page.
Converting from MBX to mbox
---------------------------
If you are using UW-IMAP and using the [MailboxFormat.mbx.txt],
you will need to convert it to [MailboxFormat.mbox.txt] format. The
conversion process isn't pretty, but here is a script that works. You will need
to get and compile the mailutil program from the UW-IMAP web site
[http://www.washington.edu/imap/].
---%<-------------------------------------------------------------------------
#! /bin/sh
# Written by Marc Perkel - public domain
# overhauled by Matthias Andree, 2006
# Usage: mbx-convert
# This code assumes there a user named "marc" with the primary group "marc".
# Change to any real user on your system.
# Yes - it look bizzare - but it gets the job done
# abort on error
set -e
user=marc
group=marc
homedir=/home/$user
if [ $# -ne 1 ] ; then
echo >&2 "Usage: $0 "
exit 1
fi
# set up automatic cleanup
trap 'rm -f "${homedir}"/in.$$ "${homedir}"/out.$$' 0
# First copy to users home dir and make the user the owner
cp "$1" "${homedir}/in.$$"
chown "$user":"$group" "${homedir}/in.$$"
# Run mailutil to convert as the user other than root
# mailutil requires this
su "$user" -c "mailutil copy in.$$ \#driver.unix/out.$$"
# create new file with same permissions/owner as old
cp -p "$1" "${1}.new"
# cat instead of copy leaves the original owner and permissions alone
if cat "${homedir}/out.$$" >"${1}.new" ; then
# cat succeeded, rename file into place
mv "${1}.new" "$1"
else
# cat failed, remove temp file
rm -f "${1}.new"
exit 1
fi
---%<-------------------------------------------------------------------------
Make a copy of some folders and test it first. Once you are satisfied that it
works then:
* Write a script to convert all your files.
* Shut down your email system so files can't be modified
* Copy all your email to a backup location in case you have to revert
* Run the script
* Turn on Dovecot and test to verify it is working
* Important - make sure that you changed your SMTP configuration to write mbox
and not MBX.
* Turn on SMTP and verify it is all working
*User comments:*
* Is this hassle actually necessary? I have run mailutil as root like this
(mailutil as provided by the PINE 4.61 package for SUSE Linux
10.0):'mailutil copy /tmp/foo.mbx.orig '#driver.unix//tmp/foo.test'' and did
not encounter any problems./-- , 2006-05-18/
* I did the same (using 'mailutil') but it doesn't maintain UIDs or
UIDVALIDITY. So I hacked[attachment:mbx2mbox.tgz this] together to do the
migration./-- , 2008-08-02/
* Tried to do 'mailutil -v copy /tmp/foo '#driver.unix'/tmp/foo.unix', but
mailutil argues 'Can't open mailbox /tmp/foo: no such mailbox'. (mailutil as
from the Debian package uw-mailutils in Debian 5.0 Lenny) strace shows that
it searches for /tmp/foo/cur, i.e. a Maildir format mailbox. (WTF?) No idea
yet how to get this working. And I'm really glad when I got rid of MBX. --
, 2009-06-19
* As Mark Crispin always says: Don't use UW-IMAP with buggy (Maildir)
patches, compile your own.
* Same problem here - just reinstalled uw-imapd, used thunderbird to create
a "normal" mailfolder and copied the old folder contents - F.Fernandez
* At least with ubuntu mailutil from uw-mailutils it starts search from
root *ALWAYS* and if you start with slash it tries to convert from
maildir format 'mailutil -v copy /tmp/foo '#driver.unix'/tmp/foo.unix' =
convert maildir formated folder /tmp/foo/cur to mbox and 'mailutil -v
copy tmp/foo '#driver.unix'/tmp/foo.unix' = convert /tmp/foo file to mbox
- Manwe, 2010-03-09
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Dict.txt 0000666 00000002661 15050120373 0007140 0 ustar 00 Dict Proxy Process
==================
Dict can be used by:
* [Quota.Dict.txt]
* [SharedMailboxes.Shared.txt]
* [Plugins.Expire.txt]
When using these, the mail processes need to have access the dict socket. By
default only "dovecot" user has access to dict socket, which doesn't typically
work in any installations. However, giving too wide permissions by default
might allow untrusted users to access the dict and cause problems.
If all users share a single UNIX UID (e.g. "vmail"), you could make the dict
socket accessible only to it:
---%<-------------------------------------------------------------------------
service dict {
unix_listener dict {
mode = 0600
user = vmail
}
}
---%<-------------------------------------------------------------------------
If you use multiple UNIX UIDs, you can add an extra group for all Dovecot mail
processes. This works even if you have untrusted system users who have shell
access to the server:
---%<-------------------------------------------------------------------------
mail_access_groups = dovecot
service dict {
unix_listener dict {
mode = 0660
group = dovecot
}
}
---%<-------------------------------------------------------------------------
However, it works with only if it's started as root. If this isn't
possible, look into using instead.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/SystemUsers.txt 0000666 00000011765 15050120373 0010570 0 ustar 00 System Users
============
System users are typically defined in '/etc/passwd' file, but this isn't
necessary. Using NSS [http://en.wikipedia.org/wiki/Name_Service_Switch] you can
configure the lookups to be done from for example LDAP. See
[AuthDatabase.Passwd.txt] userdb configuration for how to set this up.
Especially if you're using nss_ldap you must set 'blocking=yes'.
System users usually have their own separate user IDs (UIDs). This is good from
security point of view, because it means that the kernel will also prevent
users from accessing each others' mails.
If the users have direct write access to the mail files (eg. the users have
shell access), they can easily cause all sorts of mailbox corruptions. That may
generate all kinds of error messages to Dovecot's error logs, so it may be
sometimes difficult to tell if there really is a problem or if user is just
doing something stupid.
If users are going to access the mailboxes with other software than Dovecot,
it's important to make sure that their mailbox accesses are compatible. This
mostly means that with mboxes you must make sure that everyone uses the [MailboxFormat.mbox.txt].
Authentication
--------------
Admins often wish to use different passwords for IMAP and POP3 than for other
services (eg. SSH), because IMAP and POP3 clients often send the password
unencrypted over the internet without even bothering to give users any
warnings. Dovecot can easily support non-system passwords for system users.
If you wish to use system passwords, you'll want to use one of these passdbs:
* [PasswordDatabase.PAM.txt]: Most commonly used in Linux and BSDs
nowadays.
* [PasswordDatabase.BSDAuth.txt]: BSD authentication is used by
OpenBSD.
* [AuthDatabase.Passwd.txt]: System users (NSS, '/etc/passwd', or
similiar). This may work instead of PAM (mostly in some BSDs).
* [PasswordDatabase.Shadow.txt]: Shadow passwords for system users
(NSS,'/etc/shadow' or similiar). Deprecated by PAM nowadays, but it should
work with Linux and Solaris.
If you wish to use non-system passwords, you can use pretty much any of the
Dovecot's [PasswordDatabase.txt], but for simple
installations you'll probably want to use
[AuthDatabase.PasswdFile.txt].
[UserDatabase.txt] for system users is always
[AuthDatabase.Passwd.txt].
Mail Location
-------------
Usually UNIX systems are configured by default to deliver mails to
'/var/mail/username' or '/var/spool/mail/username' mboxes. You may decide to
use these, or use [MailboxFormat.Maildir.txt] format instead.
Dovecot detects the mailbox format and location automatically if
'mail_location' setting isn't set, but it's still a good idea to explicitly
tell Dovecot where to find the mails. This makes it sure that Dovecot behaves
correctly also when the user's mailbox doesn't exist at the moment (eg. a new
user). If Dovecot can't figure out where the existing mails are, it simply
gives an error message and quits. It never tries to create a missing mailbox
when autodetection is used.
See for more information how to configure the mailbox
location. Below are the highlights for mbox and maildir.
mbox
----
The '/var/mail/username' mbox is called user's INBOX. IMAP protocol supports
multiple mailboxes however, so Dovecot needs some directory where to store the
other mailboxes. Typically they're stored in '~/mail/' or '~/Mail/' directory.
All of these locations are included in mailbox location autodetection. You can
specify them manually with:
---%<-------------------------------------------------------------------------
mail_location = mbox:~/mail:INBOX=/var/mail/%u
---%<-------------------------------------------------------------------------
Remember that the first path after 'mbox:' is the mailbox root directory, never
try to give 'mbox:/var/mail/%u' because that just isn't going to work (unless
you really want to store mails under '/var/mail/%u/' directory).
If you're also using other software than Dovecot to access mboxes, you should
try to figure out what locking methods exactly they're using and update
'mbox_read_locks' and 'mbox_write_locks' settings accordingly. See locking
section in [MailboxFormat.mbox.txt] for more information.
Maildir
-------
Maildir is typically stored in '~/Maildir' directory. You can specify this
manually with:
---%<-------------------------------------------------------------------------
mail_location = maildir:~/Maildir
---%<-------------------------------------------------------------------------
Chrooting
---------
Dovecot, including several other software, allow using "/./" in home directory
path to specify the chroot path. For example '/home/./user' would chroot to
'/home'. If you want to enable this for Dovecot, add the chroot path to
'valid_chroot_dirs' setting ('/home' in the previous example). If this isn't
done, Dovecot just ignores the "/./".
(This file was created from the wiki on 2011-01-13 04:52)
wiki/PasswordDatabase.BSDAuth.txt 0000666 00000000315 15050120373 0012727 0 ustar 00 BSDAuth
=======
This is similar to [PasswordDatabase.PAM.txt], but used by OpenBSD. It
supports 'cache_key' parameter the same way as PAM.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/HowTo.PopBSMTPAndDovecot.txt 0000666 00000033614 15050120373 0012631 0 ustar 00 Contents
1. POP3 (IMAP) before SMTP
1. Are you sure you want this?
1. Problems with POP-before-SMTP
2. Advantages of POP-before-SMTP over SMTP AUTH
2. Pop-before-smtp.pl
3. DRAC
4. SQL
1. Example for postgresql, postfix
2. Example for MySQL, postfix
5. relay-ctrl
POP3 (IMAP) before SMTP
=======================
/sometimes also called SMTP-after-POP3 or SMTP-after-IMAP/
Are you sure you want this?
---------------------------
POP-before-SMTP is generally considered a kludge, originally invented to make
up for the lack of authentication in the original SMTP
[http://en.wikipedia.org/wiki/Smtp] specification for clients on dynamic IP
addresses.ESMTP [http://en.wikipedia.org/wiki/Extended_SMTP] resolved that
shortcoming long ago, and all modern mail clients and servers support it by
now. You should consider implementing ESMTP AUTH
[http://en.wikipedia.org/wiki/SMTP-AUTH] in your mail transport/submission
agent, and using it in your clients, rather than using POP-before-SMTP. See
also or .
Problems with POP-before-SMTP
-----------------------------
* *Shared IP addresses* are in widespread use. You are opening your server not
only to your user, but to anyone else who might be sharing the same IP
address, other users, other computers in the same NAT. If you lose the
connection, the next one who is assigned your IP also inherits your relay
permit. This might include virus-infected spambot machines. Or consider a
public wireless hotspot or an Internet cafe: both types of establishments
are known to be frequented by spammers.
* *Not properly implemented* in all mail clients: it only works right if the
client checks for new mail immediately before attempting to send. And it can
be very unsafe if longer timeouts are used, such that the user has time to
write an email.
* Probably others. [RobMcGee.txt] ( [RobMcGee.txt]) just
thought it was wrong to have a HOWTO page here without a warning about why
/not/ to. Know what you are doing. If you are setting up a new mail service
from scratch, by all means, do it right!
Advantages of POP-before-SMTP over SMTP AUTH
--------------------------------------------
* Likely to be relatively easier to implement in your mail submission agent.
What's easier is a matter of opinion, and it varies, of course, but probably
all MTA/MSA servers support some form of access lists without patching or
recompiling.
* Simple non-technical instructions for users: /"Remember to check for new
mail before you try to send mail."/
Pop-before-smtp.pl
==================
If you want to use pop-before-smtp.pl (from http://popbsmtp.sourceforge.net/)
together with Dovecot, you can use this regular expression to match successful
POP3 and IMAP logins:
---%<-------------------------------------------------------------------------
$pat = '^(... .. ..:..:..) \S+ (?:pop3|imap)-login: Login: .+
\[(\d+\.\d+\.\d+\.\d+)\]';
---%<-------------------------------------------------------------------------
v1.0RC2 seems to need this format to work properly:
---%<-------------------------------------------------------------------------
$pat = '^dovecot: (... .. ..:..:..) \S+ (?:pop3|imap)-login: Login: \S+ \S+ \S+
lip=(\d+\.\d+\.\d+\.\d+)';
---%<-------------------------------------------------------------------------
Note: This only works with IPv4, anyone who wants to fix it for IPv6, please do
so:)
worked for me on Fedora:
---%<-------------------------------------------------------------------------
$pat = '(?:pop3|imap)-login: (... .. ..:..:..) Info: Login: \S+
\[(\d+\.\d+\.\d+\.\d+)\]';
---%<-------------------------------------------------------------------------
With v1.0 Alpha 4, the following pattern works:
---%<-------------------------------------------------------------------------
$pat = '^(... .. ..:..:..) \S+ (?:dovecot: )?(?:imap|pop3)-login: Login: \S+
\S+ rip=(\d+\.\d+\.\d+\.\d+)'
---%<-------------------------------------------------------------------------
This works with RHEL 4.3 (at least until IPv6 really catches):
---%<-------------------------------------------------------------------------
$pat = '(?:pop3|imap)-login: (... .. ..:..:..) Info: Login: \S+
\[::ffff:(\d+\.\d+\.\d+\.\d+)\]';
---%<-------------------------------------------------------------------------
DRAC
====
There is a Dovecot plugin for DRAC [http://mail.cc.umanitoba.ca/drac/] at
drac.c [http://www.dovecot.org/patches/1.1/drac.c]. DRAC runs as a separate
daemon, maintaining a BerkeleyDB database of IPs that have successfully
authenticated via POP3 or IMAP, expiring them after 30 minutes. Installing it
therefore requires that both your POP3/IMAP server and your SMTP daemon
(Postfix/Sendmail/qmail) be set up to support it. DRAC is a small C program,
and accessing BerkeleyDB databases is efficient so it works pretty well.
The file drac.c has instructions on how to compile it in a comment at the top.
By following the instructions you will install a file drac.so in your dovecot
'lib/' directories for IMAP and/or POP3 loadable modules.
To turn on the new DRAC plugin in dovecot, you must set up these lines in your
dovecot.conf. There is a separate section for ''protocol imap'' and another
under ''protocol pop3''; make sure you enable both.
---%<-------------------------------------------------------------------------
# Support for dynamically loadable modules
mail_plugin_dir = /usr/lib/dovecot/imap
mail_plugins = drac # provide a list of all
plugins you want to load here
---%<-------------------------------------------------------------------------
Permissions note: the directory containing the drac.so file has to be readable
by ordinary users. Check your Dovecot error log for help.
To get DRAC working on your machine, download the main DRAC
[http://mail.cc.umanitoba.ca/drac/] daemon, edit the makefile as directed in
the instructions, and make and install it. You will also want to ensure that
you register the rpcs by executing rpcgen. See the Makefile for more details.
SQL
===
Advantage: you do not have a multi-megabyte Perl daemon reading your logs
Disadvantage: for each login you need the time and space to execute this script
1. tell your MTA to look up IPs authorized to relay in an SQL table
2. delete old IPs from the table regularly (cron job for example, or a
modification to the script below)
3. tell dovecot to update the SQL table upon successful login
Dovecot 1.0 (and probably 0.99) can update a SQL table with the script below.
/!\ *Note* that *you* must set up a script that deletes old IPs separately, and
*you* also must configure your MTA properly. The script *only* performs the
'update on successful login' step, which alone is insecure without expiring
older IPs!/Add your working examples to this section. This Wiki depends on your
help!/
---%<-------------------------------------------------------------------------
#!/bin/sh
# This script created 2005-08-21 by Lorens Kockum
# Released into the Public Domain
# Changes:
# 2006-06-06 Matthias Andree
# - changed $* to "$@" for more robust argument quoting
# Action: when called by dovecot 1.0 as described below, updates an SQL table
# with logged-in IP and current time, and then executes the relevant process.
# Output: normally nothing
# dovecot.conf should be modified with these lines (where
# /usr/lib/dovecot/popbsmtp.sh represents this script):
# protocol pop3 {
# mail_executable = /usr/lib/dovecot/popbsmtp.sh /usr/lib/dovecot/pop3
# }
# protocol imap {
# mail_executable = /usr/lib/dovecot/popbsmtp.sh /usr/lib/dovecot/imap
# }
# The HOME= lines are necessary to find $HOME/.my.cnf containing login info,
# because mail_executable is executed as root, but without a home directory.
# Of course this script must not be writable by anyone else than root.
(
# drop out IPs from local networks that can relay anyway
IP=`echo $IP | grep -v '^192\.168\.'`
if [ -n "$IP" ]
then
export HOME=/root/
echo "replace into popbsmtp VALUES('$IP',now());" | mysql mail
export HOME=/
fi
) >> /var/log/dovecot3 2>&1
exec "$@"
---%<-------------------------------------------------------------------------
Example for postgresql, postfix
-------------------------------
/usr/lib/dovecot/popbsmtp.sh
---%<-------------------------------------------------------------------------
#!/bin/sh
(
if [ -n "$IP" ]
then
/usr/bin/psql -U popbsmtp -d popbsmtp -c "begin;update auth set
accessed=now() where host=substring('$IP' from 8);commit;insert into auth(host,
accessed) values(substring('$IP' from 8),now());"
fi
) >> /var/log/dovecot3 2>&1
exec "$@"
---%<-------------------------------------------------------------------------
The substring call was necessary because $IP has '::ffff:' or something like
that in front of the IP address on my system. The update followed by an insert,
with the update in a transaction is necessary to replicate mysql's REPLACE INTO
functionality. The INSERT will produce an error if the IP already exists but it
doesn't matter as the UPDATE will have committed by then.
/etc/postfix/main.cf
---%<-------------------------------------------------------------------------
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
permit_tls_clientcerts
check_client_access pgsql:/etc/postfix/popbsmtp.cf
reject_unauth_destination
check_policy_service unix:private/policy
---%<-------------------------------------------------------------------------
/etc/postfix/popbsmtp.cf
---%<-------------------------------------------------------------------------
hosts = localhost
user = username
password = secret
dbname = popbsmtp
query = SELECT 'OK' as result FROM auth WHERE host = '%s'
---%<-------------------------------------------------------------------------
/etc/cron.hourly/popbsmtp_purge
---%<-------------------------------------------------------------------------
#!/bin/bash
/usr/bin/psql -U popbsmtp -d popbsmtp -c "DELETE FROM auth WHERE (now() -
accessed) > '30 minutes'::interval"
---%<-------------------------------------------------------------------------
Example for MySQL, postfix
--------------------------
Note that you can use this even if pop/imap and smtp are not on the same host
as it is the case in my setup.
First you have to create a table (in this example named "popbsmtp") with 2
fields:
* address (varchar 39, primary)
* last_seen (datetime)
varchar size 39 is for IPv6 addresses.You should definitely consider adding
IPv6 support to your popbsmtp solution because postfix and dovecot do well with
IPv6.
/!\ *address field* must be *primary* for "REPLACE into" to work.
/opt/dovecot-popbsmtp.sh
---%<-------------------------------------------------------------------------
#!/bin/sh
(
if [ -n "$IP" ]
then
echo "REPLACE INTO virtual_mail.popbsmtp (address,last_seen)
VALUES ('$IP', NOW( ))" \
| mysql -u user -p secret -h host > /dev/null 2>&1
fi
)
exec "$@"
---%<-------------------------------------------------------------------------
mail_executable in dovecot.conf looks something like this:
---%<-------------------------------------------------------------------------
mail_executable = /opt/dovecot-popbsmtp.sh /usr/libexec/dovecot/imap
---%<-------------------------------------------------------------------------
postfix map (/etc/postfix/mysql_popbsmtp_access_maps.cf):
---%<-------------------------------------------------------------------------
hosts = mysqlhost
user = user
password = secret
dbname = virtual_mail
query = SELECT 'OK' FROM popbsmtp WHERE last_seen >= DATE_SUB(NOW(),INTERVAL 30
MINUTE) AND address = '%s'
---%<-------------------------------------------------------------------------
In postfix main.cf add the following access map to your recipient restrictions
(/!\ *before* "reject_unauth_destination"):
---%<-------------------------------------------------------------------------
check_client_access mysql:$config_directory/mysql_popbsmtp_access_maps.cf
---%<-------------------------------------------------------------------------
The 30 minute relay access period is handled by the INTERVAL in DATE_SUB. So
it's safe anyway, but you should definitely run a cron job daily that deletes
older records. That's to keep the table clean and speed up lookups. You might
also need to run "OPTIMIZE TABLE" via the cron job to free up allocated space.
relay-ctrl
==========
relay-ctrl [http://untroubled.org/relay-ctrl/] consists of a few small programs
designed to fit in qmail-like command chains. The most important:
* 'relay-ctrl-allow' runs after a successful POP/IMAP login, recording the
client IP and timestamp
* 'relay-ctrl-check' runs before the SMTP server, enabling relaying if the
client IP has authenticated recently
'relay-ctrl-allow' expects to find the client IP in the environment as
'$TCPREMOTEIP'. Dovecot provides it as '$IP', so you'll need this tiny
'dovecot-settcpremoteip' wrapper script:
---%<-------------------------------------------------------------------------
#!/bin/sh
#
# Wrapper for relay-ctrl-allow that sets TCPREMOTEIP.
TCPREMOTEIP="${IP}"; export TCPREMOTEIP
exec "$@"
---%<-------------------------------------------------------------------------
Edit 'dovecot.conf' and set 'mail_executable' appropriately, e.g., for IMAP
(this is one long line):
---%<-------------------------------------------------------------------------
mail_executable = /usr/local/bin/envdir /etc/relay-ctrl
/usr/local/bin/relay-ctrl-chdir /usr/local/bin/dovecot-settcpremoteip
/usr/local/bin/relay-ctrl-allow /usr/local/libexec/dovecot/imap
Dove
---%<-------------------------------------------------------------------------
Restart Dovecot. Verify that your IMAP client still works. Verify that
relay-ctrl has recorded your client IP. Hook 'relay-ctrl-check' into your SMTP
service, as documented in the relay-ctrl README, and you're done.
(This file was created from the wiki on 2011-01-13 04:52)
wiki/mutt.txt 0000666 00000006136 15050120373 0007247 0 ustar 00 Contents
1. Using mutt with IMAP
1. configuration
2. problems
1. Move read messages to mbox
2. New mail in a folder just left
3. Authentication realm
2. References
Using mutt with IMAP
====================
configuration
-------------
First, mutt needs to be told to use IMAP. To achieve this, edit '~/.muttrc' (or
a file it 'source's) to contain:
---%<-------------------------------------------------------------------------
set spoolfile=imap://user@hostname/INBOX
set folder=imap://user@hostname/
---%<-------------------------------------------------------------------------
problems
--------
Move read messages to mbox
--------------------------
If mutt asks 'Move read messages to /home/$user/mbox? ([no]/yes):'
Your alternatives (to set in '~/.muttrc') are (pick one and ignore the others):
1. don't ask about moving messages, just do it:
---%<---------------------------------------------------------------------
set move=yes
---%<---------------------------------------------------------------------
2. don't ask about moving messages and _don't_ do it:
---%<---------------------------------------------------------------------
set move=no
---%<---------------------------------------------------------------------
3. ask about moving message, default answer 'yes':
---%<---------------------------------------------------------------------
set move=ask-yes
---%<---------------------------------------------------------------------
4. ask about moving message, default answer 'no':
---%<---------------------------------------------------------------------
set move=ask-no
---%<---------------------------------------------------------------------
New mail in a folder just left
------------------------------
There is a bug with dovecot in <=0.99. It can sometimes make mutt think there
is new email in a mailbox you just
'left'...http://www.dovecot.org/list/dovecot/2004-February/002950.html
Authentication realm
--------------------
If you are using IMAP with SASL and get error messages like 'Invalid realm' in
your dovecot log files, try putting this in your '.muttrc' or '/etc/Muttrc]':
---%<-------------------------------------------------------------------------
set imap_authenticators="plain"
---%<-------------------------------------------------------------------------
It might be easier however to just put the following in your 'dovecot.conf':
For Dovecot 1.0:
---%<-----------------------------------------------------------------------
auth default {
mechanisms = plain
}
---%<-----------------------------------------------------------------------
For Dovecot 0.99:
---%<-----------------------------------------------------------------------
auth_mechanisms = plain
---%<-----------------------------------------------------------------------
References
==========
* Official mutt homepage [http://www.mutt.org/]
* mutt with IMAP documentation [http://mutt.sourceforge.net/imap/]
* http://jamespo.org.uk/blog/archives/000271.html
(This file was created from the wiki on 2011-01-13 04:52)
wiki/Pigeonhole.Sieve.Configuration.txt 0000666 00000030663 15050120373 0014231 0 ustar 00 Pigeonhole Sieve Configuration
==============================
Basic Configuration
-------------------
To use Sieve, you will first need to make sure you are using Dovecot