From cfe6f17c3c1f76ce403195dbae8ac4141f527ba7 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 4 Feb 2020 14:32:17 +0000 Subject: [PATCH] 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 f7002b9fe..0d22aaefa 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 952195d4a..74ec1ef33 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 1141546ad..45fb63f05 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= 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 2c56b7f1e..41fd97e5b 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: F From: CALLER_NAME 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 -- 2.25.1