1 /* mboxlist.h -- Mailbox list manipulation routines
2  *
3  * Copyright (c) 1994-2008 Carnegie Mellon University.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. The name "Carnegie Mellon University" must not be used to
18  *    endorse or promote products derived from this software without
19  *    prior written permission. For permission or any legal
20  *    details, please contact
21  *      Carnegie Mellon University
22  *      Center for Technology Transfer and Enterprise Creation
23  *      4615 Forbes Avenue
24  *      Suite 302
25  *      Pittsburgh, PA  15213
26  *      (412) 268-7393, fax: (412) 268-7395
27  *      innovation@andrew.cmu.edu
28  *
29  * 4. Redistributions of any form whatsoever must retain the following
30  *    acknowledgment:
31  *    "This product includes software developed by Computing Services
32  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33  *
34  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41  */
42 
43 #ifndef INCLUDED_MBOXLIST_H
44 #define INCLUDED_MBOXLIST_H
45 
46 #include "config.h"
47 #include "cyrusdb.h"
48 #include "dlist.h"
49 #include "mailbox.h"
50 #include "auth.h"
51 #include "mboxevent.h"
52 #include "mboxname.h"
53 
54 /*
55  * Maximum length of partition name. [config.c has a limit of 70]
56  */
57 #define MAX_PARTITION_LEN 64
58 
59 /* Flags for types of mailboxes
60  *
61  * Historically, mbtype was a bitmask, which is why this set of defines looks
62  * like a bitmask.  But, that was a mistake, which we have almost-entirely
63  * moved away from.
64  *
65  * Nowadays, an mbtype should properly only ever be a single one of these
66  * values, not a bitmask.
67  *
68  * The MBTYPES_DAV and MBTYPES_NONIMAP masks remain because they remain
69  * useful for checking the flavour of an mbtype, but do not take them as
70  * indicative of good style!  Generally, if you need to set an mbtype, set
71  * it to one value, and if you need to compare an mbtype, compare it against
72  * one value.
73  */
74 #define MBTYPE_EMAIL            0  /* default mbtype is zero */
75 #define MBTYPE_REMOTE       (1<<0) /* Not on this server (part is remote host) */
76 #define MBTYPE_RESERVE      (1<<1) /* Reserved [mupdate/imapd] /
77                                       Rename Target [imapd] (part is normal, but
78                                       you are not allowed to create this mailbox,
79                                       even though it doesn't actually exist) */
80 #define MBTYPE_NETNEWS      (1<<2) /* Netnews Mailbox - NO LONGER USED */
81 #define MBTYPE_MOVING       (1<<3) /* Mailbox in mid-transfer
82                                       (part is remotehost!localpart) */
83 #define MBTYPE_DELETED      (1<<4) /* Mailbox has been deleted,
84                                       but not yet cleaned up */
85 #define MBTYPE_CALENDAR     (1<<5) /* CalDAV Calendar Mailbox */
86 #define MBTYPE_ADDRESSBOOK  (1<<6) /* CardDAV Addressbook Mailbox */
87 #define MBTYPE_COLLECTION   (1<<7) /* WebDAV Collection Mailbox */
88 #define MBTYPE_INTERMEDIATE (1<<8) /* Place holder
89                                       for non-existent ancestor mailboxes */
90 #define MBTYPE_SUBMISSION   (1<<9) /* JMAP Mail Submission Mailbox */
91 #define MBTYPE_PUSHSUBSCRIPTION   (1<<10) /* JMAP Push Subscriptions */
92 
93 #define MBTYPES_DAV     (MBTYPE_CALENDAR|MBTYPE_ADDRESSBOOK|MBTYPE_COLLECTION)
94 #define MBTYPES_NONIMAP (MBTYPE_NETNEWS|MBTYPES_DAV|MBTYPE_SUBMISSION|MBTYPE_PUSHSUBSCRIPTION)
95 
96 /* master name of the mailboxes file */
97 #define FNAME_MBOXLIST "/mailboxes.db"
98 
99 #define HOSTNAME_SIZE 512
100 
101 /* each mailbox has the following data */
102 struct mboxlist_entry {
103     char *name;
104     char *ext_name;
105     time_t mtime;
106     uint32_t uidvalidity;
107     modseq_t createdmodseq;
108     modseq_t foldermodseq;
109     int mbtype;
110     char *partition;
111     char *server; /* holds remote machine for REMOTE mailboxes */
112     char *acl;
113     /* extra fields */
114     char *uniqueid;
115     /* legacy upgrade support */
116     char *legacy_specialuse;
117 };
118 
119 typedef struct mboxlist_entry mbentry_t;
120 
121 mbentry_t *mboxlist_entry_create();
122 
123 char *mbentry_metapath(const struct mboxlist_entry *mbentry, int metatype, int isnew);
124 char *mbentry_datapath(const struct mboxlist_entry *mbentry, uint32_t);
125 
126 int mboxlist_parse_entry(mbentry_t **mbentryptr,
127                          const char *name, size_t namelen,
128                          const char *data, size_t datalen);
129 
130 mbentry_t *mboxlist_entry_copy(const mbentry_t *src);
131 
132 void mboxlist_entry_free(mbentry_t **mbentryptr);
133 
134 const char *mboxlist_mbtype_to_string(uint32_t mbtype);
135 uint32_t mboxlist_string_to_mbtype(const char *string);
136 
137 int mboxlist_delete(const char *name);
138 /* Lookup 'name' in the mailbox list. */
139 int mboxlist_lookup(const char *name, mbentry_t **mbentryptr,
140                     struct txn **tid);
141 int mboxlist_lookup_allow_all(const char *name,
142                                    mbentry_t **mbentryptr,
143                                    struct txn **tid);
144 
145 char *mboxlist_find_specialuse(const char *use, const char *userid);
146 char *mboxlist_find_uniqueid(const char *uniqueid, const char *userid,
147                              const struct auth_state *auth_state);
148 
149 
150 /* insert/delete stub entries */
151 int mboxlist_insertremote(mbentry_t *mbentry, struct txn **rettid);
152 int mboxlist_deleteremote(const char *name, struct txn **in_tid);
153 
154 /* Update a mailbox's entry */
155 int mboxlist_update(mbentry_t *mbentry, int localonly);
156 
157 /* check user's ability to create mailbox */
158 int mboxlist_createmailboxcheck(const char *name, int mbtype,
159                                 const char *partition,
160                                 int isadmin, const char *userid,
161                                 const struct auth_state *auth_state,
162                                 char **newacl, char **newpartition,
163                                 int forceuser);
164 
165 /* create mailbox */
166 /* localonly creates the local mailbox without touching mupdate */
167 /* forceuser allows the creation of user.x.<name> without a user.x */
168 /* dbonly skips filesystem operations (e.g. reconstruct) */
169 /* notify sends a MailboxCreate event notification */
170 /* if given a mailbox pointer, return the still-locked mailbox
171  * for further manipulation */
172 int mboxlist_createmailbox(const char *name, int mbtype,
173                            const char *partition,
174                            int isadmin, const char *userid,
175                            const struct auth_state *auth_state,
176                            int localonly, int forceuser, int dbonly,
177                            int notify, struct mailbox **mailboxptr);
178 
179 /* create mailbox with wrapping namespacelock */
180 int mboxlist_createmailboxlock(const char *name, int mbtype,
181                            const char *partition,
182                            int isadmin, const char *userid,
183                            const struct auth_state *auth_state,
184                            int localonly, int forceuser, int dbonly,
185                            int notify, struct mailbox **mailboxptr);
186 
187 
188 /* create mailbox with uniqueid */
189 int mboxlist_createmailbox_unq(const char *name, int mbtype,
190                            const char *partition,
191                            int isadmin, const char *userid,
192                            const struct auth_state *auth_state,
193                            int localonly, int forceuser, int dbonly,
194                            int notify, const char *uniqueid,
195                            struct mailbox **mailboxptr);
196 
197 /* create mailbox with options and uniqueid */
198 int mboxlist_createmailbox_opts(const char *name, int mbtype,
199                                 const char *partition,
200                                 int isadmin, const char *userid,
201                                 const struct auth_state *auth_state,
202                                 int options, int localonly,
203                                 int forceuser, int dbonly,
204                                 int notify, const char *uniqueid,
205                                 struct mailbox **mailboxptr);
206 
207 /* create mailbox from sync */
208 int mboxlist_createsync(const char *name, int mbtype, const char *partition,
209                         const char *userid, const struct auth_state *auth_state,
210                         int options, unsigned uidvalidity,
211                         modseq_t createdmodseq,
212                         modseq_t highestmodseq,
213                         modseq_t foldermodseq, const char *acl,
214                         const char *uniqueid, int local_only,
215                         int keep_intermediaries,
216                         struct mailbox **mboxptr);
217 
218 /* delated delete */
219 /* Translate delete into rename */
220 /* prepare MailboxDelete notification if mboxevent is not NULL */
221 int
222 mboxlist_delayed_deletemailbox(const char *name, int isadmin, const char *userid,
223                                const struct auth_state *auth_state,
224                                struct mboxevent *mboxevent,
225                                int checkacl,
226                                int localonly, int force, int keep_intermediaries);
227 /* Delete a mailbox. */
228 /* setting local_only disables any communication with the mupdate server
229  * and deletes the mailbox from the filesystem regardless of if it is
230  * MBTYPE_REMOTE or not */
231 /* force ignores errors and just tries to wipe the mailbox off the face of
232  * the planet */
233 /* prepare MailboxDelete notification if mboxevent is not NULL */
234 int mboxlist_deletemailbox(const char *name, int isadmin, const char *userid,
235                            const struct auth_state *auth_state,
236                            struct mboxevent *mboxevent,
237                            int checkacl,
238                            int local_only, int force, int keep_intermediaries);
239 /* same but with silent */
240 int mboxlist_deletemailbox_full(const char *name, int isadmin, const char *userid,
241                            const struct auth_state *auth_state,
242                            struct mboxevent *mboxevent,
243                            int checkacl,
244                            int local_only, int force,
245                            int keep_intermediaries, int silent);
246 /* same but wrap with a namespacelock */
247 int mboxlist_deletemailboxlock(const char *name, int isadmin, const char *userid,
248                            const struct auth_state *auth_state,
249                            struct mboxevent *mboxevent,
250                            int checkacl,
251                            int local_only, int force, int keep_intermediaries);
252 
253 /* rename a tree of mailboxes - renames mailbox plus any children */
254 int mboxlist_renametree(const char *oldname, const char *newname,
255                         const char *partition, unsigned uidvalidity,
256                         int isadmin, const char *userid,
257                         const struct auth_state *auth_state,
258                         struct mboxevent *mboxevent,
259                         int local_only, int forceuser, int ignorequota,
260                         int keep_intermediaries, int move_subscription);
261 /* Rename/move a mailbox (hierarchical) */
262 /* prepare MailboxRename notification if mboxevent is not NULL */
263 int mboxlist_renamemailbox(const mbentry_t *mbentry, const char *newname,
264                            const char *partition, unsigned uidvalidity,
265                            int isadmin, const char *userid,
266                            const struct auth_state *auth_state,
267                            struct mboxevent *mboxevent,
268                            int local_only, int forceuser, int ignorequota,
269                            int keep_intermediaries, int move_subscription,
270                            int silent);
271 
272 /* change ACL */
273 int mboxlist_setacl(const struct namespace *namespace, const char *name,
274                     const char *identifier, const char *rights, int isadmin,
275                     const char *userid, const struct auth_state *auth_state);
276 
277 /* Change all ACLs on mailbox */
278 int mboxlist_updateacl_raw(const char *name, const char *acl);
279 int mboxlist_sync_setacls(const char *name, const char *acl, modseq_t foldermodseq);
280 int mboxlist_update_foldermodseq(const char *name, modseq_t foldermodseq);
281 
282 int mboxlist_set_racls(int enabled);
283 
284 int mboxlist_cleanup_deletedentries(const mbentry_t *mbentry, time_t mark);
285 
286 struct findall_data {
287     const char *extname;
288     int mb_category;
289     const mbentry_t *mbentry;
290     const mbname_t *mbname;
291     int is_exactmatch;
292 };
293 
294 typedef int findall_p(struct findall_data *data, void *rock);
295 typedef int findall_cb(struct findall_data *data, void *rock);
296 
297 /* Find all mailboxes that match 'pattern'. */
298 int mboxlist_findall(struct namespace *namespace,
299                      const char *pattern, int isadmin,
300                      const char *userid, const struct auth_state *auth_state,
301                      findall_cb *proc, void *rock);
302 int mboxlist_findallmulti(struct namespace *namespace,
303                           const strarray_t *patterns, int isadmin,
304                           const char *userid, const struct auth_state *auth_state,
305                           findall_cb *proc, void *rock);
306 int mboxlist_findone(struct namespace *namespace,
307                      const char *intname, int isadmin,
308                      const char *userid, const struct auth_state *auth_state,
309                      findall_cb *proc, void *rock);
310 
311 int mboxlist_findall_withp(struct namespace *namespace,
312                      const char *pattern, int isadmin,
313                      const char *userid, const struct auth_state *auth_state,
314                      findall_p *p, findall_cb *cb, void *rock);
315 int mboxlist_findallmulti_withp(struct namespace *namespace,
316                           const strarray_t *patterns, int isadmin,
317                           const char *userid, const struct auth_state *auth_state,
318                           findall_p *p, findall_cb *cb, void *rock);
319 int mboxlist_findone_withp(struct namespace *namespace,
320                      const char *intname, int isadmin,
321                      const char *userid, const struct auth_state *auth_state,
322                      findall_p *p, findall_cb *cb, void *rock);
323 
324 /* Find a mailbox's parent (if any) */
325 int mboxlist_findparent(const char *mboxname,
326                         mbentry_t **mbentryp);
327 
328 int mboxlist_findparent_allow_all(const char *mboxname,
329                                   mbentry_t **mbentryp);
330 
331 /* direct access to subs DB */
332 typedef int user_cb(const char *userid, void *rock);
333 int mboxlist_alluser(user_cb *proc, void *rock);
334 
335 typedef int mboxlist_cb(const mbentry_t *mbentry, void *rock);
336 
337 #define MBOXTREE_TOMBSTONES (1<<0)
338 #define MBOXTREE_DELETED (1<<1)
339 #define MBOXTREE_SKIP_ROOT (1<<2)
340 #define MBOXTREE_SKIP_CHILDREN (1<<3)
341 #define MBOXTREE_SKIP_PERSONAL (1<<4)
342 #define MBOXTREE_PLUS_RACL (1<<5)
343 #define MBOXTREE_INTERMEDIATES (1<<6)
344 int mboxlist_allmbox(const char *prefix, mboxlist_cb *proc, void *rock, int flags);
345 int mboxlist_mboxtree(const char *mboxname, mboxlist_cb *proc, void *rock, int flags);
346 int mboxlist_usermboxtree(const char *userid, const struct auth_state *auth_state,
347                           mboxlist_cb *proc, void *rock, int flags);
348 int mboxlist_usersubs(const char *userid, mboxlist_cb *proc, void *rock, int flags);
349 
350 strarray_t *mboxlist_sublist(const char *userid);
351 
352 /* Find subscribed mailboxes that match 'pattern'. */
353 int mboxlist_findsub(struct namespace *namespace,
354                      const char *pattern, int isadmin,
355                      const char *userid, const struct auth_state *auth_state,
356                      findall_cb *proc, void *rock,
357                      int force);
358 int mboxlist_findsubmulti(struct namespace *namespace,
359                           const strarray_t *patterns, int isadmin,
360                           const char *userid, const struct auth_state *auth_state,
361                           findall_cb *proc, void *rock,
362                           int force);
363 
364 int mboxlist_findsub_withp(struct namespace *namespace,
365                      const char *pattern, int isadmin,
366                      const char *userid, const struct auth_state *auth_state,
367                      findall_p *p, findall_cb *cb, void *rock,
368                      int force);
369 int mboxlist_findsubmulti_withp(struct namespace *namespace,
370                           const strarray_t *patterns, int isadmin,
371                           const char *userid, const struct auth_state *auth_state,
372                           findall_p *p, findall_cb *cb, void *rock,
373                           int force);
374 
375 /* given a mailbox 'name', where should we stage messages for it?
376    'stagedir' should be MAX_MAILBOX_PATH. */
377 int mboxlist_findstage(const char *name, char *stagedir, size_t sd_len);
378 
379 /* Check 'user's subscription status for mailbox 'name' */
380 int mboxlist_checksub(const char *name, const char *userid);
381 
382 /* Change 'user's subscription status for mailbox 'name'. */
383 int mboxlist_changesub(const char *name, const char *userid,
384                        const struct auth_state *auth_state,
385                        int add, int force, int notify);
386 
387 /* set or create quota root */
388 int mboxlist_setquotas(const char *root,
389                        quota_t newquotas[QUOTA_NUMRESOURCES],
390                        modseq_t modseq, int force);
391 int mboxlist_unsetquota(const char *root);
392 
393 /* handle interemediates */
394 int mboxlist_update_intermediaries(const char *mboxname, int mbtype, modseq_t modseq);
395 int mboxlist_haschildren(const char *mboxname);
396 
397 /* open the mailboxes db */
398 void mboxlist_open(const char *name);
399 
400 /* close the database */
401 void mboxlist_close(void);
402 
403 /* initialize database structures */
404 #define MBOXLIST_SYNC 0x02
405 void mboxlist_init(int flags);
406 
407 /* done with database stuff */
408 void mboxlist_done(void);
409 
410 /* for transactions */
411 int mboxlist_commit(struct txn *tid);
412 int mboxlist_abort(struct txn *tid);
413 
414 int mboxlist_delayed_delete_isenabled(void);
415 
416 /* Promote an intermediary mailbox to a real mailbox. */
417 int mboxlist_promote_intermediary(const char *mboxname);
418 
419 #endif
420