X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/acec9514b1006e352ef283f205ecec75a9b6ff0d..4e6ae6235c68de243b1c2419027472d7659aa2b4:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index 2d9aacd31..d9b500102 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -190,7 +190,7 @@ if (STATVFS(CS path, &statbuf) != 0) log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat " "%s directory %s: %s", name, path, strerror(errno)); smtp_closedown(US"spool or log directory problem"); - exim_exit(EXIT_FAILURE); + exim_exit(EXIT_FAILURE, NULL); } *inodeptr = (statbuf.F_FILES > 0)? statbuf.F_FAVAIL : -1; @@ -343,7 +343,7 @@ if (!already_bombing_out) /* Exit from the program (non-BSMTP cases) */ -exim_exit(EXIT_FAILURE); +exim_exit(EXIT_FAILURE, NULL); } @@ -1142,7 +1142,7 @@ if (error_handling == ERRORS_SENDER) else fprintf(stderr, "exim: %s%s\n", text2, text1); /* Sic */ (void)fclose(f); -exim_exit(error_rc); +exim_exit(error_rc, US""); } @@ -1810,8 +1810,8 @@ for (;;) (and sometimes lunatic messages can have ones that are 100s of K long) we call store_release() for strings that have been copied - if the string is at the start of a block (and therefore the only thing in it, because we aren't - doing any other gets), the block gets freed. We can only do this because we - know there are no other calls to store_get() going on. */ + doing any other gets), the block gets freed. We can only do this release if + there were no allocations since the once that we want to free. */ if (ptr >= header_size - 4) { @@ -1820,9 +1820,10 @@ for (;;) header_size *= 2; if (!store_extend(next->text, oldsize, header_size)) { + BOOL release_ok = store_last_get[store_pool] == next->text; uschar *newtext = store_get(header_size); memcpy(newtext, next->text, ptr); - store_release(next->text); + if (release_ok) store_release(next->text); next->text = newtext; } } @@ -3324,7 +3325,7 @@ if (extract_recip && (bad_addresses != NULL || recipients_count == 0)) { Uunlink(spool_name); (void)fclose(data_file); - exim_exit(error_rc); + exim_exit(error_rc, US"receiving"); } } @@ -3388,99 +3389,96 @@ else #ifndef DISABLE_DKIM if (!dkim_disable_verify) { - /* Finish verification, this will log individual signature results to - the mainlog */ + /* Finish verification */ dkim_exim_verify_finish(); /* Check if we must run the DKIM ACL */ if (acl_smtp_dkim && dkim_verify_signers && *dkim_verify_signers) { - uschar *dkim_verify_signers_expanded = + uschar * dkim_verify_signers_expanded = expand_string(dkim_verify_signers); - if (!dkim_verify_signers_expanded) + gstring * results = NULL; + int signer_sep = 0; + const uschar * ptr; + uschar * item; + gstring * seen_items = NULL; + int old_pool = store_pool; + + store_pool = POOL_PERM; /* Allow created variables to live to data ACL */ + + if (!(ptr = dkim_verify_signers_expanded)) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of dkim_verify_signers option failed: %s", expand_string_message); - else - { - int sep = 0; - const uschar *ptr = dkim_verify_signers_expanded; - uschar *item = NULL; - gstring * seen_items = NULL; - - /* Default to OK when no items are present */ - rc = OK; - while ((item = string_nextinlist(&ptr, &sep, NULL, 0))) - { - /* Prevent running ACL for an empty item */ - if (!item || !*item) continue; - - /* Only run ACL once for each domain or identity, - no matter how often it appears in the expanded list. */ - if (seen_items) - { - uschar *seen_item; - const uschar *seen_items_list = string_from_gstring(seen_items); - BOOL seen_this_item = FALSE; - - while ((seen_item = string_nextinlist(&seen_items_list, &sep, - NULL, 0))) - if (Ustrcmp(seen_item,item) == 0) - { - seen_this_item = TRUE; - break; - } - - if (seen_this_item) - { - DEBUG(D_receive) - debug_printf("acl_smtp_dkim: skipping signer %s, " - "already seen\n", item); - continue; - } - - seen_items = string_cat(seen_items, ":"); - } - - seen_items = string_cat(seen_items, item); - - DEBUG(D_receive) - debug_printf("calling acl_smtp_dkim for dkim_cur_signer=%s\n", - item); - - dkim_exim_acl_setup(item); - rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, - &user_msg, &log_msg); - - if (rc != OK) + /* Default to OK when no items are present */ + rc = OK; + while ((item = string_nextinlist(&ptr, &signer_sep, NULL, 0))) + { + /* Prevent running ACL for an empty item */ + if (!item || !*item) continue; + + /* Only run ACL once for each domain or identity, + no matter how often it appears in the expanded list. */ + if (seen_items) + { + uschar * seen_item; + const uschar * seen_items_list = string_from_gstring(seen_items); + int seen_sep = ':'; + BOOL seen_this_item = FALSE; + + while ((seen_item = string_nextinlist(&seen_items_list, &seen_sep, + NULL, 0))) + if (Ustrcmp(seen_item,item) == 0) + { + seen_this_item = TRUE; + break; + } + + if (seen_this_item) { DEBUG(D_receive) - debug_printf("acl_smtp_dkim: acl_check returned %d on %s, " - "skipping remaining items\n", rc, item); - cancel_cutthrough_connection(TRUE, US"dkim acl not ok"); - break; + debug_printf("acl_smtp_dkim: skipping signer %s, " + "already seen\n", item); + continue; } - } - add_acl_headers(ACL_WHERE_DKIM, US"DKIM"); - if (rc == DISCARD) - { - recipients_count = 0; - blackholed_by = US"DKIM ACL"; - if (log_msg != NULL) - blackhole_log_msg = string_sprintf(": %s", log_msg); - } - else if (rc != OK) - { - Uunlink(spool_name); - if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0) - smtp_yield = FALSE; /* No more messages after dropped connection */ - smtp_reply = US""; /* Indicate reply already sent */ - message_id[0] = 0; /* Indicate no message accepted */ - goto TIDYUP; /* Skip to end of function */ - } - } + + seen_items = string_catn(seen_items, ":", 1); + } + seen_items = string_cat(seen_items, item); + + rc = dkim_exim_acl_run(item, &results, &user_msg, &log_msg); + if (rc != OK) + { + DEBUG(D_receive) + debug_printf("acl_smtp_dkim: acl_check returned %d on %s, " + "skipping remaining items\n", rc, item); + cancel_cutthrough_connection(TRUE, US"dkim acl not ok"); + break; + } + } + dkim_verify_status = string_from_gstring(results); + store_pool = old_pool; + add_acl_headers(ACL_WHERE_DKIM, US"DKIM"); + if (rc == DISCARD) + { + recipients_count = 0; + blackholed_by = US"DKIM ACL"; + if (log_msg) + blackhole_log_msg = string_sprintf(": %s", log_msg); + } + else if (rc != OK) + { + Uunlink(spool_name); + if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0) + smtp_yield = FALSE; /* No more messages after dropped connection */ + smtp_reply = US""; /* Indicate reply already sent */ + message_id[0] = 0; /* Indicate no message accepted */ + goto TIDYUP; /* Skip to end of function */ + } } + else + dkim_exim_verify_log_all(); } #endif /* DISABLE_DKIM */