]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: Add quota_mailbox_count setting
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 7 Jun 2024 10:23:17 +0000 (13:23 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 8 Jul 2024 10:31:58 +0000 (10:31 +0000)
src/plugins/quota/quota-private.h
src/plugins/quota/quota-storage.c
src/plugins/quota/quota.c

index 5bf76a7d3a401e4a8635892524b7461e6bc7f8ef..6311bdd31036a0be43fe8cdbe1af6d023b20669a 100644 (file)
@@ -28,6 +28,7 @@ struct quota_settings {
                struct quota_transaction_context *ctx, uoff_t size,
                const char **error_r);
 
+       unsigned int max_mailbox_count;
        uoff_t max_mail_size;
        unsigned int max_messages_per_mailbox;
        const char *quota_exceeded_msg;
index efead36ea3d7bdb7d6c62cc48c4e533ca516c696..b853d87b7b81d20b91cfc0b2beba2cf0178cb09a 100644 (file)
@@ -116,6 +116,32 @@ static void quota_mail_expunge(struct mail *_mail)
        qmail->super.expunge(_mail);
 }
 
+static int
+quota_create_box(struct mailbox *box, const struct mailbox_update *update,
+                bool directory)
+{
+       struct quota_mailbox *qbox = QUOTA_CONTEXT_REQUIRE(box);
+       struct quota_user *quser =
+               QUOTA_USER_CONTEXT_REQUIRE(box->storage->user);
+       struct quota_settings *quota_set = quser->quota->set;
+       unsigned int mailbox_count;
+
+       if (quota_set->max_mailbox_count == 0) {
+               /* no mailbox count limit */
+       } else if (mailbox_is_autocreated(box)) {
+               /* Always allow autocreated mailbox to be created.
+                  There shouldn't be many of them */
+       } else if (mailbox_list_get_count(box->list, &mailbox_count) < 0) {
+               mail_storage_copy_list_error(box->storage, box->list);
+               return -1;
+       } else if (mailbox_count >= quota_set->max_mailbox_count) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_LIMIT,
+                                      "Maximum number of mailboxes reached");
+               return -1;
+       }
+       return qbox->module_ctx.super.create_box(box, update, directory);
+}
+
 static int
 quota_get_status(struct mailbox *box, enum mailbox_status_items items,
                 struct mailbox_status *status_r)
@@ -596,6 +622,7 @@ void quota_mailbox_allocated(struct mailbox *box)
        qbox->module_ctx.super = *v;
        box->vlast = &qbox->module_ctx.super;
 
+       v->create_box = quota_create_box;
        v->get_status = quota_get_status;
        v->transaction_begin = quota_mailbox_transaction_begin;
        v->transaction_commit = quota_mailbox_transaction_commit;
index 6cdaca08cc5ec31c875578511b6f33d02d5144fc..2f9dacdbeb5df0b10269b2d0e3921c65e851db7a 100644 (file)
@@ -314,6 +314,15 @@ int quota_user_read_settings(struct mail_user *user,
        if (quota_set->quota_exceeded_msg == NULL)
                quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG;
 
+       const char *mailbox_count =
+               mail_user_plugin_getenv(user, "quota_mailbox_count");
+       if (mailbox_count != NULL) {
+               if (str_to_uint(mailbox_count, &quota_set->max_mailbox_count) < 0) {
+                       *error_r = "Invalid quota_mailbox_count";
+                       return -1;
+               }
+       }
+
        const char *max_size = mail_user_plugin_getenv(user,
                                                       "quota_max_mail_size");
        if (max_size != NULL) {