X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/cf8b11a5399e64e50b6cd58f56a98197aca599d8..c361138493e8f0f5d6f7d66d362737d92dba1269:/src/src/acl.c diff --git a/src/src/acl.c b/src/src/acl.c index 3e06cdf30..afbb93e5c 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.69 2007/01/30 11:45:20 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.74 2007/02/14 15:33:40 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -53,6 +53,7 @@ enum { ACLC_ACL, ACLC_BMI_OPTIN, #endif ACLC_CONDITION, + ACLC_CONTINUE, ACLC_CONTROL, #ifdef WITH_CONTENT_SCAN ACLC_DECODE, @@ -101,10 +102,10 @@ enum { ACLC_ACL, #endif ACLC_VERIFY }; -/* ACL conditions/modifiers: "delay", "control", "endpass", "message", -"log_message", "log_reject_target", "logwrite", and "set" are modifiers that -look like conditions but always return TRUE. They are used for their side -effects. */ +/* ACL conditions/modifiers: "delay", "control", "continue", "endpass", +"message", "log_message", "log_reject_target", "logwrite", and "set" are +modifiers that look like conditions but always return TRUE. They are used for +their side effects. */ static uschar *conditions[] = { US"acl", @@ -114,6 +115,7 @@ static uschar *conditions[] = { US"bmi_optin", #endif US"condition", + US"continue", US"control", #ifdef WITH_CONTENT_SCAN US"decode", @@ -187,7 +189,9 @@ enum { CONTROL_FAKEDEFER, CONTROL_FAKEREJECT, CONTROL_NO_MULTILINE, - CONTROL_NO_PIPELINING + CONTROL_NO_PIPELINING, + CONTROL_NO_DELAY_FLUSH, + CONTROL_NO_CALLOUT_FLUSH }; /* ACL control names; keep in step with the table above! This list is used for @@ -219,9 +223,11 @@ static uschar *controls[] = { US"fakereject", US"no_multiline", US"no_pipelining", + US"no_delay_flush", + US"no_callout_flush" }; -/* Flags to indicate for which conditions /modifiers a string expansion is done +/* Flags to indicate for which conditions/modifiers a string expansion is done at the outer level. In the other cases, expansion already occurs in the checking functions. */ @@ -233,6 +239,7 @@ static uschar cond_expand_at_top[] = { TRUE, /* bmi_optin */ #endif TRUE, /* condition */ + TRUE, /* continue */ TRUE, /* control */ #ifdef WITH_CONTENT_SCAN TRUE, /* decode */ @@ -292,6 +299,7 @@ static uschar cond_modifiers[] = { TRUE, /* bmi_optin */ #endif FALSE, /* condition */ + TRUE, /* continue */ TRUE, /* control */ #ifdef WITH_CONTENT_SCAN FALSE, /* decode */ @@ -341,9 +349,9 @@ static uschar cond_modifiers[] = { FALSE /* verify */ }; -/* Bit map vector of which conditions are not allowed at certain times. For -each condition, there's a bitmap of dis-allowed times. For some, it is easier -to specify the negation of a small number of allowed times. */ +/* Bit map vector of which conditions and modifiers are not allowed at certain +times. For each condition, there's a bitmap of dis-allowed times. For some, it +is easier to specify the negation of a small number of allowed times. */ static unsigned int cond_forbids[] = { 0, /* acl */ @@ -371,6 +379,8 @@ static unsigned int cond_forbids[] = { 0, /* condition */ + 0, /* continue */ + /* Certain types of control are always allowed, so we let it through always and check in the control processing itself. */ @@ -593,6 +603,12 @@ static unsigned int control_forbids[] = { (1<next) *log_msgptr = string_sprintf("invalid \"condition\" value \"%s\"", arg); break; + case ACLC_CONTINUE: /* Always succeeds */ + break; + case ACLC_CONTROL: control_type = decode_control(arg, &p, where, log_msgptr); @@ -2605,6 +2626,14 @@ for (; cb != NULL; cb = cb->next) pipelining_enable = FALSE; break; + case CONTROL_NO_DELAY_FLUSH: + disable_delay_flush = TRUE; + break; + + case CONTROL_NO_CALLOUT_FLUSH: + disable_callout_flush = TRUE; + break; + case CONTROL_FAKEDEFER: case CONTROL_FAKEREJECT: fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL; @@ -2720,13 +2749,18 @@ for (; cb != NULL; cb = cb->next) can't. The poll() function does not do the right thing, and in any case it is not always available. - NOTE: If ever this state of affairs changes, remember that we may be + NOTE 1: If ever this state of affairs changes, remember that we may be dealing with stdin/stdout here, in addition to TCP/IP connections. - Whatever is done must work in both cases. To detected the stdin/stdout - case, check for smtp_in or smtp_out being NULL. */ + Also, delays may be specified for non-SMTP input, where smtp_out and + smtp_in will be NULL. Whatever is done must work in all cases. + + NOTE 2: The added feature of flushing the output before a delay must + apply only to SMTP input. Hence the test for smtp_out being non-NULL. + */ else { + if (smtp_out != NULL && !disable_delay_flush) mac_smtp_fflush(); while (delay > 0) delay = sleep(delay); } } @@ -3622,48 +3656,9 @@ if (rc == FAIL_DROP && where == ACL_WHERE_MAILAUTH) /* Before giving a response, take a look at the length of any user message, and split it up into multiple lines if possible. */ -if (*user_msgptr != NULL && Ustrlen(*user_msgptr) > 75) - { - uschar *s = *user_msgptr = string_copy(*user_msgptr); - uschar *ss = s; - - for (;;) - { - int i = 0; - while (i < 75 && *ss != 0 && *ss != '\n') ss++, i++; - if (*ss == 0) break; - if (*ss == '\n') - s = ++ss; - else - { - uschar *t = ss + 1; - uschar *tt = NULL; - while (--t > s + 35) - { - if (*t == ' ') - { - if (t[-1] == ':') { tt = t; break; } - if (tt == NULL) tt = t; - } - } - - if (tt == NULL) /* Can't split behind - try ahead */ - { - t = ss + 1; - while (*t != 0) - { - if (*t == ' ' || *t == '\n') - { tt = t; break; } - t++; - } - } - - if (tt == NULL) break; /* Can't find anywhere to split */ - *tt = '\n'; - s = ss = tt+1; - } - } - } +*user_msgptr = string_split_message(*user_msgptr); +if (fake_response != OK) + fake_response_text = string_split_message(fake_response_text); return rc; }