[exim-cvs] ACL: Fix parsing of control=queue_only

トップ ページ
このメッセージを削除
このメッセージに返信
著者: Exim Git Commits Mailing List
日付:  
To: exim-cvs
題目: [exim-cvs] ACL: Fix parsing of control=queue_only
Gitweb: https://git.exim.org/exim.git/commitdiff/cfe6f17c3c1f76ce403195dbae8ac4141f527ba7
Commit:     cfe6f17c3c1f76ce403195dbae8ac4141f527ba7
Parent:     6b3e96244682c63893ff3884b06bff68104ce2c8
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Tue Feb 4 14:32:17 2020 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Feb 4 15:32:24 2020 +0000


    ACL: Fix parsing of control=queue_only


    Broken-by: 9438970c97
---
 doc/doc-docbook/spec.xfpt |  4 ++--
 src/src/acl.c             | 38 +++++++++++++++++---------------------
 test/log/0505             |  2 +-
 test/rejectlog/0505       |  2 +-
 4 files changed, 21 insertions(+), 25 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index f7002b9..0d22aae 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -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
diff --git a/src/src/acl.c b/src/src/acl.c
index 952195d..74ec1ef 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -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:
diff --git a/test/log/0505 b/test/log/0505
index 1141546..45fb63f 100644
--- a/test/log/0505
+++ b/test/log/0505
@@ -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@???> 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
diff --git a/test/rejectlog/0505 b/test/rejectlog/0505
index 2c56b7f..41fd97e 100644
--- a/test/rejectlog/0505
+++ b/test/rejectlog/0505
@@ -19,4 +19,4 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
 I Message-Id: <E10HmaY-0005vi-00@???>
 F From: CALLER_NAME <CALLER@???>
   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