X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/5bb786d5ad568a88d50d15452aacc8404047e5ca..f2738aab2d72569b6d47b788099f6ebab701b2b2:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index ae7045068..a56ff473e 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -290,12 +290,11 @@ Returns: FALSE if there isn't enough space, or if the information cannot BOOL receive_check_fs(int msg_size) { -int_eximarith_t space; int inodes; if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0) { - space = receive_statvfs(TRUE, &inodes); + int_eximarith_t space = receive_statvfs(TRUE, &inodes); DEBUG(D_receive) debug_printf("spool directory space = " PR_EXIM_ARITH "K inodes = %d " @@ -313,7 +312,7 @@ if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0) if (check_log_space > 0 || check_log_inodes > 0) { - space = receive_statvfs(FALSE, &inodes); + int_eximarith_t space = receive_statvfs(FALSE, &inodes); DEBUG(D_receive) debug_printf("log directory space = " PR_EXIM_ARITH "K inodes = %d " @@ -1204,6 +1203,8 @@ static void give_local_error(int errcode, uschar *text1, uschar *text2, int error_rc, FILE *f, header_line *hptr) { +DEBUG(D_all) debug_printf("%s%s\n", text2, text1); + if (error_handling == ERRORS_SENDER) { error_block eblock; @@ -1572,6 +1573,7 @@ uschar * timestamp = expand_string(US"${tod_full}"); header_line * received_header= header_list; if (recipients_count == 1) received_for = recipients_list[0].address; +GET_OPTION("received_header_text"); received = expand_string(received_header_text); received_for = NULL; @@ -2199,8 +2201,9 @@ OVERSIZE: { if (!f.sender_address_forced) { - uschar *uucp_sender = expand_string(uucp_from_sender); - if (!uucp_sender) + uschar * uucp_sender; + GET_OPTION("uucp_from_sender"); + if (!(uucp_sender = expand_string(uucp_from_sender))) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of \"%s\" failed after matching " "\"From \" line: %s", uucp_from_sender, expand_string_message); @@ -2622,12 +2625,12 @@ if (extract_recip) if ((h->type == htype_to || h->type == htype_cc || h->type == htype_bcc) && (!contains_resent_headers || strncmpic(h->text, US"resent-", 7) == 0)) { - uschar *s = Ustrchr(h->text, ':') + 1; + uschar * s = Ustrchr(h->text, ':') + 1; while (isspace(*s)) s++; f.parse_allow_group = TRUE; /* Allow address group syntax */ - while (*s != 0) + while (*s) { uschar *ss = parse_find_address_end(s, FALSE); uschar *recipient, *errmess, *pp; @@ -2635,7 +2638,7 @@ if (extract_recip) /* Check on maximum */ - if (recipients_max > 0 && ++rcount > recipients_max) + if (recipients_max_expanded > 0 && ++rcount > recipients_max_expanded) give_local_error(ERRMESS_TOOMANYRECIP, US"too many recipients", US"message rejected: ", error_rc, stdin, NULL); /* Does not return */ @@ -2819,6 +2822,7 @@ if ( !msgid_header /* Permit only letters, digits, dots, and hyphens in the domain */ + GET_OPTION("message_id_header_domain"); if (message_id_domain) { uschar *new_id_domain = expand_string(message_id_domain); @@ -2840,6 +2844,7 @@ if ( !msgid_header /* Permit all characters except controls and RFC 2822 specials in the additional text part. */ + GET_OPTION("message_id_header_text"); if (message_id_text) { uschar *new_id_text = expand_string(message_id_text); @@ -3069,7 +3074,7 @@ if ( from_header it has already been rewritten as part of verification for SMTP input. */ DEBUG(D_rewrite) - { debug_printf("global rewrite rules\n"); acl_level++; } + { debug_printf("rewrite rules on sender address\n"); acl_level++; } if (global_rewrite_rules && !sender_address_unrewritten && *sender_address) { /* deconst ok as src was not const */ @@ -3096,7 +3101,7 @@ documented as happening *after* recipient addresses are taken from the headers by the -t command line option. An added Sender: gets rewritten here. */ DEBUG(D_rewrite) - { debug_printf("rewrite headers\n"); acl_level++; } + { debug_printf("qualify and rewrite headers\n"); acl_level++; } for (header_line * h = header_list->next, * newh; h; h = h->next) if ((newh = rewrite_header(h, NULL, NULL, global_rewrite_rules, rewrite_existflags, TRUE))) @@ -3135,9 +3140,11 @@ new Received:) has not yet been set. */ DEBUG(D_receive) { debug_printf(">>Headers after rewriting and local additions:\n"); + acl_level++; for (header_line * h = header_list->next; h; h = h->next) - debug_printf("%c %s", h->type, h->text); + debug_printf_indent("%c %s", h->type, h->text); debug_printf("\n"); + acl_level--; } /* The headers are now complete in store. If we are running in filter @@ -3513,6 +3520,7 @@ else dkim_exim_verify_finish(); /* Check if we must run the DKIM ACL */ + GET_OPTION("acl_smtp_dkim"); if (acl_smtp_dkim && dkim_verify_signers && *dkim_verify_signers) { uschar * dkim_verify_signers_expanded = @@ -3602,11 +3610,14 @@ else #endif /* DISABLE_DKIM */ #ifdef WITH_CONTENT_SCAN - if ( recipients_count > 0 - && acl_smtp_mime - && !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by) - ) - goto TIDYUP; + if (recipients_count > 0) + { + GET_OPTION("acl_smtp_mime"); + if (acl_smtp_mime + && !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by) + ) + goto TIDYUP; + } #endif /* WITH_CONTENT_SCAN */ #ifdef SUPPORT_DMARC @@ -3614,67 +3625,73 @@ else #endif #ifndef DISABLE_PRDR - if (prdr_requested && recipients_count > 1 && acl_smtp_data_prdr) + if (prdr_requested && recipients_count > 1) { - int all_pass = OK; - int all_fail = FAIL; + GET_OPTION("acl_smtp_data_prdr"); + if (acl_smtp_data_prdr) + { + int all_pass = OK; + int all_fail = FAIL; - smtp_printf("353 PRDR content analysis beginning\r\n", SP_MORE); - /* Loop through recipients, responses must be in same order received */ - for (unsigned int c = 0; recipients_count > c; c++) - { - const uschar * addr = recipients_list[c].address; - uschar * msg= US"PRDR R=<%s> %s"; - uschar * code; - DEBUG(D_receive) - debug_printf("PRDR processing recipient %s (%d of %d)\n", - addr, c+1, recipients_count); - rc = acl_check(ACL_WHERE_PRDR, addr, - acl_smtp_data_prdr, &user_msg, &log_msg); - - /* If any recipient rejected content, indicate it in final message */ - all_pass |= rc; - /* If all recipients rejected, indicate in final message */ - all_fail &= rc; - - switch (rc) - { - case OK: case DISCARD: code = US"250"; break; - case DEFER: code = US"450"; break; - default: code = US"550"; break; - } - if (user_msg != NULL) - smtp_user_msg(code, user_msg); - else + smtp_printf("353 PRDR content analysis beginning\r\n", SP_MORE); + /* Loop through recipients, responses must be in same order received */ + for (unsigned int c = 0; recipients_count > c; c++) { + const uschar * addr = recipients_list[c].address; + uschar * msg= US"PRDR R=<%s> %s"; + uschar * code; + DEBUG(D_receive) + debug_printf("PRDR processing recipient %s (%d of %d)\n", + addr, c+1, recipients_count); + rc = acl_check(ACL_WHERE_PRDR, addr, + acl_smtp_data_prdr, &user_msg, &log_msg); + + /* If any recipient rejected content, indicate it in final message */ + all_pass |= rc; + /* If all recipients rejected, indicate in final message */ + all_fail &= rc; + switch (rc) - { - case OK: case DISCARD: - msg = string_sprintf(CS msg, addr, "acceptance"); break; - case DEFER: - msg = string_sprintf(CS msg, addr, "temporary refusal"); break; - default: - msg = string_sprintf(CS msg, addr, "refusal"); break; - } - smtp_user_msg(code, msg); - } - if (log_msg) log_write(0, LOG_MAIN, "PRDR %s %s", addr, log_msg); - else if (user_msg) log_write(0, LOG_MAIN, "PRDR %s %s", addr, user_msg); - else log_write(0, LOG_MAIN, "%s", CS msg); + { + case OK: case DISCARD: code = US"250"; break; + case DEFER: code = US"450"; break; + default: code = US"550"; break; + } + if (user_msg != NULL) + smtp_user_msg(code, user_msg); + else + { + switch (rc) + { + case OK: case DISCARD: + msg = string_sprintf(CS msg, addr, "acceptance"); break; + case DEFER: + msg = string_sprintf(CS msg, addr, "temporary refusal"); break; + default: + msg = string_sprintf(CS msg, addr, "refusal"); break; + } + smtp_user_msg(code, msg); + } + if (log_msg) log_write(0, LOG_MAIN, "PRDR %s %s", addr, log_msg); + else if (user_msg) log_write(0, LOG_MAIN, "PRDR %s %s", addr, user_msg); + else log_write(0, LOG_MAIN, "%s", CS msg); - if (rc != OK) { receive_remove_recipient(addr); c--; } - } - /* Set up final message, used if data acl gives OK */ - smtp_reply = string_sprintf("%s id=%s message %s", - all_fail == FAIL ? US"550" : US"250", - message_id, - all_fail == FAIL - ? US"rejected for all recipients" - : all_pass == OK - ? US"accepted" - : US"accepted for some recipients"); - if (recipients_count == 0) - goto NOT_ACCEPTED; + if (rc != OK) { receive_remove_recipient(addr); c--; } + } + /* Set up final message, used if data acl gives OK */ + smtp_reply = string_sprintf("%s id=%s message %s", + all_fail == FAIL ? US"550" : US"250", + message_id, + all_fail == FAIL + ? US"rejected for all recipients" + : all_pass == OK + ? US"accepted" + : US"accepted for some recipients"); + if (recipients_count == 0) + goto NOT_ACCEPTED; + } + else + prdr_requested = FALSE; } else prdr_requested = FALSE; @@ -3683,6 +3700,7 @@ else /* Check the recipients count again, as the MIME ACL might have changed them. */ + GET_OPTION("acl_smtp_data"); if (acl_smtp_data && recipients_count > 0) { rc = acl_check(ACL_WHERE_DATA, NULL, acl_smtp_data, &user_msg, &log_msg); @@ -3720,6 +3738,7 @@ else { #ifdef WITH_CONTENT_SCAN + GET_OPTION("acl_not_smtp_mime"); if ( acl_not_smtp_mime && !run_mime_acl(acl_not_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by) @@ -3727,9 +3746,10 @@ else goto TIDYUP; #endif /* WITH_CONTENT_SCAN */ + GET_OPTION("acl_not_smtp"); if (acl_not_smtp) { - uschar *user_msg, *log_msg; + uschar * user_msg, * log_msg; f.authentication_local = TRUE; rc = acl_check(ACL_WHERE_NOTSMTP, NULL, acl_not_smtp, &user_msg, &log_msg); if (rc == DISCARD) @@ -4052,7 +4072,15 @@ else receive_messagecount++; -if (fflush(spool_data_file)) +if ( fflush(spool_data_file) +#if _POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE >= 500 +# ifdef ENABLE_DISABLE_FSYNC + || !disable_fsync && fdatasync(data_fd) +# else + || fdatasync(data_fd) +# endif +#endif + ) { errmsg = string_sprintf("Spool write error: %s", strerror(errno)); log_write(0, LOG_MAIN, "%s\n", errmsg);