1 #ifndef maildiraclt_h 2 #define maildiraclt_h 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 9 /* 10 ** Copyright 2003-2004 Double Precision, Inc. 11 ** See COPYING for distribution information. 12 */ 13 14 #if HAVE_CONFIG_H 15 #include "config.h" 16 #endif 17 18 19 /* 20 ** A basic ACL entity. Be generic, it's just a character string. 21 ** However, we do keep it in collating order. 22 ** 23 ** These functions return 0 on success, <0 on error. 24 */ 25 26 typedef char *maildir_aclt; 27 28 29 /* 30 ** Initialize an aclt. The second or third args specify its initial value. 31 ** Both may be NULL. Only one can be non-NULL. 32 */ 33 34 int maildir_aclt_init(maildir_aclt *aclt, 35 const char *initvalue_cstr, 36 const maildir_aclt *initvalue_cpy); 37 38 /* Destroy an aclt after it is no longer used. */ 39 40 void maildir_aclt_destroy(maildir_aclt *aclt); 41 42 43 /* Add or remove access chars. */ 44 45 int maildir_aclt_add(maildir_aclt *aclt, 46 const char *add_strs, 47 const maildir_aclt *add_aclt); 48 49 int maildir_aclt_del(maildir_aclt *aclt, 50 const char *del_strs, 51 const maildir_aclt *del_aclt); 52 53 /* return a const char * that contains the acl */ 54 55 #define maildir_aclt_ascstr(t) (*(t) ? (const char *)*(t):"") 56 57 58 /* Next level up, a list of <identifier,acl>s */ 59 60 struct maildir_aclt_node { 61 struct maildir_aclt_node *prev; 62 struct maildir_aclt_node *next; 63 char *identifier; 64 maildir_aclt acl; 65 }; 66 67 typedef struct { 68 struct maildir_aclt_node *head; 69 struct maildir_aclt_node *tail; 70 } maildir_aclt_list; 71 72 73 /* Initialize and destroy the list */ 74 75 void maildir_aclt_list_init(maildir_aclt_list *aclt_list); 76 void maildir_aclt_list_destroy(maildir_aclt_list *aclt_list); 77 78 /* Add an <identifier,acl> pair. Returns 0 on success, -1 on failure */ 79 80 int maildir_aclt_list_add(maildir_aclt_list *aclt_list, 81 const char *identifier, 82 const char *aclt_str, 83 maildir_aclt *aclt_cpy); 84 85 /* Remove an identifier */ 86 87 int maildir_aclt_list_del(maildir_aclt_list *aclt_list, 88 const char *identifier); 89 90 /* 91 ** Enumerate the ACL list. The callback function, cb_func, gets 92 ** invoked for each ACL list entry. The callback function receives: 93 ** identifier+rights pair; as well as the transparent pass-through 94 ** argument. A nonzero return from the callback function terminates 95 ** the enumeration, and maildir_aclt_list_enum itself returns 96 ** non-zero. A zero return continues the enumeration. After the 97 ** entire list is enumerated maildir_aclt_list_enum returns 0. 98 */ 99 100 int maildir_aclt_list_enum(maildir_aclt_list *aclt_list, 101 int (*cb_func)(const char *identifier, 102 const maildir_aclt *acl, 103 void *cb_arg), 104 void *cb_arg); 105 106 /* Find an identifier */ 107 108 const maildir_aclt *maildir_aclt_list_find(maildir_aclt_list *aclt_list, 109 const char *identifier); 110 111 /* maildir-level acl ops */ 112 113 #define ACL_LOOKUP "l" 114 #define ACL_READ "r" 115 #define ACL_SEEN "s" 116 #define ACL_WRITE "w" 117 #define ACL_INSERT "i" 118 #define ACL_POST "p" 119 #define ACL_CREATE "c" 120 #define ACL_DELETEFOLDER "x" 121 #define ACL_DELETEMSGS "t" 122 #define ACL_EXPUNGE "e" 123 #define ACL_ADMINISTER "a" 124 125 #define ACL_ALL \ 126 ACL_ADMINISTER \ 127 ACL_CREATE \ 128 ACL_EXPUNGE \ 129 ACL_INSERT \ 130 ACL_LOOKUP \ 131 ACL_READ \ 132 ACL_SEEN \ 133 ACL_DELETEMSGS \ 134 ACL_WRITE \ 135 ACL_DELETEFOLDER 136 137 #define ACL_DELETE_SPECIAL "d" 138 139 #define ACLFILE "courierimapacl" 140 #define ACLHIERDIR "courierimaphieracl" 141 142 143 #define MAILDIR_ACL_ANYONE(s) \ 144 (strcmp( (s), "anonymous") == 0 || \ 145 strcmp( (s), "anyone") == 0) 146 147 148 /* 149 ** Set maildir_acl_disabled to 1 to effectively disable ACL support, and its 150 ** overhead. 151 ** 152 ** If maildir_acl_disabled is set, maildir_acl_read never goes to disk to 153 ** read the ACL file, instead it returns a fixed ACL list which only contains 154 ** an entry for "owner", and gives "owner" all ACL rights, except the 155 ** ADMINISTER right, relying on higher level code to refuse to set new 156 ** ACLs unless the existing ACL gives administer right. 157 ** 158 ** Additionally, maildir_acl_disabled turns off the hook in maildir_acl_compute 159 ** that grants ADMINISTER to "owner" irrespective of what the ACLs actually 160 ** say. 161 */ 162 163 extern int maildir_acl_disabled; 164 165 /* 166 ** Read ACLs for maildir maildir.path. 167 ** 168 ** maildir: Path to the main maildir. 169 ** 170 ** path: ".folder.subfolder". 171 ** 172 ** aclt_list is an uninitialized maildir_aclt_list 173 ** 174 ** Returns 0 for success, <0 for failure. 175 */ 176 177 int maildir_acl_read(maildir_aclt_list *aclt_list, 178 const char *maildir, 179 const char *path); 180 181 /* 182 ** Write ACLs for maildir maildir.path. 183 ** 184 ** Returns 0 for success, <0 for failure. 185 ** 186 ** Additional parameters: 187 ** 188 ** owner: the owner entity of the folder represented by 'path'. 189 ** 190 ** err_failedrights: if not NULL, *err_failedrights will be initialized to 191 ** a non-null identifier string if maildir_acl_set fails because aclt_list 192 ** illegally revokes minimum rights from the identifier (admin/lookup). 193 ** 194 */ 195 196 int maildir_acl_write(maildir_aclt_list *aclt_list, 197 const char *maildir, 198 const char *path, 199 const char *owner, 200 const char **err_failedrights); 201 202 /* Remove stale ACL entries */ 203 204 int maildir_acl_reset(const char *maildir); 205 206 /* Remove a particular ACL entry */ 207 208 int maildir_acl_delete(const char *maildir, 209 const char *path); /* .folder.subfolder */ 210 211 /* 212 ** Compute my access rights. Initializes 'aclt'. 'aclt_list' is the ACL. 213 ** 214 ** The callback function should return >0 if identifier refers to the entity 215 ** whose access rights are to be computed; 0 if it does not, <0 if an error 216 ** occured. 217 ** 218 ** As a special case, maildir_acl_compute() handles "anonymous" and "anyone" 219 ** identifiers on its own. 220 ** 221 ** As a special case, if the callback function returns >0 for the identifier 222 ** "owner", the computed access rights will always include the ADMIN right. 223 ** 224 ** maildir_aclt_compute() uses ACL2=UNION; the computed access rights 225 ** consist of the union of all rights granted to all identifiers that include 226 ** the entity, minus the union of all reights revoked from all identifiers 227 ** that include the entity. 228 */ 229 int maildir_acl_compute(maildir_aclt *aclt, maildir_aclt_list *aclt_list, 230 int (*cb_func)(const char *identifier, 231 void *void_arg), void *void_arg); 232 233 /* 234 ** A wrapper for maildir_acl_compute that compares against a 235 ** const char * array. 236 */ 237 238 int maildir_acl_compute_array(maildir_aclt *aclt, 239 maildir_aclt_list *aclt_list, 240 const char * const *identifiers); 241 242 /* 243 ** A wrapper for maildir_acl_compute. 244 ** 245 ** Compute 'rights' - my rights on the mailbox. 246 ** 247 ** acl_list: the mailbox's ACL. 248 ** 249 ** me: my login identifier. 250 ** 251 ** folder_owner: the owner of the mailbox folder whose rights are computed 252 ** 253 ** OTHER: The "OPTIONS" environment variable is parsed to obtain a list of 254 ** account groups 'me' belongs to. 255 ** 256 ** Returns 0 upon success, after placing the computed access rights in 257 ** 'rights'. 258 */ 259 260 int maildir_acl_computerights(maildir_aclt *rights, 261 maildir_aclt_list *acl_list, 262 const char *me, 263 const char *folder_owner); 264 265 /* 266 ** Convenience functions: 267 ** 268 ** maildir_acl_canlistrights: return true if the given rights indicate that 269 ** the rights themselves can be viewed (one of the following must be present: 270 ** ACL_LOOKUP, ACL_READ, ACL_INSERT[0], ACL_CREATE[0], ACL_DELETEFOLDER, 271 ** ACL_EXPUNGE[0], or ACL_ADMINISTER). 272 */ 273 274 int maildir_acl_canlistrights(const char *myrights); 275 276 #ifdef __cplusplus 277 } 278 #endif 279 280 #endif 281