Add quota/quota_filecount transport option modifier "no_check" Bug 1115
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sun, 25 Jun 2017 20:54:08 +0000 (22:54 +0200)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sun, 25 Jun 2017 21:00:18 +0000 (23:00 +0200)
This option modifier allows to ignore the quota limits, but update
the maildirsize file.

19 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/transports/appendfile.c
src/src/transports/appendfile.h
test/confs/5010 [new file with mode: 0644]
test/confs/5011 [new file with mode: 0644]
test/confs/5012 [new file with mode: 0644]
test/log/5010 [new file with mode: 0644]
test/log/5011 [new file with mode: 0644]
test/log/5012 [new file with mode: 0644]
test/mail/5010.maildirsize [new file with mode: 0644]
test/mail/5010.new/1.myhost.test.ex [new file with mode: 0644]
test/mail/5011.maildirsize [new file with mode: 0644]
test/mail/5012.maildirsize [new file with mode: 0644]
test/mail/5012.new/1.myhost.test.ex [new file with mode: 0644]
test/mail/5012.new/2.myhost.test.ex [new file with mode: 0644]
test/scripts/5000-maildir/5010 [new file with mode: 0644]
test/scripts/5000-maildir/5011 [new symlink]
test/scripts/5000-maildir/5012 [new symlink]

index 7816bc2..4a239b7 100644 (file)
@@ -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.
index 5fd7fbb..d0d5cf2 100644 (file)
@@ -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
 ------------
index da5d8aa..5620071 100644 (file)
@@ -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
index 52dc3ba..7033085 100644 (file)
@@ -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 (file)
index 0000000..927f4a4
--- /dev/null
@@ -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 (file)
index 0000000..f1a19a8
--- /dev/null
@@ -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 (file)
index 0000000..f4715bf
--- /dev/null
@@ -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 (file)
index 0000000..deaedc6
--- /dev/null
@@ -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 <userx@test.ex> 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 (file)
index 0000000..e0c7efe
--- /dev/null
@@ -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 (file)
index 0000000..e2d436a
--- /dev/null
@@ -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 <userx@test.ex> 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 <userx@test.ex> 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 (file)
index 0000000..f6a87c4
--- /dev/null
@@ -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 (file)
index 0000000..4b89548
--- /dev/null
@@ -0,0 +1,17 @@
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@test.ex>)
+       id 10HmaX-0005vi-00
+       for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@test.ex>
+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 (file)
index 0000000..f6a87c4
--- /dev/null
@@ -0,0 +1,2 @@
+30S,1C
+ddd d
diff --git a/test/mail/5012.maildirsize b/test/mail/5012.maildirsize
new file mode 100644 (file)
index 0000000..69ef867
--- /dev/null
@@ -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 (file)
index 0000000..4b89548
--- /dev/null
@@ -0,0 +1,17 @@
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@test.ex>)
+       id 10HmaX-0005vi-00
+       for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@test.ex>
+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 (file)
index 0000000..ffc6a3b
--- /dev/null
@@ -0,0 +1,28 @@
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@test.ex>)
+       id 10HmaY-0005vi-00
+       for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@test.ex>
+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 (file)
index 0000000..9d30c01
--- /dev/null
@@ -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 (symlink)
index 0000000..c95870f
--- /dev/null
@@ -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 (symlink)
index 0000000..c95870f
--- /dev/null
@@ -0,0 +1 @@
+5010
\ No newline at end of file