From: Sergey Kitov Date: Thu, 6 Jul 2017 12:45:24 +0000 (+0300) Subject: lmtp: Fix for wrong session id of mail user when saving mail, quota checking on X-Git-Tag: 2.3.0.rc1~1308 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2092da86f3a332e8d7eae1300a3b9852fed8f2f8;p=thirdparty%2Fdovecot%2Fcore.git lmtp: Fix for wrong session id of mail user when saving mail, quota checking on When quota is checked mail user is allocated with custom ":quota" session id suffix without incrementing service user session id counter --- diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index b37b7b73e4..d5d88495b1 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -651,6 +651,7 @@ static int mail_storage_service_init_post(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, struct mail_storage_service_privileges *priv, + const char *session_id_suffix, struct mail_user **mail_user_r, const char **error_r) { @@ -678,15 +679,23 @@ mail_storage_service_init_post(struct mail_storage_service_ctx *ctx, user->input.session_create_time; mail_user->session_restored = TRUE; } - if (user->session_id_counter++ == 0) { - mail_user->session_id = - p_strdup(mail_user->pool, user->input.session_id); - } else { + + if (session_id_suffix == NULL) { + if (user->session_id_counter++ == 0) { + mail_user->session_id = + p_strdup(mail_user->pool, user->input.session_id); + } else { + mail_user->session_id = + p_strdup_printf(mail_user->pool, "%s:%u", + user->input.session_id, + user->session_id_counter); + } + } else mail_user->session_id = - p_strdup_printf(mail_user->pool, "%s:%u", + p_strdup_printf(mail_user->pool, "%s:%s", user->input.session_id, - user->session_id_counter); - } + session_id_suffix); + mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL : p_strarray_dup(mail_user->pool, user->input.userdb_fields); @@ -1359,6 +1368,7 @@ void mail_storage_service_save_userdb_fields(struct mail_storage_service_ctx *ct static int mail_storage_service_next_real(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, + const char *session_id_suffix, struct mail_user **mail_user_r, const char **error_r) { @@ -1438,6 +1448,7 @@ mail_storage_service_next_real(struct mail_storage_service_ctx *ctx, module_dir_init(mail_storage_service_modules); if (mail_storage_service_init_post(ctx, user, &priv, + session_id_suffix, mail_user_r, error_r) < 0) return -2; return 0; @@ -1447,6 +1458,19 @@ int mail_storage_service_next(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, struct mail_user **mail_user_r, const char **error_r) +{ + return mail_storage_service_next_with_session_suffix(ctx, + user, + NULL, + mail_user_r, + error_r); +} + +int mail_storage_service_next_with_session_suffix(struct mail_storage_service_ctx *ctx, + struct mail_storage_service_user *user, + const char *session_id_suffix, + struct mail_user **mail_user_r, + const char **error_r) { char *old_log_prefix = i_strdup(i_get_failure_prefix()); int ret; @@ -1454,7 +1478,9 @@ int mail_storage_service_next(struct mail_storage_service_ctx *ctx, mail_storage_service_set_log_prefix(ctx, user->user_set, user, &user->input, NULL); i_set_failure_prefix("%s", old_log_prefix); - ret = mail_storage_service_next_real(ctx, user, mail_user_r, error_r); + ret = mail_storage_service_next_real(ctx, user, + session_id_suffix, + mail_user_r, error_r); if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) != 0) i_set_failure_prefix("%s", old_log_prefix); i_free(old_log_prefix); diff --git a/src/lib-storage/mail-storage-service.h b/src/lib-storage/mail-storage-service.h index 22f5b04034..e047a719f6 100644 --- a/src/lib-storage/mail-storage-service.h +++ b/src/lib-storage/mail-storage-service.h @@ -102,6 +102,12 @@ int mail_storage_service_next(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, struct mail_user **mail_user_r, const char **error_r); +/* Returns 0 if ok, -1 if fatal error, -2 if error is user-specific. */ +int mail_storage_service_next_with_session_suffix(struct mail_storage_service_ctx *ctx, + struct mail_storage_service_user *user, + const char *session_id_postfix, + struct mail_user **mail_user_r, + const char **error_r); void mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user); /* Combine lookup() and next() into one call. */ diff --git a/src/lmtp/commands.c b/src/lmtp/commands.c index fd71a0405d..770406a267 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -554,8 +554,18 @@ lmtp_rcpt_to_is_over_quota(struct client *client, if (!client->lmtp_set->lmtp_rcpt_check_quota) return 0; - ret = mail_storage_service_next(storage_service, - rcpt->service_user, &user, &errstr); + /* mail user will be created second time when mail is saved, + so it's session_id needs to be different, + but second time session_id needs to be the same as rcpt session_id and + mail user session id for the first rcpt should not overlap with session id + of the second recipient, so add custom ":quota" suffix to the session_id without + session_id counter increment, so next time mail user will get + the same session id as rcpt */ + ret = mail_storage_service_next_with_session_suffix(storage_service, + rcpt->service_user, + "quota", + &user, &errstr); + if (ret < 0) { i_error("Failed to initialize user %s: %s", rcpt->address, errstr); return -1;