Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 112912 | Differences between
and this patch

Collapse All | Expand All

(-)cyrus-imapd-2.2.12/README.autocreate (+181 lines)
Line 0 Link Here
1
Cyrus IMAP autocreate Inbox patch
2
----------------------------------
3
4
NOTE : This patch has been created at the University of Athens. For more info, as well 
5
as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr 
6
7
The design of Cyrus IMAP server does not predict the automatic creation of users'
8
INBOX folders. The creation of a user's INBOX is considered to be an external task,
9
that has to be completed as part of the user e-mail account creation procedure. 
10
Hence, to create a new e-mail account the site administrator has to 
11
a) Include the new account in the user database for the authentication procedure
12
   (e.g. sasldb, shadow, mysql, ldap).
13
b) Create the corresponding INBOX folder. 
14
15
Alternatively, the user, if succesfully authenticated, may create his own INBOX folder,
16
as long as the configuration of the site allows it (see "autocreatequota" in imapd.conf).
17
Unlike what uncareful readers may think, enabling the "autocreatequota" option, doesn't 
18
lead to the automatic INBOX folder creation by Cyrus IMAP server.
19
In fact, "autocreate" means that the IMAP clients are allowed to automatically create 
20
the user INBOX. 
21
22
This patch adds the functionality of automatic creation of the users' INBOX folders into
23
the Cyrus IMAP server. It is implemented as two features, namely the  "create on login"
24
and "create on post".
25
 
26
27
28
Create on login
29
===============
30
This feauture provides automatic creation of a user's INBOX folder when all of the 
31
following requirements are met:
32
33
i)  The user has succesfully passed the authentication procedure.
34
35
ii) The user's authorization ID (typically the same as the user's
36
authentication ID)  doesn't belong to the imap_admins or admins
37
accounts (see imapd.conf).
38
39
iii) The "autocreatequota" option in the imap configuration file 
40
has been set to a non zero value. 
41
42
iv) The corresponding to the user's authorizationID INBOX folder
43
does not exist.
44
45
The user's first login is the most typical case when all four requirements are met. 
46
Note that if the authenticatedID is allowed to proxy to another account for which 
47
all of the above requirements are met, the corresponding INBOX folder for that account 
48
will be created.
49
50
51
52
Create on post
53
==============
54
This feauture provides automatic creation of a user's INBOX folder when all of the 
55
following requirements are met. 
56
57
i) An e-mail message addressed to the user has been received.  
58
59
ii) The recipient is not any of the imap_admins or admins accounts. 
60
Note that passing e-mails to admins or imap_admins accounts from 
61
the MTA to LMTP should be avoided in any case.
62
63
iii) The recipient's INBOX does not exist.
64
65
iv) The "autocreatequota" option in the imap configuration file 
66
has been set to a non zero value. 
67
68
v) The "createonpost" option in the imap configuration file 
69
has been switched on. 
70
71
72
Besides the automatic creation of INBOX folder, additional functionalities are
73
provided:
74
75
A) Automatic creation of INBOX subfolders controlled by "autocreateinboxfolders"
76
configuration option. eg 
77
78
autocreateinboxfolders: sent|drafts|spam|templates
79
80
B) Automatic subscription of INBOX subfolders controlled by "autosubscribeinboxfolders"
81
configuration option. eg
82
83
autosubscribeinboxfolders: sent|spam
84
85
Obviously, only subscription to subfolders included in the "autocreateinboxfolder"
86
list is meaningfull. 
87
88
C) Automatic subscription to shared folders (bulletin boards). The user gets
89
automatically subscribed to the shared folders declared in the "autosubscribesharedfolders"
90
configuration option in imapd.conf.
91
eg autosubscribesharedfolders: public_folder | public_folder.subfolder
92
93
In order the above action to succeed, the shared folder has to pre-exist the INBOX creation
94
and the user must have the apropriate permissions in order to be able to subscribe to the
95
shared folder.
96
97
* A new config option has been added. 'autosubscribe_all_sharedfolders' is a yes/no
98
option. When set to yes, the user is automatically subscribed to all shared folders one 
99
has permission to subscribe to. Please, note that when this option is set to yes, then
100
'autosubscribesharedfolders' option is overriden.
101
102
D) Automatic creation of a predefined default sieve script.
103
104
This is very useful when a default sieve script is used for every user. Usually, a
105
default anti-spam script may me be written in a file and copied to each user
106
sieve scripts upon the INBOX creation. The imapd.conf options that have been added
107
are 'autocreate_sieve_script', 'autocreate_sieve_compiledscript' and 
108
'generate_compiled_sieve_script'. 
109
110
autocreate_sieve_script configuration option refers to the full path of the file 
111
that contains the sieve script. The default value is null and if no file is defined,
112
then no default script is created upon INBOX creation. (The feature is disabled)
113
eg autocreate_sieve_script: /etc/default_sieve_script
114
115
autocreate_sieve_compiledscript configuration option refers to the full path of the
116
file that contains the bytecode compiled sieve script. If this filename is defined
117
in imapd.conf and the file exists, then it is automatically copied in the user's sieve
118
directory. If it is not defined, then a bytecode sieve script gets on the fly compiled
119
by the daemon. 
120
eg autocreate_sieve_compiledscript: /etc/default_sieve_script.bc
121
122
generate_compiled_sieve_script is a boolean option that triggers the compilation of the 
123
source sieve script to bytecode sieve script. The file that the bytecode script will
124
be saved is pointed by autocreate_sieve_compiledscript.
125
126
Ways of compiling a sieve script : 
127
1. Compile a sieve script using the standard sievec utility, distributed by CMU
128
2. Compile a sieve script using the compile_sieve utility, released by UoA. This 
129
   tool is almost identical to the sievec utility, with the difference that it 
130
   reads the input and output file from autocreate_sieve_script and 
131
   autocreate_sieve_compiledscript options in imapd.conf
132
3. Let cyrus create a compiled sieve script using a source script. Cyrus can be
133
   instructed to save the compiled script any time a compiled script does not exist.
134
135
NOTES : 
136
1. In order this functionality to work, the following requirements must have been met:
137
   - 'sieveusehomedir' option must be 'no' in the configuration (default).
138
   - 'sievedir' option must have a valid value.
139
2. Currently, this patch checks the validity of the source script while generating a 
140
   bytecode compiled script, but not the validity of the bytecode sieve script file.
141
   The administrator should make sure that the provided files contain a valid sieve
142
   script as well as the compiled script is updated every time the source script changes.
143
144
145
146
Issues to be considered 
147
=======================
148
149
I) In order to use the create on post feauture one should be absolutely sure that: 
150
a) The MTA checks the validity of the e-mail recipient before sending the e-mail to
151
LMTP. This is an RFC821 requirement. This usually expands to "the mta should be 
152
able to use the account database as user mailbox database". 
153
b) Only authorized accounts/services can talk to LMTP.
154
155
II) Especially in the case of imap logins, the current patch implementation checks
156
for the INBOX folder existence upon login, causing an extra mailbox lookup in most 
157
of the cases. 
158
A better approach would be to chase the "IMAP_MAILBOX_NONEXISTENT" error code and
159
check if the error is associated with an INBOX folder. However, this would mess up
160
Cyrus code. The way it was implemented may not have been the most performance
161
optimized, but it produces a much cleaner and simple patch.
162
163
164
165
Virtual Domains Support
166
=======================
167
168
Virtual domains are supported by all versions of the patch for cyrus-imapd-2.2.1-BETA and 
169
later. However, it is not possible to declare different INBOX subfolders to be created or 
170
shared folders to be subscribed to for every domain.
171
172
173
174
Things to be done
175
=================
176
177
1. Support MURDER architecture. 
178
179
180
For more information and updates please visit http://email.uoa.gr/autocreate
181
(-)cyrus-imapd-2.2.12/imap/Makefile.in (-48 / +52 lines)
Lines 104-110 Link Here
104
	convert_code.o duplicate.o saslclient.o saslserver.o signals.o \
104
	convert_code.o duplicate.o saslclient.o saslserver.o signals.o \
105
	annotate.o search_engines.o squat.o squat_internal.o mbdump.o \
105
	annotate.o search_engines.o squat.o squat_internal.o mbdump.o \
106
	imapparse.o telemetry.o user.o notify.o protocol.o quota_db.o \
106
	imapparse.o telemetry.o user.o notify.o protocol.o quota_db.o \
107
	$(SEEN) $(IDLE)
107
	autosieve.o $(SEEN) $(IDLE)
108
108
109
IMAPDOBJS=pushstats.o backend.o imapd.o index.o tls.o version.o
109
IMAPDOBJS=pushstats.o backend.o imapd.o index.o tls.o version.o
110
110
Lines 122-128 Link Here
122
	fud smmapd reconstruct quota mbpath ipurge \
122
	fud smmapd reconstruct quota mbpath ipurge \
123
	cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \
123
	cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \
124
	ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \
124
	ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \
125
	@IMAP_PROGS@
125
	compile_sieve @IMAP_PROGS@
126
126
127
BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \
127
BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \
128
	lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \
128
	lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \
Lines 188-194 Link Here
188
### Services
188
### Services
189
idled: idled.o mutex_fake.o libimap.a $(DEPLIBS)
189
idled: idled.o mutex_fake.o libimap.a $(DEPLIBS)
190
	$(CC) $(LDFLAGS) -o idled \
190
	$(CC) $(LDFLAGS) -o idled \
191
	 idled.o mutex_fake.o libimap.a $(DEPLIBS) $(LIBS)
191
	 idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
192
192
193
lmtpd: lmtpd.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) \
193
lmtpd: lmtpd.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) \
194
	$(DEPLIBS) $(SERVICE)
194
	$(DEPLIBS) $(SERVICE)
Lines 214-223 Link Here
214
	 $(SERVICE) lmtpproxyd.o backend.o $(LMTPOBJS) mutex_fake.o \
214
	 $(SERVICE) lmtpproxyd.o backend.o $(LMTPOBJS) mutex_fake.o \
215
	 libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
215
	 libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
216
216
217
imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
217
imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
218
	$(CC) $(LDFLAGS) -o imapd \
218
	$(CC) $(LDFLAGS) -o imapd \
219
	 $(SERVICE) $(IMAPDOBJS) mutex_fake.o \
219
	 $(SERVICE) $(IMAPDOBJS) mutex_fake.o \
220
	libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
220
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
221
221
222
imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
222
imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
223
	$(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \
223
	$(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \
Lines 232-238 Link Here
232
proxyd: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
232
proxyd: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
233
	$(CC) $(LDFLAGS) -o proxyd \
233
	$(CC) $(LDFLAGS) -o proxyd \
234
	 $(SERVICE) $(PROXYDOBJS) mutex_fake.o libimap.a \
234
	 $(SERVICE) $(PROXYDOBJS) mutex_fake.o libimap.a \
235
	 $(DEPLIBS) $(LIBS) $(LIB_WRAP)
235
	 $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
236
236
237
proxyd.pure: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
237
proxyd.pure: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
238
	$(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o proxyd.pure \
238
	$(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o proxyd.pure \
Lines 244-250 Link Here
244
	$(CC) $(LDFLAGS) -o mupdate \
244
	$(CC) $(LDFLAGS) -o mupdate \
245
	 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
245
	 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
246
	 mutex_pthread.o tls.o libimap.a \
246
	 mutex_pthread.o tls.o libimap.a \
247
	 $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
247
	 $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
248
248
249
mupdate.pure: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o \
249
mupdate.pure: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o \
250
	libimap.a $(DEPLIBS)
250
	libimap.a $(DEPLIBS)
Lines 252-343 Link Here
252
	 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
252
	 $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \
253
	 mutex_pthread.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
253
	 mutex_pthread.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread
254
254
255
pop3d: pop3d.o backend.o tls.o mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE)
255
pop3d: pop3d.o backend.o tls.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
256
	$(CC) $(LDFLAGS) -o pop3d pop3d.o backend.o tls.o $(SERVICE) \
256
	$(CC) $(LDFLAGS) -o pop3d pop3d.o backend.o tls.o $(SERVICE) \
257
	 mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
257
	 mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
258
258
259
nntpd: nntpd.o backend.o index.o smtpclient.o spool.o tls.o \
259
nntpd: nntpd.o backend.o index.o smtpclient.o spool.o tls.o \
260
	 mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE)
260
	 mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE)
261
	$(CC) $(LDFLAGS) -o nntpd nntpd.o backend.o index.o spool.o \
261
	$(CC) $(LDFLAGS) -o nntpd nntpd.o backend.o index.o spool.o \
262
	 smtpclient.o tls.o $(SERVICE) mutex_fake.o nntp_err.o \
262
	 smtpclient.o tls.o $(SERVICE) mutex_fake.o nntp_err.o \
263
	 libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
263
	 libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
264
264
265
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 \
266
	$(CC) $(LDFLAGS) -o fud $(SERVICE) fud.o mutex_fake.o libimap.a \
267
	$(DEPLIBS) $(LIBS) $(LIB_WRAP)
267
	$(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
268
268
269
smmapd: smmapd.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE)
269
smmapd: smmapd.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
270
	$(CC) $(LDFLAGS) -o smmapd $(SERVICE) smmapd.o mutex_fake.o libimap.a \
270
	$(CC) $(LDFLAGS) -o smmapd $(SERVICE) smmapd.o mutex_fake.o libimap.a \
271
	$(DEPLIBS) $(LIBS) $(LIB_WRAP)
271
	$(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
272
272
273
### Command Line Utilities
273
### Command Line Utilities
274
arbitron: arbitron.o $(CLIOBJS) libimap.a $(DEPLIBS)
274
arbitron: arbitron.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
275
	$(CC) $(LDFLAGS) -o arbitron arbitron.o $(CLIOBJS) \
275
	$(CC) $(LDFLAGS) -o arbitron arbitron.o $(CLIOBJS) \
276
	libimap.a $(DEPLIBS) $(LIBS)
276
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
277
278
compile_sieve: compile_sieve.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
279
	$(CC) $(LDFLAGS) -o compile_sieve compile_sieve.o $(CLIOBJS) \
280
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
277
281
278
cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(DEPLIBS)
282
cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
279
	$(CC) $(LDFLAGS) -o cvt_cyrusdb cvt_cyrusdb.o $(CLIOBJS) \
283
	$(CC) $(LDFLAGS) -o cvt_cyrusdb cvt_cyrusdb.o $(CLIOBJS) \
280
	libimap.a $(DEPLIBS) $(LIBS)
284
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
281
285
282
chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(DEPLIBS)
286
chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
283
	$(CC) $(LDFLAGS) -o chk_cyrus chk_cyrus.o $(CLIOBJS) \
287
	$(CC) $(LDFLAGS) -o chk_cyrus chk_cyrus.o $(CLIOBJS) \
284
	libimap.a $(DEPLIBS) $(LIBS)
288
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
285
289
286
deliver: deliver.o backend.o $(LMTPOBJS) mutex_fake.o libimap.a $(DEPLIBS)
290
deliver: deliver.o backend.o $(LMTPOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS)
287
	$(CC) $(LDFLAGS) -o deliver deliver.o backend.o $(LMTPOBJS) \
291
	$(CC) $(LDFLAGS) -o deliver deliver.o backend.o $(LMTPOBJS) \
288
	mutex_fake.o libimap.a $(DEPLIBS) $(LIBS)
292
	mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
289
293
290
ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS)
294
ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
291
	$(CC) $(LDFLAGS) -o \
295
	$(CC) $(LDFLAGS) -o \
292
	 $@ ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
296
	 $@ ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
293
297
294
ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(DEPLIBS)
298
ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
295
	$(CC) $(LDFLAGS) -o $@ ctl_mboxlist.o mupdate-client.o $(CLIOBJS) \
299
	$(CC) $(LDFLAGS) -o $@ ctl_mboxlist.o mupdate-client.o $(CLIOBJS) \
296
	libimap.a $(DEPLIBS) $(LIBS)
300
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
297
301
298
ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS)
302
ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
299
	$(CC) $(LDFLAGS) -o \
303
	$(CC) $(LDFLAGS) -o \
300
	 $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
304
	 $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
301
305
302
cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(DEPLIBS)
306
cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
303
	$(CC) $(LDFLAGS) -o $@ cyr_expire.o $(CLIOBJS) \
307
	$(CC) $(LDFLAGS) -o $@ cyr_expire.o $(CLIOBJS) \
304
	libimap.a $(DEPLIBS) $(LIBS)
308
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
305
309
306
fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS)
310
fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
307
	$(CC) $(LDFLAGS) -o \
311
	$(CC) $(LDFLAGS) -o \
308
	 $@ fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
312
	 $@ fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
309
313
310
squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(DEPLIBS)
314
squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
311
	$(CC) $(LDFLAGS) -o squatter squatter.o index.o squat_build.o \
315
	$(CC) $(LDFLAGS) -o squatter squatter.o index.o squat_build.o \
312
	$(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
316
	$(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
313
317
314
mbpath: mbpath.o $(CLIOBJS) libimap.a $(DEPLIBS)
318
mbpath: mbpath.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
315
	$(CC) $(LDFLAGS) -o mbpath mbpath.o $(CLIOBJS) libimap.a \
319
	$(CC) $(LDFLAGS) -o mbpath mbpath.o $(CLIOBJS) libimap.a \
316
	$(DEPLIBS) $(LIBS)
320
	$(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
317
321
318
ipurge: ipurge.o $(CLIOBJS) libimap.a $(DEPLIBS)
322
ipurge: ipurge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
319
	$(CC) $(LDFLAGS) -o ipurge ipurge.o $(CLIOBJS) \
323
	$(CC) $(LDFLAGS) -o ipurge ipurge.o $(CLIOBJS) \
320
	libimap.a $(DEPLIBS) $(LIBS)
324
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
321
325
322
cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(DEPLIBS)
326
cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
323
	$(CC) $(LDFLAGS) -o cyrdump cyrdump.o index.o $(CLIOBJS) \
327
	$(CC) $(LDFLAGS) -o cyrdump cyrdump.o index.o $(CLIOBJS) \
324
	libimap.a $(DEPLIBS) $(LIBS)
328
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
325
329
326
mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS)
330
mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
327
	$(CC) $(LDFLAGS) -o \
331
	$(CC) $(LDFLAGS) -o \
328
	 mbexamine mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
332
	 mbexamine mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
329
333
330
reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS)
334
reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
331
	$(CC) $(LDFLAGS) -o \
335
	$(CC) $(LDFLAGS) -o \
332
	 reconstruct reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
336
	 reconstruct reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
333
337
334
quota: quota.o $(CLIOBJS) libimap.a $(DEPLIBS)
338
quota: quota.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
335
	$(CC) $(LDFLAGS) -o quota quota.o $(CLIOBJS) \
339
	$(CC) $(LDFLAGS) -o quota quota.o $(CLIOBJS) \
336
	libimap.a $(DEPLIBS) $(LIBS)
340
	libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
337
341
338
tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS)
342
tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
339
	$(CC) $(LDFLAGS) -o \
343
	$(CC) $(LDFLAGS) -o \
340
	 $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
344
	 $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
341
345
342
### Other Misc Targets
346
### Other Misc Targets
343
347
(-)cyrus-imapd-2.2.12/imap/autosieve.c (+587 lines)
Line 0 Link Here
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#ifdef HAVE_UNISTD_H
6
#include <unistd.h>
7
#endif
8
9
#include <errno.h>
10
#include <sys/types.h>
11
#include <sys/stat.h>
12
#include <sys/uio.h>
13
#include <fcntl.h>
14
#include <ctype.h>
15
#include <time.h>
16
#include <syslog.h>
17
#include <com_err.h>
18
#include <config.h>
19
20
#include "global.h"
21
#include "util.h"
22
#include "mailbox.h"
23
#include "imap_err.h"
24
#include "sieve_interface.h"
25
#include "script.h"
26
27
#define TIMSIEVE_FAIL 	-1
28
#define TIMSIEVE_OK 	0
29
#define MAX_FILENAME	1024
30
31
static int get_script_name(char *sievename, size_t buflen, const char *filename);
32
static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir);
33
int autoadd_sieve(char *userid, const char *source_script);
34
35
static void fatal(const char *s, int code);
36
static void foo(void);
37
static int sieve_notify(void *ac __attribute__((unused)),
38
                        void *interp_context __attribute__((unused)),
39
                        void *script_context __attribute__((unused)),
40
                        void *message_context __attribute__((unused)),
41
                        const char **errmsg __attribute__((unused)));
42
static int mysieve_error(int lineno, const char *msg,
43
                  void *i __attribute__((unused)), void *s);
44
static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
45
46
47
sieve_vacation_t vacation2 = {
48
    0,                          /* min response */
49
    0,                          /* max response */
50
    (sieve_callback *) &foo,    /* autorespond() */
51
    (sieve_callback *) &foo     /* send_response() */
52
};
53
54
55
/*
56
 * Find the name of the sieve script
57
 * given the source script and compiled script names
58
 */
59
static int get_script_name(char *sievename, size_t buflen, const char *filename)
60
{
61
  char *p;
62
  int r;
63
64
  p = strrchr(filename, '/');
65
  if (p == NULL)
66
      p = (char *) filename;
67
  else
68
      p++;
69
70
  r = strlcpy(sievename, p, buflen) - buflen;
71
  return (r >= 0 || r == -buflen ? 1 : 0);
72
}
73
74
75
/*
76
 * Find the directory where the sieve scripts of the user
77
 * reside
78
 */
79
static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir)
80
{
81
    char *user = NULL, *domain = NULL;
82
83
    /* Setup the user and the domain */
84
    if(config_virtdomains && (domain = strchr(userid, '@'))) {
85
        user = (char *) xmalloc((domain - userid +1) * sizeof(char));
86
        strlcpy(user, userid, domain - userid + 1);
87
        domain++;
88
    } else
89
        user = userid;
90
91
    /*  Find the dir path where the sieve scripts of the user will reside */   
92
    if (config_virtdomains && domain) {
93
         if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/",
94
              sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain), domain, dir_hash_c(user), user) >= buflen) {
95
                 free(user);
96
                 return 1;
97
 	 }
98
    } else {
99
         if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/", 
100
     	      sieve_dir, dir_hash_c(user), user) >= buflen) 
101
                 return 1;
102
    }
103
104
    /* Free the xmalloced user memory, reserved above */
105
    if(user != userid)
106
        free(user);
107
108
    return 0;
109
}
110
111
int autoadd_sieve(char *userid, const char *source_script)
112
{   
113
    sieve_script_t *s = NULL;
114
    bytecode_info_t *bc = NULL;
115
    char *err = NULL;
116
    FILE *in_stream, *out_fp;
117
    int out_fd, in_fd, r, k;
118
    int do_compile = 0;
119
    const char *sieve_dir = NULL;
120
    const char *compiled_source_script = NULL;
121
    char sievename[MAX_FILENAME];
122
    char sieve_script_name[MAX_FILENAME];
123
    char sieve_script_dir[MAX_FILENAME];
124
    char sieve_bcscript_name[MAX_FILENAME];
125
    char sieve_default[MAX_FILENAME];
126
    char sieve_tmpname[MAX_FILENAME];
127
    char sieve_bctmpname[MAX_FILENAME];
128
    char sieve_bclink_name[MAX_FILENAME];
129
    char buf[4096];
130
    mode_t oldmask;
131
    struct stat statbuf;
132
133
    /* We don't support using the homedirectory, like timsieved */
134
    if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) {
135
        syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf");
136
        return 1;
137
    }
138
139
    /* Check if sievedir is defined in imapd.conf */
140
    if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) { 
141
        syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf");
142
        return 1;
143
    }
144
145
    /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */
146
    if(!(compiled_source_script  = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
147
        syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it");
148
        do_compile = 1;
149
    }
150
151
    if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) {
152
        syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory");
153
        return 1;
154
    }
155
156
    if (get_script_name(sievename, sizeof(sievename), source_script)) {
157
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script);
158
        return 1;
159
    }
160
161
    if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) {
162
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
163
        return 1;
164
    }
165
    if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) {
166
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
167
        return 1;
168
    }    
169
    if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) {
170
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
171
        return 1;
172
    }
173
    if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) {
174
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
175
        return 1;
176
    }
177
    if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) {
178
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
179
        return 1;
180
    }
181
    if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name))  {
182
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
183
        return 1;
184
    }
185
186
    /* Check if a default sieve filter alrady exists */
187
    if(!stat(sieve_default,&statbuf)) {
188
        syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists");
189
        fclose(in_stream);
190
        return 1;
191
    }
192
193
    /* Open the source script. if there is a problem with that exit */
194
    in_stream = fopen(source_script, "r");
195
    if(!in_stream) {
196
        syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script);
197
        return 1;
198
    }
199
    
200
    
201
    /* 
202
     * At this point we start the modifications of the filesystem 
203
     */
204
205
    /* Create the directory where the sieve scripts will reside */
206
    r = cyrus_mkdir(sieve_script_dir, 0755);
207
    if(r == -1) {
208
        /* If this fails we just leave */
209
        syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name);
210
        return 1;
211
    }
212
213
    /*
214
     * We open the file that will be used as the bc file. If this file exists, overwrite it 
215
     * since something bad has happened. We open the file here so that this error checking is
216
     * done before we try to open the rest of the files to start copying etc. 
217
     */
218
    out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
219
    if(out_fd < 0) {
220
        if(errno == EEXIST) {
221
            syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname);
222
        } else if (errno == EACCES) {
223
            syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname);
224
            fclose(in_stream);
225
            return 1;
226
        } else {
227
            syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname);
228
            fclose(in_stream);
229
            return 1;
230
        }
231
    }
232
233
    if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) {
234
        while((r = read(in_fd, buf, sizeof(buf))) > 0) {
235
            if((k=write(out_fd, buf,r)) < 0) {
236
                syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno);
237
                close(out_fd);
238
                close(in_fd);
239
                fclose(in_stream);
240
                unlink(sieve_bctmpname);
241
                return 1;
242
           }
243
        } 
244
245
        if(r == 0) { /* EOF */
246
            close(out_fd);
247
            close(in_fd);
248
        } else if (r < 0) {
249
            syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it", 
250
                           compiled_source_script);
251
            close(in_fd);
252
            do_compile = 1;
253
            if(lseek(out_fd, 0, SEEK_SET)) {
254
                syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting");
255
                return 1;
256
            }
257
        }
258
        close(in_fd);
259
    } else {
260
        if(compiled_source_script)
261
              syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script);
262
        do_compile = 1;
263
    }
264
265
266
    /* Because we failed to open a precompiled bc sieve script, we compile one */
267
    if(do_compile) {
268
       if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
269
            if(err && *err) {
270
               syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err);
271
               free(err);
272
            } else
273
                syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script");
274
    
275
            unlink(sieve_bctmpname);
276
            fclose(in_stream);
277
            close(out_fd);
278
            return 1;
279
        }
280
281
        /* generate the bytecode */
282
        if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) {
283
            syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script");
284
            /* removing the copied script and cleaning up memory */
285
            unlink(sieve_bctmpname);
286
            sieve_script_free(&s);
287
            fclose(in_stream);
288
            close(out_fd);
289
            return 1;
290
        }
291
292
        if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) {
293
            syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script");
294
            /* removing the copied script and cleaning up memory */
295
            unlink(sieve_bctmpname);
296
            sieve_free_bytecode(&bc);
297
            sieve_script_free(&s);
298
            fclose(in_stream);
299
            close(out_fd);
300
            return 1;
301
        }
302
303
        /* clean up the memory */
304
        sieve_free_bytecode(&bc);
305
        sieve_script_free(&s);
306
    }
307
308
    close(out_fd);
309
    rewind(in_stream);
310
311
    /* Copy the initial script */
312
    oldmask = umask(077);
313
    if((out_fp = fopen(sieve_tmpname, "w")) == NULL) {
314
        syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname);
315
        unlink(sieve_bctmpname);
316
        umask(oldmask);
317
        fclose(in_stream);
318
        return 1;
319
    }
320
    umask(oldmask);
321
322
    while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) {
323
        if( fwrite(buf,sizeof(char), r, out_fp) != r) {
324
            syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname);
325
            fclose(out_fp);
326
            unlink(sieve_tmpname);
327
            unlink(sieve_bctmpname);
328
            fclose(in_stream);
329
            return 1;
330
        }
331
    }
332
    
333
    if(feof(in_stream)) {
334
        fclose(out_fp);
335
    } else { /* ferror */
336
        fclose(out_fp);
337
        unlink(sieve_tmpname);
338
        unlink(sieve_bctmpname);
339
        fclose(in_stream);
340
        return 1;
341
    }
342
343
    /* Renaming the necessary stuff */
344
    if(rename(sieve_tmpname, sieve_script_name)) {
345
        unlink(sieve_tmpname);
346
        unlink(sieve_bctmpname);
347
        return 1;
348
    }
349
350
    if(rename(sieve_bctmpname, sieve_bcscript_name)) {
351
        unlink(sieve_bctmpname);
352
        unlink(sieve_bcscript_name);
353
        return 1;
354
    }
355
356
    /* end now with the symlink */
357
    if(symlink(sieve_bclink_name, sieve_default)) {
358
        if(errno != EEXIST) {
359
            syslog(LOG_WARNING, "autocreate_sieve: problem making the default link.");
360
            /* Lets delete the files */
361
            unlink(sieve_script_name);
362
            unlink(sieve_bcscript_name);
363
        }
364
    }
365
366
    /* 
367
     * If everything has succeeded AND we have compiled the script AND we have requested
368
     * to generate the global script so that it is not compiled each time then we create it.
369
     */
370
    if(do_compile && 
371
          config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) {
372
373
        if(!compiled_source_script) {
374
            syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf");
375
            return 0;
376
        }
377
378
        if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname))
379
            return 0;
380
381
        /*
382
         * Copy everything from the newly created bc sieve sieve script.
383
         */
384
        if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) {
385
            return 0;
386
        }
387
388
        if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
389
            if(errno == EEXIST) {
390
               /* Someone is already doing this so just bail out. */
391
               syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname);
392
                close(in_fd);
393
                return 0; 
394
            } else if (errno == EACCES) {
395
                syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname);
396
                close(in_fd);
397
                return 0;
398
            } else {
399
                syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname);
400
                close(in_fd);
401
                return 0;
402
            }
403
        }
404
405
        while((r = read(in_fd, buf, sizeof(buf))) > 0) {
406
            if((k = write(out_fd,buf,r)) < 0) {
407
                syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
408
                close(out_fd);
409
                close(in_fd);
410
                unlink(sieve_tmpname);
411
                return 0;
412
           }
413
        }
414
415
        if(r == 0 ) { /*EOF */
416
            close(out_fd);
417
            close(in_fd);
418
        } else if (r < 0) {
419
                syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
420
                close(out_fd);
421
                close(in_fd);
422
                unlink(sieve_tmpname);
423
                return 0;
424
        }
425
426
        /* Rename the temporary created sieve script to its final name. */
427
        if(rename(sieve_tmpname, compiled_source_script)) {
428
            if(errno != EEXIST) {
429
               unlink(sieve_tmpname);
430
               unlink(compiled_source_script);
431
        }
432
            return 0;
433
        }
434
435
        syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script);
436
    }
437
438
    return 0;
439
}
440
441
static void fatal(const char *s, int code)
442
{   
443
    printf("Fatal error: %s (%d)\r\n", s, code);
444
    exit(1);
445
}
446
447
/* to make larry's stupid functions happy :) */
448
static void foo(void)
449
{
450
    fatal("stub function called", 0);
451
}
452
453
static int sieve_notify(void *ac __attribute__((unused)),
454
                        void *interp_context __attribute__((unused)),
455
                        void *script_context __attribute__((unused)),
456
                        void *message_context __attribute__((unused)),
457
                        const char **errmsg __attribute__((unused)))
458
{
459
    fatal("stub function called", 0);
460
    return SIEVE_FAIL;
461
}
462
463
static int mysieve_error(int lineno, const char *msg,
464
                  void *i __attribute__((unused)), void *s)
465
{
466
    char buf[1024];
467
    char **errstr = (char **) s;
468
469
    snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
470
    *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
471
    syslog(LOG_DEBUG, "%s", buf);
472
    strcat(*errstr, buf);
473
474
    return SIEVE_OK;
475
}
476
477
/* end the boilerplate */
478
479
/* returns TRUE or FALSE */
480
int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
481
{
482
    sieve_interp_t *i;
483
    sieve_script_t *s;
484
    int res;
485
486
    res = sieve_interp_alloc(&i, NULL);
487
    if (res != SIEVE_OK) {
488
        syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res);
489
        return TIMSIEVE_FAIL;
490
    }
491
492
    res = sieve_register_redirect(i, (sieve_callback *) &foo);
493
    if (res != SIEVE_OK) {
494
        syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res);
495
        return TIMSIEVE_FAIL;
496
    }
497
    res = sieve_register_discard(i, (sieve_callback *) &foo);
498
    if (res != SIEVE_OK) {
499
        syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res);
500
        return TIMSIEVE_FAIL;
501
    }
502
    res = sieve_register_reject(i, (sieve_callback *) &foo);
503
    if (res != SIEVE_OK) {
504
        syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res);
505
        return TIMSIEVE_FAIL;
506
    }
507
    res = sieve_register_fileinto(i, (sieve_callback *) &foo);
508
    if (res != SIEVE_OK) {
509
        syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res);
510
        return TIMSIEVE_FAIL;
511
    }
512
    res = sieve_register_keep(i, (sieve_callback *) &foo);
513
    if (res != SIEVE_OK) {
514
        syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res);
515
        return TIMSIEVE_FAIL;
516
    }
517
518
    res = sieve_register_imapflags(i, NULL);
519
    if (res != SIEVE_OK) {
520
        syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res);
521
        return TIMSIEVE_FAIL;
522
    }
523
524
    res = sieve_register_size(i, (sieve_get_size *) &foo);
525
    if (res != SIEVE_OK) {
526
        syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res);
527
        return TIMSIEVE_FAIL;
528
    }
529
530
    res = sieve_register_header(i, (sieve_get_header *) &foo);
531
    if (res != SIEVE_OK) {
532
        syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res);
533
        return TIMSIEVE_FAIL;
534
    }
535
536
    res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
537
    if (res != SIEVE_OK) {
538
        syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res);
539
        return TIMSIEVE_FAIL;
540
    }
541
542
    res = sieve_register_vacation(i, &vacation2);
543
    if (res != SIEVE_OK) {
544
        syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res);
545
        return TIMSIEVE_FAIL;
546
    }
547
548
    res = sieve_register_notify(i, &sieve_notify);
549
    if (res != SIEVE_OK) {
550
        syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res);
551
        return TIMSIEVE_FAIL;
552
    }
553
554
    res = sieve_register_parse_error(i, &mysieve_error);
555
    if (res != SIEVE_OK) {
556
        syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res);
557
        return TIMSIEVE_FAIL;
558
    }
559
560
    rewind(stream);
561
562
    *errstr = (char *) xmalloc(20 * sizeof(char));
563
    strcpy(*errstr, "script errors:\r\n");
564
565
    res = sieve_script_parse(i, stream, errstr, &s);
566
567
    if (res == SIEVE_OK) {
568
        if(ret) {
569
            *ret = s;
570
        } else {
571
            sieve_script_free(&s);
572
        }
573
        free(*errstr);
574
        *errstr = NULL;
575
    }
576
577
    /* free interpreter */
578
    sieve_interp_free(&i);
579
580
    return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
581
}
582
583
/*
584
 * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of
585
 * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present
586
 */
587
(-)cyrus-imapd-2.2.12/imap/compile_sieve.c (+364 lines)
Line 0 Link Here
1
/* This tool compiles the sieve script from a command
2
line so that it can be used wby the autoadd patch */
3
#include <stdio.h>
4
#include <stdlib.h>
5
6
#include <config.h>
7
#include <string.h>
8
#ifdef HAVE_UNISTD_H
9
#include <unistd.h>
10
#endif
11
#include <errno.h>
12
#include <sys/types.h>
13
#include <sys/stat.h>
14
#include <sys/uio.h>
15
#include <fcntl.h>
16
#include <ctype.h>
17
#include <time.h>
18
#include <com_err.h>
19
20
#include "global.h"
21
22
#include "util.h"
23
#include "mailbox.h"
24
#include "imap_err.h"
25
#include "sieve_interface.h"
26
#include "script.h"
27
28
#include <pwd.h>
29
30
#define TIMSIEVE_FAIL 		-1
31
#define TIMSIEVE_OK 		0
32
#define MAX_FILENAME_SIZE	100
33
34
/* Needed by libconfig */
35
const int config_need_data = 0;
36
37
static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
38
39
static void fatal(const char *s, int code)
40
{   
41
    printf("Fatal error: %s (%d)\r\n", s, code);
42
43
    exit(1);
44
}
45
46
void usage(void)
47
{
48
    fprintf(stderr,
49
            "Usage:\n\tcompile_sieve [-C <altconfig>] [-i <infile> -o <outfile>]\n");
50
    exit(-1);
51
}
52
53
54
int main (int argc, char **argv)
55
{   
56
57
    sieve_script_t *s = NULL;
58
    bytecode_info_t *bc = NULL;
59
    char *err = NULL;
60
    FILE *in_stream;
61
    int  out_fd,r, k, opt;
62
    char *source_script = NULL;
63
    char *compiled_source_script = NULL;
64
    mode_t oldmask;
65
    struct stat statbuf;
66
    char *alt_config = NULL;
67
    extern char *optarg;
68
    char sieve_tmpname[MAX_MAILBOX_NAME+1];
69
70
    if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);
71
72
    while((opt = getopt(argc, argv, "C:i:o:")) != EOF) {
73
        switch (opt) {
74
            case 'C': /* alt config file */
75
	        alt_config =  optarg;
76
	        break;
77
	    case 'i': /* input script file */
78
		source_script = optarg;
79
		break;
80
	    case 'o': /* output script file */
81
		compiled_source_script = optarg;
82
		break;
83
	    default:
84
	        usage();
85
		break;
86
	}
87
    }
88
89
    if(source_script && !compiled_source_script) {
90
	    fprintf(stderr, "No output file was defined\n");
91
	    usage();
92
    } else if (!source_script && compiled_source_script) {
93
	    fprintf(stderr, "No input file was defined\n");
94
	    usage();
95
    }	
96
97
    /*
98
     * If no <infile> has been defined, then read them from
99
     * the configuration file.
100
     */
101
    if (!source_script && !compiled_source_script) { 
102
	    cyrus_init(alt_config, "compile_sieve", 0);
103
104
	    /* Initially check if we want to have the sieve script created */
105
	    if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) {
106
        	fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n");
107
	        return 1;
108
	    }
109
110
	    /* Check if we have an already compiled sieve script*/
111
	    if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
112
	        fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n");
113
		return 1;
114
	    }
115
116
	    if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) {
117
       		/* 
118
		 * At this point the only think that is inconsistent is the directory 
119
		 * that was created. But if the user will have any sieve scripts then 
120
		 * they will eventually go there, so no big deal 
121
		 */
122
	        fprintf(stderr, 
123
			"In imapd.conf the full path of the filenames must be defined\n");
124
	       	return 1;
125
	    }
126
    }
127
128
    printf("input file : %s, output file : %s\n", source_script, compiled_source_script);
129
130
131
    if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) {
132
	    fprintf(stderr, "Filename %s is too big\n", compiled_source_script);
133
	    return 1;
134
    }
135
    	
136
    snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script);
137
138
    in_stream = fopen(source_script,"r");
139
140
    if(!in_stream) {
141
        fprintf(stderr,"Unable to open %s source sieve script\n",source_script);
142
        return;
143
    }
144
145
    /* 
146
     * We open the file that will be used as the bc file. If this file exists, overwrite it 
147
     * since something bad has happened. We open the file here so that this error checking is
148
     * done before we try to open the rest of the files to start copying etc. 
149
     */
150
    out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
151
    if(out_fd < 0) {
152
        if(errno == EEXIST) {
153
            fprintf(stderr, "File %s already exists\n", sieve_tmpname);
154
        } else if (errno == EACCES) {
155
            fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n",
156
			    sieve_tmpname);
157
        } else {
158
            fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n", 
159
			    sieve_tmpname);
160
        }
161
	
162
	fclose(in_stream);
163
	return 1;
164
    }
165
166
    if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
167
        if(err && *err) {
168
           fprintf(stderr, "Error while parsing script %s\n",err);
169
           free(err);
170
        }
171
        else
172
            fprintf(stderr,"Error while parsing script\n");
173
            unlink(sieve_tmpname);
174
	    fclose(in_stream);
175
	    close(out_fd);
176
        return;
177
   }
178
179
180
    /* generate the bytecode */
181
    if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) {
182
        fprintf(stderr,"Error occured while compiling sieve script\n");
183
        /* removing the copied script and cleaning up memory */
184
        unlink(sieve_tmpname);
185
        sieve_script_free(&s);
186
        fclose(in_stream);
187
        close(out_fd);
188
        return;
189
    }
190
    if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) {
191
        fprintf(stderr, "Error occured while emitting sieve script\n");
192
        unlink(sieve_tmpname);
193
        sieve_free_bytecode(&bc);
194
        sieve_script_free(&s);
195
        fclose(in_stream);
196
        close(out_fd);
197
        return;
198
    }
199
200
    /* clean up the memory */
201
    sieve_free_bytecode(&bc);
202
    sieve_script_free(&s);
203
204
    close(out_fd);
205
206
    if(rename(sieve_tmpname, compiled_source_script)) {
207
        if(errno != EEXIST) {
208
            unlink(sieve_tmpname);
209
            unlink(compiled_source_script);
210
            return 1;
211
        }
212
    }
213
    return 0;
214
}
215
216
217
/* to make larry's stupid functions happy :) */
218
static void foo(void)
219
{
220
    fatal("stub function called", 0);
221
}
222
223
extern sieve_vacation_t vacation2;/* = {
224
    0,                          / min response /
225
    0,                          / max response /
226
    (sieve_callback *) &foo,    / autorespond() /
227
    (sieve_callback *) &foo     / send_response() /
228
}; */
229
230
static int sieve_notify(void *ac __attribute__((unused)),
231
                        void *interp_context __attribute__((unused)),
232
                        void *script_context __attribute__((unused)),
233
                        void *message_context __attribute__((unused)),
234
                        const char **errmsg __attribute__((unused)))
235
{
236
    fatal("stub function called", 0);
237
    return SIEVE_FAIL;
238
}
239
240
static int mysieve_error(int lineno, const char *msg,
241
                  void *i __attribute__((unused)), void *s)
242
{
243
    char buf[1024];
244
    char **errstr = (char **) s;
245
246
    snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
247
    *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
248
    fprintf(stderr, "%s\n", buf);
249
    strcat(*errstr, buf);
250
251
    return SIEVE_OK;
252
}
253
254
/* end the boilerplate */
255
256
/* returns TRUE or FALSE */
257
int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
258
{
259
    sieve_interp_t *i;
260
    sieve_script_t *s;
261
    int res;
262
263
    res = sieve_interp_alloc(&i, NULL);
264
    if (res != SIEVE_OK) {
265
        fprintf(stderr, "sieve_interp_alloc() returns %d\n", res);
266
        return TIMSIEVE_FAIL;
267
    }
268
269
    res = sieve_register_redirect(i, (sieve_callback *) &foo);
270
    if (res != SIEVE_OK) {
271
        fprintf(stderr, "sieve_register_redirect() returns %d\n", res);
272
        return TIMSIEVE_FAIL;
273
    }
274
    res = sieve_register_discard(i, (sieve_callback *) &foo);
275
    if (res != SIEVE_OK) {
276
        fprintf(stderr, "sieve_register_discard() returns %d\n", res);
277
        return TIMSIEVE_FAIL;
278
    }
279
    res = sieve_register_reject(i, (sieve_callback *) &foo);
280
    if (res != SIEVE_OK) {
281
        fprintf(stderr, "sieve_register_reject() returns %d\n", res);
282
        return TIMSIEVE_FAIL;
283
    }
284
    res = sieve_register_fileinto(i, (sieve_callback *) &foo);
285
    if (res != SIEVE_OK) {
286
        fprintf(stderr, "sieve_register_fileinto() returns %d\n", res);
287
        return TIMSIEVE_FAIL;
288
    }
289
    res = sieve_register_keep(i, (sieve_callback *) &foo);
290
    if (res != SIEVE_OK) {
291
        fprintf(stderr, "sieve_register_keep() returns %d\n", res);
292
        return TIMSIEVE_FAIL;
293
    }
294
295
    res = sieve_register_imapflags(i, NULL);
296
    if (res != SIEVE_OK) {
297
        fprintf(stderr, "sieve_register_imapflags() returns %d\n", res);
298
        return TIMSIEVE_FAIL;
299
    }
300
301
    res = sieve_register_size(i, (sieve_get_size *) &foo);
302
    if (res != SIEVE_OK) {
303
        fprintf(stderr, "sieve_register_size() returns %d\n", res);
304
        return TIMSIEVE_FAIL;
305
    }
306
307
    res = sieve_register_header(i, (sieve_get_header *) &foo);
308
    if (res != SIEVE_OK) {
309
        fprintf(stderr, "sieve_register_header() returns %d\n", res);
310
        return TIMSIEVE_FAIL;
311
    }
312
313
    res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
314
    if (res != SIEVE_OK) {
315
        fprintf(stderr, "sieve_register_envelope() returns %d\n", res);
316
        return TIMSIEVE_FAIL;
317
    }
318
319
    res = sieve_register_vacation(i, &vacation2);
320
    if (res != SIEVE_OK) {
321
        fprintf(stderr, "sieve_register_vacation() returns %d\n", res);
322
        return TIMSIEVE_FAIL;
323
    }
324
325
    res = sieve_register_notify(i, &sieve_notify);
326
    if (res != SIEVE_OK) {
327
        fprintf(stderr, "sieve_register_notify() returns %d\n", res);
328
        return TIMSIEVE_FAIL;
329
    }
330
331
    res = sieve_register_parse_error(i, &mysieve_error);
332
    if (res != SIEVE_OK) {
333
        fprintf(stderr, "sieve_register_parse_error() returns %d\n", res);
334
        return TIMSIEVE_FAIL;
335
    }
336
337
    rewind(stream);
338
339
    *errstr = (char *) xmalloc(20 * sizeof(char));
340
    strcpy(*errstr, "script errors:\r\n");
341
342
    res = sieve_script_parse(i, stream, errstr, &s);
343
344
    if (res == SIEVE_OK) {
345
        if(ret) {
346
            *ret = s;
347
        } else {
348
            sieve_script_free(&s);
349
        }
350
        free(*errstr);
351
        *errstr = NULL;
352
    }
353
354
    /* free interpreter */
355
    sieve_interp_free(&i);
356
357
    return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
358
}
359
360
361
362
363
364
(-)cyrus-imapd-2.2.12/imap/imapd.c (+42 lines)
Lines 158-163 Link Here
158
void motd_file(int fd);
158
void motd_file(int fd);
159
void shut_down(int code);
159
void shut_down(int code);
160
void fatal(const char *s, int code);
160
void fatal(const char *s, int code);
161
void autocreate_inbox(void);
161
162
162
void cmdloop(void);
163
void cmdloop(void);
163
void cmd_login(char *tag, char *user);
164
void cmd_login(char *tag, char *user);
Lines 1693-1698 Link Here
1693
}
1694
}
1694
1695
1695
/*
1696
/*
1697
 * Autocreate Inbox and subfolders upon login
1698
 */
1699
void autocreate_inbox()
1700
{
1701
    char inboxname[MAX_MAILBOX_NAME+1];
1702
    int autocreatequota;
1703
    int r;
1704
 
1705
    /*
1706
     * Exlude admin's accounts
1707
     */
1708
    if (imapd_userisadmin || imapd_userisproxyadmin)
1709
        return;
1710
 
1711
    /*
1712
     * Exclude anonymous
1713
     */
1714
    if (!strcmp(imapd_userid, "anonymous"))
1715
        return;
1716
 
1717
    if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) {
1718
        /* This is actyally not required
1719
           as long as the lenght of userid is ok */
1720
           r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace,
1721
                                      "INBOX", imapd_userid, inboxname);
1722
           if (!r)
1723
               r = mboxlist_lookup(inboxname, NULL, NULL, NULL);
1724
 
1725
           if (r == IMAP_MAILBOX_NONEXISTENT)
1726
               mboxlist_autocreateinbox(&imapd_namespace, imapd_userid,
1727
                         imapd_authstate, inboxname, autocreatequota);
1728
     }
1729
}
1730
1731
1732
/*
1696
 * Perform a LOGIN command
1733
 * Perform a LOGIN command
1697
 */
1734
 */
1698
void cmd_login(char *tag, char *user)
1735
void cmd_login(char *tag, char *user)
Lines 1848-1853 Link Here
1848
				strcspn(imapd_userid, "@") : 0);
1885
				strcspn(imapd_userid, "@") : 0);
1849
1886
1850
    freebuf(&passwdbuf);
1887
    freebuf(&passwdbuf);
1888
1889
    autocreate_inbox();
1890
1851
    return;
1891
    return;
1852
}
1892
}
1853
1893
Lines 1993-1998 Link Here
1993
				config_virtdomains ?
2033
				config_virtdomains ?
1994
				strcspn(imapd_userid, "@") : 0);
2034
				strcspn(imapd_userid, "@") : 0);
1995
2035
2036
    autocreate_inbox();
2037
1996
    return;
2038
    return;
1997
}
2039
}
1998
2040
(-)cyrus-imapd-2.2.12/imap/lmtpd.c (+69 lines)
Lines 106-111 Link Here
106
static FILE *spoolfile(message_data_t *msgdata);
106
static FILE *spoolfile(message_data_t *msgdata);
107
static void removespool(message_data_t *msgdata);
107
static void removespool(message_data_t *msgdata);
108
108
109
static int autocreate_inbox(char *rcpt_userid);
110
109
/* current namespace */
111
/* current namespace */
110
static struct namespace lmtpd_namespace;
112
static struct namespace lmtpd_namespace;
111
113
Lines 504-513 Link Here
504
    exit(code);
506
    exit(code);
505
}
507
}
506
508
509
/*
510
 * Autocreate Inbox and subfolders upon login
511
 */
512
int autocreate_inbox(char *rcpt_userid)
513
{
514
    struct auth_state *authstate;
515
    char inboxname[MAX_MAILBOX_NAME+1];
516
    int rcptisadmin;
517
    int autocreatequota;
518
    int r;
519
520
    if(rcpt_userid == NULL)
521
	    return IMAP_MAILBOX_NONEXISTENT;
522
    
523
    /*
524
     * Exclude anonymous
525
     */
526
    if (!strcmp(rcpt_userid, "anonymous"))
527
        return IMAP_MAILBOX_NONEXISTENT;
528
529
    /*
530
     * Check for autocreatequota and createonpost
531
     */
532
    if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) ||
533
        !(config_getswitch(IMAPOPT_CREATEONPOST)))
534
        return IMAP_MAILBOX_NONEXISTENT;
535
536
    /*
537
     * Exclude admin's accounts
538
     */
539
     authstate = auth_newstate(rcpt_userid);
540
     rcptisadmin = global_authisa(authstate, IMAPOPT_ADMINS);
541
     if (rcptisadmin)
542
          return IMAP_MAILBOX_NONEXISTENT;
543
544
     r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace,
545
                                "INBOX", rcpt_userid, inboxname);
546
     if (!r)
547
     r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid,
548
                         authstate, inboxname, autocreatequota);
549
     return r;
550
}
551
552
507
static int verify_user(const char *user, const char *domain, const char *mailbox,
553
static int verify_user(const char *user, const char *domain, const char *mailbox,
508
		       long quotacheck, struct auth_state *authstate)
554
		       long quotacheck, struct auth_state *authstate)
509
{
555
{
510
    char namebuf[MAX_MAILBOX_NAME+1] = "";
556
    char namebuf[MAX_MAILBOX_NAME+1] = "";
557
    char *userinbox = NULL;
511
    int r = 0;
558
    int r = 0;
512
559
513
    if ((!user && !mailbox) ||
560
    if ((!user && !mailbox) ||
Lines 545-550 Link Here
545
	 */
592
	 */
546
	r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
593
	r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
547
			 !user ? ACL_POST : 0, quotacheck > 0 ? 0 : quotacheck);
594
			 !user ? ACL_POST : 0, quotacheck > 0 ? 0 : quotacheck);
595
        if (r == IMAP_MAILBOX_NONEXISTENT && user) {
596
	    if(domain) {
597
		int k;
598
		userinbox = (char *)xmalloc((strlen(user)+strlen(domain)+2)*sizeof(char));
599
		k = strlcpy(userinbox, user, strlen(user)+1);
600
		*(userinbox + k) = '@';
601
		strlcpy(userinbox+k+1, domain, strlen(domain)+1);
602
	    }
603
	    else userinbox = user;
604
            /* 
605
	     * Try to create automatically the mailbox, if
606
	     * autocreate inbox option is enabled.
607
	     */
608
	    r = autocreate_inbox(userinbox);
609
	    
610
	    if(userinbox != user)
611
		free(userinbox);
612
	    if (!r)
613
                r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
614
				0, quotacheck > 0 ? 0 : quotacheck);
615
    	}
616
548
    }
617
    }
549
618
550
    if (r) syslog(LOG_DEBUG, "verify_user(%s) failed: %s", namebuf,
619
    if (r) syslog(LOG_DEBUG, "verify_user(%s) failed: %s", namebuf,
(-)cyrus-imapd-2.2.12/imap/mboxlist.c (+359 lines)
Lines 81-86 Link Here
81
#include "mboxlist.h"
81
#include "mboxlist.h"
82
#include "quota.h"
82
#include "quota.h"
83
83
84
#ifdef USE_SIEVE
85
extern int autoadd_sieve(char *userid, 
86
		const char *source_script);
87
#endif
88
89
84
#define DB config_mboxlist_db
90
#define DB config_mboxlist_db
85
#define SUBDB config_subscription_db
91
#define SUBDB config_subscription_db
86
92
Lines 98-108 Link Here
98
static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
104
static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
99
				void *rock);
105
				void *rock);
100
106
107
static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
108
			      void *rock);
109
110
static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
111
                        char *userid, char *auth_userid,
112
                        struct auth_state *auth_state);
113
101
struct change_rock {
114
struct change_rock {
102
    struct quota *quota;
115
    struct quota *quota;
103
    struct txn **tid;
116
    struct txn **tid;
104
};
117
};
105
118
119
/*
120
 * Struct needed to be passed as void *rock to
121
 * mboxlist_autochangesub();
122
 */
123
struct changesub_rock_st {
124
        char *userid;
125
        char *auth_userid;
126
        struct auth_state *auth_state;
127
};
128
129
106
#define FNAME_SUBSSUFFIX ".sub"
130
#define FNAME_SUBSSUFFIX ".sub"
107
131
108
/*
132
/*
Lines 3124-3126 Link Here
3124
3148
3125
    return DB->abort(mbdb, tid);
3149
    return DB->abort(mbdb, tid);
3126
}
3150
}
3151
3152
/*
3153
 * Automatically subscribe user to *ALL* shared folders,
3154
 * one has permissions to be subscribed to.
3155
 * INBOX subfolders are excluded.
3156
 */
3157
static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
3158
                        void *rock) {
3159
3160
  struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock;
3161
  char *userid = changesub_rock->userid;
3162
  char *auth_userid = changesub_rock->auth_userid;
3163
  struct auth_state *auth_state = changesub_rock->auth_state;
3164
  int r;
3165
3166
3167
  if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */
3168
     (strlen(name) > 5  && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */
3169
     (strlen(name) > 4  && !strncmp(name, "user.", 5)))   /* Exclude other users' folders */
3170
	  return 0;
3171
3172
     
3173
  r = mboxlist_changesub(name, userid, auth_state, 1, 0);
3174
3175
  if (r) {
3176
      syslog(LOG_WARNING,
3177
             "autosubscribe: User %s to folder %s, subscription failed: %s",
3178
             auth_userid, name, error_message(r));
3179
  } else {
3180
      syslog(LOG_NOTICE,
3181
             "autosubscribe: User %s to folder %s, subscription succeeded",
3182
             auth_userid, name);
3183
  }
3184
3185
  return 0;
3186
}
3187
3188
#define SEP '|'
3189
3190
/*
3191
 * Automatically subscribe user to a shared folder.
3192
 * Subscription is done successfully, if the shared
3193
 * folder exists and the user has the necessary 
3194
 * permissions.
3195
 */
3196
static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
3197
                        char *userid, char *auth_userid,
3198
                        struct auth_state *auth_state) {
3199
        
3200
    const char *sub ;
3201
    char *p, *q, *next_sub;
3202
    char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1];
3203
    int len;
3204
    int r = 0;
3205
    int subscribe_all_sharedfolders = 0;
3206
3207
    subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS);
3208
3209
    /*
3210
     * If subscribeallsharedfolders is set to yes in imapd.conf, then
3211
     * subscribe user to every shared folder one has the apropriate 
3212
     * permissions.
3213
     */
3214
    if(subscribe_all_sharedfolders) {
3215
       char pattern[MAX_MAILBOX_PATH+1];
3216
       struct changesub_rock_st changesub_rock;
3217
3218
       strcpy(pattern, "*");
3219
       changesub_rock.userid = userid;
3220
       changesub_rock.auth_userid = auth_userid;
3221
       changesub_rock.auth_state = auth_state;
3222
3223
       r = mboxlist_findall(namespace, pattern, 0, userid,
3224
                            auth_state, mboxlist_autochangesub, &changesub_rock);
3225
3226
       return r;
3227
    }
3228
3229
    if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL)
3230
       return r;
3231
3232
    next_sub = (char *) sub;
3233
    while (*next_sub) {
3234
        for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
3235
        for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
3236
        for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
3237
        if (!*p ) continue;
3238
3239
        len = q - p + 1;
3240
        /* Check for folder length */
3241
        if (len  > sizeof(folder)-1)
3242
                continue;
3243
3244
        if (!r) {
3245
                strncpy(folder, p, len);
3246
                folder[len] = '\0';
3247
3248
               strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name));
3249
               len = strlcat(name, folder, sizeof(name));
3250
3251
               r = (namespace->mboxname_tointernal) (namespace, name, userid,
3252
                                                                  mailboxname);
3253
       }
3254
                                                                  
3255
        if (!r)
3256
               r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0);
3257
3258
        if (!r) {
3259
                syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded", 
3260
                       userid, folder);
3261
        } else {
3262
                syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s", 
3263
                       userid, folder, error_message(r));
3264
                r = 0;
3265
        }
3266
    }
3267
3268
    return r;
3269
}
3270
3271
3272
3273
int mboxlist_autocreateinbox(struct namespace *namespace,
3274
                        char *userid,
3275
                        struct auth_state *auth_state,
3276
                        char *mailboxname, int autocreatequota) {
3277
    char name [MAX_MAILBOX_NAME+1];
3278
    char folder [MAX_MAILBOX_NAME+1];
3279
    char *auth_userid = NULL;
3280
    char *partition = NULL;
3281
    const char *crt;
3282
    const char *sub;
3283
    char *p, *q, *next_crt, *next_sub;
3284
    int len;
3285
    int r = 0;
3286
    int numcrt = 0;
3287
    int numsub = 0;
3288
#ifdef USE_SIEVE
3289
    const char *source_script;
3290
#endif
3291
3292
   /*
3293
    * While this is not needed for admins
3294
    * and imap_admins accounts, it would be
3295
    * better to separate *all* admins and
3296
    * proxyservers from normal accounts
3297
    * (accounts that have mailboxes).
3298
    * UOA Specific note(1): Even if we do not
3299
    * exclude these servers-classes here,
3300
    * UOA specific code, will neither return
3301
    * role, nor create INBOX, because none of these
3302
    * administrative accounts belong to  the
3303
    * mailRecipient objectclass, or have imapPartition.
3304
    * UOA Specific note(2): Another good reason for doing
3305
    * this, is to prevent the code, from getting into
3306
    * cyrus_ldap.c because of the continues MSA logins to LMTPd.
3307
    */
3308
3309
   /*
3310
    * admins and the coresponding imap
3311
    * service, had already been excluded.
3312
    */
3313
3314
   /*
3315
    * Do we really need group membership
3316
    * for admins or service_admins?
3317
    */
3318
    if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
3319
    if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
3320
3321
   /*
3322
    * Do we really need group membership
3323
    * for proxyservers?
3324
    */
3325
    if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
3326
    if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
3327
3328
    auth_userid = auth_canonuser(auth_state);
3329
3330
    if (auth_userid == NULL) {
3331
         /*
3332
          * Couldn't get cannon userid
3333
          */
3334
          syslog(LOG_ERR,
3335
                 "Could not get cannon userid for user %s", userid);
3336
          return IMAP_PARTITION_UNKNOWN;
3337
    }
3338
3339
#if 0
3340
        /*
3341
         * Get Partition info or return.
3342
         * (Here you should propably use
3343
         * you own "get_partition(char *userid)"
3344
         * function. Otherwise all new INBOXes will be
3345
         * created into whatever partition has been declared
3346
         * as default in your imapd.conf)
3347
         */
3348
3349
        partition = get_partition(userid);
3350
3351
        if (partition == NULL) {
3352
            /*
3353
             * Couldn't get partition info
3354
             */
3355
            syslog(LOG_ERR,
3356
                   "Could not get imapPartition info for user %s", userid);
3357
            return IMAP_PARTITION_UNKNOWN;
3358
        }
3359
#endif
3360
3361
    r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
3362
                                      1, userid, auth_state, 0, 0, 0);
3363
3364
    if (!r && autocreatequota > 0)
3365
        r = mboxlist_setquota(mailboxname, autocreatequota, 0);
3366
3367
    if (!r)
3368
        r = mboxlist_changesub(mailboxname, userid,
3369
                              auth_state, 1, 1);
3370
3371
    if (!r) {
3372
       syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s", 
3373
               auth_userid, partition == NULL ? "default" : partition);
3374
    } else {
3375
       syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s", 
3376
               auth_userid, error_message(r));
3377
    }
3378
3379
3380
#if 0
3381
    /* Allocated from get_partition, and not needed any more */
3382
    free_partition(partition);
3383
#endif
3384
3385
    if (r) return r;
3386
3387
3388
    /* INBOX's subfolders */
3389
    if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS)))
3390
        sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS);
3391
3392
    /* Roll through crt */
3393
    next_crt = (char *) crt;
3394
    while (next_crt!=NULL && *next_crt) {
3395
          for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++);
3396
          for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++);
3397
          for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--);
3398
3399
          if (!*p) continue;
3400
3401
          len = q - p + 1;
3402
3403
          /* First time we check for length */
3404
          if (len > sizeof(folder) - 5)
3405
              r = IMAP_MAILBOX_BADNAME;
3406
3407
          if (!r) {
3408
                  strncpy(folder, p, len);
3409
                  folder[len] = '\0';
3410
3411
                  strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name));
3412
                  len = strlcat(name, folder, sizeof(name));
3413
          }
3414
3415
          if (!r)
3416
            r = (namespace->mboxname_tointernal) (namespace, name, userid,
3417
                                                 mailboxname);
3418
          if (!r)
3419
             r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
3420
                                            1, userid, auth_state, 0, 0, 0);
3421
3422
          if (!r) {
3423
            numcrt++;
3424
            syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.", 
3425
               auth_userid, name);
3426
         } else {
3427
             syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s", 
3428
               auth_userid, name, error_message(r));
3429
             r=0;
3430
             continue;
3431
          }
3432
3433
          /* Roll through sub */
3434
          next_sub = (char *) sub;
3435
          while (next_sub!=NULL && *next_sub) {
3436
                for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
3437
                for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
3438
                for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
3439
                if (!*p ) continue;
3440
3441
                len = q - p + 1;
3442
3443
                if (len != strlen(folder) || strncmp(folder, p, len))
3444
                    continue;
3445
3446
                r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1);
3447
3448
               if (!r) {
3449
                   numsub++;
3450
                   syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded",
3451
                       auth_userid, name);
3452
               } else
3453
                    syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to  %s failed. %s",
3454
                       auth_userid, name, error_message(r));
3455
3456
                break;
3457
         }
3458
    }
3459
3460
    if (crt!=NULL && *crt)
3461
       syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d", 
3462
               auth_userid, numcrt, numsub);
3463
3464
    /*
3465
     * Check if shared folders are available for subscription.
3466
     */
3467
    mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state);
3468
3469
#ifdef USE_SIEVE
3470
    /*
3471
     * Here the autocreate sieve script feature is iniated from.
3472
     */
3473
    source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT);
3474
 
3475
    if (source_script) {
3476
        if (!autoadd_sieve(userid, source_script))
3477
            syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid);
3478
        else
3479
            syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid);
3480
    }
3481
#endif
3482
3483
    return r;
3484
}
3485
(-)cyrus-imapd-2.2.12/imap/mboxlist.h (+6 lines)
Lines 197-200 Link Here
197
int mboxlist_commit(struct txn *tid);
197
int mboxlist_commit(struct txn *tid);
198
int mboxlist_abort(struct txn *tid);
198
int mboxlist_abort(struct txn *tid);
199
199
200
int mboxlist_autocreateinbox(struct namespace *namespace,
201
                        char *userid,
202
                        struct auth_state *auth_state,
203
                        char *mailboxname, int autocreatequota);
204
205
200
#endif
206
#endif
(-)cyrus-imapd-2.2.12/imap/pop3d.c (+47 lines)
Lines 152-157 Link Here
152
static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* <rand.time@hostname> */
152
static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* <rand.time@hostname> */
153
static void cmd_apop(char *response);
153
static void cmd_apop(char *response);
154
154
155
static int autocreate_inbox(char *inboxname, char *userid);
156
155
static void cmd_auth(char *arg);
157
static void cmd_auth(char *arg);
156
static void cmd_capa(void);
158
static void cmd_capa(void);
157
static void cmd_pass(char *pass);
159
static void cmd_pass(char *pass);
Lines 1084-1089 Link Here
1084
	popd_userid = xstrdup(p);
1086
	popd_userid = xstrdup(p);
1085
	prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
1087
	prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
1086
    }
1088
    }
1089
1087
}
1090
}
1088
1091
1089
void cmd_pass(char *pass)
1092
void cmd_pass(char *pass)
Lines 1328-1333 Link Here
1328
}
1331
}
1329
1332
1330
/*
1333
/*
1334
 * Autocreate Inbox and subfolders upon login
1335
 */
1336
int autocreate_inbox(char *inboxname, char *auth_userid)
1337
{
1338
    struct auth_state *authstate;
1339
    int userisadmin;
1340
    int autocreatequota;
1341
    int r;
1342
1343
    if(inboxname == NULL || auth_userid == NULL)
1344
	    return IMAP_MAILBOX_NONEXISTENT;
1345
    
1346
    /*
1347
     * Exclude anonymous
1348
     */
1349
    if (!strcmp(popd_userid, "anonymous"))
1350
        return IMAP_MAILBOX_NONEXISTENT;
1351
1352
    /*
1353
     * Check for autocreatequota
1354
     */
1355
    if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)))
1356
        return IMAP_MAILBOX_NONEXISTENT;
1357
1358
    /*
1359
     * Exclude admin's accounts
1360
     */
1361
1362
     authstate = auth_newstate(popd_userid);
1363
     userisadmin = global_authisa(authstate, IMAPOPT_ADMINS);
1364
     if (userisadmin)
1365
          return IMAP_MAILBOX_NONEXISTENT;
1366
1367
     r = mboxlist_autocreateinbox(&popd_namespace, auth_userid,
1368
                         authstate, inboxname, autocreatequota);
1369
     return r;
1370
}
1371
1372
1373
/*
1331
 * Complete the login process by opening and locking the user's inbox
1374
 * Complete the login process by opening and locking the user's inbox
1332
 */
1375
 */
1333
int openinbox(void)
1376
int openinbox(void)
Lines 1349-1354 Link Here
1349
					      userid, inboxname);
1392
					      userid, inboxname);
1350
1393
1351
    if (!r) r = mboxlist_detail(inboxname, &type, NULL, &server, &acl, NULL);
1394
    if (!r) r = mboxlist_detail(inboxname, &type, NULL, &server, &acl, NULL);
1395
    /* Try once again after autocreate_inbox */
1396
    if (r == IMAP_MAILBOX_NONEXISTENT && !(r = autocreate_inbox(inboxname, userid)))
1397
        r = mboxlist_detail(inboxname, &type, NULL, &server, &acl, NULL);
1398
1352
    if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) &&
1399
    if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) &&
1353
	(!acl ||
1400
	(!acl ||
1354
	 !((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) {
1401
	 !((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) {
(-)cyrus-imapd-2.2.12/lib/auth.h (+2 lines)
Lines 60-63 Link Here
60
extern struct auth_state *auth_newstate(const char *identifier);
60
extern struct auth_state *auth_newstate(const char *identifier);
61
extern void auth_freestate(struct auth_state *auth_state);
61
extern void auth_freestate(struct auth_state *auth_state);
62
62
63
extern char *auth_canonuser(struct auth_state *auth_state);
64
63
#endif /* INCLUDED_AUTH_H */
65
#endif /* INCLUDED_AUTH_H */
(-)cyrus-imapd-2.2.12/lib/auth_krb.c (+8 lines)
Lines 338-340 Link Here
338
    free((char *)auth_state);
338
    free((char *)auth_state);
339
}
339
}
340
340
341
char *
342
auth_canonuser(struct auth_state *auth_state)
343
{
344
    if (auth_state)
345
       return auth_state->userid;
346
    return NULL;
347
}
348
(-)cyrus-imapd-2.2.12/lib/auth_krb5.c (+7 lines)
Lines 193-196 Link Here
193
    free(auth_state);
193
    free(auth_state);
194
}
194
}
195
195
196
char *
197
auth_canonuser(struct auth_state *auth_state)
198
{
199
    if (auth_state)
200
       return auth_state->userid;
201
    return NULL;
202
}
196
203
(-)cyrus-imapd-2.2.12/lib/auth_pts.c (+8 lines)
Lines 349-351 Link Here
349
{
349
{
350
    free(auth_state);
350
    free(auth_state);
351
}
351
}
352
353
char *auth_canonuser(struct auth_state *auth_state)
354
{
355
    if (auth_state)
356
       return auth_state->userid.id;
357
    return NULL;
358
}
359
(-)cyrus-imapd-2.2.12/lib/auth_unix.c (+7 lines)
Lines 267-270 Link Here
267
    free((char *)auth_state);
267
    free((char *)auth_state);
268
}
268
}
269
269
270
char *auth_canonuser(struct auth_state *auth_state)
271
{
272
    if (auth_state)
273
         return auth_state->userid;
274
    
275
    return NULL;
276
}
270
277
(-)cyrus-imapd-2.2.12/lib/imapoptions (+45 lines)
Lines 169-174 Link Here
169
/* Number of seconds to wait before returning a timeout failure when
169
/* Number of seconds to wait before returning a timeout failure when
170
   performing a client connection (e.g. in a murder enviornment) */
170
   performing a client connection (e.g. in a murder enviornment) */
171
171
172
{ "createonpost", 0, SWITCH }
173
/* If yes, when lmtpd receives an incoming mail for an INBOX that does not exist,
174
   then the INBOX is automatically created by lmtpd. */
175
176
{ "autocreateinboxfolders", NULL, STRING }
177
/* If a user does not have an INBOX created then the INBOX as well as some INBOX subfolders are
178
   created under two conditions.
179
     1. The user logins via the IMAP or the POP3 protocol. (autocreatequota option must have a nonzero value)
180
     2. A message arrives for the user through the LMTPD protocol.(createonpost option must yes)
181
   autocreateinboxfolders is a list of INBOX's subfolders separated by a "|", that are automatically created by the server
182
   under the previous two situations. */
183
184
{ "autosubscribeinboxfolders", NULL, STRING }
185
/* A list of folder names, separated by "|" that the users get automatically subscribed to, when their INBOX
186
  is created.
187
  These folder names must have been included in the autocreateinboxfolders option of the imapd.conf. */
188
189
{ "autosubscribesharedfolders", NULL, STRING }
190
/* A list of shared folders (bulletin boards), separated by "|" that the users get
191
   automatically subscribed to, after their INBOX
192
   is created. The shared folder must have been created and the user must have the
193
   required permissions to get subscribed to the it. Otherwise the subscription fails. */
194
195
{ "autosubscribe_all_sharedfolders", 0, SWITCH }
196
/* If set to yes then the user is automatically subscribed to all shared folders, one has permission
197
   to subscribe to. */
198
199
{ "autocreate_sieve_script", NULL, STRING }
200
/* The full path of a file that contains a sieve script. This script automatically becomes a
201
   user's initial default sieve filter script. When this option is not defined, no default 
202
   sieve filter is created. The file must be readable by the cyrus daemon. */
203
204
{ "autocreate_sieve_compiledscript", NULL, STRING }
205
/* The full path of a file that contains a compiled in bytecode sieve script. This script 
206
   automatically becomes a user's initial default sieve filter script. 
207
   If this option is not specified, or the filename doesn't exist then the script defined 
208
   by autocreate_sieve_script is compiled on the fly and installed as the user's default
209
   sieve script */
210
211
{ "generate_compiled_sieve_script", 0, SWITCH }
212
/* If set to yes and no compiled sieve script file exists then the sieve script that is 
213
   compiled on the fly will be saved in the file name that autocreate_sieve_compiledscript 
214
   option points. In order a compiled script to be generated, autocreate_sieve_script and 
215
   autocreate_sieve_compiledscript must have valid values */
216
172
{ "configdirectory", NULL, STRING }
217
{ "configdirectory", NULL, STRING }
173
/* The pathname of the IMAP configuration directory.  This field is
218
/* The pathname of the IMAP configuration directory.  This field is
174
   required. */
219
   required. */
(-)cyrus-imapd-2.2.12/notifyd/Makefile.in (-1 / +2 lines)
Lines 69-78 Link Here
69
SERVICE=../master/service.o
69
SERVICE=../master/service.o
70
70
71
IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
71
IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
72
SIEVE_LIBS = @SIEVE_LIBS@
72
IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
73
IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
73
LIB_WRAP = @LIB_WRAP@
74
LIB_WRAP = @LIB_WRAP@
74
LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS)
75
LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS)
75
DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
76
DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
76
77
77
PURIFY=/usr/local/bin/purify
78
PURIFY=/usr/local/bin/purify
78
PUREOPT=-best-effort
79
PUREOPT=-best-effort
(-)cyrus-imapd-2.2.12/notifyd/notifyd.c (-1 / +1 lines)
Lines 97-103 Link Here
97
97
98
#define NOTIFY_MAXSIZE 8192
98
#define NOTIFY_MAXSIZE 8192
99
99
100
int do_notify()
100
static int do_notify()
101
{
101
{
102
    struct sockaddr_un sun_data;
102
    struct sockaddr_un sun_data;
103
    socklen_t sunlen = sizeof(sun_data);
103
    socklen_t sunlen = sizeof(sun_data);
(-)cyrus-imapd-2.2.12/ptclient/Makefile.in (-1 / +2 lines)
Lines 57-66 Link Here
57
AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@
57
AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@
58
AFS_LIBS = @AFS_LIBS@
58
AFS_LIBS = @AFS_LIBS@
59
IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
59
IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
60
SIEVE_LIBS = @SIEVE_LIBS@
60
LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@
61
LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@
61
LIB_SASL = @LIB_SASL@
62
LIB_SASL = @LIB_SASL@
62
LIB_WRAP = @LIB_WRAP@
63
LIB_WRAP = @LIB_WRAP@
63
DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
64
DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ 
64
UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o
65
UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o
65
66
66
LDAP_LIBS=@LDAP_LIBS@
67
LDAP_LIBS=@LDAP_LIBS@

Return to bug 112912