From d291c7670e4c370cdc4f631ea58f82c7f4f87823 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 25 Jun 2017 22:54:08 +0200 Subject: [PATCH] Add quota/quota_filecount transport option modifier "no_check" Bug 1115 This option modifier allows to ignore the quota limits, but update the maildirsize file. --- doc/doc-docbook/spec.xfpt | 8 +++- doc/doc-txt/NewStuff | 3 ++ src/src/transports/appendfile.c | 60 +++++++++++++++++++++-------- src/src/transports/appendfile.h | 2 + test/confs/5010 | 35 +++++++++++++++++ test/confs/5011 | 35 +++++++++++++++++ test/confs/5012 | 35 +++++++++++++++++ test/log/5010 | 12 ++++++ test/log/5011 | 18 +++++++++ test/log/5012 | 6 +++ test/mail/5010.maildirsize | 2 + test/mail/5010.new/1.myhost.test.ex | 17 ++++++++ test/mail/5011.maildirsize | 2 + test/mail/5012.maildirsize | 3 ++ test/mail/5012.new/1.myhost.test.ex | 17 ++++++++ test/mail/5012.new/2.myhost.test.ex | 28 ++++++++++++++ test/scripts/5000-maildir/5010 | 35 +++++++++++++++++ test/scripts/5000-maildir/5011 | 1 + test/scripts/5000-maildir/5012 | 1 + 19 files changed, 304 insertions(+), 16 deletions(-) create mode 100644 test/confs/5010 create mode 100644 test/confs/5011 create mode 100644 test/confs/5012 create mode 100644 test/log/5010 create mode 100644 test/log/5011 create mode 100644 test/log/5012 create mode 100644 test/mail/5010.maildirsize create mode 100644 test/mail/5010.new/1.myhost.test.ex create mode 100644 test/mail/5011.maildirsize create mode 100644 test/mail/5012.maildirsize create mode 100644 test/mail/5012.new/1.myhost.test.ex create mode 100644 test/mail/5012.new/2.myhost.test.ex create mode 100644 test/scripts/5000-maildir/5010 create mode 120000 test/scripts/5000-maildir/5011 create mode 120000 test/scripts/5000-maildir/5012 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 7816bc26d..4a239b73c 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -22128,10 +22128,14 @@ the obvious value which users understand most easily. The value of the option is expanded, and must then be a numerical value (decimal point allowed), optionally followed by one of the letters K, M, or G, -for kilobytes, megabytes, or gigabytes. If Exim is running on a system with +for kilobytes, megabytes, or gigabytes, optionally followed by a slash +and further option modifiers. If Exim is running on a system with large file support (Linux and FreeBSD have this), mailboxes larger than 2G can be handled. +The option modifier &%no_check%& can be used to force delivery even if the over +quota condition is met. The quota gets updated as usual. + &*Note*&: A value of zero is interpreted as &"no quota"&. The expansion happens while Exim is running as root, before it changes uid for @@ -22166,6 +22170,8 @@ can only be used if &%quota%& is also set. The value is expanded; an expansion failure causes delivery to be deferred. A value of zero is interpreted as &"no quota"&. +The option modifier &%no_check%& can be used to force delivery even if the over +quota condition is met. The quota gets updated as usual. .option quota_is_inclusive appendfile boolean true See &%quota%& above. diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 5fd7fbb29..d0d5cf22c 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -38,6 +38,9 @@ Version 4.90 8. New main configuration option "commandline_checks_require_admin" to restrict who can use various introspection options. + 9. New option modifier "no_check" for quota and quota_filecount + appendfile transport. + Version 4.89 ------------ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index da5d8aa0a..56200710f 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -234,7 +234,9 @@ appendfile_transport_options_block appendfile_transport_option_defaults = { FALSE, /* mailstore_format */ FALSE, /* mbx_format */ FALSE, /* quota_warn_threshold_is_percent */ - TRUE /* quota_is_inclusive */ + TRUE, /* quota_is_inclusive */ + FALSE, /* quota_no_check */ + FALSE /* quota_filecount_no_check */ }; @@ -285,9 +287,11 @@ mailbox_filecount */ for (i = 0; i < 5; i++) { double d; + int no_check = 0; uschar *which = NULL; - if (q == NULL) d = default_value; else + if (q == NULL) d = default_value; + else { uschar *rest; uschar *s = expand_string(q); @@ -321,12 +325,21 @@ for (i = 0; i < 5; i++) rest++; } + + /* For quota and quota_filecount there may be options + appended. Currently only "no_check", so we can be lazy parsing it */ + if (i < 2 && Ustrstr(rest, "/no_check") == rest) + { + no_check = 1; + rest += sizeof("/no_check") - 1; + } + while (isspace(*rest)) rest++; if (*rest != 0) { *errmsg = string_sprintf("Malformed value \"%s\" (expansion of \"%s\") " - "in %s transport", s, q, tblock->name); + "in %s transport [%s]", s, q, tblock->name); return FAIL; } } @@ -338,12 +351,14 @@ for (i = 0; i < 5; i++) case 0: if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4) which = US"quota"; ob->quota_value = (off_t)d; + ob->quota_no_check = no_check; q = ob->quota_filecount; break; case 1: if (d >= 2.0*1024.0*1024.0*1024.0) which = US"quota_filecount"; ob->quota_filecount_value = (int)d; + ob->quota_filecount_no_check = no_check; q = ob->quota_warn_threshold; break; @@ -1383,10 +1398,13 @@ else DEBUG(D_transport) { debug_printf("appendfile: mode=%o notify_comsat=%d quota=" OFF_T_FMT + "%s" " warning=" OFF_T_FMT "%s\n" " %s=%s format=%s\n message_prefix=%s\n message_suffix=%s\n " "maildir_use_size_file=%s\n", mode, ob->notify_comsat, ob->quota_value, + ob->quota_no_check? " (no_check)" : "", + ob->quota_filecount_no_check? " (no_check_filecount)" : "", ob->quota_warn_threshold_value, ob->quota_warn_threshold_is_percent? "%" : "", isdirectory? "directory" : "file", @@ -2777,21 +2795,33 @@ if (!disable_quota && ob->quota_value > 0) debug_printf(" file count quota = %d count = %d\n", ob->quota_filecount_value, mailbox_filecount); } + if (mailbox_size + (ob->quota_is_inclusive? message_size:0) > ob->quota_value) { - DEBUG(D_transport) debug_printf("mailbox quota exceeded\n"); - yield = DEFER; - errno = ERRNO_EXIMQUOTA; - } - else if (ob->quota_filecount_value > 0 && - mailbox_filecount + (ob->quota_is_inclusive ? 1:0) > - ob->quota_filecount_value) - { - DEBUG(D_transport) debug_printf("mailbox file count quota exceeded\n"); - yield = DEFER; - errno = ERRNO_EXIMQUOTA; - filecount_msg = US" filecount"; + + if (!ob->quota_no_check) + { + DEBUG(D_transport) debug_printf("mailbox quota exceeded\n"); + yield = DEFER; + errno = ERRNO_EXIMQUOTA; + } + else DEBUG(D_transport) debug_printf("mailbox quota exceeded but ignored\n"); + } + + if (ob->quota_filecount_value > 0 + && mailbox_filecount + (ob->quota_is_inclusive ? 1:0) > + ob->quota_filecount_value) + if(!ob->quota_filecount_no_check) + { + DEBUG(D_transport) debug_printf("mailbox file count quota exceeded\n"); + yield = DEFER; + errno = ERRNO_EXIMQUOTA; + filecount_msg = US" filecount"; + } + else DEBUG(D_transport) if (ob->quota_filecount_no_check) + debug_printf("mailbox file count quota exceeded but ignored\n"); + } /* If we are writing in MBX format, what we actually do is to write the message diff --git a/src/src/transports/appendfile.h b/src/src/transports/appendfile.h index 52dc3baca..70330857d 100644 --- a/src/src/transports/appendfile.h +++ b/src/src/transports/appendfile.h @@ -70,6 +70,8 @@ typedef struct { BOOL mbx_format; BOOL quota_warn_threshold_is_percent; BOOL quota_is_inclusive; + BOOL quota_no_check; + BOOL quota_filecount_no_check; } appendfile_transport_options_block; /* Restricted creation options */ diff --git a/test/confs/5010 b/test/confs/5010 new file mode 100644 index 000000000..927f4a442 --- /dev/null +++ b/test/confs/5010 @@ -0,0 +1,35 @@ +# Exim test configuration 5010 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +qualify_domain = test.ex + + +# ----- Routers ----- + +begin routers + +all: + driver = accept + retry_use_local_part + transport = local_delivery + + +# ----- Transports ----- + +begin transports + +local_delivery: + driver = appendfile + directory = DIR/test-mail + maildir_format + quota = 30/no_check + quota_filecount = 1 + user = CALLER + maildir_use_size_file + +# End diff --git a/test/confs/5011 b/test/confs/5011 new file mode 100644 index 000000000..f1a19a85d --- /dev/null +++ b/test/confs/5011 @@ -0,0 +1,35 @@ +# Exim test configuration 5011 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +qualify_domain = test.ex + + +# ----- Routers ----- + +begin routers + +all: + driver = accept + retry_use_local_part + transport = local_delivery + + +# ----- Transports ----- + +begin transports + +local_delivery: + driver = appendfile + directory = DIR/test-mail + maildir_format + quota = 30 + quota_filecount = 1/no_check + user = CALLER + maildir_use_size_file + +# End diff --git a/test/confs/5012 b/test/confs/5012 new file mode 100644 index 000000000..f4715bfab --- /dev/null +++ b/test/confs/5012 @@ -0,0 +1,35 @@ +# Exim test configuration 5011 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +qualify_domain = test.ex + + +# ----- Routers ----- + +begin routers + +all: + driver = accept + retry_use_local_part + transport = local_delivery + + +# ----- Transports ----- + +begin transports + +local_delivery: + driver = appendfile + directory = DIR/test-mail + maildir_format + quota = 30/no_check + quota_filecount = 1/no_check + user = CALLER + maildir_use_size_file + +# End diff --git a/test/log/5010 b/test/log/5010 new file mode 100644 index 000000000..deaedc617 --- /dev/null +++ b/test/log/5010 @@ -0,0 +1,12 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 => userx R=all T=local_delivery +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 == userx@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed filecount quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmaY-0005vi-00 ** userx@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 == CALLER@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed filecount quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmaZ-0005vi-00 ** CALLER@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmaZ-0005vi-00 CALLER@test.ex: error ignored +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed diff --git a/test/log/5011 b/test/log/5011 new file mode 100644 index 000000000..e0c7efe99 --- /dev/null +++ b/test/log/5011 @@ -0,0 +1,18 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 == CALLER@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmaY-0005vi-00 ** CALLER@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmaY-0005vi-00 CALLER@test.ex: error ignored +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 == userx@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmaZ-0005vi-00 ** userx@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 == CALLER@test.ex R=all T=local_delivery defer (-22): mailbox is full (MTA-imposed quota exceeded while writing to tmp/MAILDIR.myhost.test.ex) +1999-03-02 09:44:33 10HmbA-0005vi-00 ** CALLER@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmbA-0005vi-00 CALLER@test.ex: error ignored +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed diff --git a/test/log/5012 b/test/log/5012 new file mode 100644 index 000000000..e2d436abc --- /dev/null +++ b/test/log/5012 @@ -0,0 +1,6 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 => userx R=all T=local_delivery +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 => userx R=all T=local_delivery +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed diff --git a/test/mail/5010.maildirsize b/test/mail/5010.maildirsize new file mode 100644 index 000000000..f6a87c4bb --- /dev/null +++ b/test/mail/5010.maildirsize @@ -0,0 +1,2 @@ +30S,1C +ddd d diff --git a/test/mail/5010.new/1.myhost.test.ex b/test/mail/5010.new/1.myhost.test.ex new file mode 100644 index 000000000..4b8954864 --- /dev/null +++ b/test/mail/5010.new/1.myhost.test.ex @@ -0,0 +1,17 @@ +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. diff --git a/test/mail/5011.maildirsize b/test/mail/5011.maildirsize new file mode 100644 index 000000000..f6a87c4bb --- /dev/null +++ b/test/mail/5011.maildirsize @@ -0,0 +1,2 @@ +30S,1C +ddd d diff --git a/test/mail/5012.maildirsize b/test/mail/5012.maildirsize new file mode 100644 index 000000000..69ef86707 --- /dev/null +++ b/test/mail/5012.maildirsize @@ -0,0 +1,3 @@ +30S,1C +ddd d +ddd d diff --git a/test/mail/5012.new/1.myhost.test.ex b/test/mail/5012.new/1.myhost.test.ex new file mode 100644 index 000000000..4b8954864 --- /dev/null +++ b/test/mail/5012.new/1.myhost.test.ex @@ -0,0 +1,17 @@ +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. diff --git a/test/mail/5012.new/2.myhost.test.ex b/test/mail/5012.new/2.myhost.test.ex new file mode 100644 index 000000000..ffc6a3bf8 --- /dev/null +++ b/test/mail/5012.new/2.myhost.test.ex @@ -0,0 +1,28 @@ +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaY-0005vi-00 + for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. diff --git a/test/scripts/5000-maildir/5010 b/test/scripts/5000-maildir/5010 new file mode 100644 index 000000000..9d30c01c3 --- /dev/null +++ b/test/scripts/5000-maildir/5010 @@ -0,0 +1,35 @@ +# quota and maildir with no_check_support (5010, 5011, 5012) +exim -odi userx@test.ex +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +**** +exim -odi userx@test.ex +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +This is a message of a reasonable size. Fifty here. +**** +no_msglog_check diff --git a/test/scripts/5000-maildir/5011 b/test/scripts/5000-maildir/5011 new file mode 120000 index 000000000..c95870fcb --- /dev/null +++ b/test/scripts/5000-maildir/5011 @@ -0,0 +1 @@ +5010 \ No newline at end of file diff --git a/test/scripts/5000-maildir/5012 b/test/scripts/5000-maildir/5012 new file mode 120000 index 000000000..c95870fcb --- /dev/null +++ b/test/scripts/5000-maildir/5012 @@ -0,0 +1 @@ +5010 \ No newline at end of file -- 2.30.2