bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenacllist_clear(struct acl_backend_vfile *backend, uoff_t file_size)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen i_array_init(&backend->acllist, I_MAX(16, file_size / 60));
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainenstatic bool acl_list_get_root_dir(struct acl_backend_vfile *backend,
8d9540a4536e294e69beb3d1f5b378eb06ba8bdaTimo Sirainen storage = mailbox_list_get_namespace(backend->backend.list)->storage;
8d9540a4536e294e69beb3d1f5b378eb06ba8bdaTimo Sirainen type = (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0 ?
8d9540a4536e294e69beb3d1f5b378eb06ba8bdaTimo Sirainen MAILBOX_LIST_PATH_TYPE_CONTROL : MAILBOX_LIST_PATH_TYPE_DIR;
8d9540a4536e294e69beb3d1f5b378eb06ba8bdaTimo Sirainen if (!mailbox_list_get_root_path(backend->backend.list, type, &rootdir))
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen maildir = mailbox_list_get_root_forced(backend->backend.list,
d6407ae9e545d41fe6152bba47602f3299c26236Timo Sirainen /* dovecot-acl-list would show up as a mailbox if we
d6407ae9e545d41fe6152bba47602f3299c26236Timo Sirainen created it to root dir. since we don't really have
d6407ae9e545d41fe6152bba47602f3299c26236Timo Sirainen any other good alternatives, place it to control
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen rootdir = mailbox_list_get_root_forced(backend->backend.list,
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainenstatic bool acl_list_get_path(struct acl_backend_vfile *backend,
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen const char **path_r)
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen if (!acl_list_get_root_dir(backend, &root_dir, &type))
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen *path_r = t_strconcat(root_dir, "/"ACLLIST_FILENAME, NULL);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenstatic int acl_backend_vfile_acllist_read(struct acl_backend_vfile *backend)
9aef7a5fcee899c061d35ed8f2fca6b0b5bee3d5Timo Sirainen /* we're never going to build acllist for this namespace. */
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen /* see if the file's mtime has changed */
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi input = i_stream_create_fd(fd, (size_t)-1);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acllist.mtime = acllist.mtime * 10 + (*p - '0');
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acllist.name = p_strdup(backend->acllist_pool, p + 1);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenvoid acl_backend_vfile_acllist_refresh(struct acl_backend_vfile *backend)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen if (acl_backend_vfile_acllist_read(backend) < 0) {
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen (void)acl_backend_vfile_acllist_rebuild(backend);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenacllist_append(struct acl_backend_vfile *backend, struct ostream *output,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen name = mailbox_list_get_storage_name(backend->backend.list, vname);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acl_cache_flush(backend->backend.cache, name);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen aclobj = acl_object_init_from_name(&backend->backend, name);
3cd0463d17cf9ecbc3d826d60b36800d09f0633cTimo Sirainen if (acl_rights_has_nonowner_lookup_changes(&rights))
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen if (acl_backend_vfile_object_get_mtime(aclobj, &acllist.mtime) < 0)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acllist.name = p_strdup(backend->acllist_pool, name);
b6dab893cde3810ef3c3179531d487c41dbf027fTimo Sirainenacl_backend_vfile_acllist_try_rebuild(struct acl_backend_vfile *backend)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen struct mailbox_list *list = backend->backend.list;
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen if (!acl_list_get_root_dir(backend, &rootdir, &type))
60b42c6dfdf9edcca8a96b380ef9a0adc60c2464Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_UNUSABLE) != 0) {
60b42c6dfdf9edcca8a96b380ef9a0adc60c2464Timo Sirainen /* we can't write anything here */
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen str_printfa(path, "%s/%s", rootdir, mailbox_list_get_temp_prefix(list));
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen /* Build it into a temporary file and rename() over. There's no need
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen to use locking, because even if multiple processes are rebuilding
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen the file at the same time the result should be the same. */
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen mailbox_list_get_root_permissions(list, &perm);
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen fd = safe_mkstemp_group(path, perm.file_create_mode,
94f84d1c3f786d1b92dd2a1507f83a2dad887c56Timo Sirainen if (mailbox_list_mkdir_root(backend->backend.list,
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen fd = safe_mkstemp_group(path, perm.file_create_mode,
b16c5adb08f16484dd3b6bccc6f42a49ead51af5Timo Sirainen /* Ignore silently if we can't create it */
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen output = o_stream_create_fd_file(fd, 0, FALSE);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen if (acllist_append(backend, output, info->vname) < 0) {
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen if (!acl_list_get_path(backend, &acllist_path))
81e6e1ef0feef60644a4c4b745d82a4c98223affTimo Sirainen struct acl_user *auser = ACL_USER_CONTEXT(ns->user);
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi /* FIXME: dict rebuild is expensive, try to avoid it */
81e6e1ef0feef60644a4c4b745d82a4c98223affTimo Sirainen (void)acl_lookup_dict_rebuild(auser->acl_lookup_dict);
b6dab893cde3810ef3c3179531d487c41dbf027fTimo Sirainenint acl_backend_vfile_acllist_rebuild(struct acl_backend_vfile *backend)
b6dab893cde3810ef3c3179531d487c41dbf027fTimo Sirainen if (acl_backend_vfile_acllist_try_rebuild(backend) == 0)
b6dab893cde3810ef3c3179531d487c41dbf027fTimo Sirainen /* delete it to make sure it gets rebuilt later */
3bbd5fd417b3b91c509a9174f1c21d5d3665b0adTimo Sirainen if (!acl_list_get_path(backend, &acllist_path))
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenstatic const struct acl_backend_vfile_acllist *
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenacl_backend_vfile_acllist_find(struct acl_backend_vfile *backend,
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen const struct acl_backend_vfile_acllist *acllist;
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenvoid acl_backend_vfile_acllist_verify(struct acl_backend_vfile *backend,
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen const struct acl_backend_vfile_acllist *acllist;
ae3979ff72bac46826291cff3ff85c0dd41120c6Timo Sirainen if (backend->rebuilding_acllist || backend->iterating_acllist)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acllist = acl_backend_vfile_acllist_find(backend, name);
ae3979ff72bac46826291cff3ff85c0dd41120c6Timo Sirainen if (acllist != NULL && acllist->mtime != mtime)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen (void)acl_backend_vfile_acllist_rebuild(backend);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenacl_backend_vfile_nonowner_iter_init(struct acl_backend *_backend)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen ctx = i_new(struct acl_mailbox_list_context_vfile, 1);
37c72fa0cd3f1d74d79b64afb3fb6da5ffd4fe3aAki Tuomibool acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *_ctx,
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen const char **name_r)
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen (struct acl_mailbox_list_context_vfile *)_ctx;
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen const struct acl_backend_vfile_acllist *acllist;
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainen acllist = array_get(&backend->acllist, &count);
2f122b4db3f0d4eeb59ff9d306e54b2009d72cf9Timo Sirainenacl_backend_vfile_nonowner_iter_deinit(struct acl_mailbox_list_context *ctx)
579e70631b8474d20fd3829f477c62950e5f9635Timo Sirainenint acl_backend_vfile_nonowner_lookups_rebuild(struct acl_backend *_backend)