Mercurial > dovecot > original-hg > dovecot-1.2
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 } |