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