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)
{
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);
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)
{
struct mail_storage_service_privileges priv;
module_dir_init(mail_storage_service_modules);
if (mail_storage_service_init_post(ctx, user, &priv,
+ session_id_suffix,
mail_user_r, &error) < 0) {
i_error("User initialization failed: %s", error);
return -2;
int mail_storage_service_next(struct mail_storage_service_ctx *ctx,
struct mail_storage_service_user *user,
struct mail_user **mail_user_r)
+{
+ return mail_storage_service_next_with_session_suffix(ctx,
+ user,
+ NULL,
+ mail_user_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)
{
char *old_log_prefix = i_strdup(i_get_failure_prefix());
int ret;
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);
+ ret = mail_storage_service_next_real(ctx, user, session_id_suffix,
+ mail_user_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);
int mail_storage_service_next(struct mail_storage_service_ctx *ctx,
struct mail_storage_service_user *user,
struct mail_user **mail_user_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);
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. */
if (!client->lmtp_set->lmtp_rcpt_check_quota)
return 0;
- ret = mail_storage_service_next(storage_service,
- rcpt->service_user, &user);
+ /* 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);
if (ret < 0)
return -1;