X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/6ea85e9a4ac76f292db7bb946d6ada8d3ac93a2d..aa6dc51334206deff2ec80bfcbcf543714efe6d6:/src/src/acl.c diff --git a/src/src/acl.c b/src/src/acl.c index 8274e0c73..277ea8d4f 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.66 2006/09/25 10:14:20 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.76 2007/06/19 13:32:06 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2006 */ +/* Copyright (c) University of Cambridge 1995 - 2007 */ /* See the file NOTICE for conditions of use and distribution. */ /* Code for handling Access Control Lists (ACLs) */ @@ -27,9 +27,20 @@ static uschar *verbs[] = { US"accept", US"defer", US"deny", US"discard", US"drop", US"require", US"warn" }; -/* For each verb, the condition for which "message" is used */ - -static int msgcond[] = { FAIL, OK, OK, FAIL, OK, FAIL, OK }; +/* For each verb, the conditions for which "message" or "log_message" are used +are held as a bitmap. This is to avoid expanding the strings unnecessarily. For +"accept", the FAIL case is used only after "endpass", but that is selected in +the code. */ + +static int msgcond[] = { + (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); @@ -2582,6 +2625,18 @@ for (; cb != NULL; cb = cb->next) no_multiline_responses = TRUE; break; + case CONTROL_NO_PIPELINING: + 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; @@ -2697,13 +2752,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); } } @@ -3035,13 +3095,8 @@ for (; cb != NULL; cb = cb->next) /* If the result is the one for which "message" and/or "log_message" are used, -handle the values of these options. Most verbs have but a single return for -which the messages are relevant, but for "discard", it's useful to have the log -message both when it succeeds and when it fails. Also, for an "accept" that -appears in a QUIT ACL, we want to handle the user message. Since only "accept" -and "warn" are permitted in that ACL, we don't need to test the verb. - -These modifiers act in different ways: +handle the values of these modifiers. If there isn't a log message set, we make +it the same as the user message. "message" is a user message that will be included in an SMTP response. Unless it is empty, it overrides any previously set user message. @@ -3049,23 +3104,29 @@ it is empty, it overrides any previously set user message. "log_message" is a non-user message, and it adds to any existing non-user message that is already set. -If there isn't a log message set, we make it the same as the user message. */ +Most verbs have but a single return for which the messages are relevant, but +for "discard", it's useful to have the log message both when it succeeds and +when it fails. For "accept", the message is used in the OK case if there is no +"endpass", but (for backwards compatibility) in the FAIL case if "endpass" is +present. */ + +if (*epp && rc == OK) user_message = NULL; -if (((rc == FAIL_DROP)? FAIL : rc) == msgcond[verb] || - (verb == ACL_DISCARD && rc == OK) || - (where == ACL_WHERE_QUIT)) +if (((1< 75) - { - uschar *s = *user_msgptr = string_copy(*user_msgptr); - uschar *ss = s; +/* Before giving a response, take a look at the length of any user message, and +split it up into multiple lines if possible. */ - 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; }