Mercurial > dovecot > core-2.2
changeset 12575:c39557b7662d
Merged fixes from v2.0 tree.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 01 Jan 2011 15:59:02 +0200 |
parents | 917f3699af5b (current diff) c1e71f579adc (diff) |
children | 1e425fe18dea |
files | TODO src/imap/imap-search.c src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/mail-storage.h src/plugins/acl/acl-mailbox-list.c |
diffstat | 25 files changed, 121 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/auth/auth-request.c Sat Jan 01 15:59:02 2011 +0200 @@ -354,6 +354,22 @@ result == PASSDB_RESULT_OK); } +static void auth_request_userdb_reply_update_user(struct auth_request *request) +{ + const char *str, *p; + + str = t_strdup(auth_stream_reply_export(request->userdb_reply)); + + /* reset the reply and add the new username */ + auth_stream_reply_reset(request->userdb_reply); + auth_stream_reply_add(request->userdb_reply, NULL, request->user); + + /* add the rest */ + p = strchr(str, '\t'); + if (p != NULL) + auth_stream_reply_import(request->userdb_reply, p + 1); +} + static bool auth_request_master_lookup_finish(struct auth_request *request) { struct auth_passdb *passdb; @@ -368,6 +384,8 @@ request->master_user = request->user; request->user = request->requested_login_user; request->requested_login_user = NULL; + if (request->userdb_reply != NULL) + auth_request_userdb_reply_update_user(request); request->skip_password_check = TRUE; request->passdb_password = NULL; @@ -1079,22 +1097,6 @@ auth_stream_reply_add(request->extra_fields, name, value); } -static void auth_request_userdb_reply_update_user(struct auth_request *request) -{ - const char *str, *p; - - str = t_strdup(auth_stream_reply_export(request->userdb_reply)); - - /* reset the reply and add the new username */ - auth_stream_reply_reset(request->userdb_reply); - auth_stream_reply_add(request->userdb_reply, NULL, request->user); - - /* add the rest */ - p = strchr(str, '\t'); - if (p != NULL) - auth_stream_reply_import(request->userdb_reply, p + 1); -} - static const char * get_updated_username(const char *old_username, const char *name, const char *value)
--- a/src/auth/passdb-checkpassword.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/auth/passdb-checkpassword.c Sat Jan 01 15:59:02 2011 +0200 @@ -35,6 +35,9 @@ "LF characters in checkpassword reply"); result = PASSDB_RESULT_INTERNAL_FAILURE; } else { + auth_request_log_debug(request->request, + "checkpassword", "input: %s", + str_c(request->input_buf)); auth_request_set_fields(request->request, t_strsplit(str_c(request->input_buf), "\t"), NULL);
--- a/src/auth/passdb-vpopmail.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/auth/passdb-vpopmail.c Sat Jan 01 15:59:02 2011 +0200 @@ -35,7 +35,7 @@ struct vpopmail_passdb_module *module = (struct vpopmail_passdb_module *)_module; - if (strcmp(request->service, "IMAP") == 0) { + if (strcasecmp(request->service, "IMAP") == 0) { if ((vpw->pw_flags & NO_IMAP) != 0) { /* IMAP from webmail IP may still be allowed */ if (!net_ip_compare(&module->webmail_ip, @@ -49,7 +49,7 @@ } } if ((vpw->pw_flags & NO_POP) != 0 && - strcmp(request->service, "POP3") == 0) + strcasecmp(request->service, "POP3") == 0) return TRUE; return FALSE; } @@ -137,8 +137,8 @@ } #ifdef HAVE_VPOPMAIL_OPEN_SMTP_RELAY - if (strcmp(request->service, "POP3") == 0 || - strcmp(request->service, "IMAP") == 0) { + if (strcasecmp(request->service, "POP3") == 0 || + strcasecmp(request->service, "IMAP") == 0) { const char *host = net_ip2addr(&request->remote_ip); if (host != NULL) { /* use putenv() directly rather than env_put() which
--- a/src/doveadm/doveadm-auth.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/doveadm/doveadm-auth.c Sat Jan 01 15:59:02 2011 +0200 @@ -65,7 +65,7 @@ } } auth_master_deinit(&conn); - return ret == 0 ? 1 : 0; + return ret; } static void @@ -250,15 +250,23 @@ cmd_user_list(auth_socket_path, argv + optind); } else { bool first = TRUE; + bool notfound = FALSE; while ((input.username = argv[optind++]) != NULL) { if (first) first = FALSE; else putchar('\n'); - if (cmd_user_input(auth_socket_path, &input) < 0) + switch (cmd_user_input(auth_socket_path, &input)) { + case -1: exit(1); + case 0: + notfound = TRUE; + break; + } } + if (notfound) + exit(2); } }
--- a/src/doveadm/doveadm-mail-list-iter.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/doveadm/doveadm-mail-list-iter.c Sat Jan 01 15:59:02 2011 +0200 @@ -18,7 +18,8 @@ static int search_args_get_mailbox_patterns(const struct mail_search_arg *args, - ARRAY_TYPE(const_string) *patterns) + ARRAY_TYPE(const_string) *patterns, + bool *have_guid_r) { const struct mail_search_arg *subargs; @@ -30,7 +31,7 @@ subargs = args->value.subargs; for (; subargs != NULL; subargs = subargs->next) { if (!search_args_get_mailbox_patterns(subargs, - patterns)) + patterns, have_guid_r)) return 0; } break; @@ -42,6 +43,9 @@ } array_append(patterns, &args->value.str, 1); break; + case SEARCH_MAILBOX_GUID: + *have_guid_r = TRUE; + break; default: break; } @@ -58,14 +62,18 @@ struct doveadm_mail_list_iter *iter; ARRAY_TYPE(const_string) patterns; enum namespace_type ns_mask = NAMESPACE_PRIVATE; + bool have_guid = FALSE; iter = i_new(struct doveadm_mail_list_iter, 1); iter->search_args = search_args; t_array_init(&patterns, 16); - search_args_get_mailbox_patterns(search_args->args, &patterns); + search_args_get_mailbox_patterns(search_args->args, &patterns, + &have_guid); if (array_count(&patterns) == 0) { iter_flags |= MAILBOX_LIST_ITER_SKIP_ALIASES; + if (have_guid) + ns_mask |= NAMESPACE_SHARED | NAMESPACE_PUBLIC; array_append(&patterns, &all_pattern, 1); } else { iter_flags |= MAILBOX_LIST_ITER_STAR_WITHIN_NS;
--- a/src/imap/imap-search.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/imap/imap-search.c Sat Jan 01 15:59:02 2011 +0200 @@ -280,6 +280,7 @@ } str_append(str, "\r\n"); o_stream_send(client->output, str_data(str), str_len(str)); + str_free(&str); } static void search_update_mail(struct imap_search_context *ctx)
--- a/src/lda/main.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lda/main.c Sat Jan 01 15:59:02 2011 +0200 @@ -154,13 +154,6 @@ i_free(sender); if (input->v_offset == 0) { - if (deliver_mail == NULL) { - /* no Sieve or any other plugin. this input stream - simply passes to mailbox_save(), so it doesn't need - to be seekable and we can avoid creating temp files - for large mails. */ - return input; - } input2 = input; i_stream_ref(input2); } else {
--- a/src/lib-master/master-interface.h Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-master/master-interface.h Sat Jan 01 15:59:02 2011 +0200 @@ -68,13 +68,16 @@ /* Shared pipe to master, used to send master_status reports */ #define MASTER_STATUS_FD 5 +/* Pipe to master, used to detect when it dies. (MASTER_STATUS_FD would have + been fine for this, except it's inefficient in Linux) */ +#define MASTER_DEAD_FD 6 /* First file descriptor where process is expected to be listening. The file descriptor count is given in -s parameter, defaulting to 1. master_status.available_count reports how many accept()s we're still accepting. Once no children are listening, master will do it and create new child processes when needed. */ -#define MASTER_LISTEN_FD_FIRST 6 +#define MASTER_LISTEN_FD_FIRST 7 /* Timeouts: base everything on how long we can wait for login clients. */ #define MASTER_LOGIN_TIMEOUT_SECS (3*60)
--- a/src/lib-master/master-login-auth.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-master/master-login-auth.c Sat Jan 01 15:59:02 2011 +0200 @@ -289,7 +289,7 @@ request_internal_failure(request, "Internal auth failure"); } else { - i_error("Internal tuah failure: %s " + i_error("Internal auth failure: %s " "(client-pid=%u client-id=%u)", error, request->client_pid, request->auth_id); request->callback(NULL, error, request->context);
--- a/src/lib-master/master-service.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-master/master-service.c Sat Jan 01 15:59:02 2011 +0200 @@ -375,7 +375,7 @@ master_service_set_service_count(service, count); /* start listening errors for status fd, it means master died */ - service->io_status_error = io_add(MASTER_STATUS_FD, IO_ERROR, + service->io_status_error = io_add(MASTER_DEAD_FD, IO_ERROR, master_status_error, service); } else { master_service_set_client_limit(service, 1);
--- a/src/lib-storage/index/index-mailbox-check.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/index/index-mailbox-check.c Sat Jan 01 15:59:02 2011 +0200 @@ -72,6 +72,8 @@ struct io *io = NULL; struct index_notify_io *aio; + i_assert(box->notify_min_interval > 0); + (void)io_add_notify(path, notify_callback, box, &io); if (io != NULL) { aio = i_new(struct index_notify_io, 1);
--- a/src/lib-storage/index/index-sort.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/index/index-sort.c Sat Jan 01 15:59:02 2011 +0200 @@ -309,7 +309,7 @@ const char *str; int ret; - if ((ret = mail_get_first_header_utf8(mail, header, &str)) <= 0) { + if ((ret = mail_get_first_header(mail, header, &str)) <= 0) { *addr_r = NULL; return ret; }
--- a/src/lib-storage/list/mailbox-list-delete.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-delete.c Sat Jan 01 15:59:02 2011 +0200 @@ -97,7 +97,7 @@ if (trash_dir == trash_dest) { trash_dest = t_strconcat(trash_dir, "/", unique_fname(), NULL); - } else if (unlink_directory(trash_dest, TRUE) < 0 && + } else if (mailbox_list_delete_trash(trash_dest) < 0 && (errno != ENOTEMPTY || count >= 5)) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", trash_dest); @@ -105,7 +105,7 @@ } } - if (unlink_directory(trash_dir, TRUE) < 0 && + if (mailbox_list_delete_trash(trash_dir) < 0 && errno != ENOTEMPTY && errno != EBUSY) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", trash_dir); @@ -189,7 +189,7 @@ str_append(full_path, d->d_name); if (mailbox_dir) { - if (unlink_directory(str_c(full_path), TRUE) < 0) { + if (mailbox_list_delete_trash(str_c(full_path)) < 0) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", str_c(full_path)); @@ -297,7 +297,7 @@ rmdir_path) < 0) return; } else { - if (unlink_directory(path, TRUE) < 0 && + if (mailbox_list_delete_trash(path) < 0 && errno != ENOENT && errno != ENOTEMPTY) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", path); @@ -314,3 +314,17 @@ mailbox_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL); mailbox_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX); } + +int mailbox_list_delete_trash(const char *path) +{ + if (unlink_directory(path, TRUE) < 0) { + if (errno == ELOOP) { + /* it's a symlink? try just deleting it */ + if (unlink(path) == 0) + return 0; + errno = ELOOP; + return -1; + } + } + return 0; +}
--- a/src/lib-storage/list/mailbox-list-delete.h Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-delete.h Sat Jan 01 15:59:02 2011 +0200 @@ -15,5 +15,6 @@ void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, enum mailbox_list_path_type type); +int mailbox_list_delete_trash(const char *path); #endif
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Sat Jan 01 15:59:02 2011 +0200 @@ -6,6 +6,7 @@ #include "unlink-directory.h" #include "imap-match.h" #include "mailbox-tree.h" +#include "mailbox-list-delete.h" #include "mailbox-list-subscriptions.h" #include "mailbox-list-maildir.h" @@ -256,7 +257,7 @@ path = t_strdup_printf("%s/%s", ctx->dir, fname); if (stat(path, &st) == 0 && st.st_mtime < ioloop_time - 3600) - (void)unlink_directory(path, TRUE); + (void)mailbox_list_delete_trash(path); return TRUE; }
--- a/src/lib-storage/mail-storage.h Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib-storage/mail-storage.h Sat Jan 01 15:59:02 2011 +0200 @@ -641,7 +641,11 @@ int mail_get_first_header(struct mail *mail, const char *field, const char **value_r); /* Like mail_get_first_header(), but decode MIME encoded words to UTF-8. - Also multiline headers are returned unfolded. */ + Also multiline headers are returned unfolded. + + Do not use this function for getting structured fields (e.g. address fields), + because decoding may break the structuring. Instead parse them first and + only afterwards decode the encoded words. */ int mail_get_first_header_utf8(struct mail *mail, const char *field, const char **value_r); /* Return a NULL-terminated list of values for each found field. @@ -649,7 +653,8 @@ int mail_get_headers(struct mail *mail, const char *field, const char *const **value_r); /* Like mail_get_headers(), but decode MIME encoded words to UTF-8. - Also multiline headers are returned unfolded. */ + Also multiline headers are returned unfolded. + Do not use for structured fields (see mail_get_first_header_utf8()). */ int mail_get_headers_utf8(struct mail *mail, const char *field, const char *const **value_r); /* Returns stream containing specified headers. */
--- a/src/lib/network.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib/network.c Sat Jan 01 15:59:02 2011 +0200 @@ -371,7 +371,8 @@ /* create the socket */ fd = socket(so.sin.sin_family, SOCK_STREAM, 0); #ifdef HAVE_IPV6 - if (fd == -1 && (errno == EINVAL || errno == EAFNOSUPPORT)) { + if (fd == -1 && my_ip == NULL && + (errno == EINVAL || errno == EAFNOSUPPORT)) { /* IPv6 is not supported by OS */ so.sin.sin_family = AF_INET; so.sin.sin_addr.s_addr = INADDR_ANY;
--- a/src/lib/unlink-directory.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/lib/unlink-directory.c Sat Jan 01 15:59:02 2011 +0200 @@ -59,7 +59,12 @@ return -1; if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; + if ((st.st_mode & S_IFMT) != S_IFLNK) + errno = ENOTDIR; + else { + /* be compatible with O_NOFOLLOW */ + errno = ELOOP; + } return -1; }
--- a/src/master/common.h Sat Jan 01 15:56:37 2011 +0200 +++ b/src/master/common.h Sat Jan 01 15:59:02 2011 +0200 @@ -9,7 +9,7 @@ extern gid_t master_gid; extern bool core_dumps_disabled; extern const char *ssl_manual_key_password; -extern int null_fd; +extern int null_fd, master_dead_pipe_fd[2]; extern struct service_list *services; void process_exec(const char *cmd, const char *extra_args[]) ATTR_NORETURN;
--- a/src/master/main.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/master/main.c Sat Jan 01 15:59:02 2011 +0200 @@ -42,7 +42,7 @@ gid_t master_gid; bool core_dumps_disabled; const char *ssl_manual_key_password; -int null_fd; +int null_fd, master_dead_pipe_fd[2]; struct service_list *services; static char *pidfile_path; @@ -412,7 +412,7 @@ lib_signals_set_handler(SIGUSR1, TRUE, sig_log_reopen, NULL); lib_signals_set_handler(SIGCHLD, TRUE, sig_reap_children, NULL); lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); - lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); + lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); create_pid_file(pidfile_path); create_config_symlink(set); @@ -712,6 +712,10 @@ i_fatal("Can't open /dev/null: %m"); fd_close_on_exec(null_fd, TRUE); } while (null_fd <= STDERR_FILENO); + if (pipe(master_dead_pipe_fd) < 0) + i_fatal("pipe() failed: %m"); + fd_close_on_exec(master_dead_pipe_fd[0], TRUE); + fd_close_on_exec(master_dead_pipe_fd[1], TRUE); set = master_settings_read(); if (ask_key_pass) {
--- a/src/master/service-process.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/master/service-process.c Sat Jan 01 15:59:02 2011 +0200 @@ -116,6 +116,7 @@ break; } dup2_append(&dups, service->status_fd[1], MASTER_STATUS_FD); + dup2_append(&dups, master_dead_pipe_fd[1], MASTER_DEAD_FD); if (service->type == SERVICE_TYPE_LOG) { /* keep stderr as-is. this is especially important when
--- a/src/plugins/acl/acl-mailbox-list.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/plugins/acl/acl-mailbox-list.c Sat Jan 01 15:59:02 2011 +0200 @@ -487,7 +487,8 @@ { struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list); - acl_backend_deinit(&alist->rights.backend); + if (alist->rights.backend != NULL) + acl_backend_deinit(&alist->rights.backend); alist->module_ctx.super.deinit(list); }
--- a/src/plugins/quota/doveadm-quota.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/plugins/quota/doveadm-quota.c Sat Jan 01 15:59:02 2011 +0200 @@ -49,6 +49,9 @@ struct quota_user *quser = QUOTA_USER_CONTEXT(user); struct quota_root *const *root; + if (quser == NULL) + i_fatal("Quota not enabled"); + array_foreach(&quser->quota->roots, root) cmd_quota_get_root(*root); } @@ -86,6 +89,9 @@ struct quota_root *const *root; struct quota_transaction_context trans; + if (quser == NULL) + i_fatal("Quota not enabled"); + memset(&trans, 0, sizeof(trans)); trans.quota = quser->quota; trans.recalculate = TRUE;
--- a/src/plugins/quota/quota.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/plugins/quota/quota.c Sat Jan 01 15:59:02 2011 +0200 @@ -1092,9 +1092,12 @@ if (ctx->failed) ret = -1; else if (ctx->bytes_used != 0 || ctx->count_used != 0 || - ctx->recalculate) { + ctx->recalculate) T_BEGIN { + ARRAY_DEFINE(warn_roots, struct quota_root *); + mailbox_name = mailbox_get_vname(ctx->box); roots = array_get(&ctx->quota->roots, &count); + t_array_init(&warn_roots, count); for (i = 0; i < count; i++) { if (!quota_root_is_visible(roots[i], ctx->box, FALSE)) continue; @@ -1108,13 +1111,15 @@ if (roots[i]->backend.v.update(roots[i], ctx) < 0) ret = -1; + else + array_append(&warn_roots, &roots[i], 1); } /* execute quota warnings after all updates. this makes it work correctly regardless of whether backend.get_resource() returns updated values before backend.update() or not */ - for (i = 0; i < count; i++) - quota_warnings_execute(ctx, roots[i]); - } + array_foreach(&warn_roots, roots) + quota_warnings_execute(ctx, *roots); + } T_END; i_free(ctx); return ret;
--- a/src/plugins/snarf/snarf-plugin.c Sat Jan 01 15:56:37 2011 +0200 +++ b/src/plugins/snarf/snarf-plugin.c Sat Jan 01 15:59:02 2011 +0200 @@ -37,6 +37,10 @@ enum mail_error error; int ret; + /* make sure the destination mailbox has been opened */ + if (mailbox_open(destbox) < 0) + return -1; + if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0) return -1;