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
 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.
 .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...
 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
             ...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
 /* 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;
 
 typedef struct condition_def {
   uschar       *name;
@@ -367,7 +368,6 @@ enum {
   CONTROL_NO_PIPELINING,
 
   CONTROL_QUEUE,
   CONTROL_NO_PIPELINING,
 
   CONTROL_QUEUE,
-  CONTROL_QUEUE_ONLY,
   CONTROL_SUBMISSION,
   CONTROL_SUPPRESS_LOCAL_FIXUPS,
 #ifdef SUPPORT_I18N
   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)
   },
            // 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,
 
 [CONTROL_SUBMISSION] =
   { US"submission",              TRUE,
@@ -2122,7 +2113,9 @@ return ERROR;
 *        Check argument for control= modifier    *
 *************************************************/
 
 *        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=
 
 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;
 {
 int idx, len;
 control_def * d;
+uschar c;
 
 if (  (idx = find_control(arg, controls_list, nelem(controls_list))) < 0
 
 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);
    )  )
   {
   *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
@@ -3168,15 +3162,17 @@ for (; cb; cb = cb->next)
          break;
 
        case CONTROL_QUEUE:
          break;
 
        case CONTROL_QUEUE:
-       case CONTROL_QUEUE_ONLY:
          f.queue_only_policy = TRUE;
          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");
          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:
          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 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
 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