changeset 21816:869db4bcecdb

lib-storage: Replace MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE with explicit mail_user_autoexpunge() This allows better control of which users are being autoexpunged. This patch changes behavior at least in two ways now: 1) After shared folder access, the owner user isn't autoexpunged at deinit. Although this is a bit questionable of whether it should be or not. 2) LMTP's quota check at RCPT TO stage doesn't trigger autoexpunging.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 23 Mar 2017 14:15:49 +0200
parents 920e7214f3b4
children df29d7876ea5
files src/imap/imap-client.c src/imap/main.c src/lib-storage/mail-storage-service.c src/lib-storage/mail-storage-service.h src/lib-storage/mail-user.c src/lib-storage/mail-user.h src/lmtp/commands.c src/lmtp/main.c src/pop3/main.c src/pop3/pop3-client.c
diffstat 10 files changed, 25 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/imap-client.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/imap/imap-client.c	Thu Mar 23 14:15:49 2017 +0200
@@ -19,6 +19,7 @@
 #include "mail-error.h"
 #include "mail-namespace.h"
 #include "mail-storage-service.h"
+#include "mail-autoexpunge.h"
 #include "imap-state.h"
 #include "imap-search.h"
 #include "imap-notify.h"
@@ -453,10 +454,13 @@
 	/* i/ostreams are already closed at this stage, so fd can be closed */
 	fd_close_maybe_stdio(&client->fd_in, &client->fd_out);
 
-	/* refresh proctitle before a potentially long-running user unref */
+	/* Autoexpunging might run for a long time. Disconnect the client
+	   before it starts, and refresh proctitle so it's clear that it's
+	   doing autoexpunging. We've also sent DISCONNECT to anvil already,
+	   because this is background work and shouldn't really be counted
+	   as an active IMAP session for the user. */
 	imap_refresh_proctitle();
-	/* Free the user after client is already disconnected. It may start
-	   some background work like autoexpunging. */
+	mail_user_autoexpunge(client->user);
 	mail_user_unref(&client->user);
 
 	/* free the i/ostreams after mail_user_unref(), which could trigger
--- a/src/imap/main.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/imap/main.c	Thu Mar 23 14:15:49 2017 +0200
@@ -374,8 +374,7 @@
 	};
 	struct master_login_settings login_set;
 	enum master_service_flags service_flags = 0;
-	enum mail_storage_service_flags storage_service_flags =
-		MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+	enum mail_storage_service_flags storage_service_flags = 0;
 	const char *username = NULL, *auth_socket_path = "auth-master";
 	int c;
 
--- a/src/lib-storage/mail-storage-service.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lib-storage/mail-storage-service.c	Thu Mar 23 14:15:49 2017 +0200
@@ -678,8 +678,6 @@
 	}
 	mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL :
 		p_strarray_dup(mail_user->pool, user->input.userdb_fields);
-	mail_user->autoexpunge_enabled =
-		(user->flags & MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE) != 0;
 	
 	mail_set = mail_user_set_get_storage_set(mail_user);
 
--- a/src/lib-storage/mail-storage-service.h	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lib-storage/mail-storage-service.h	Thu Mar 23 14:15:49 2017 +0200
@@ -34,8 +34,6 @@
 	MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS		= 0x400,
 	/* Don't create namespaces, only the user. */
 	MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES		= 0x800,
-	/* Enable autoexpunging at deinit. */
-	MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE		= 0x1000
 };
 
 struct mail_storage_service_input {
--- a/src/lib-storage/mail-user.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lib-storage/mail-user.c	Thu Mar 23 14:15:49 2017 +0200
@@ -189,9 +189,6 @@
 		return;
 	}
 
-	if (user->autoexpunge_enabled && user->namespaces_created)
-		mail_user_autoexpunge(user);
-
 	user->deinitializing = TRUE;
 
 	/* call deinit() with refcount=1, otherwise we may assert-crash in
--- a/src/lib-storage/mail-user.h	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lib-storage/mail-user.h	Thu Mar 23 14:15:49 2017 +0200
@@ -95,8 +95,6 @@
 	unsigned int admin:1;
 	/* Enable all statistics gathering */
 	unsigned int stats_enabled:1;
-	/* Enable autoexpunging at deinit. */
-	unsigned int autoexpunge_enabled:1;
 	/* This session was restored (e.g. IMAP unhibernation) */
 	unsigned int session_restored:1;
 };
--- a/src/lmtp/commands.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lmtp/commands.c	Thu Mar 23 14:15:49 2017 +0200
@@ -27,6 +27,7 @@
 #include "index/raw/raw-storage.h"
 #include "lda-settings.h"
 #include "lmtp-settings.h"
+#include "mail-autoexpunge.h"
 #include "mail-namespace.h"
 #include "mail-deliver.h"
 #include "main.h"
@@ -945,8 +946,10 @@
 		if (ret == 0)
 			return TRUE;
 		/* failed. try the next one. */
-		if (client->state.dest_user != NULL)
+		if (client->state.dest_user != NULL) {
+			mail_user_autoexpunge(client->state.dest_user);
 			mail_user_unref(&client->state.dest_user);
+		}
 	}
 	return FALSE;
 }
@@ -1034,9 +1037,10 @@
 	src_mail = client->state.raw_mail;
 	while (client_deliver_next(client, src_mail, session)) {
 		if (client->state.first_saved_mail == NULL ||
-		    client->state.first_saved_mail == src_mail)
+		    client->state.first_saved_mail == src_mail) {
+			mail_user_autoexpunge(client->state.dest_user);
 			mail_user_unref(&client->state.dest_user);
-		else {
+		} else {
 			/* use the first saved message to save it elsewhere too.
 			   this might allow hard linking the files. */
 			client->state.dest_user = NULL;
@@ -1065,6 +1069,7 @@
 		mail_free(&mail);
 		mailbox_transaction_rollback(&trans);
 		mailbox_free(&box);
+		mail_user_autoexpunge(user);
 		mail_user_unref(&user);
 	}
 
--- a/src/lmtp/main.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/lmtp/main.c	Thu Mar 23 14:15:49 2017 +0200
@@ -88,8 +88,7 @@
 		MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
 		MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP |
 		MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
-		MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT |
-		MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+		MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT;
 	int c;
 
 	if (IS_STANDALONE()) {
--- a/src/pop3/main.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/pop3/main.c	Thu Mar 23 14:15:49 2017 +0200
@@ -215,8 +215,7 @@
 	};
 	struct master_login_settings login_set;
 	enum master_service_flags service_flags = 0;
-	enum mail_storage_service_flags storage_service_flags =
-		MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE;
+	enum mail_storage_service_flags storage_service_flags = 0;
 	const char *username = NULL, *auth_socket_path = "auth-master";
 	int c;
 
--- a/src/pop3/pop3-client.c	Thu Mar 23 14:08:53 2017 +0200
+++ b/src/pop3/pop3-client.c	Thu Mar 23 14:15:49 2017 +0200
@@ -17,6 +17,7 @@
 #include "master-service.h"
 #include "mail-storage.h"
 #include "mail-storage-service.h"
+#include "mail-autoexpunge.h"
 #include "pop3-commands.h"
 #include "mail-search-build.h"
 #include "mail-namespace.h"
@@ -648,8 +649,13 @@
 
 	fd_close_maybe_stdio(&client->fd_in, &client->fd_out);
 
-	/* refresh proctitle before a potentially long-running user unref */
+	/* Autoexpunging might run for a long time. Disconnect the client
+	   before it starts, and refresh proctitle so it's clear that it's
+	   doing autoexpunging. We've also sent DISCONNECT to anvil already,
+	   because this is background work and shouldn't really be counted
+	   as an active POP3 session for the user. */
 	pop3_refresh_proctitle();
+	mail_user_autoexpunge(client->user);
 	mail_user_unref(&client->user);
 	mail_storage_service_user_unref(&client->service_user);