From: Timo Sirainen Date: Tue, 18 Jun 2024 09:30:28 +0000 (+0300) Subject: quota: Add quota_mailbox_message_count setting X-Git-Tag: 2.4.0~1564 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a71b4d42f61b83cd5cf77a9bacdab262a4e98944;p=thirdparty%2Fdovecot%2Fcore.git quota: Add quota_mailbox_message_count setting --- diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index 6ba3b812bf..5bf76a7d3a 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -29,6 +29,7 @@ struct quota_settings { const char **error_r); uoff_t max_mail_size; + unsigned int max_messages_per_mailbox; const char *quota_exceeded_msg; bool debug:1; bool initialized:1; diff --git a/src/plugins/quota/quota-status.c b/src/plugins/quota/quota-status.c index 9175e3599d..041f75d079 100644 --- a/src/plugins/quota/quota-status.c +++ b/src/plugins/quota/quota-status.c @@ -191,6 +191,7 @@ static void client_handle_request(struct quota_client *client) "quota_status_toolarge"); /* fall through */ case QUOTA_ALLOC_RESULT_OVER_QUOTA: + case QUOTA_ALLOC_RESULT_OVER_QUOTA_MAILBOX_LIMIT: if (value == NULL) value = mail_user_plugin_getenv(user, "quota_status_overquota"); diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index a1d08ee580..efead36ea3 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -60,6 +60,7 @@ static void quota_set_storage_error(struct quota_transaction_context *qt, mail_storage_set_error(storage, MAIL_ERROR_LIMIT, errstr); break; case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT: + case QUOTA_ALLOC_RESULT_OVER_QUOTA_MAILBOX_LIMIT: case QUOTA_ALLOC_RESULT_OVER_QUOTA: mail_storage_set_error(storage, MAIL_ERROR_NOQUOTA, errstr); break; diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index b33f6cae00..6cdaca08cc 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -287,6 +287,8 @@ const char *quota_alloc_result_errstr(enum quota_alloc_result res, case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT: case QUOTA_ALLOC_RESULT_OVER_QUOTA: return qt->quota->set->quota_exceeded_msg; + case QUOTA_ALLOC_RESULT_OVER_QUOTA_MAILBOX_LIMIT: + return "Too many messages in the mailbox"; } i_unreached(); } @@ -324,6 +326,19 @@ int quota_user_read_settings(struct mail_user *user, } } + const char *max_box_count = + mail_user_plugin_getenv(user, "quota_mailbox_message_count"); + if (max_box_count != NULL) { + const char *error; + if (str_parse_uint(max_box_count, + "a_set->max_messages_per_mailbox, + &error) < 0) { + *error_r = t_strdup_printf( + "quota_mailbox_message_count: %s", error); + return -1; + } + } + p_array_init("a_set->root_sets, pool, 4); if (i_strocpy(root_name, "quota", sizeof(root_name)) < 0) i_unreached(); @@ -937,6 +952,7 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx, enum quota_get_result *error_result_r, const char **error_r) { + const struct quota_settings *set = ctx->quota->set; struct quota_root *const *roots; const char *mailbox_name, *error; unsigned int i, count; @@ -1033,6 +1049,22 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx, } } } + + if (set->max_messages_per_mailbox != 0) { + struct mailbox_status status; + mailbox_get_open_status(ctx->box, STATUS_MESSAGES, &status); + if (status.messages <= set->max_messages_per_mailbox) { + diff = set->max_messages_per_mailbox - status.messages; + if (ctx->count_ceil > diff) + ctx->count_ceil = diff; + } else { + /* over quota */ + ctx->count_ceil = 0; + diff = status.messages - set->max_messages_per_mailbox; + if (ctx->count_over < diff) + ctx->count_over = diff; + } + } return 0; } @@ -1419,6 +1451,14 @@ static enum quota_alloc_result quota_default_test_alloc( if (!quota_transaction_is_over(ctx, size)) return QUOTA_ALLOC_RESULT_OK; + if (ctx->quota->set->max_messages_per_mailbox != 0) { + struct mailbox_status status; + mailbox_get_open_status(ctx->box, STATUS_MESSAGES, &status); + unsigned int new_count = status.messages + ctx->count_used; + if (new_count >= ctx->quota->set->max_messages_per_mailbox) + return QUOTA_ALLOC_RESULT_OVER_QUOTA_MAILBOX_LIMIT; + } + /* limit reached. */ roots = array_get(&ctx->quota->roots, &count); for (i = 0; i < count; i++) { diff --git a/src/plugins/quota/quota.h b/src/plugins/quota/quota.h index 8de2d8ef6f..d669a26848 100644 --- a/src/plugins/quota/quota.h +++ b/src/plugins/quota/quota.h @@ -47,6 +47,8 @@ enum quota_alloc_result { QUOTA_ALLOC_RESULT_OVER_QUOTA, /* Mail size is larger than even the maximum allowed quota. */ QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT, + /* Maximum number of messages per mailbox was reached */ + QUOTA_ALLOC_RESULT_OVER_QUOTA_MAILBOX_LIMIT, /* Blocked by ongoing background quota calculation. */ QUOTA_ALLOC_RESULT_BACKGROUND_CALC, };