1 /* mboxname.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_MBOXNAME_H
44 #define INCLUDED_MBOXNAME_H
45 
46 #include "auth.h"
47 #include "strarray.h"
48 #include "util.h"
49 
50 #define MAX_NAMESPACE_PREFIX 40
51 
52 /* placeholder character for '.' in mailboxnames */
53 #define DOTCHAR '^'
54 
55 /* list of our namespaces */
56 enum { NAMESPACE_INBOX = 0,
57        NAMESPACE_USER = 1,
58        NAMESPACE_SHARED = 2 };
59 
60 /* categorise mailboxes */
61 enum { MBNAME_INBOX = 1,
62        MBNAME_INBOXSUB = 2,
63        MBNAME_ALTINBOX = 3,
64        MBNAME_ALTPREFIX = 4,
65        MBNAME_OWNER = 5,
66        MBNAME_OTHERUSER = 6,
67        MBNAME_SHARED = 7,
68        MBNAME_OWNERDELETED = 8,
69        MBNAME_OTHERDELETED = 9 };
70 
71 /* structure holding server namespace info */
72 struct namespace {
73     char hier_sep;
74     int isalt;  /* are we using the alternate namespace? */
75     int isadmin; /* current user is an admin */
76     char prefix[3][MAX_NAMESPACE_PREFIX+1];
77     int accessible[3];
78 };
79 
80 #define NAMESPACE_INITIALIZER { '.', 0, 0, \
81                                 { "INBOX.", "user.", "" }, \
82                                 { 0, 0, 0, } }
83 
84 struct mboxlock {
85     char *name;
86     int lock_fd;
87     int locktype;       /* LOCK_NONE or LOCK_SHARED or LOCK_EXCLUSIVE */
88 };
89 
90 struct mbname_parts;
91 
92 typedef struct mbname_parts mbname_t;
93 
94 const char *mbname_userid(const mbname_t *mbname);
95 const char *mbname_intname(const mbname_t *mbname);
96 const char *mbname_extname(const mbname_t *mbname, const struct namespace *ns, const char *userid);
97 int mbname_category(const mbname_t *mbname, const struct namespace *ns, const char *userid);
98 const char *mbname_category_prefix(int category, const struct namespace *ns);
99 const char *mbname_domain(const mbname_t *mbname);
100 const char *mbname_localpart(const mbname_t *mbname);
101 const strarray_t *mbname_boxes(const mbname_t *mbname);
102 time_t mbname_isdeleted(const mbname_t *mbname);
103 const char *mbname_recipient(const mbname_t *mbname, const struct namespace *ns);
104 
105 mbname_t *mbname_from_userid(const char *userid);
106 mbname_t *mbname_from_localdom(const char *localpart, const char *domain);
107 mbname_t *mbname_from_intname(const char *intname);
108 mbname_t *mbname_from_extname(const char *extname, const struct namespace *ns, const char *userid);
109 mbname_t *mbname_from_extsub(const char *extsub, const struct namespace *ns, const char *userid);
110 mbname_t *mbname_from_recipient(const char *recip, const struct namespace *ns);
111 mbname_t *mbname_dup(const mbname_t *mbname);
112 
113 void mbname_downcaseuser(mbname_t *mbname);
114 void mbname_set_localpart(mbname_t *mbname, const char *localpart);
115 void mbname_set_domain(mbname_t *mbname, const char *domain);
116 void mbname_set_isdeleted(mbname_t *mbname, time_t del);
117 void mbname_set_boxes(mbname_t *mbname, const strarray_t *boxes);
118 void mbname_push_boxes(mbname_t *mbname, const char *item);
119 char *mbname_pop_boxes(mbname_t *mbname); /* free it yourself punk */
120 void mbname_truncate_boxes(mbname_t *mbname, size_t len);
121 void mbname_free(mbname_t **mbnamep);
122 
123 char *mboxname_from_externalUTF8(const char *extname,
124                                  const struct namespace *ns, const char *userid);
125 char *mboxname_from_external(const char *extname, const struct namespace *ns, const char *userid);
126 char *mboxname_to_external(const char *intname, const struct namespace *ns, const char *userid);
127 
128 
129 int open_mboxlocks_exist(void);
130 int mboxname_lock(const char *mboxname, struct mboxlock **mboxlockptr,
131                   int locktype);
132 void mboxname_release(struct mboxlock **mboxlockptr);
133 int mboxname_islocked(const char *mboxname);
134 struct mboxlock *mboxname_usernamespacelock(const char *mboxname);
135 
136 /* Create namespace based on config options. */
137 int mboxname_init_namespace(struct namespace *namespace, int isadmin);
138 
139 struct namespace *mboxname_get_adminnamespace();
140 
141 /* Return nonzero if 'userid' owns the (internal) mailbox 'name'. */
142 int mboxname_userownsmailbox(const char *userid, const char *name);
143 
144 /*
145  * If (internal) mailbox 'name' is a user's mailbox (optionally INBOX),
146  * returns 1, otherwise returns 0.
147  */
148 int mboxname_isusermailbox(const char *name, int isinbox);
149 
150 int mboxname_isusertrash(const char *name);
151 
152 /*
153  * If (internal) mailbox 'name' is in the DELETED namespace.
154  * If timestampp is not NULL, the delete timestamp encoded in
155  * the name is parsed and filled in.
156  * returns boolean
157  */
158 int mboxname_isdeletedmailbox(const char *name, time_t *timestampp);
159 
160 /*
161  * If (internal) mailbox 'name' is a CALENDAR mailbox
162  * returns boolean
163  */
164 int mboxname_iscalendarmailbox(const char *name, int mbtype);
165 
166 /*
167  * If (internal) mailbox 'name' is a ADDRESSBOOK mailbox
168  * returns boolean
169  */
170 int mboxname_isaddressbookmailbox(const char *name, int mbtype);
171 
172 /*
173  * If (internal) mailbox 'name' is a DAVDRIVE mailbox
174  * returns boolean
175  */
176 int mboxname_isdavdrivemailbox(const char *name, int mbtype);
177 
178 /*
179  * If (internal) mailbox 'name' is a DAVNOTIFICATIONS mailbox
180  * returns boolean
181  */
182 int mboxname_isdavnotificationsmailbox(const char *name, int mbtype);
183 
184 /* If (internal) mailbox is a user's top-level Notes mailbox,
185  * returns boolean
186  */
187 int mboxname_isnotesmailbox(const char *name, int mbtype);
188 
189 /*
190  * If (internal) mailbox 'name' is a user's #jmapsubmission mailbox
191  * returns boolean
192  */
193 int mboxname_issubmissionmailbox(const char *name, int mbtype);
194 
195 /*
196  * If (internal) mailbox 'name' is a user's #jmappushsubscription mailbox
197  * returns boolean
198  */
199 int mboxname_ispushsubscriptionmailbox(const char *name, int mbtype);
200 
201 /*
202  * If (internal) mailbox 'name' is a user's #jmap upload mailbox
203  * returns boolean
204  */
205 int mboxname_isjmapuploadmailbox(const char *name, int mbtype);
206 
207 #define mboxname_isnonimapmailbox(name, mbtype)            \
208     (mboxname_iscalendarmailbox(name, mbtype)              \
209      || mboxname_isaddressbookmailbox(name, mbtype)        \
210      || mboxname_isdavdrivemailbox(name, mbtype)           \
211      || mboxname_isdavnotificationsmailbox(name, mbtype)   \
212      || mboxname_isnotesmailbox(name, mbtype)              \
213      || mboxname_issubmissionmailbox(name, mbtype)         \
214      || mboxname_ispushsubscriptionmailbox(name, mbtype)  \
215      || mboxname_isjmapuploadmailbox(name, mbtype))
216 
217 /* check if one mboxname is a parent or same as the other */
218 int mboxname_is_prefix(const char *longstr, const char *shortstr);
219 /* check if one mboxname contains the parent of the other mboxname */
220 int mboxname_contains_parent(const char *mboxname, const char *prev);
221 /* Return the internal mailbox name that is ancestor to mboxname1
222  * and mboxname2. Return NULL for INBOX or different owners. */
223 char *mboxname_common_ancestor(const char *mboxname1, const char *mboxname2);
224 
225 void mboxname_hash(char *buf, size_t buf_len,
226                    const char *root,
227                    const char *name) ;
228 
229 /*
230  * Translate (internal) inboxname into corresponding userid,
231  * and vice-versa.
232  */
233 /* returns a malloc'd mailbox */
234 char *mboxname_to_userid(const char *mboxname);
235 char *mboxname_user_mbox(const char *userid, const char *subfolder);
236 char *mboxname_user_mbox_external(const char *userid, const char *extsubfolder);
237 char *mboxname_abook(const char *userid, const char *collection);
238 char *mboxname_cal(const char *userid, const char *collection);
239 
240 /*
241  * Check whether two mboxnames have the same userid.
242  */
243 int mbname_same_userid(const mbname_t *a, const mbname_t *b);
244 int mboxname_same_userid(const char *mboxname1, const char *mboxname2);
245 
246 
247 /*
248  * Access files (or directories by leaving last parameter
249  * zero) for a particular mailbox on partition.
250  */
251 char *mboxname_datapath(const char *partition,
252                         const char *mboxname,
253                         const char *uniqueid,
254                         unsigned long uid);
255 
256 char *mboxname_archivepath(const char *partition,
257                            const char *mboxname,
258                            const char *uniqueid,
259                            unsigned long uid);
260 
261 char *mboxname_metapath(const char *partition,
262                         const char *mboxname,
263                         const char *uniqueid,
264                         int metafile, int isnew);
265 
266 char *mboxname_lockpath(const char *mboxname);
267 char *mboxname_lockpath_suffix(const char *mboxname, const char *suffix);
268 
269 /*
270  * Return nonzero if (internal) mailbox 'name' consists of legal characters.
271  * If using the unixhierarchysep '/', DOTCHAR ('.' placeholder) is allowed.
272  */
273 int mboxname_policycheck(const char *name);
274 
275 void mboxname_todeleted(const char *name, char *result, int withtime);
276 
277 /*
278  * Given a writable buffer containing an internal mbox name,
279  * convert that buffer in-place to be the name of the mbox'
280  * parent (by truncating off the last component).
281  * Returns 0 if no more truncation is possible, 1 otherwise.
282  */
283 int mboxname_make_parent(char *namebuf);
284 
285 
286 char *mboxname_conf_getpath(const mbname_t *mbname,
287                             const char *suffix);
288 
289 /* ======================== COUNTERS ==================== */
290 
291 struct mboxname_counters {
292     uint32_t generation;
293     uint32_t version;
294     modseq_t highestmodseq;
295     modseq_t mailmodseq;
296     modseq_t caldavmodseq;
297     modseq_t carddavmodseq;
298     modseq_t notesmodseq;
299     modseq_t mailfoldersmodseq;
300     modseq_t caldavfoldersmodseq;
301     modseq_t carddavfoldersmodseq;
302     modseq_t notesfoldersmodseq;
303     modseq_t quotamodseq;
304     modseq_t raclmodseq;
305     modseq_t submissionmodseq;
306     modseq_t submissionfoldersmodseq;
307     modseq_t maildeletedmodseq;
308     modseq_t caldavdeletedmodseq;
309     modseq_t carddavdeletedmodseq;
310     modseq_t notesdeletedmodseq;
311     modseq_t submissiondeletedmodseq;
312     modseq_t mailfoldersdeletedmodseq;
313     modseq_t caldavfoldersdeletedmodseq;
314     modseq_t carddavfoldersdeletedmodseq;
315     modseq_t notesfoldersdeletedmodseq;
316     modseq_t submissionfoldersdeletedmodseq;
317     modseq_t davnotificationmodseq;
318     modseq_t davnotificationdeletedmodseq;
319     modseq_t davnotificationfoldersmodseq;
320     modseq_t davnotificationfoldersdeletedmodseq;
321     modseq_t jmapnotificationmodseq;
322     modseq_t jmapnotificationdeletedmodseq;
323     modseq_t jmapnotificationfoldersmodseq;
324     modseq_t jmapnotificationfoldersdeletedmodseq;
325     uint32_t uidvalidity;
326 };
327 
328 int mboxname_read_counters(const char *mboxname, struct mboxname_counters *vals);
329 #define MBOXMODSEQ_ISFOLDER (1<<0)
330 #define MBOXMODSEQ_ISDELETE (1<<1)
331 modseq_t mboxname_nextmodseq(const char *mboxname, modseq_t last, int mbtype, int flags);
332 modseq_t mboxname_setmodseq(const char *mboxname, modseq_t val, int mbtype, int flags);
333 uint32_t mboxname_readuidvalidity(const char *mboxname);
334 uint32_t mboxname_nextuidvalidity(const char *mboxname, uint32_t last);
335 uint32_t mboxname_setuidvalidity(const char *mboxname, uint32_t val);
336 modseq_t mboxname_readquotamodseq(const char *mboxname);
337 modseq_t mboxname_nextquotamodseq(const char *mboxname, modseq_t last);
338 modseq_t mboxname_setquotamodseq(const char *mboxname, modseq_t val);
339 modseq_t mboxname_readraclmodseq(const char *mboxname);
340 modseq_t mboxname_nextraclmodseq(const char *mboxname, modseq_t last);
341 modseq_t mboxname_setraclmodseq(const char *mboxname, modseq_t val);
342 
343 #endif
344