comparison src/plugins/acl/acl-backend-vfile-acllist.c @ 9205:4c8175452173 HEAD

acl+mbox: Create dovecot-acl-list to control dir.
author Timo Sirainen <tss@iki.fi>
date Tue, 07 Jul 2009 22:27:55 -0400
parents 2bbf175bb6d3
children bf4f542ec6df
comparison
equal deleted inserted replaced
9204:f3c6cabae3af 9205:4c8175452173
36 p_clear(backend->acllist_pool); 36 p_clear(backend->acllist_pool);
37 array_clear(&backend->acllist); 37 array_clear(&backend->acllist);
38 } 38 }
39 } 39 }
40 40
41 static const char *acl_list_get_path(struct acl_backend_vfile *backend)
42 {
43 struct mail_storage *storage;
44 const char *rootdir, *maildir;
45 bool is_file;
46
47 rootdir = mailbox_list_get_path(backend->backend.list, NULL,
48 MAILBOX_LIST_PATH_TYPE_DIR);
49
50 storage = mailbox_list_get_namespace(backend->backend.list)->storage;
51 (void)mail_storage_get_mailbox_path(storage, "", &is_file);
52 if (is_file) {
53 maildir = mailbox_list_get_path(backend->backend.list, NULL,
54 MAILBOX_LIST_PATH_TYPE_MAILBOX);
55 if (strcmp(maildir, rootdir) == 0) {
56 /* dovecot-acl-list would show up as a mailbox if we
57 created it to root dir. since we don't really have
58 any other good alternatives, place it to control
59 dir */
60 rootdir = mailbox_list_get_path(backend->backend.list,
61 NULL, MAILBOX_LIST_PATH_TYPE_CONTROL);
62 }
63 }
64 return t_strconcat(rootdir, "/"ACLLIST_FILENAME, NULL);
65 }
66
41 static int acl_backend_vfile_acllist_read(struct acl_backend_vfile *backend) 67 static int acl_backend_vfile_acllist_read(struct acl_backend_vfile *backend)
42 { 68 {
43 struct acl_backend_vfile_acllist acllist; 69 struct acl_backend_vfile_acllist acllist;
44 struct istream *input; 70 struct istream *input;
45 struct stat st; 71 struct stat st;
46 const char *rootdir, *path, *line, *p; 72 const char *path, *line, *p;
47 int fd, ret = 0; 73 int fd, ret = 0;
48 74
49 backend->acllist_last_check = ioloop_time; 75 backend->acllist_last_check = ioloop_time;
50 76
51 rootdir = mailbox_list_get_path(backend->backend.list, NULL, 77 path = acl_list_get_path(backend);
52 MAILBOX_LIST_PATH_TYPE_DIR); 78 if (path == NULL) {
53 if (rootdir == NULL) {
54 /* we're never going to build acllist for this namespace. */ 79 /* we're never going to build acllist for this namespace. */
55 i_array_init(&backend->acllist, 1); 80 i_array_init(&backend->acllist, 1);
56 return 0; 81 return 0;
57 } 82 }
58 path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir);
59 83
60 if (backend->acllist_mtime != 0) { 84 if (backend->acllist_mtime != 0) {
61 /* see if the file's mtime has changed */ 85 /* see if the file's mtime has changed */
62 if (stat(path, &st) < 0) { 86 if (stat(path, &st) < 0) {
63 if (errno == ENOENT) 87 if (errno == ENOENT)
163 acl_object_deinit(&aclobj); 187 acl_object_deinit(&aclobj);
164 return ret < 0 ? -1 : 0; 188 return ret < 0 ? -1 : 0;
165 } 189 }
166 190
167 static int 191 static int
192 acllist_rename(struct acl_backend_vfile *backend, const char *temp_path)
193 {
194 const char *acllist_path;
195
196 acllist_path = acl_list_get_path(backend);
197 if (rename(temp_path, acllist_path) == 0)
198 return 0;
199
200 if (errno == ENOENT) {
201 if (mailbox_list_create_parent_dir(backend->backend.list, NULL,
202 acllist_path) < 0)
203 return -1;
204 if (rename(temp_path, acllist_path) == 0)
205 return 0;
206 }
207
208 i_error("rename(%s, %s) failed: %m", temp_path, acllist_path);
209 return -1;
210 }
211
212 static int
168 acl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend) 213 acl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend)
169 { 214 {
170 struct mailbox_list *list = backend->backend.list; 215 struct mailbox_list *list = backend->backend.list;
171 struct mail_namespace *ns; 216 struct mail_namespace *ns;
172 struct mailbox_list_iterate_context *iter; 217 struct mailbox_list_iterate_context *iter;
173 const struct mailbox_info *info; 218 const struct mailbox_info *info;
174 const char *rootdir, *acllist_path, *origin; 219 const char *rootdir, *origin;
175 struct ostream *output; 220 struct ostream *output;
176 struct stat st; 221 struct stat st;
177 string_t *path; 222 string_t *path;
178 mode_t mode; 223 mode_t mode;
179 gid_t gid; 224 gid_t gid;
242 if (close(fd) < 0) { 287 if (close(fd) < 0) {
243 i_error("close(%s) failed: %m", str_c(path)); 288 i_error("close(%s) failed: %m", str_c(path));
244 ret = -1; 289 ret = -1;
245 } 290 }
246 291
247 if (ret == 0) { 292 if (ret == 0)
248 acllist_path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir); 293 ret = acllist_rename(backend, str_c(path));
249 if (rename(str_c(path), acllist_path) < 0) {
250 i_error("rename(%s, %s) failed: %m",
251 str_c(path), acllist_path);
252 ret = -1;
253 }
254 }
255 if (ret == 0) { 294 if (ret == 0) {
256 struct acl_user *auser = ACL_USER_CONTEXT(ns->user); 295 struct acl_user *auser = ACL_USER_CONTEXT(ns->user);
257 296
258 backend->acllist_mtime = st.st_mtime; 297 backend->acllist_mtime = st.st_mtime;
259 backend->acllist_last_check = ioloop_time; 298 backend->acllist_last_check = ioloop_time;
268 return ret; 307 return ret;
269 } 308 }
270 309
271 int acl_backend_vfile_acllist_rebuild(struct acl_backend_vfile *backend) 310 int acl_backend_vfile_acllist_rebuild(struct acl_backend_vfile *backend)
272 { 311 {
273 const char *rootdir, *acllist_path; 312 const char *acllist_path;
274 313
275 if (acl_backend_vfile_acllist_try_rebuild(backend) == 0) 314 if (acl_backend_vfile_acllist_try_rebuild(backend) == 0)
276 return 0; 315 return 0;
277 else { 316 else {
278 /* delete it to make sure it gets rebuilt later */ 317 /* delete it to make sure it gets rebuilt later */
279 rootdir = mailbox_list_get_path(backend->backend.list, NULL, 318 acllist_path = acl_list_get_path(backend);
280 MAILBOX_LIST_PATH_TYPE_DIR);
281 acllist_path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir);
282 if (unlink(acllist_path) < 0 && errno != ENOENT) 319 if (unlink(acllist_path) < 0 && errno != ENOENT)
283 i_error("unlink(%s) failed: %m", acllist_path); 320 i_error("unlink(%s) failed: %m", acllist_path);
284 return -1; 321 return -1;
285 } 322 }
286 } 323 }