]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/cyrus-imapd-2.2.12-autocreate-0.9.4.diff
tor: Bump package version to 6 and fix backup.
[people/teissler/ipfire-2.x.git] / src / patches / cyrus-imapd-2.2.12-autocreate-0.9.4.diff
1 diff -Naur cyrus-imapd-2.2.12/README.autocreate cyrus-imapd-2.2.12.autocreate2/README.autocreate
2 --- cyrus-imapd-2.2.12/README.autocreate 1970-01-01 02:00:00.000000000 +0200
3 +++ cyrus-imapd-2.2.12.autocreate2/README.autocreate 2005-10-19 14:48:57.930991000 +0300
4 @@ -0,0 +1,181 @@
5 +Cyrus IMAP autocreate Inbox patch
6 +----------------------------------
7 +
8 +NOTE : This patch has been created at the University of Athens. For more info, as well
9 +as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr
10 +
11 +The design of Cyrus IMAP server does not predict the automatic creation of users'
12 +INBOX folders. The creation of a user's INBOX is considered to be an external task,
13 +that has to be completed as part of the user e-mail account creation procedure.
14 +Hence, to create a new e-mail account the site administrator has to
15 +a) Include the new account in the user database for the authentication procedure
16 + (e.g. sasldb, shadow, mysql, ldap).
17 +b) Create the corresponding INBOX folder.
18 +
19 +Alternatively, the user, if succesfully authenticated, may create his own INBOX folder,
20 +as long as the configuration of the site allows it (see "autocreatequota" in imapd.conf).
21 +Unlike what uncareful readers may think, enabling the "autocreatequota" option, doesn't
22 +lead to the automatic INBOX folder creation by Cyrus IMAP server.
23 +In fact, "autocreate" means that the IMAP clients are allowed to automatically create
24 +the user INBOX.
25 +
26 +This patch adds the functionality of automatic creation of the users' INBOX folders into
27 +the Cyrus IMAP server. It is implemented as two features, namely the "create on login"
28 +and "create on post".
29 +
30 +
31 +
32 +Create on login
33 +===============
34 +This feauture provides automatic creation of a user's INBOX folder when all of the
35 +following requirements are met:
36 +
37 +i) The user has succesfully passed the authentication procedure.
38 +
39 +ii) The user's authorization ID (typically the same as the user's
40 +authentication ID) doesn't belong to the imap_admins or admins
41 +accounts (see imapd.conf).
42 +
43 +iii) The "autocreatequota" option in the imap configuration file
44 +has been set to a non zero value.
45 +
46 +iv) The corresponding to the user's authorizationID INBOX folder
47 +does not exist.
48 +
49 +The user's first login is the most typical case when all four requirements are met.
50 +Note that if the authenticatedID is allowed to proxy to another account for which
51 +all of the above requirements are met, the corresponding INBOX folder for that account
52 +will be created.
53 +
54 +
55 +
56 +Create on post
57 +==============
58 +This feauture provides automatic creation of a user's INBOX folder when all of the
59 +following requirements are met.
60 +
61 +i) An e-mail message addressed to the user has been received.
62 +
63 +ii) The recipient is not any of the imap_admins or admins accounts.
64 +Note that passing e-mails to admins or imap_admins accounts from
65 +the MTA to LMTP should be avoided in any case.
66 +
67 +iii) The recipient's INBOX does not exist.
68 +
69 +iv) The "autocreatequota" option in the imap configuration file
70 +has been set to a non zero value.
71 +
72 +v) The "createonpost" option in the imap configuration file
73 +has been switched on.
74 +
75 +
76 +Besides the automatic creation of INBOX folder, additional functionalities are
77 +provided:
78 +
79 +A) Automatic creation of INBOX subfolders controlled by "autocreateinboxfolders"
80 +configuration option. eg
81 +
82 +autocreateinboxfolders: sent|drafts|spam|templates
83 +
84 +B) Automatic subscription of INBOX subfolders controlled by "autosubscribeinboxfolders"
85 +configuration option. eg
86 +
87 +autosubscribeinboxfolders: sent|spam
88 +
89 +Obviously, only subscription to subfolders included in the "autocreateinboxfolder"
90 +list is meaningfull.
91 +
92 +C) Automatic subscription to shared folders (bulletin boards). The user gets
93 +automatically subscribed to the shared folders declared in the "autosubscribesharedfolders"
94 +configuration option in imapd.conf.
95 +eg autosubscribesharedfolders: public_folder | public_folder.subfolder
96 +
97 +In order the above action to succeed, the shared folder has to pre-exist the INBOX creation
98 +and the user must have the apropriate permissions in order to be able to subscribe to the
99 +shared folder.
100 +
101 +* A new config option has been added. 'autosubscribe_all_sharedfolders' is a yes/no
102 +option. When set to yes, the user is automatically subscribed to all shared folders one
103 +has permission to subscribe to. Please, note that when this option is set to yes, then
104 +'autosubscribesharedfolders' option is overriden.
105 +
106 +D) Automatic creation of a predefined default sieve script.
107 +
108 +This is very useful when a default sieve script is used for every user. Usually, a
109 +default anti-spam script may me be written in a file and copied to each user
110 +sieve scripts upon the INBOX creation. The imapd.conf options that have been added
111 +are 'autocreate_sieve_script', 'autocreate_sieve_compiledscript' and
112 +'generate_compiled_sieve_script'.
113 +
114 +autocreate_sieve_script configuration option refers to the full path of the file
115 +that contains the sieve script. The default value is null and if no file is defined,
116 +then no default script is created upon INBOX creation. (The feature is disabled)
117 +eg autocreate_sieve_script: /etc/default_sieve_script
118 +
119 +autocreate_sieve_compiledscript configuration option refers to the full path of the
120 +file that contains the bytecode compiled sieve script. If this filename is defined
121 +in imapd.conf and the file exists, then it is automatically copied in the user's sieve
122 +directory. If it is not defined, then a bytecode sieve script gets on the fly compiled
123 +by the daemon.
124 +eg autocreate_sieve_compiledscript: /etc/default_sieve_script.bc
125 +
126 +generate_compiled_sieve_script is a boolean option that triggers the compilation of the
127 +source sieve script to bytecode sieve script. The file that the bytecode script will
128 +be saved is pointed by autocreate_sieve_compiledscript.
129 +
130 +Ways of compiling a sieve script :
131 +1. Compile a sieve script using the standard sievec utility, distributed by CMU
132 +2. Compile a sieve script using the compile_sieve utility, released by UoA. This
133 + tool is almost identical to the sievec utility, with the difference that it
134 + reads the input and output file from autocreate_sieve_script and
135 + autocreate_sieve_compiledscript options in imapd.conf
136 +3. Let cyrus create a compiled sieve script using a source script. Cyrus can be
137 + instructed to save the compiled script any time a compiled script does not exist.
138 +
139 +NOTES :
140 +1. In order this functionality to work, the following requirements must have been met:
141 + - 'sieveusehomedir' option must be 'no' in the configuration (default).
142 + - 'sievedir' option must have a valid value.
143 +2. Currently, this patch checks the validity of the source script while generating a
144 + bytecode compiled script, but not the validity of the bytecode sieve script file.
145 + The administrator should make sure that the provided files contain a valid sieve
146 + script as well as the compiled script is updated every time the source script changes.
147 +
148 +
149 +
150 +Issues to be considered
151 +=======================
152 +
153 +I) In order to use the create on post feauture one should be absolutely sure that:
154 +a) The MTA checks the validity of the e-mail recipient before sending the e-mail to
155 +LMTP. This is an RFC821 requirement. This usually expands to "the mta should be
156 +able to use the account database as user mailbox database".
157 +b) Only authorized accounts/services can talk to LMTP.
158 +
159 +II) Especially in the case of imap logins, the current patch implementation checks
160 +for the INBOX folder existence upon login, causing an extra mailbox lookup in most
161 +of the cases.
162 +A better approach would be to chase the "IMAP_MAILBOX_NONEXISTENT" error code and
163 +check if the error is associated with an INBOX folder. However, this would mess up
164 +Cyrus code. The way it was implemented may not have been the most performance
165 +optimized, but it produces a much cleaner and simple patch.
166 +
167 +
168 +
169 +Virtual Domains Support
170 +=======================
171 +
172 +Virtual domains are supported by all versions of the patch for cyrus-imapd-2.2.1-BETA and
173 +later. However, it is not possible to declare different INBOX subfolders to be created or
174 +shared folders to be subscribed to for every domain.
175 +
176 +
177 +
178 +Things to be done
179 +=================
180 +
181 +1. Support MURDER architecture.
182 +
183 +
184 +For more information and updates please visit http://email.uoa.gr/autocreate
185 +
186 diff -Naur cyrus-imapd-2.2.12/imap/Makefile.in cyrus-imapd-2.2.12.autocreate2/imap/Makefile.in
187 --- cyrus-imapd-2.2.12/imap/Makefile.in 2004-05-28 21:03:02.000000000 +0300
188 +++ cyrus-imapd-2.2.12.autocreate2/imap/Makefile.in 2005-10-19 14:48:57.935240000 +0300
189 @@ -104,7 +104,7 @@
190 convert_code.o duplicate.o saslclient.o saslserver.o signals.o \
191 annotate.o search_engines.o squat.o squat_internal.o mbdump.o \
192 imapparse.o telemetry.o user.o notify.o protocol.o quota_db.o \
193 - $(SEEN) $(IDLE)
194 + autosieve.o $(SEEN) $(IDLE)
195
196 IMAPDOBJS=pushstats.o backend.o imapd.o index.o tls.o version.o
197
198 @@ -122,7 +122,7 @@
199 fud smmapd reconstruct quota mbpath ipurge \
200 cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \
201 ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \
202 - @IMAP_PROGS@
203 + compile_sieve @IMAP_PROGS@
204
205 BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \
206 lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \
207 @@ -188,7 +188,7 @@
208 ### Services
209 idled: idled.o mutex_fake.o libimap.a $(DEPLIBS)
210 $(CC) $(LDFLAGS) -o idled \
211 - idled.o mutex_fake.o libimap.a $(DEPLIBS) $(LIBS)
212 + idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
213
214 lmtpd: lmtpd.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) \
215 $(DEPLIBS) $(SERVICE)
216 @@ -214,10 +214,10 @@
217 $(SERVICE) lmtpproxyd.o backend.o $(LMTPOBJS) mutex_fake.o \
218 libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
219
220 -imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
221 +imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
222 $(CC) $(LDFLAGS) -o imapd \
223 $(SERVICE) $(IMAPDOBJS) mutex_fake.o \
224 - libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
225 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
226
227 imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
228 $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \
229 @@ -232,7 +232,7 @@
230 proxyd: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
231 $(CC) $(LDFLAGS) -o proxyd \
232 $(SERVICE) $(PROXYDOBJS) mutex_fake.o libimap.a \
233 - $(DEPLIBS) $(LIBS) $(LIB_WRAP)
234 + $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
235
236 proxyd.pure: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
237 $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o proxyd.pure \
238 @@ -244,7 +244,7 @@
239 $(CC) $(LDFLAGS) -o mupdate \
240 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
241 mutex_pthread.o tls.o libimap.a \
242 - $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
243 + $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
244
245 mupdate.pure: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o \
246 libimap.a $(DEPLIBS)
247 @@ -252,92 +252,96 @@
248 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
249 mutex_pthread.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
250
251 -pop3d: pop3d.o backend.o tls.o mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
252 +pop3d: pop3d.o backend.o tls.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
253 $(CC) $(LDFLAGS) -o pop3d pop3d.o backend.o tls.o $(SERVICE) \
254 - mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
255 + mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
256
257 nntpd: nntpd.o backend.o index.o smtpclient.o spool.o tls.o \
258 mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE)
259 $(CC) $(LDFLAGS) -o nntpd nntpd.o backend.o index.o spool.o \
260 smtpclient.o tls.o $(SERVICE) mutex_fake.o nntp_err.o \
261 - libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
262 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
263
264 -fud: fud.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE)
265 +fud: fud.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
266 $(CC) $(LDFLAGS) -o fud $(SERVICE) fud.o mutex_fake.o libimap.a \
267 - $(DEPLIBS) $(LIBS) $(LIB_WRAP)
268 + $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
269
270 -smmapd: smmapd.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE)
271 +smmapd: smmapd.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
272 $(CC) $(LDFLAGS) -o smmapd $(SERVICE) smmapd.o mutex_fake.o libimap.a \
273 - $(DEPLIBS) $(LIBS) $(LIB_WRAP)
274 + $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
275
276 ### Command Line Utilities
277 -arbitron: arbitron.o $(CLIOBJS) libimap.a $(DEPLIBS)
278 +arbitron: arbitron.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
279 $(CC) $(LDFLAGS) -o arbitron arbitron.o $(CLIOBJS) \
280 - libimap.a $(DEPLIBS) $(LIBS)
281 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
282 +
283 +compile_sieve: compile_sieve.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
284 + $(CC) $(LDFLAGS) -o compile_sieve compile_sieve.o $(CLIOBJS) \
285 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
286
287 -cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(DEPLIBS)
288 +cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
289 $(CC) $(LDFLAGS) -o cvt_cyrusdb cvt_cyrusdb.o $(CLIOBJS) \
290 - libimap.a $(DEPLIBS) $(LIBS)
291 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
292
293 -chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(DEPLIBS)
294 +chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
295 $(CC) $(LDFLAGS) -o chk_cyrus chk_cyrus.o $(CLIOBJS) \
296 - libimap.a $(DEPLIBS) $(LIBS)
297 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
298
299 -deliver: deliver.o backend.o $(LMTPOBJS) mutex_fake.o libimap.a $(DEPLIBS)
300 +deliver: deliver.o backend.o $(LMTPOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
301 $(CC) $(LDFLAGS) -o deliver deliver.o backend.o $(LMTPOBJS) \
302 - mutex_fake.o libimap.a $(DEPLIBS) $(LIBS)
303 + mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
304
305 -ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS)
306 +ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
307 $(CC) $(LDFLAGS) -o \
308 - $@ ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
309 + $@ ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
310
311 -ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(DEPLIBS)
312 +ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
313 $(CC) $(LDFLAGS) -o $@ ctl_mboxlist.o mupdate-client.o $(CLIOBJS) \
314 - libimap.a $(DEPLIBS) $(LIBS)
315 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
316
317 -ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS)
318 +ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
319 $(CC) $(LDFLAGS) -o \
320 - $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
321 + $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
322
323 -cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(DEPLIBS)
324 +cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
325 $(CC) $(LDFLAGS) -o $@ cyr_expire.o $(CLIOBJS) \
326 - libimap.a $(DEPLIBS) $(LIBS)
327 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
328
329 -fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS)
330 +fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
331 $(CC) $(LDFLAGS) -o \
332 - $@ fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
333 + $@ fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
334
335 -squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(DEPLIBS)
336 +squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
337 $(CC) $(LDFLAGS) -o squatter squatter.o index.o squat_build.o \
338 - $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
339 + $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
340
341 -mbpath: mbpath.o $(CLIOBJS) libimap.a $(DEPLIBS)
342 +mbpath: mbpath.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
343 $(CC) $(LDFLAGS) -o mbpath mbpath.o $(CLIOBJS) libimap.a \
344 - $(DEPLIBS) $(LIBS)
345 + $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
346
347 -ipurge: ipurge.o $(CLIOBJS) libimap.a $(DEPLIBS)
348 +ipurge: ipurge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
349 $(CC) $(LDFLAGS) -o ipurge ipurge.o $(CLIOBJS) \
350 - libimap.a $(DEPLIBS) $(LIBS)
351 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
352
353 -cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(DEPLIBS)
354 +cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
355 $(CC) $(LDFLAGS) -o cyrdump cyrdump.o index.o $(CLIOBJS) \
356 - libimap.a $(DEPLIBS) $(LIBS)
357 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
358
359 -mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS)
360 +mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
361 $(CC) $(LDFLAGS) -o \
362 - mbexamine mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
363 + mbexamine mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
364
365 -reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS)
366 +reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
367 $(CC) $(LDFLAGS) -o \
368 - reconstruct reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
369 + reconstruct reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
370
371 -quota: quota.o $(CLIOBJS) libimap.a $(DEPLIBS)
372 +quota: quota.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
373 $(CC) $(LDFLAGS) -o quota quota.o $(CLIOBJS) \
374 - libimap.a $(DEPLIBS) $(LIBS)
375 + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
376
377 -tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS)
378 +tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
379 $(CC) $(LDFLAGS) -o \
380 - $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
381 + $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
382
383 ### Other Misc Targets
384
385 diff -Naur cyrus-imapd-2.2.12/imap/autosieve.c cyrus-imapd-2.2.12.autocreate2/imap/autosieve.c
386 --- cyrus-imapd-2.2.12/imap/autosieve.c 1970-01-01 02:00:00.000000000 +0200
387 +++ cyrus-imapd-2.2.12.autocreate2/imap/autosieve.c 2005-10-19 14:48:57.940098000 +0300
388 @@ -0,0 +1,587 @@
389 +#include <stdio.h>
390 +#include <stdlib.h>
391 +#include <string.h>
392 +
393 +#ifdef HAVE_UNISTD_H
394 +#include <unistd.h>
395 +#endif
396 +
397 +#include <errno.h>
398 +#include <sys/types.h>
399 +#include <sys/stat.h>
400 +#include <sys/uio.h>
401 +#include <fcntl.h>
402 +#include <ctype.h>
403 +#include <time.h>
404 +#include <syslog.h>
405 +#include <com_err.h>
406 +#include <config.h>
407 +
408 +#include "global.h"
409 +#include "util.h"
410 +#include "mailbox.h"
411 +#include "imap_err.h"
412 +#include "sieve_interface.h"
413 +#include "script.h"
414 +
415 +#define TIMSIEVE_FAIL -1
416 +#define TIMSIEVE_OK 0
417 +#define MAX_FILENAME 1024
418 +
419 +static int get_script_name(char *sievename, size_t buflen, const char *filename);
420 +static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir);
421 +int autoadd_sieve(char *userid, const char *source_script);
422 +
423 +static void fatal(const char *s, int code);
424 +static void foo(void);
425 +static int sieve_notify(void *ac __attribute__((unused)),
426 + void *interp_context __attribute__((unused)),
427 + void *script_context __attribute__((unused)),
428 + void *message_context __attribute__((unused)),
429 + const char **errmsg __attribute__((unused)));
430 +static int mysieve_error(int lineno, const char *msg,
431 + void *i __attribute__((unused)), void *s);
432 +static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
433 +
434 +
435 +sieve_vacation_t vacation2 = {
436 + 0, /* min response */
437 + 0, /* max response */
438 + (sieve_callback *) &foo, /* autorespond() */
439 + (sieve_callback *) &foo /* send_response() */
440 +};
441 +
442 +
443 +/*
444 + * Find the name of the sieve script
445 + * given the source script and compiled script names
446 + */
447 +static int get_script_name(char *sievename, size_t buflen, const char *filename)
448 +{
449 + char *p;
450 + int r;
451 +
452 + p = strrchr(filename, '/');
453 + if (p == NULL)
454 + p = (char *) filename;
455 + else
456 + p++;
457 +
458 + r = strlcpy(sievename, p, buflen) - buflen;
459 + return (r >= 0 || r == -buflen ? 1 : 0);
460 +}
461 +
462 +
463 +/*
464 + * Find the directory where the sieve scripts of the user
465 + * reside
466 + */
467 +static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir)
468 +{
469 + char *user = NULL, *domain = NULL;
470 +
471 + /* Setup the user and the domain */
472 + if(config_virtdomains && (domain = strchr(userid, '@'))) {
473 + user = (char *) xmalloc((domain - userid +1) * sizeof(char));
474 + strlcpy(user, userid, domain - userid + 1);
475 + domain++;
476 + } else
477 + user = userid;
478 +
479 + /* Find the dir path where the sieve scripts of the user will reside */
480 + if (config_virtdomains && domain) {
481 + if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/",
482 + sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain), domain, dir_hash_c(user), user) >= buflen) {
483 + free(user);
484 + return 1;
485 + }
486 + } else {
487 + if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/",
488 + sieve_dir, dir_hash_c(user), user) >= buflen)
489 + return 1;
490 + }
491 +
492 + /* Free the xmalloced user memory, reserved above */
493 + if(user != userid)
494 + free(user);
495 +
496 + return 0;
497 +}
498 +
499 +int autoadd_sieve(char *userid, const char *source_script)
500 +{
501 + sieve_script_t *s = NULL;
502 + bytecode_info_t *bc = NULL;
503 + char *err = NULL;
504 + FILE *in_stream, *out_fp;
505 + int out_fd, in_fd, r, k;
506 + int do_compile = 0;
507 + const char *sieve_dir = NULL;
508 + const char *compiled_source_script = NULL;
509 + char sievename[MAX_FILENAME];
510 + char sieve_script_name[MAX_FILENAME];
511 + char sieve_script_dir[MAX_FILENAME];
512 + char sieve_bcscript_name[MAX_FILENAME];
513 + char sieve_default[MAX_FILENAME];
514 + char sieve_tmpname[MAX_FILENAME];
515 + char sieve_bctmpname[MAX_FILENAME];
516 + char sieve_bclink_name[MAX_FILENAME];
517 + char buf[4096];
518 + mode_t oldmask;
519 + struct stat statbuf;
520 +
521 + /* We don't support using the homedirectory, like timsieved */
522 + if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) {
523 + syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf");
524 + return 1;
525 + }
526 +
527 + /* Check if sievedir is defined in imapd.conf */
528 + if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) {
529 + syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf");
530 + return 1;
531 + }
532 +
533 + /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */
534 + if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
535 + syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it");
536 + do_compile = 1;
537 + }
538 +
539 + if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) {
540 + syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory");
541 + return 1;
542 + }
543 +
544 + if (get_script_name(sievename, sizeof(sievename), source_script)) {
545 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script);
546 + return 1;
547 + }
548 +
549 + if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) {
550 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
551 + return 1;
552 + }
553 + if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) {
554 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
555 + return 1;
556 + }
557 + if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) {
558 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
559 + return 1;
560 + }
561 + if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) {
562 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
563 + return 1;
564 + }
565 + if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) {
566 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
567 + return 1;
568 + }
569 + if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name)) {
570 + syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
571 + return 1;
572 + }
573 +
574 + /* Check if a default sieve filter alrady exists */
575 + if(!stat(sieve_default,&statbuf)) {
576 + syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists");
577 + fclose(in_stream);
578 + return 1;
579 + }
580 +
581 + /* Open the source script. if there is a problem with that exit */
582 + in_stream = fopen(source_script, "r");
583 + if(!in_stream) {
584 + syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script);
585 + return 1;
586 + }
587 +
588 +
589 + /*
590 + * At this point we start the modifications of the filesystem
591 + */
592 +
593 + /* Create the directory where the sieve scripts will reside */
594 + r = cyrus_mkdir(sieve_script_dir, 0755);
595 + if(r == -1) {
596 + /* If this fails we just leave */
597 + syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name);
598 + return 1;
599 + }
600 +
601 + /*
602 + * We open the file that will be used as the bc file. If this file exists, overwrite it
603 + * since something bad has happened. We open the file here so that this error checking is
604 + * done before we try to open the rest of the files to start copying etc.
605 + */
606 + out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
607 + if(out_fd < 0) {
608 + if(errno == EEXIST) {
609 + syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname);
610 + } else if (errno == EACCES) {
611 + syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname);
612 + fclose(in_stream);
613 + return 1;
614 + } else {
615 + syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname);
616 + fclose(in_stream);
617 + return 1;
618 + }
619 + }
620 +
621 + if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) {
622 + while((r = read(in_fd, buf, sizeof(buf))) > 0) {
623 + if((k=write(out_fd, buf,r)) < 0) {
624 + syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno);
625 + close(out_fd);
626 + close(in_fd);
627 + fclose(in_stream);
628 + unlink(sieve_bctmpname);
629 + return 1;
630 + }
631 + }
632 +
633 + if(r == 0) { /* EOF */
634 + close(out_fd);
635 + close(in_fd);
636 + } else if (r < 0) {
637 + syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it",
638 + compiled_source_script);
639 + close(in_fd);
640 + do_compile = 1;
641 + if(lseek(out_fd, 0, SEEK_SET)) {
642 + syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting");
643 + return 1;
644 + }
645 + }
646 + close(in_fd);
647 + } else {
648 + if(compiled_source_script)
649 + syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script);
650 + do_compile = 1;
651 + }
652 +
653 +
654 + /* Because we failed to open a precompiled bc sieve script, we compile one */
655 + if(do_compile) {
656 + if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
657 + if(err && *err) {
658 + syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err);
659 + free(err);
660 + } else
661 + syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script");
662 +
663 + unlink(sieve_bctmpname);
664 + fclose(in_stream);
665 + close(out_fd);
666 + return 1;
667 + }
668 +
669 + /* generate the bytecode */
670 + if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) {
671 + syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script");
672 + /* removing the copied script and cleaning up memory */
673 + unlink(sieve_bctmpname);
674 + sieve_script_free(&s);
675 + fclose(in_stream);
676 + close(out_fd);
677 + return 1;
678 + }
679 +
680 + if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) {
681 + syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script");
682 + /* removing the copied script and cleaning up memory */
683 + unlink(sieve_bctmpname);
684 + sieve_free_bytecode(&bc);
685 + sieve_script_free(&s);
686 + fclose(in_stream);
687 + close(out_fd);
688 + return 1;
689 + }
690 +
691 + /* clean up the memory */
692 + sieve_free_bytecode(&bc);
693 + sieve_script_free(&s);
694 + }
695 +
696 + close(out_fd);
697 + rewind(in_stream);
698 +
699 + /* Copy the initial script */
700 + oldmask = umask(077);
701 + if((out_fp = fopen(sieve_tmpname, "w")) == NULL) {
702 + syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname);
703 + unlink(sieve_bctmpname);
704 + umask(oldmask);
705 + fclose(in_stream);
706 + return 1;
707 + }
708 + umask(oldmask);
709 +
710 + while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) {
711 + if( fwrite(buf,sizeof(char), r, out_fp) != r) {
712 + syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname);
713 + fclose(out_fp);
714 + unlink(sieve_tmpname);
715 + unlink(sieve_bctmpname);
716 + fclose(in_stream);
717 + return 1;
718 + }
719 + }
720 +
721 + if(feof(in_stream)) {
722 + fclose(out_fp);
723 + } else { /* ferror */
724 + fclose(out_fp);
725 + unlink(sieve_tmpname);
726 + unlink(sieve_bctmpname);
727 + fclose(in_stream);
728 + return 1;
729 + }
730 +
731 + /* Renaming the necessary stuff */
732 + if(rename(sieve_tmpname, sieve_script_name)) {
733 + unlink(sieve_tmpname);
734 + unlink(sieve_bctmpname);
735 + return 1;
736 + }
737 +
738 + if(rename(sieve_bctmpname, sieve_bcscript_name)) {
739 + unlink(sieve_bctmpname);
740 + unlink(sieve_bcscript_name);
741 + return 1;
742 + }
743 +
744 + /* end now with the symlink */
745 + if(symlink(sieve_bclink_name, sieve_default)) {
746 + if(errno != EEXIST) {
747 + syslog(LOG_WARNING, "autocreate_sieve: problem making the default link.");
748 + /* Lets delete the files */
749 + unlink(sieve_script_name);
750 + unlink(sieve_bcscript_name);
751 + }
752 + }
753 +
754 + /*
755 + * If everything has succeeded AND we have compiled the script AND we have requested
756 + * to generate the global script so that it is not compiled each time then we create it.
757 + */
758 + if(do_compile &&
759 + config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) {
760 +
761 + if(!compiled_source_script) {
762 + syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf");
763 + return 0;
764 + }
765 +
766 + if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname))
767 + return 0;
768 +
769 + /*
770 + * Copy everything from the newly created bc sieve sieve script.
771 + */
772 + if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) {
773 + return 0;
774 + }
775 +
776 + if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
777 + if(errno == EEXIST) {
778 + /* Someone is already doing this so just bail out. */
779 + syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname);
780 + close(in_fd);
781 + return 0;
782 + } else if (errno == EACCES) {
783 + syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname);
784 + close(in_fd);
785 + return 0;
786 + } else {
787 + syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname);
788 + close(in_fd);
789 + return 0;
790 + }
791 + }
792 +
793 + while((r = read(in_fd, buf, sizeof(buf))) > 0) {
794 + if((k = write(out_fd,buf,r)) < 0) {
795 + syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
796 + close(out_fd);
797 + close(in_fd);
798 + unlink(sieve_tmpname);
799 + return 0;
800 + }
801 + }
802 +
803 + if(r == 0 ) { /*EOF */
804 + close(out_fd);
805 + close(in_fd);
806 + } else if (r < 0) {
807 + syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
808 + close(out_fd);
809 + close(in_fd);
810 + unlink(sieve_tmpname);
811 + return 0;
812 + }
813 +
814 + /* Rename the temporary created sieve script to its final name. */
815 + if(rename(sieve_tmpname, compiled_source_script)) {
816 + if(errno != EEXIST) {
817 + unlink(sieve_tmpname);
818 + unlink(compiled_source_script);
819 + }
820 + return 0;
821 + }
822 +
823 + syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script);
824 + }
825 +
826 + return 0;
827 +}
828 +
829 +static void fatal(const char *s, int code)
830 +{
831 + printf("Fatal error: %s (%d)\r\n", s, code);
832 + exit(1);
833 +}
834 +
835 +/* to make larry's stupid functions happy :) */
836 +static void foo(void)
837 +{
838 + fatal("stub function called", 0);
839 +}
840 +
841 +static int sieve_notify(void *ac __attribute__((unused)),
842 + void *interp_context __attribute__((unused)),
843 + void *script_context __attribute__((unused)),
844 + void *message_context __attribute__((unused)),
845 + const char **errmsg __attribute__((unused)))
846 +{
847 + fatal("stub function called", 0);
848 + return SIEVE_FAIL;
849 +}
850 +
851 +static int mysieve_error(int lineno, const char *msg,
852 + void *i __attribute__((unused)), void *s)
853 +{
854 + char buf[1024];
855 + char **errstr = (char **) s;
856 +
857 + snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
858 + *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
859 + syslog(LOG_DEBUG, "%s", buf);
860 + strcat(*errstr, buf);
861 +
862 + return SIEVE_OK;
863 +}
864 +
865 +/* end the boilerplate */
866 +
867 +/* returns TRUE or FALSE */
868 +int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
869 +{
870 + sieve_interp_t *i;
871 + sieve_script_t *s;
872 + int res;
873 +
874 + res = sieve_interp_alloc(&i, NULL);
875 + if (res != SIEVE_OK) {
876 + syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res);
877 + return TIMSIEVE_FAIL;
878 + }
879 +
880 + res = sieve_register_redirect(i, (sieve_callback *) &foo);
881 + if (res != SIEVE_OK) {
882 + syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res);
883 + return TIMSIEVE_FAIL;
884 + }
885 + res = sieve_register_discard(i, (sieve_callback *) &foo);
886 + if (res != SIEVE_OK) {
887 + syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res);
888 + return TIMSIEVE_FAIL;
889 + }
890 + res = sieve_register_reject(i, (sieve_callback *) &foo);
891 + if (res != SIEVE_OK) {
892 + syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res);
893 + return TIMSIEVE_FAIL;
894 + }
895 + res = sieve_register_fileinto(i, (sieve_callback *) &foo);
896 + if (res != SIEVE_OK) {
897 + syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res);
898 + return TIMSIEVE_FAIL;
899 + }
900 + res = sieve_register_keep(i, (sieve_callback *) &foo);
901 + if (res != SIEVE_OK) {
902 + syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res);
903 + return TIMSIEVE_FAIL;
904 + }
905 +
906 + res = sieve_register_imapflags(i, NULL);
907 + if (res != SIEVE_OK) {
908 + syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res);
909 + return TIMSIEVE_FAIL;
910 + }
911 +
912 + res = sieve_register_size(i, (sieve_get_size *) &foo);
913 + if (res != SIEVE_OK) {
914 + syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res);
915 + return TIMSIEVE_FAIL;
916 + }
917 +
918 + res = sieve_register_header(i, (sieve_get_header *) &foo);
919 + if (res != SIEVE_OK) {
920 + syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res);
921 + return TIMSIEVE_FAIL;
922 + }
923 +
924 + res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
925 + if (res != SIEVE_OK) {
926 + syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res);
927 + return TIMSIEVE_FAIL;
928 + }
929 +
930 + res = sieve_register_vacation(i, &vacation2);
931 + if (res != SIEVE_OK) {
932 + syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res);
933 + return TIMSIEVE_FAIL;
934 + }
935 +
936 + res = sieve_register_notify(i, &sieve_notify);
937 + if (res != SIEVE_OK) {
938 + syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res);
939 + return TIMSIEVE_FAIL;
940 + }
941 +
942 + res = sieve_register_parse_error(i, &mysieve_error);
943 + if (res != SIEVE_OK) {
944 + syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res);
945 + return TIMSIEVE_FAIL;
946 + }
947 +
948 + rewind(stream);
949 +
950 + *errstr = (char *) xmalloc(20 * sizeof(char));
951 + strcpy(*errstr, "script errors:\r\n");
952 +
953 + res = sieve_script_parse(i, stream, errstr, &s);
954 +
955 + if (res == SIEVE_OK) {
956 + if(ret) {
957 + *ret = s;
958 + } else {
959 + sieve_script_free(&s);
960 + }
961 + free(*errstr);
962 + *errstr = NULL;
963 + }
964 +
965 + /* free interpreter */
966 + sieve_interp_free(&i);
967 +
968 + return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
969 +}
970 +
971 +/*
972 + * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of
973 + * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present
974 + */
975 +
976 diff -Naur cyrus-imapd-2.2.12/imap/compile_sieve.c cyrus-imapd-2.2.12.autocreate2/imap/compile_sieve.c
977 --- cyrus-imapd-2.2.12/imap/compile_sieve.c 1970-01-01 02:00:00.000000000 +0200
978 +++ cyrus-imapd-2.2.12.autocreate2/imap/compile_sieve.c 2005-10-19 14:48:57.943407000 +0300
979 @@ -0,0 +1,364 @@
980 +/* This tool compiles the sieve script from a command
981 +line so that it can be used wby the autoadd patch */
982 +#include <stdio.h>
983 +#include <stdlib.h>
984 +
985 +#include <config.h>
986 +#include <string.h>
987 +#ifdef HAVE_UNISTD_H
988 +#include <unistd.h>
989 +#endif
990 +#include <errno.h>
991 +#include <sys/types.h>
992 +#include <sys/stat.h>
993 +#include <sys/uio.h>
994 +#include <fcntl.h>
995 +#include <ctype.h>
996 +#include <time.h>
997 +#include <com_err.h>
998 +
999 +#include "global.h"
1000 +
1001 +#include "util.h"
1002 +#include "mailbox.h"
1003 +#include "imap_err.h"
1004 +#include "sieve_interface.h"
1005 +#include "script.h"
1006 +
1007 +#include <pwd.h>
1008 +
1009 +#define TIMSIEVE_FAIL -1
1010 +#define TIMSIEVE_OK 0
1011 +#define MAX_FILENAME_SIZE 100
1012 +
1013 +/* Needed by libconfig */
1014 +const int config_need_data = 0;
1015 +
1016 +static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
1017 +
1018 +static void fatal(const char *s, int code)
1019 +{
1020 + printf("Fatal error: %s (%d)\r\n", s, code);
1021 +
1022 + exit(1);
1023 +}
1024 +
1025 +void usage(void)
1026 +{
1027 + fprintf(stderr,
1028 + "Usage:\n\tcompile_sieve [-C <altconfig>] [-i <infile> -o <outfile>]\n");
1029 + exit(-1);
1030 +}
1031 +
1032 +
1033 +int main (int argc, char **argv)
1034 +{
1035 +
1036 + sieve_script_t *s = NULL;
1037 + bytecode_info_t *bc = NULL;
1038 + char *err = NULL;
1039 + FILE *in_stream;
1040 + int out_fd,r, k, opt;
1041 + char *source_script = NULL;
1042 + char *compiled_source_script = NULL;
1043 + mode_t oldmask;
1044 + struct stat statbuf;
1045 + char *alt_config = NULL;
1046 + extern char *optarg;
1047 + char sieve_tmpname[MAX_MAILBOX_NAME+1];
1048 +
1049 + if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);
1050 +
1051 + while((opt = getopt(argc, argv, "C:i:o:")) != EOF) {
1052 + switch (opt) {
1053 + case 'C': /* alt config file */
1054 + alt_config = optarg;
1055 + break;
1056 + case 'i': /* input script file */
1057 + source_script = optarg;
1058 + break;
1059 + case 'o': /* output script file */
1060 + compiled_source_script = optarg;
1061 + break;
1062 + default:
1063 + usage();
1064 + break;
1065 + }
1066 + }
1067 +
1068 + if(source_script && !compiled_source_script) {
1069 + fprintf(stderr, "No output file was defined\n");
1070 + usage();
1071 + } else if (!source_script && compiled_source_script) {
1072 + fprintf(stderr, "No input file was defined\n");
1073 + usage();
1074 + }
1075 +
1076 + /*
1077 + * If no <infile> has been defined, then read them from
1078 + * the configuration file.
1079 + */
1080 + if (!source_script && !compiled_source_script) {
1081 + cyrus_init(alt_config, "compile_sieve", 0);
1082 +
1083 + /* Initially check if we want to have the sieve script created */
1084 + if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) {
1085 + fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n");
1086 + return 1;
1087 + }
1088 +
1089 + /* Check if we have an already compiled sieve script*/
1090 + if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
1091 + fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n");
1092 + return 1;
1093 + }
1094 +
1095 + if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) {
1096 + /*
1097 + * At this point the only think that is inconsistent is the directory
1098 + * that was created. But if the user will have any sieve scripts then
1099 + * they will eventually go there, so no big deal
1100 + */
1101 + fprintf(stderr,
1102 + "In imapd.conf the full path of the filenames must be defined\n");
1103 + return 1;
1104 + }
1105 + }
1106 +
1107 + printf("input file : %s, output file : %s\n", source_script, compiled_source_script);
1108 +
1109 +
1110 + if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) {
1111 + fprintf(stderr, "Filename %s is too big\n", compiled_source_script);
1112 + return 1;
1113 + }
1114 +
1115 + snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script);
1116 +
1117 + in_stream = fopen(source_script,"r");
1118 +
1119 + if(!in_stream) {
1120 + fprintf(stderr,"Unable to open %s source sieve script\n",source_script);
1121 + return;
1122 + }
1123 +
1124 + /*
1125 + * We open the file that will be used as the bc file. If this file exists, overwrite it
1126 + * since something bad has happened. We open the file here so that this error checking is
1127 + * done before we try to open the rest of the files to start copying etc.
1128 + */
1129 + out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
1130 + if(out_fd < 0) {
1131 + if(errno == EEXIST) {
1132 + fprintf(stderr, "File %s already exists\n", sieve_tmpname);
1133 + } else if (errno == EACCES) {
1134 + fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n",
1135 + sieve_tmpname);
1136 + } else {
1137 + fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n",
1138 + sieve_tmpname);
1139 + }
1140 +
1141 + fclose(in_stream);
1142 + return 1;
1143 + }
1144 +
1145 + if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
1146 + if(err && *err) {
1147 + fprintf(stderr, "Error while parsing script %s\n",err);
1148 + free(err);
1149 + }
1150 + else
1151 + fprintf(stderr,"Error while parsing script\n");
1152 + unlink(sieve_tmpname);
1153 + fclose(in_stream);
1154 + close(out_fd);
1155 + return;
1156 + }
1157 +
1158 +
1159 + /* generate the bytecode */
1160 + if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) {
1161 + fprintf(stderr,"Error occured while compiling sieve script\n");
1162 + /* removing the copied script and cleaning up memory */
1163 + unlink(sieve_tmpname);
1164 + sieve_script_free(&s);
1165 + fclose(in_stream);
1166 + close(out_fd);
1167 + return;
1168 + }
1169 + if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) {
1170 + fprintf(stderr, "Error occured while emitting sieve script\n");
1171 + unlink(sieve_tmpname);
1172 + sieve_free_bytecode(&bc);
1173 + sieve_script_free(&s);
1174 + fclose(in_stream);
1175 + close(out_fd);
1176 + return;
1177 + }
1178 +
1179 + /* clean up the memory */
1180 + sieve_free_bytecode(&bc);
1181 + sieve_script_free(&s);
1182 +
1183 + close(out_fd);
1184 +
1185 + if(rename(sieve_tmpname, compiled_source_script)) {
1186 + if(errno != EEXIST) {
1187 + unlink(sieve_tmpname);
1188 + unlink(compiled_source_script);
1189 + return 1;
1190 + }
1191 + }
1192 + return 0;
1193 +}
1194 +
1195 +
1196 +/* to make larry's stupid functions happy :) */
1197 +static void foo(void)
1198 +{
1199 + fatal("stub function called", 0);
1200 +}
1201 +
1202 +extern sieve_vacation_t vacation2;/* = {
1203 + 0, / min response /
1204 + 0, / max response /
1205 + (sieve_callback *) &foo, / autorespond() /
1206 + (sieve_callback *) &foo / send_response() /
1207 +}; */
1208 +
1209 +static int sieve_notify(void *ac __attribute__((unused)),
1210 + void *interp_context __attribute__((unused)),
1211 + void *script_context __attribute__((unused)),
1212 + void *message_context __attribute__((unused)),
1213 + const char **errmsg __attribute__((unused)))
1214 +{
1215 + fatal("stub function called", 0);
1216 + return SIEVE_FAIL;
1217 +}
1218 +
1219 +static int mysieve_error(int lineno, const char *msg,
1220 + void *i __attribute__((unused)), void *s)
1221 +{
1222 + char buf[1024];
1223 + char **errstr = (char **) s;
1224 +
1225 + snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
1226 + *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
1227 + fprintf(stderr, "%s\n", buf);
1228 + strcat(*errstr, buf);
1229 +
1230 + return SIEVE_OK;
1231 +}
1232 +
1233 +/* end the boilerplate */
1234 +
1235 +/* returns TRUE or FALSE */
1236 +int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
1237 +{
1238 + sieve_interp_t *i;
1239 + sieve_script_t *s;
1240 + int res;
1241 +
1242 + res = sieve_interp_alloc(&i, NULL);
1243 + if (res != SIEVE_OK) {
1244 + fprintf(stderr, "sieve_interp_alloc() returns %d\n", res);
1245 + return TIMSIEVE_FAIL;
1246 + }
1247 +
1248 + res = sieve_register_redirect(i, (sieve_callback *) &foo);
1249 + if (res != SIEVE_OK) {
1250 + fprintf(stderr, "sieve_register_redirect() returns %d\n", res);
1251 + return TIMSIEVE_FAIL;
1252 + }
1253 + res = sieve_register_discard(i, (sieve_callback *) &foo);
1254 + if (res != SIEVE_OK) {
1255 + fprintf(stderr, "sieve_register_discard() returns %d\n", res);
1256 + return TIMSIEVE_FAIL;
1257 + }
1258 + res = sieve_register_reject(i, (sieve_callback *) &foo);
1259 + if (res != SIEVE_OK) {
1260 + fprintf(stderr, "sieve_register_reject() returns %d\n", res);
1261 + return TIMSIEVE_FAIL;
1262 + }
1263 + res = sieve_register_fileinto(i, (sieve_callback *) &foo);
1264 + if (res != SIEVE_OK) {
1265 + fprintf(stderr, "sieve_register_fileinto() returns %d\n", res);
1266 + return TIMSIEVE_FAIL;
1267 + }
1268 + res = sieve_register_keep(i, (sieve_callback *) &foo);
1269 + if (res != SIEVE_OK) {
1270 + fprintf(stderr, "sieve_register_keep() returns %d\n", res);
1271 + return TIMSIEVE_FAIL;
1272 + }
1273 +
1274 + res = sieve_register_imapflags(i, NULL);
1275 + if (res != SIEVE_OK) {
1276 + fprintf(stderr, "sieve_register_imapflags() returns %d\n", res);
1277 + return TIMSIEVE_FAIL;
1278 + }
1279 +
1280 + res = sieve_register_size(i, (sieve_get_size *) &foo);
1281 + if (res != SIEVE_OK) {
1282 + fprintf(stderr, "sieve_register_size() returns %d\n", res);
1283 + return TIMSIEVE_FAIL;
1284 + }
1285 +
1286 + res = sieve_register_header(i, (sieve_get_header *) &foo);
1287 + if (res != SIEVE_OK) {
1288 + fprintf(stderr, "sieve_register_header() returns %d\n", res);
1289 + return TIMSIEVE_FAIL;
1290 + }
1291 +
1292 + res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
1293 + if (res != SIEVE_OK) {
1294 + fprintf(stderr, "sieve_register_envelope() returns %d\n", res);
1295 + return TIMSIEVE_FAIL;
1296 + }
1297 +
1298 + res = sieve_register_vacation(i, &vacation2);
1299 + if (res != SIEVE_OK) {
1300 + fprintf(stderr, "sieve_register_vacation() returns %d\n", res);
1301 + return TIMSIEVE_FAIL;
1302 + }
1303 +
1304 + res = sieve_register_notify(i, &sieve_notify);
1305 + if (res != SIEVE_OK) {
1306 + fprintf(stderr, "sieve_register_notify() returns %d\n", res);
1307 + return TIMSIEVE_FAIL;
1308 + }
1309 +
1310 + res = sieve_register_parse_error(i, &mysieve_error);
1311 + if (res != SIEVE_OK) {
1312 + fprintf(stderr, "sieve_register_parse_error() returns %d\n", res);
1313 + return TIMSIEVE_FAIL;
1314 + }
1315 +
1316 + rewind(stream);
1317 +
1318 + *errstr = (char *) xmalloc(20 * sizeof(char));
1319 + strcpy(*errstr, "script errors:\r\n");
1320 +
1321 + res = sieve_script_parse(i, stream, errstr, &s);
1322 +
1323 + if (res == SIEVE_OK) {
1324 + if(ret) {
1325 + *ret = s;
1326 + } else {
1327 + sieve_script_free(&s);
1328 + }
1329 + free(*errstr);
1330 + *errstr = NULL;
1331 + }
1332 +
1333 + /* free interpreter */
1334 + sieve_interp_free(&i);
1335 +
1336 + return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
1337 +}
1338 +
1339 +
1340 +
1341 +
1342 +
1343 +
1344 diff -Naur cyrus-imapd-2.2.12/imap/imapd.c cyrus-imapd-2.2.12.autocreate2/imap/imapd.c
1345 --- cyrus-imapd-2.2.12/imap/imapd.c 2005-02-14 08:39:55.000000000 +0200
1346 +++ cyrus-imapd-2.2.12.autocreate2/imap/imapd.c 2005-10-19 14:48:57.966749000 +0300
1347 @@ -158,6 +158,7 @@
1348 void motd_file(int fd);
1349 void shut_down(int code);
1350 void fatal(const char *s, int code);
1351 +void autocreate_inbox(void);
1352
1353 void cmdloop(void);
1354 void cmd_login(char *tag, char *user);
1355 @@ -1693,6 +1694,42 @@
1356 }
1357
1358 /*
1359 + * Autocreate Inbox and subfolders upon login
1360 + */
1361 +void autocreate_inbox()
1362 +{
1363 + char inboxname[MAX_MAILBOX_NAME+1];
1364 + int autocreatequota;
1365 + int r;
1366 +
1367 + /*
1368 + * Exlude admin's accounts
1369 + */
1370 + if (imapd_userisadmin || imapd_userisproxyadmin)
1371 + return;
1372 +
1373 + /*
1374 + * Exclude anonymous
1375 + */
1376 + if (!strcmp(imapd_userid, "anonymous"))
1377 + return;
1378 +
1379 + if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) {
1380 + /* This is actyally not required
1381 + as long as the lenght of userid is ok */
1382 + r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace,
1383 + "INBOX", imapd_userid, inboxname);
1384 + if (!r)
1385 + r = mboxlist_lookup(inboxname, NULL, NULL, NULL);
1386 +
1387 + if (r == IMAP_MAILBOX_NONEXISTENT)
1388 + mboxlist_autocreateinbox(&imapd_namespace, imapd_userid,
1389 + imapd_authstate, inboxname, autocreatequota);
1390 + }
1391 +}
1392 +
1393 +
1394 +/*
1395 * Perform a LOGIN command
1396 */
1397 void cmd_login(char *tag, char *user)
1398 @@ -1848,6 +1885,9 @@
1399 strcspn(imapd_userid, "@") : 0);
1400
1401 freebuf(&passwdbuf);
1402 +
1403 + autocreate_inbox();
1404 +
1405 return;
1406 }
1407
1408 @@ -1993,6 +2033,8 @@
1409 config_virtdomains ?
1410 strcspn(imapd_userid, "@") : 0);
1411
1412 + autocreate_inbox();
1413 +
1414 return;
1415 }
1416
1417 diff -Naur cyrus-imapd-2.2.12/imap/lmtpd.c cyrus-imapd-2.2.12.autocreate2/imap/lmtpd.c
1418 --- cyrus-imapd-2.2.12/imap/lmtpd.c 2004-12-17 18:32:15.000000000 +0200
1419 +++ cyrus-imapd-2.2.12.autocreate2/imap/lmtpd.c 2005-10-19 14:48:57.971145000 +0300
1420 @@ -106,6 +106,8 @@
1421 static FILE *spoolfile(message_data_t *msgdata);
1422 static void removespool(message_data_t *msgdata);
1423
1424 +static int autocreate_inbox(char *rcpt_userid);
1425 +
1426 /* current namespace */
1427 static struct namespace lmtpd_namespace;
1428
1429 @@ -504,10 +506,55 @@
1430 exit(code);
1431 }
1432
1433 +/*
1434 + * Autocreate Inbox and subfolders upon login
1435 + */
1436 +int autocreate_inbox(char *rcpt_userid)
1437 +{
1438 + struct auth_state *authstate;
1439 + char inboxname[MAX_MAILBOX_NAME+1];
1440 + int rcptisadmin;
1441 + int autocreatequota;
1442 + int r;
1443 +
1444 + if(rcpt_userid == NULL)
1445 + return IMAP_MAILBOX_NONEXISTENT;
1446 +
1447 + /*
1448 + * Exclude anonymous
1449 + */
1450 + if (!strcmp(rcpt_userid, "anonymous"))
1451 + return IMAP_MAILBOX_NONEXISTENT;
1452 +
1453 + /*
1454 + * Check for autocreatequota and createonpost
1455 + */
1456 + if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) ||
1457 + !(config_getswitch(IMAPOPT_CREATEONPOST)))
1458 + return IMAP_MAILBOX_NONEXISTENT;
1459 +
1460 + /*
1461 + * Exclude admin's accounts
1462 + */
1463 + authstate = auth_newstate(rcpt_userid);
1464 + rcptisadmin = global_authisa(authstate, IMAPOPT_ADMINS);
1465 + if (rcptisadmin)
1466 + return IMAP_MAILBOX_NONEXISTENT;
1467 +
1468 + r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace,
1469 + "INBOX", rcpt_userid, inboxname);
1470 + if (!r)
1471 + r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid,
1472 + authstate, inboxname, autocreatequota);
1473 + return r;
1474 +}
1475 +
1476 +
1477 static int verify_user(const char *user, const char *domain, const char *mailbox,
1478 long quotacheck, struct auth_state *authstate)
1479 {
1480 char namebuf[MAX_MAILBOX_NAME+1] = "";
1481 + char *userinbox = NULL;
1482 int r = 0;
1483
1484 if ((!user && !mailbox) ||
1485 @@ -545,6 +592,28 @@
1486 */
1487 r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
1488 !user ? ACL_POST : 0, quotacheck > 0 ? 0 : quotacheck);
1489 + if (r == IMAP_MAILBOX_NONEXISTENT && user) {
1490 + if(domain) {
1491 + int k;
1492 + userinbox = (char *)xmalloc((strlen(user)+strlen(domain)+2)*sizeof(char));
1493 + k = strlcpy(userinbox, user, strlen(user)+1);
1494 + *(userinbox + k) = '@';
1495 + strlcpy(userinbox+k+1, domain, strlen(domain)+1);
1496 + }
1497 + else userinbox = user;
1498 + /*
1499 + * Try to create automatically the mailbox, if
1500 + * autocreate inbox option is enabled.
1501 + */
1502 + r = autocreate_inbox(userinbox);
1503 +
1504 + if(userinbox != user)
1505 + free(userinbox);
1506 + if (!r)
1507 + r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
1508 + 0, quotacheck > 0 ? 0 : quotacheck);
1509 + }
1510 +
1511 }
1512
1513 if (r) syslog(LOG_DEBUG, "verify_user(%s) failed: %s", namebuf,
1514 diff -Naur cyrus-imapd-2.2.12/imap/mboxlist.c cyrus-imapd-2.2.12.autocreate2/imap/mboxlist.c
1515 --- cyrus-imapd-2.2.12/imap/mboxlist.c 2004-07-26 21:08:03.000000000 +0300
1516 +++ cyrus-imapd-2.2.12.autocreate2/imap/mboxlist.c 2005-10-19 14:49:25.972032000 +0300
1517 @@ -81,6 +81,12 @@
1518 #include "mboxlist.h"
1519 #include "quota.h"
1520
1521 +#ifdef USE_SIEVE
1522 +extern int autoadd_sieve(char *userid,
1523 + const char *source_script);
1524 +#endif
1525 +
1526 +
1527 #define DB config_mboxlist_db
1528 #define SUBDB config_subscription_db
1529
1530 @@ -98,11 +104,29 @@
1531 static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
1532 void *rock);
1533
1534 +static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
1535 + void *rock);
1536 +
1537 +static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
1538 + char *userid, char *auth_userid,
1539 + struct auth_state *auth_state);
1540 +
1541 struct change_rock {
1542 struct quota *quota;
1543 struct txn **tid;
1544 };
1545
1546 +/*
1547 + * Struct needed to be passed as void *rock to
1548 + * mboxlist_autochangesub();
1549 + */
1550 +struct changesub_rock_st {
1551 + char *userid;
1552 + char *auth_userid;
1553 + struct auth_state *auth_state;
1554 +};
1555 +
1556 +
1557 #define FNAME_SUBSSUFFIX ".sub"
1558
1559 /*
1560 @@ -3124,3 +3148,338 @@
1561
1562 return DB->abort(mbdb, tid);
1563 }
1564 +
1565 +/*
1566 + * Automatically subscribe user to *ALL* shared folders,
1567 + * one has permissions to be subscribed to.
1568 + * INBOX subfolders are excluded.
1569 + */
1570 +static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
1571 + void *rock) {
1572 +
1573 + struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock;
1574 + char *userid = changesub_rock->userid;
1575 + char *auth_userid = changesub_rock->auth_userid;
1576 + struct auth_state *auth_state = changesub_rock->auth_state;
1577 + int r;
1578 +
1579 +
1580 + if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */
1581 + (strlen(name) > 5 && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */
1582 + (strlen(name) > 4 && !strncmp(name, "user.", 5))) /* Exclude other users' folders */
1583 + return 0;
1584 +
1585 +
1586 + r = mboxlist_changesub(name, userid, auth_state, 1, 0);
1587 +
1588 + if (r) {
1589 + syslog(LOG_WARNING,
1590 + "autosubscribe: User %s to folder %s, subscription failed: %s",
1591 + auth_userid, name, error_message(r));
1592 + } else {
1593 + syslog(LOG_NOTICE,
1594 + "autosubscribe: User %s to folder %s, subscription succeeded",
1595 + auth_userid, name);
1596 + }
1597 +
1598 + return 0;
1599 +}
1600 +
1601 +#define SEP '|'
1602 +
1603 +/*
1604 + * Automatically subscribe user to a shared folder.
1605 + * Subscription is done successfully, if the shared
1606 + * folder exists and the user has the necessary
1607 + * permissions.
1608 + */
1609 +static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
1610 + char *userid, char *auth_userid,
1611 + struct auth_state *auth_state) {
1612 +
1613 + const char *sub ;
1614 + char *p, *q, *next_sub;
1615 + char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1];
1616 + int len;
1617 + int r = 0;
1618 + int subscribe_all_sharedfolders = 0;
1619 +
1620 + subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS);
1621 +
1622 + /*
1623 + * If subscribeallsharedfolders is set to yes in imapd.conf, then
1624 + * subscribe user to every shared folder one has the apropriate
1625 + * permissions.
1626 + */
1627 + if(subscribe_all_sharedfolders) {
1628 + char pattern[MAX_MAILBOX_PATH+1];
1629 + struct changesub_rock_st changesub_rock;
1630 +
1631 + strcpy(pattern, "*");
1632 + changesub_rock.userid = userid;
1633 + changesub_rock.auth_userid = auth_userid;
1634 + changesub_rock.auth_state = auth_state;
1635 +
1636 + r = mboxlist_findall(namespace, pattern, 0, userid,
1637 + auth_state, mboxlist_autochangesub, &changesub_rock);
1638 +
1639 + return r;
1640 + }
1641 +
1642 + if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL)
1643 + return r;
1644 +
1645 + next_sub = (char *) sub;
1646 + while (*next_sub) {
1647 + for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
1648 + for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
1649 + for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
1650 + if (!*p ) continue;
1651 +
1652 + len = q - p + 1;
1653 + /* Check for folder length */
1654 + if (len > sizeof(folder)-1)
1655 + continue;
1656 +
1657 + if (!r) {
1658 + strncpy(folder, p, len);
1659 + folder[len] = '\0';
1660 +
1661 + strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name));
1662 + len = strlcat(name, folder, sizeof(name));
1663 +
1664 + r = (namespace->mboxname_tointernal) (namespace, name, userid,
1665 + mailboxname);
1666 + }
1667 +
1668 + if (!r)
1669 + r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0);
1670 +
1671 + if (!r) {
1672 + syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded",
1673 + userid, folder);
1674 + } else {
1675 + syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s",
1676 + userid, folder, error_message(r));
1677 + r = 0;
1678 + }
1679 + }
1680 +
1681 + return r;
1682 +}
1683 +
1684 +
1685 +
1686 +int mboxlist_autocreateinbox(struct namespace *namespace,
1687 + char *userid,
1688 + struct auth_state *auth_state,
1689 + char *mailboxname, int autocreatequota) {
1690 + char name [MAX_MAILBOX_NAME+1];
1691 + char folder [MAX_MAILBOX_NAME+1];
1692 + char *auth_userid = NULL;
1693 + char *partition = NULL;
1694 + const char *crt;
1695 + const char *sub;
1696 + char *p, *q, *next_crt, *next_sub;
1697 + int len;
1698 + int r = 0;
1699 + int numcrt = 0;
1700 + int numsub = 0;
1701 +#ifdef USE_SIEVE
1702 + const char *source_script;
1703 +#endif
1704 +
1705 + /*
1706 + * While this is not needed for admins
1707 + * and imap_admins accounts, it would be
1708 + * better to separate *all* admins and
1709 + * proxyservers from normal accounts
1710 + * (accounts that have mailboxes).
1711 + * UOA Specific note(1): Even if we do not
1712 + * exclude these servers-classes here,
1713 + * UOA specific code, will neither return
1714 + * role, nor create INBOX, because none of these
1715 + * administrative accounts belong to the
1716 + * mailRecipient objectclass, or have imapPartition.
1717 + * UOA Specific note(2): Another good reason for doing
1718 + * this, is to prevent the code, from getting into
1719 + * cyrus_ldap.c because of the continues MSA logins to LMTPd.
1720 + */
1721 +
1722 + /*
1723 + * admins and the coresponding imap
1724 + * service, had already been excluded.
1725 + */
1726 +
1727 + /*
1728 + * Do we really need group membership
1729 + * for admins or service_admins?
1730 + */
1731 + if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
1732 + if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
1733 +
1734 + /*
1735 + * Do we really need group membership
1736 + * for proxyservers?
1737 + */
1738 + if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
1739 + if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
1740 +
1741 + auth_userid = auth_canonuser(auth_state);
1742 +
1743 + if (auth_userid == NULL) {
1744 + /*
1745 + * Couldn't get cannon userid
1746 + */
1747 + syslog(LOG_ERR,
1748 + "Could not get cannon userid for user %s", userid);
1749 + return IMAP_PARTITION_UNKNOWN;
1750 + }
1751 +
1752 +#if 0
1753 + /*
1754 + * Get Partition info or return.
1755 + * (Here you should propably use
1756 + * you own "get_partition(char *userid)"
1757 + * function. Otherwise all new INBOXes will be
1758 + * created into whatever partition has been declared
1759 + * as default in your imapd.conf)
1760 + */
1761 +
1762 + partition = get_partition(userid);
1763 +
1764 + if (partition == NULL) {
1765 + /*
1766 + * Couldn't get partition info
1767 + */
1768 + syslog(LOG_ERR,
1769 + "Could not get imapPartition info for user %s", userid);
1770 + return IMAP_PARTITION_UNKNOWN;
1771 + }
1772 +#endif
1773 +
1774 + r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
1775 + 1, userid, auth_state, 0, 0, 0);
1776 +
1777 + if (!r && autocreatequota > 0)
1778 + r = mboxlist_setquota(mailboxname, autocreatequota, 0);
1779 +
1780 + if (!r)
1781 + r = mboxlist_changesub(mailboxname, userid,
1782 + auth_state, 1, 1);
1783 +
1784 + if (!r) {
1785 + syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s",
1786 + auth_userid, partition == NULL ? "default" : partition);
1787 + } else {
1788 + syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s",
1789 + auth_userid, error_message(r));
1790 + }
1791 +
1792 +
1793 +#if 0
1794 + /* Allocated from get_partition, and not needed any more */
1795 + free_partition(partition);
1796 +#endif
1797 +
1798 + if (r) return r;
1799 +
1800 +
1801 + /* INBOX's subfolders */
1802 + if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS)))
1803 + sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS);
1804 +
1805 + /* Roll through crt */
1806 + next_crt = (char *) crt;
1807 + while (next_crt!=NULL && *next_crt) {
1808 + for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++);
1809 + for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++);
1810 + for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--);
1811 +
1812 + if (!*p) continue;
1813 +
1814 + len = q - p + 1;
1815 +
1816 + /* First time we check for length */
1817 + if (len > sizeof(folder) - 5)
1818 + r = IMAP_MAILBOX_BADNAME;
1819 +
1820 + if (!r) {
1821 + strncpy(folder, p, len);
1822 + folder[len] = '\0';
1823 +
1824 + strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name));
1825 + len = strlcat(name, folder, sizeof(name));
1826 + }
1827 +
1828 + if (!r)
1829 + r = (namespace->mboxname_tointernal) (namespace, name, userid,
1830 + mailboxname);
1831 + if (!r)
1832 + r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
1833 + 1, userid, auth_state, 0, 0, 0);
1834 +
1835 + if (!r) {
1836 + numcrt++;
1837 + syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.",
1838 + auth_userid, name);
1839 + } else {
1840 + syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s",
1841 + auth_userid, name, error_message(r));
1842 + r=0;
1843 + continue;
1844 + }
1845 +
1846 + /* Roll through sub */
1847 + next_sub = (char *) sub;
1848 + while (next_sub!=NULL && *next_sub) {
1849 + for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
1850 + for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
1851 + for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
1852 + if (!*p ) continue;
1853 +
1854 + len = q - p + 1;
1855 +
1856 + if (len != strlen(folder) || strncmp(folder, p, len))
1857 + continue;
1858 +
1859 + r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1);
1860 +
1861 + if (!r) {
1862 + numsub++;
1863 + syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded",
1864 + auth_userid, name);
1865 + } else
1866 + syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to %s failed. %s",
1867 + auth_userid, name, error_message(r));
1868 +
1869 + break;
1870 + }
1871 + }
1872 +
1873 + if (crt!=NULL && *crt)
1874 + syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d",
1875 + auth_userid, numcrt, numsub);
1876 +
1877 + /*
1878 + * Check if shared folders are available for subscription.
1879 + */
1880 + mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state);
1881 +
1882 +#ifdef USE_SIEVE
1883 + /*
1884 + * Here the autocreate sieve script feature is iniated from.
1885 + */
1886 + source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT);
1887 +
1888 + if (source_script) {
1889 + if (!autoadd_sieve(userid, source_script))
1890 + syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid);
1891 + else
1892 + syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid);
1893 + }
1894 +#endif
1895 +
1896 + return r;
1897 +}
1898 +
1899 diff -Naur cyrus-imapd-2.2.12/imap/mboxlist.h cyrus-imapd-2.2.12.autocreate2/imap/mboxlist.h
1900 --- cyrus-imapd-2.2.12/imap/mboxlist.h 2004-03-17 20:07:49.000000000 +0200
1901 +++ cyrus-imapd-2.2.12.autocreate2/imap/mboxlist.h 2005-10-19 14:48:58.027033000 +0300
1902 @@ -197,4 +197,10 @@
1903 int mboxlist_commit(struct txn *tid);
1904 int mboxlist_abort(struct txn *tid);
1905
1906 +int mboxlist_autocreateinbox(struct namespace *namespace,
1907 + char *userid,
1908 + struct auth_state *auth_state,
1909 + char *mailboxname, int autocreatequota);
1910 +
1911 +
1912 #endif
1913 diff -Naur cyrus-imapd-2.2.12/imap/pop3d.c cyrus-imapd-2.2.12.autocreate2/imap/pop3d.c
1914 --- cyrus-imapd-2.2.12/imap/pop3d.c 2005-01-04 17:06:13.000000000 +0200
1915 +++ cyrus-imapd-2.2.12.autocreate2/imap/pop3d.c 2005-10-19 14:48:58.033335000 +0300
1916 @@ -152,6 +152,8 @@
1917 static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* <rand.time@hostname> */
1918 static void cmd_apop(char *response);
1919
1920 +static int autocreate_inbox(char *inboxname, char *userid);
1921 +
1922 static void cmd_auth(char *arg);
1923 static void cmd_capa(void);
1924 static void cmd_pass(char *pass);
1925 @@ -1084,6 +1086,7 @@
1926 popd_userid = xstrdup(p);
1927 prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
1928 }
1929 +
1930 }
1931
1932 void cmd_pass(char *pass)
1933 @@ -1328,6 +1331,46 @@
1934 }
1935
1936 /*
1937 + * Autocreate Inbox and subfolders upon login
1938 + */
1939 +int autocreate_inbox(char *inboxname, char *auth_userid)
1940 +{
1941 + struct auth_state *authstate;
1942 + int userisadmin;
1943 + int autocreatequota;
1944 + int r;
1945 +
1946 + if(inboxname == NULL || auth_userid == NULL)
1947 + return IMAP_MAILBOX_NONEXISTENT;
1948 +
1949 + /*
1950 + * Exclude anonymous
1951 + */
1952 + if (!strcmp(popd_userid, "anonymous"))
1953 + return IMAP_MAILBOX_NONEXISTENT;
1954 +
1955 + /*
1956 + * Check for autocreatequota
1957 + */
1958 + if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)))
1959 + return IMAP_MAILBOX_NONEXISTENT;
1960 +
1961 + /*
1962 + * Exclude admin's accounts
1963 + */
1964 +
1965 + authstate = auth_newstate(popd_userid);
1966 + userisadmin = global_authisa(authstate, IMAPOPT_ADMINS);
1967 + if (userisadmin)
1968 + return IMAP_MAILBOX_NONEXISTENT;
1969 +
1970 + r = mboxlist_autocreateinbox(&popd_namespace, auth_userid,
1971 + authstate, inboxname, autocreatequota);
1972 + return r;
1973 +}
1974 +
1975 +
1976 +/*
1977 * Complete the login process by opening and locking the user's inbox
1978 */
1979 int openinbox(void)
1980 @@ -1349,6 +1392,10 @@
1981 userid, inboxname);
1982
1983 if (!r) r = mboxlist_detail(inboxname, &type, NULL, &server, &acl, NULL);
1984 + /* Try once again after autocreate_inbox */
1985 + if (r == IMAP_MAILBOX_NONEXISTENT && !(r = autocreate_inbox(inboxname, userid)))
1986 + r = mboxlist_detail(inboxname, &type, NULL, &server, &acl, NULL);
1987 +
1988 if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) &&
1989 (!acl ||
1990 !((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) {
1991 diff -Naur cyrus-imapd-2.2.12/lib/auth.h cyrus-imapd-2.2.12.autocreate2/lib/auth.h
1992 --- cyrus-imapd-2.2.12/lib/auth.h 2003-10-22 21:50:12.000000000 +0300
1993 +++ cyrus-imapd-2.2.12.autocreate2/lib/auth.h 2005-10-19 14:48:58.035324000 +0300
1994 @@ -60,4 +60,6 @@
1995 extern struct auth_state *auth_newstate(const char *identifier);
1996 extern void auth_freestate(struct auth_state *auth_state);
1997
1998 +extern char *auth_canonuser(struct auth_state *auth_state);
1999 +
2000 #endif /* INCLUDED_AUTH_H */
2001 diff -Naur cyrus-imapd-2.2.12/lib/auth_krb.c cyrus-imapd-2.2.12.autocreate2/lib/auth_krb.c
2002 --- cyrus-imapd-2.2.12/lib/auth_krb.c 2003-11-11 05:26:00.000000000 +0200
2003 +++ cyrus-imapd-2.2.12.autocreate2/lib/auth_krb.c 2005-10-19 14:48:58.038180000 +0300
2004 @@ -338,3 +338,11 @@
2005 free((char *)auth_state);
2006 }
2007
2008 +char *
2009 +auth_canonuser(struct auth_state *auth_state)
2010 +{
2011 + if (auth_state)
2012 + return auth_state->userid;
2013 + return NULL;
2014 +}
2015 +
2016 diff -Naur cyrus-imapd-2.2.12/lib/auth_krb5.c cyrus-imapd-2.2.12.autocreate2/lib/auth_krb5.c
2017 --- cyrus-imapd-2.2.12/lib/auth_krb5.c 2004-01-16 17:28:58.000000000 +0200
2018 +++ cyrus-imapd-2.2.12.autocreate2/lib/auth_krb5.c 2005-10-19 14:48:58.040108000 +0300
2019 @@ -193,4 +193,11 @@
2020 free(auth_state);
2021 }
2022
2023 +char *
2024 +auth_canonuser(struct auth_state *auth_state)
2025 +{
2026 + if (auth_state)
2027 + return auth_state->userid;
2028 + return NULL;
2029 +}
2030
2031 diff -Naur cyrus-imapd-2.2.12/lib/auth_pts.c cyrus-imapd-2.2.12.autocreate2/lib/auth_pts.c
2032 --- cyrus-imapd-2.2.12/lib/auth_pts.c 2004-02-25 01:11:37.000000000 +0200
2033 +++ cyrus-imapd-2.2.12.autocreate2/lib/auth_pts.c 2005-10-19 14:48:58.042343000 +0300
2034 @@ -349,3 +349,11 @@
2035 {
2036 free(auth_state);
2037 }
2038 +
2039 +char *auth_canonuser(struct auth_state *auth_state)
2040 +{
2041 + if (auth_state)
2042 + return auth_state->userid.id;
2043 + return NULL;
2044 +}
2045 +
2046 diff -Naur cyrus-imapd-2.2.12/lib/auth_unix.c cyrus-imapd-2.2.12.autocreate2/lib/auth_unix.c
2047 --- cyrus-imapd-2.2.12/lib/auth_unix.c 2004-09-14 01:49:29.000000000 +0300
2048 +++ cyrus-imapd-2.2.12.autocreate2/lib/auth_unix.c 2005-10-19 14:48:58.044431000 +0300
2049 @@ -267,4 +267,11 @@
2050 free((char *)auth_state);
2051 }
2052
2053 +char *auth_canonuser(struct auth_state *auth_state)
2054 +{
2055 + if (auth_state)
2056 + return auth_state->userid;
2057 +
2058 + return NULL;
2059 +}
2060
2061 diff -Naur cyrus-imapd-2.2.12/lib/imapoptions cyrus-imapd-2.2.12.autocreate2/lib/imapoptions
2062 --- cyrus-imapd-2.2.12/lib/imapoptions 2004-07-21 22:07:45.000000000 +0300
2063 +++ cyrus-imapd-2.2.12.autocreate2/lib/imapoptions 2005-10-19 14:48:58.048748000 +0300
2064 @@ -169,6 +169,51 @@
2065 /* Number of seconds to wait before returning a timeout failure when
2066 performing a client connection (e.g. in a murder enviornment) */
2067
2068 +{ "createonpost", 0, SWITCH }
2069 +/* If yes, when lmtpd receives an incoming mail for an INBOX that does not exist,
2070 + then the INBOX is automatically created by lmtpd. */
2071 +
2072 +{ "autocreateinboxfolders", NULL, STRING }
2073 +/* If a user does not have an INBOX created then the INBOX as well as some INBOX subfolders are
2074 + created under two conditions.
2075 + 1. The user logins via the IMAP or the POP3 protocol. (autocreatequota option must have a nonzero value)
2076 + 2. A message arrives for the user through the LMTPD protocol.(createonpost option must yes)
2077 + autocreateinboxfolders is a list of INBOX's subfolders separated by a "|", that are automatically created by the server
2078 + under the previous two situations. */
2079 +
2080 +{ "autosubscribeinboxfolders", NULL, STRING }
2081 +/* A list of folder names, separated by "|" that the users get automatically subscribed to, when their INBOX
2082 + is created.
2083 + These folder names must have been included in the autocreateinboxfolders option of the imapd.conf. */
2084 +
2085 +{ "autosubscribesharedfolders", NULL, STRING }
2086 +/* A list of shared folders (bulletin boards), separated by "|" that the users get
2087 + automatically subscribed to, after their INBOX
2088 + is created. The shared folder must have been created and the user must have the
2089 + required permissions to get subscribed to the it. Otherwise the subscription fails. */
2090 +
2091 +{ "autosubscribe_all_sharedfolders", 0, SWITCH }
2092 +/* If set to yes then the user is automatically subscribed to all shared folders, one has permission
2093 + to subscribe to. */
2094 +
2095 +{ "autocreate_sieve_script", NULL, STRING }
2096 +/* The full path of a file that contains a sieve script. This script automatically becomes a
2097 + user's initial default sieve filter script. When this option is not defined, no default
2098 + sieve filter is created. The file must be readable by the cyrus daemon. */
2099 +
2100 +{ "autocreate_sieve_compiledscript", NULL, STRING }
2101 +/* The full path of a file that contains a compiled in bytecode sieve script. This script
2102 + automatically becomes a user's initial default sieve filter script.
2103 + If this option is not specified, or the filename doesn't exist then the script defined
2104 + by autocreate_sieve_script is compiled on the fly and installed as the user's default
2105 + sieve script */
2106 +
2107 +{ "generate_compiled_sieve_script", 0, SWITCH }
2108 +/* If set to yes and no compiled sieve script file exists then the sieve script that is
2109 + compiled on the fly will be saved in the file name that autocreate_sieve_compiledscript
2110 + option points. In order a compiled script to be generated, autocreate_sieve_script and
2111 + autocreate_sieve_compiledscript must have valid values */
2112 +
2113 { "configdirectory", NULL, STRING }
2114 /* The pathname of the IMAP configuration directory. This field is
2115 required. */
2116 diff -Naur cyrus-imapd-2.2.12/notifyd/Makefile.in cyrus-imapd-2.2.12.autocreate2/notifyd/Makefile.in
2117 --- cyrus-imapd-2.2.12/notifyd/Makefile.in 2004-05-28 21:03:06.000000000 +0300
2118 +++ cyrus-imapd-2.2.12.autocreate2/notifyd/Makefile.in 2005-10-19 14:48:58.050575000 +0300
2119 @@ -69,10 +69,11 @@
2120 SERVICE=../master/service.o
2121
2122 IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
2123 +SIEVE_LIBS = @SIEVE_LIBS@
2124 IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
2125 LIB_WRAP = @LIB_WRAP@
2126 LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS)
2127 -DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
2128 +DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
2129
2130 PURIFY=/usr/local/bin/purify
2131 PUREOPT=-best-effort
2132 diff -Naur cyrus-imapd-2.2.12/notifyd/notifyd.c cyrus-imapd-2.2.12.autocreate2/notifyd/notifyd.c
2133 --- cyrus-imapd-2.2.12/notifyd/notifyd.c 2004-12-17 18:32:25.000000000 +0200
2134 +++ cyrus-imapd-2.2.12.autocreate2/notifyd/notifyd.c 2005-10-19 14:48:58.052220000 +0300
2135 @@ -97,7 +97,7 @@
2136
2137 #define NOTIFY_MAXSIZE 8192
2138
2139 -int do_notify()
2140 +static int do_notify()
2141 {
2142 struct sockaddr_un sun_data;
2143 socklen_t sunlen = sizeof(sun_data);
2144 diff -Naur cyrus-imapd-2.2.12/ptclient/Makefile.in cyrus-imapd-2.2.12.autocreate2/ptclient/Makefile.in
2145 --- cyrus-imapd-2.2.12/ptclient/Makefile.in 2004-05-28 21:03:08.000000000 +0300
2146 +++ cyrus-imapd-2.2.12.autocreate2/ptclient/Makefile.in 2005-10-19 14:48:58.053762000 +0300
2147 @@ -57,10 +57,11 @@
2148 AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@
2149 AFS_LIBS = @AFS_LIBS@
2150 IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
2151 +SIEVE_LIBS = @SIEVE_LIBS@
2152 LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@
2153 LIB_SASL = @LIB_SASL@
2154 LIB_WRAP = @LIB_WRAP@
2155 -DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
2156 +DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
2157 UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o
2158
2159 LDAP_LIBS=@LDAP_LIBS@