X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsrc%2Facl.c;h=78b30addc04c8c060747eec9dbca8bb2daa27163;hb=e28326d8a5aad335b724b9ff1e5222c914e56143;hp=5709a11aba41dfca9e3cf09c0b204da510810257;hpb=641cb756c2435863f776dfdee060338d482219c2;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/acl.c b/src/src/acl.c index 5709a11ab..78b30addc 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.65 2006/09/19 14:31:06 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.73 2007/02/07 11:24:56 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) 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; @@ -2684,13 +2740,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); } } @@ -2844,6 +2905,29 @@ for (; cb != NULL; cb = cb->next) &deliver_localpart_data); break; + case ACLC_LOG_REJECT_TARGET: + { + int logbits = 0; + int sep = 0; + uschar *s = arg; + uschar *ss; + while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)) + != NULL) + { + if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN; + else if (Ustrcmp(ss, "panic") == 0) logbits |= LOG_PANIC; + else if (Ustrcmp(ss, "reject") == 0) logbits |= LOG_REJECT; + else + { + logbits |= LOG_MAIN|LOG_REJECT; + log_write(0, LOG_MAIN|LOG_PANIC, "unknown log name \"%s\" in " + "\"log_reject_target\" in %s ACL", ss, acl_wherenames[where]); + } + } + log_reject_target = logbits; + } + break; + case ACLC_LOGWRITE: { int logbits = 0; @@ -2870,6 +2954,8 @@ for (; cb != NULL; cb = cb->next) s++; } while (isspace(*s)) s++; + + if (logbits == 0) logbits = LOG_MAIN; log_write(0, logbits, "%s", string_printing(s)); } @@ -2878,7 +2964,7 @@ for (; cb != NULL; cb = cb->next) #ifdef WITH_CONTENT_SCAN case ACLC_MALWARE: { - /* Seperate the regular expression and any optional parameters. */ + /* Separate the regular expression and any optional parameters. */ uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size); /* Run the malware backend. */ rc = malware(&ss); @@ -2997,13 +3083,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. @@ -3011,23 +3092,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; - - 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++; - } - } +/* Before giving a response, take a look at the length of any user message, and +split it up into multiple lines if possible. */ - 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; }