Skip to content

Commit

Permalink
quota: Add quota_max_mail_size setting
Browse files Browse the repository at this point in the history
  • Loading branch information
mrannanj authored and sirainen committed Mar 27, 2017
1 parent 9edefd4 commit 690f935
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/example-config/conf.d/90-quota.conf
Expand Up @@ -22,6 +22,9 @@ plugin {
# over quota, if the quota doesn't grow too high. Default is to allow as
# long as quota will stay under 10% above the limit. Also allowed e.g. 10M.
#quota_grace = 10%%

# Quota plugin can also limit the maximum accepted mail size.
#quota_max_mail_size = 100M
}

##
Expand Down
1 change: 1 addition & 0 deletions src/plugins/quota/Makefile.am
Expand Up @@ -10,6 +10,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib-dict \
-I$(top_srcdir)/src/lib-index \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-storage \
-I$(top_srcdir)/src/lib-storage/index \
-I$(top_srcdir)/src/lib-storage/index/maildir \
Expand Down
1 change: 1 addition & 0 deletions src/plugins/quota/quota-private.h
Expand Up @@ -25,6 +25,7 @@ struct quota_settings {
enum quota_alloc_result (*test_alloc)(
struct quota_transaction_context *ctx, uoff_t size);

uoff_t max_mail_size;
const char *quota_exceeded_msg;
unsigned int debug:1;
unsigned int initialized:1;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/quota/quota-status.c
Expand Up @@ -102,6 +102,7 @@ static void client_handle_request(struct quota_client *client)
if (value == NULL)
value = "OK";
break;
case QUOTA_ALLOC_RESULT_OVER_MAXSIZE:
/* even over maximum quota */
case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT:
value = mail_user_plugin_getenv(user,
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/quota/quota-storage.c
Expand Up @@ -52,6 +52,9 @@ static void quota_set_storage_error(struct quota_transaction_context *qt,
{
const char *errstr = quota_alloc_result_errstr(res, qt);
switch (res) {
case QUOTA_ALLOC_RESULT_OVER_MAXSIZE:
mail_storage_set_error(storage, MAIL_ERROR_LIMIT, errstr);
break;
case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT:
case QUOTA_ALLOC_RESULT_OVER_QUOTA:
mail_storage_set_error(storage, MAIL_ERROR_NOQUOTA, errstr);
Expand Down
24 changes: 23 additions & 1 deletion src/plugins/quota/quota.c
Expand Up @@ -13,6 +13,7 @@
#include "mailbox-list-private.h"
#include "quota-private.h"
#include "quota-fs.h"
#include "settings-parser.h"

#include <sys/wait.h>

Expand Down Expand Up @@ -226,6 +227,9 @@ const char *quota_alloc_result_errstr(enum quota_alloc_result res,
return "OK";
case QUOTA_ALLOC_RESULT_TEMPFAIL:
return "Internal quota calculation error";
case QUOTA_ALLOC_RESULT_OVER_MAXSIZE:
return "Mail size is larger than the maximum size allowed by "
"server configuration";
case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT:
case QUOTA_ALLOC_RESULT_OVER_QUOTA:
return qt->quota->set->quota_exceeded_msg;
Expand Down Expand Up @@ -254,6 +258,18 @@ int quota_user_read_settings(struct mail_user *user,
quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG;
quota_set->vsizes = mail_user_plugin_getenv(user, "quota_vsizes") != NULL;

const char *max_size = mail_user_plugin_getenv(user,
"quota_max_mail_size");
if (max_size != NULL) {
const char *error = NULL;
if (settings_get_size(max_size, &quota_set->max_mail_size,
&error) < 0) {
*error_r = t_strdup_printf("quota_max_mail_size: %s",
error);
return -1;
}
}

p_array_init(&quota_set->root_sets, pool, 4);
if (i_strocpy(root_name, "quota", sizeof(root_name)) < 0)
i_unreached();
Expand All @@ -272,7 +288,8 @@ int quota_user_read_settings(struct mail_user *user,
if (i_snprintf(root_name, sizeof(root_name), "quota%d", i) < 0)
i_unreached();
}
if (array_count(&quota_set->root_sets) == 0) {
if (quota_set->max_mail_size == 0 &&
array_count(&quota_set->root_sets) == 0) {
pool_unref(&pool);
return 0;
}
Expand Down Expand Up @@ -1211,6 +1228,11 @@ enum quota_alloc_result quota_test_alloc(struct quota_transaction_context *ctx,

if (quota_transaction_set_limits(ctx) < 0)
return QUOTA_ALLOC_RESULT_TEMPFAIL;

uoff_t max_size = ctx->quota->set->max_mail_size;
if (max_size > 0 && size > max_size)
return QUOTA_ALLOC_RESULT_OVER_MAXSIZE;

if (ctx->no_quota_updates)
return QUOTA_ALLOC_RESULT_OK;
/* this is a virtual function mainly for trash plugin and similar,
Expand Down
1 change: 1 addition & 0 deletions src/plugins/quota/quota.h
Expand Up @@ -33,6 +33,7 @@ enum quota_recalculate {
enum quota_alloc_result {
QUOTA_ALLOC_RESULT_OK,
QUOTA_ALLOC_RESULT_TEMPFAIL,
QUOTA_ALLOC_RESULT_OVER_MAXSIZE,
QUOTA_ALLOC_RESULT_OVER_QUOTA,
/* Mail size is larger than even the maximum allowed quota. */
QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT,
Expand Down

0 comments on commit 690f935

Please sign in to comment.