ACL: Fix parsing of control=queue_only
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 4 Feb 2020 14:32:17 +0000 (14:32 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 4 Feb 2020 15:32:24 +0000 (15:32 +0000)
Broken-by: 9438970c97
doc/doc-docbook/spec.xfpt
src/src/acl.c
test/log/0505
test/rejectlog/0505

index f7002b9fe7893685b88d73e2c87edd4b4294d491..0d22aaefa3017dbb22306429003e6d5cd7afa545 100644 (file)
@@ -30151,7 +30151,7 @@ in several different ways. For example:
 It can be at the end of an &%accept%& statement:
 .code
     accept  ...some conditions
-            control = queue_only
+            control = queue
 .endd
 In this case, the control is applied when this statement yields &"accept"&, in
 other words, when the conditions are all true.
@@ -30160,7 +30160,7 @@ other words, when the conditions are all true.
 It can be in the middle of an &%accept%& statement:
 .code
     accept  ...some conditions...
-            control = queue_only
+            control = queue
             ...some more conditions...
 .endd
 If the first set of conditions are true, the control is applied, even if the
index 952195d4a294bb125045b854668502fde5fc4f8e..74ec1ef33f78f8702eed3f1bdc0348bef22ca8e2 100644 (file)
@@ -112,7 +112,8 @@ enum { ACLC_ACL,
 /* ACL conditions/modifiers: "delay", "control", "continue", "endpass",
 "message", "log_message", "log_reject_target", "logwrite", "queue" and "set" are
 modifiers that look like conditions but always return TRUE. They are used for
-their side effects. */
+their side effects.  Do not invent new modifier names that result in one name
+being the prefix of another; the binary-search in the list will go wrong. */
 
 typedef struct condition_def {
   uschar       *name;
@@ -367,7 +368,6 @@ enum {
   CONTROL_NO_PIPELINING,
 
   CONTROL_QUEUE,
-  CONTROL_QUEUE_ONLY,
   CONTROL_SUBMISSION,
   CONTROL_SUPPRESS_LOCAL_FIXUPS,
 #ifdef SUPPORT_I18N
@@ -511,15 +511,6 @@ static control_def controls_list[] = {
            // ACL_BIT_PRDR|    /* Not allow one user to freeze for all */
            ACL_BIT_NOTSMTP | ACL_BIT_MIME)
   },
-[CONTROL_QUEUE_ONLY] =
-  { US"queue_only",            TRUE,
-         (unsigned)
-         ~(ACL_BIT_MAIL | ACL_BIT_RCPT |
-           ACL_BIT_PREDATA | ACL_BIT_DATA |
-           // ACL_BIT_PRDR|    /* Not allow one user to freeze for all */
-           ACL_BIT_NOTSMTP | ACL_BIT_MIME)
-  },
-
 
 [CONTROL_SUBMISSION] =
   { US"submission",              TRUE,
@@ -2122,7 +2113,9 @@ return ERROR;
 *        Check argument for control= modifier    *
 *************************************************/
 
-/* Called from acl_check_condition() below
+/* Called from acl_check_condition() below.
+To handle the case "queue_only" we accept an _ in the
+initial / option-switch position.
 
 Arguments:
   arg         the argument string for control=
@@ -2138,10 +2131,11 @@ decode_control(const uschar *arg, const uschar **pptr, int where, uschar **log_m
 {
 int idx, len;
 control_def * d;
+uschar c;
 
 if (  (idx = find_control(arg, controls_list, nelem(controls_list))) < 0
-   || (  arg[len = Ustrlen((d = controls_list+idx)->name)] != 0
-      && (!d->has_option || arg[len] != '/')
+   || (  (c = arg[len = Ustrlen((d = controls_list+idx)->name)]) != 0
+      && (!d->has_option || c != '/' && c != '_')
    )  )
   {
   *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
@@ -3168,15 +3162,17 @@ for (; cb; cb = cb->next)
          break;
 
        case CONTROL_QUEUE:
-       case CONTROL_QUEUE_ONLY:
          f.queue_only_policy = TRUE;
+         if (Ustrcmp(p, "_only") == 0)
+           p += 5;
+         else while (*p == '/')
+           if (Ustrncmp(p, "/only", 5) == 0)
+             { p += 5; f.queue_smtp = FALSE; }
+           else if (Ustrncmp(p, "/first_pass_route", 17) == 0)
+             { p += 17; f.queue_smtp = TRUE; }
+           else
+             break;
          cancel_cutthrough_connection(TRUE, US"queueing forced");
-         while (*p == '/')
-           if (Ustrncmp(p, "/first_pass_route", 17) == 0)
-             {
-             p += 17;
-             f.queue_smtp = TRUE;
-             }
          break;
 
        case CONTROL_SUBMISSION:
index 1141546ad98ca771494900f4bebee79ada0fef85..45fb63f0524874a3f90b64d4426bbb4aceeb7066 100644 (file)
@@ -3,4 +3,4 @@
 1999-03-02 09:44:33 U=CALLER temporarily rejected EHLO or HELO xxx: cannot use "control=submission" in EHLO or HELO ACL
 1999-03-02 09:44:33 ACL for QUIT returned ERROR: cannot use "control=freeze" in QUIT ACL
 1999-03-02 09:44:33 10HmaY-0005vi-00 F=<CALLER@myhost.test.ex> rejected by non-SMTP ACL: cannot use "control=enforce_sync" in non-SMTP ACL
-1999-03-02 09:44:33 U=CALLER temporarily rejected connection in "connect" ACL: cannot use "control=queue_only" in connection ACL
+1999-03-02 09:44:33 U=CALLER temporarily rejected connection in "connect" ACL: cannot use "control=queue" in connection ACL
index 2c56b7f1ea6d0c87ab33ffe6bd6ede8b046c7408..41fd97e5b702ef3518f271016972baa672a461f4 100644 (file)
@@ -19,4 +19,4 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
 I Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
 F From: CALLER_NAME <CALLER@myhost.test.ex>
   Date: Tue, 2 Mar 1999 09:44:33 +0000
-1999-03-02 09:44:33 U=CALLER temporarily rejected connection in "connect" ACL: cannot use "control=queue_only" in connection ACL
+1999-03-02 09:44:33 U=CALLER temporarily rejected connection in "connect" ACL: cannot use "control=queue" in connection ACL