diff options
author | Phil Pennock <pdp@exim.org> | 2013-03-05 16:59:49 -0500 |
---|---|---|
committer | Phil Pennock <pdp@exim.org> | 2013-03-05 16:59:49 -0500 |
commit | ead37e6cf7dd3108cf1b197d3fa58ca52935c6bd (patch) | |
tree | 44bd9fec39d06fa739647ea710e47fd4e4e0baa1 | |
parent | 05c39afa86ea3d0dd619e7d75554c701f96d2da4 (diff) |
Handle recursion better, caused by ACLs.
Issue debugged by Todd Lyons, this fix from me.
-rw-r--r-- | src/src/receive.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/src/receive.c b/src/src/receive.c index e0c1c7393..56de9fbb3 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -286,32 +286,50 @@ Returns: it doesn't void receive_bomb_out(uschar *reason, uschar *msg) { + static BOOL already_bombing_out; +/* The smtp_notquit_exit() below can call ACLs which can trigger recursive +timeouts, if someone has something slow in their quit ACL. Since the only +things we should be doing are to close down cleanly ASAP, on the second +pass we also close down stuff that might be opened again, before bypassing +the ACL call and exiting. */ + /* If spool_name is set, it contains the name of the data file that is being written. Unlink it before closing so that it cannot be picked up by a delivery process. Ensure that any header file is also removed. */ -if (spool_name[0] != 0) +if (spool_name[0] != '\0') { Uunlink(spool_name); spool_name[Ustrlen(spool_name) - 1] = 'H'; Uunlink(spool_name); + spool_name[0] = '\0'; } /* Now close the file if it is open, either as a fd or a stream. */ -if (data_file != NULL) (void)fclose(data_file); - else if (data_fd >= 0) (void)close(data_fd); +if (data_file != NULL) + { + (void)fclose(data_file); + data_file = NULL; +} else if (data_fd >= 0) { + (void)close(data_fd); + data_fd = -1; + } /* Attempt to close down an SMTP connection tidily. For non-batched SMTP, call smtp_notquit_exit(), which runs the NOTQUIT ACL, if present, and handles the SMTP response. */ -if (smtp_input) +if (!already_bombing_out) { - if (smtp_batched_input) - moan_smtp_batch(NULL, "421 %s - message abandoned", msg); /* No return */ - smtp_notquit_exit(reason, US"421", US"%s %s - closing connection.", - smtp_active_hostname, msg); + already_bombing_out = TRUE; + if (smtp_input) + { + if (smtp_batched_input) + moan_smtp_batch(NULL, "421 %s - message abandoned", msg); /* No return */ + smtp_notquit_exit(reason, US"421", US"%s %s - closing connection.", + smtp_active_hostname, msg); + } } /* Exit from the program (non-BSMTP cases) */ |