1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
Lazy expunge
============
The idea behind this plugin is that expunged mails and deleted mailboxes stay
around for a while, so that user can undelete them without assistance from
sysadmin. The expunged mails won't be counted in user's quota. The plugin
itself doesn't clean up the expunged messages, you'll have to do it some other
way (see below).
The plugin is configured by defining namespaces where the mails are moved. You
can decide if you want the namespaces to be visible to clients, or if you want
to show them only via some special webmail interface.
1 mailbox (v2.2.24+)
--------------------
You create a single mailbox. All messages that are expunged from all the
mailboxes are moved there. This is the simplest configuration. The mailbox is
created automatically. You probably also want to hide it with an ACL.
---%<-------------------------------------------------------------------------
mail_plugins = $mail_plugins lazy_expunge acl
plugin {
lazy_expunge = .EXPUNGED
acl = vfile:/etc/dovecot/dovecot.acl
# Expunged messages most likely don't want to be included in quota:
quota_rule2 = .EXPUNGED:ignore
}
---%<-------------------------------------------------------------------------
Where '/etc/dovecot/dovecot.acl' contains:
---%<-------------------------------------------------------------------------
.EXPUNGED owner rwstipekxa
---%<-------------------------------------------------------------------------
You could also leave the permissions empty if you don't want to allow clients
to access it at all.
1 namespace
-----------
You create only a single namespace. When a message is expunged from mailbox
/<name>/, it's moved to a mailbox /<name>/ in the expunge namespace. When an
entire mailbox /<name>/ is deleted, it's also moved to this namespace as
/<name>/. If it already exists, their contents are merged.
Example configuration:
---%<-------------------------------------------------------------------------
# the default namespace
namespace {
prefix =
separator = /
inbox = yes
}
# namespace for lazy_expunge plugin:
namespace {
prefix = .EXPUNGED/
hidden = yes
list = no
separator = /
location = maildir:~/Maildir/expunged
}
mail_plugins = $mail_plugins lazy_expunge
plugin {
lazy_expunge = .EXPUNGED/
}
---%<-------------------------------------------------------------------------
3 namespaces (obsolete, v2.0 only)
----------------------------------
The namespaces are:
1. Expunged messages namespace. Whenever a message is expunged in mailbox
/<name>/, it's moved to a mailbox /<name>/ in this namespace. The mailboxes
are created automatically as needed.
2. Deleted mailboxes namespace. Whenever a mailbox /<name>/ is deleted, it's
moved here with name /<name>-YYYMMDD-hhmmss/. The timestamp is there so
that the mailbox can be deleted multiple times. If the mailbox is deleted
multiple times within a second, random 16bit hex value is appended to it.
3. Expunged messages in a deleted mailbox namespace. When a mailbox is deleted
and it has messages in its expunged namespace, the mailbox is moved from
the expunged namespace to this namespace. The destination mailbox name is
the same as in the 2nd namespace (ie. contains the same timestamp).
Example configuration:
---%<-------------------------------------------------------------------------
# the default namespace
namespace {
prefix =
separator = /
inbox = yes
}
# namespaces for lazy_expunge plugin:
namespace {
prefix = .EXPUNGED/
separator = /
location = maildir:~/Maildir/expunged
}
namespace {
prefix = .DELETED/
separator = /
location = maildir:~/Maildir/deleted
}
namespace {
prefix = .DELETED/.EXPUNGED/
separator = /
location = maildir:~/Maildir/deleted/expunged
}
mail_plugins = $mail_plugins lazy_expunge
plugin {
lazy_expunge = .EXPUNGED/ .DELETED/ .DELETED/.EXPUNGED/
}
---%<-------------------------------------------------------------------------
Multi-dbox
----------
With multi-dbox use different MAILBOXDIRs (so copying between namespaces works
quickly within the same storage), but otherwise exactly the same paths (index,
control):
---%<-------------------------------------------------------------------------
# the default namespace
namespace {
prefix =
inbox = yes
location = mdbox:~/mdbox:INDEX=/var/index/%d/%n
}
# lazy_expunge namespace(s):
namespace {
prefix = .EXPUNGED/
hidden = yes
list = no
subscriptions = no
location = mdbox:~/mdbox:INDEX=/var/index/%d/%n:MAILBOXDIR=expunged
# If mailbox_list_index=yes is enabled, it needs a separate index file
(v2.2.28+):
#location =
mdbox:~/mdbox:INDEX=/var/index/%d/%n:MAILBOXDIR=expunged:LISTINDEX=expunged.list.index
}
---%<-------------------------------------------------------------------------
Copy only the last instance (v2.2+)
-----------------------------------
If mail has multiple copies (via IMAP COPY), each copy is normally moved to
lazy expunge namespace when it's expunged. With v2.2+ you can set 'plugin {
lazy_expunge_only_last_instance = yes }' to copy only the last instance and
immediately expunge the others. This may be useful if you want to provide a
flat list of all expunged mails without duplicates in your webmail. With many
clients this means that the last instance is always in the Trash mailbox.
Cleaning up
-----------
doveadm
-------
---%<-------------------------------------------------------------------------
doveadm expunge mailbox 'deleted/*' savedsince 1d
---%<-------------------------------------------------------------------------
cronjob
-------
Run something like this for each user every night (not actually tested if it
works, and vulnerable to TOCTTOU if the user can place symlinks in any of the
directories find is traversing):
---%<-------------------------------------------------------------------------
# delete a day old mails
find Maildir/expunged Maildir/deleted Maildir/deleted/expunged \
-type f ! -cmin 1440 -print0 | xargs -0 rm
---%<-------------------------------------------------------------------------
Trash plugin
------------
<Trash plugin> [Plugins.Trash.txt] with some help from <Quota plugin>
[Quota.txt] could probably be used to keep the expunged and deleted mailboxes
under a specified size (not tested).
Expire plugin
-------------
<Expire plugin> [Plugins.Expire.txt] was created to keep track of mails in
specific mailboxes, and expunge them when they've been there for a specified
amount of time. It keeps an internal database (e.g. SQL) of all such mailboxes,
so it doesn't have to go through all the mailboxes for all the users.
(This file was created from the wiki on 2019-06-19 12:42)
|