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