ph10 2007/08/22 11:10:24 BST
Modified files:
exim-doc/doc-txt ChangeLog NewStuff
exim-src ACKNOWLEDGMENTS
exim-src/src acl.c expand.c functions.h globals.c
globals.h log.c macros.h readconf.c
receive.c smtp_in.c
Added files:
exim-test/confs 0562
exim-test/log 0562
exim-test/rejectlog 0562
exim-test/scripts/0000-Basic 0562
exim-test/stderr 0562
exim-test/stdout 0562
Log:
Add the NOTQUIT ACL.
Revision Changes Path
1.523 +2 -0 exim/exim-doc/doc-txt/ChangeLog
1.155 +32 -0 exim/exim-doc/doc-txt/NewStuff
1.79 +2 -1 exim/exim-src/ACKNOWLEDGMENTS
1.78 +4 -3 exim/exim-src/src/acl.c
1.89 +1 -0 exim/exim-src/src/expand.c
1.38 +2 -1 exim/exim-src/src/functions.h
1.77 +7 -0 exim/exim-src/src/globals.c
1.58 +2 -0 exim/exim-src/src/globals.h
1.13 +6 -4 exim/exim-src/src/log.c
1.36 +1 -0 exim/exim-src/src/macros.h
1.32 +1 -0 exim/exim-src/src/readconf.c
1.40 +18 -18 exim/exim-src/src/receive.c
1.60 +122 -14 exim/exim-src/src/smtp_in.c
1.1 +28 -0 exim/exim-test/confs/0562 (new)
1.1 +16 -0 exim/exim-test/log/0562 (new)
1.1 +14 -0 exim/exim-test/rejectlog/0562 (new)
1.1 +66 -0 exim/exim-test/scripts/0000-Basic/0562 (new)
1.1 +2 -0 exim/exim-test/stderr/0562 (new)
1.1 +88 -0 exim/exim-test/stdout/0562 (new)
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.522
retrieving revision 1.523
diff -u -r1.522 -r1.523
--- ChangeLog 17 Aug 2007 11:16:45 -0000 1.522
+++ ChangeLog 22 Aug 2007 10:10:23 -0000 1.523
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.522 2007/08/17 11:16:45 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.523 2007/08/22 10:10:23 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -81,6 +81,8 @@
PH/16 Another patch from the Sieve maintainer.
+PH/17 Added the NOTQUIT ACL, based on a patch from Ted Cooper.
+
Exim version 4.67
Index: NewStuff
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/NewStuff,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -r1.154 -r1.155
--- NewStuff 27 Jun 2007 11:01:51 -0000 1.154
+++ NewStuff 22 Aug 2007 10:10:23 -0000 1.155
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.154 2007/06/27 11:01:51 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.155 2007/08/22 10:10:23 ph10 Exp $
New Features in Exim
--------------------
@@ -87,6 +87,38 @@
the load for each incoming message in an SMTP session. Otherwise, once one
message is queued, the remainder are also.
+ 9. There is a new ACL, specified by smtp_notquit_acl, which is run in most
+ cases when an SMTP session ends without sending QUIT. However, when Exim
+ itself is is bad trouble, such as being unable to write to its log files,
+ this ACL is not run, because it might try to do things (such as write to
+ log files) that make the situation even worse.
+
+ Like the QUIT ACL, this new ACL is provided to make it possible to gather
+ statistics. Whatever it returns (accept or deny) is immaterial. The "delay"
+ modifier is forbidden in this ACL.
+
+ When the NOTQUIT ACL is running, the variable $smtp_notquit_reason is set
+ to a string that indicates the reason for the termination of the SMTP
+ connection. The possible values are:
+
+ acl-drop Another ACL issued a "drop" command
+ bad-commands Too many unknown or non-mail commands
+ command-timeout Timeout while reading SMTP commands
+ connection-lost The SMTP connection has been lost
+ data-timeout Timeout while reading message data
+ local-scan-error The local_scan() function crashed
+ local-scan-timeout The local_scan() function timed out
+ signal-exit SIGTERM or SIGINT
+ synchronization-error SMTP synchronization error
+ tls-failed TLS failed to start
+
+ In most cases when an SMTP connection is closed without having received
+ QUIT, Exim sends an SMTP response message before actually closing the
+ connection. With the exception of acl-drop, the default message can be
+ overridden by the "message" modifier in the NOTQUIT ACL. In the case of a
+ "drop" verb in another ACL, it is the message from the other ACL that is
+ used.
+
Version 4.67
------------
Index: ACKNOWLEDGMENTS
===================================================================
RCS file: /home/cvs/exim/exim-src/ACKNOWLEDGMENTS,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -r1.78 -r1.79
--- ACKNOWLEDGMENTS 20 Jun 2007 14:13:39 -0000 1.78
+++ ACKNOWLEDGMENTS 22 Aug 2007 10:10:23 -0000 1.79
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-src/ACKNOWLEDGMENTS,v 1.78 2007/06/20 14:13:39 ph10 Exp $
+$Cambridge: exim/exim-src/ACKNOWLEDGMENTS,v 1.79 2007/08/22 10:10:23 ph10 Exp $
EXIM ACKNOWLEDGEMENTS
@@ -20,7 +20,7 @@
Philip Hazel
Lists created: 20 November 2002
-Last updated: 20 June 2007
+Last updated: 22 August 2007
THE OLD LIST
@@ -93,6 +93,7 @@
Oliver Cook Suggested patch for exigrep & rejected messages
Patch to add sender/host info to local_scan() rejects
Suggested patch to add queue time to "Completed"
+Ted Cooper Suggested patch for NOTQUIT ACL
Jennifer Corley Designing the new Exim logo
John Dalbec Patch for quota_warn_threshold bug
Vivek Dasmohapatra Suggested patch for CRL support
Index: acl.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/acl.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- acl.c 20 Jun 2007 14:13:39 -0000 1.77
+++ acl.c 22 Aug 2007 10:10:23 -0000 1.78
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/acl.c,v 1.77 2007/06/20 14:13:39 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/acl.c,v 1.78 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -350,8 +350,9 @@
};
/* Bit map vector of which conditions and modifiers are not allowed at certain
-times. For each condition, there's a bitmap of dis-allowed times. For some, it
-is easier to specify the negation of a small number of allowed times. */
+times. For each condition and modifier, there's a bitmap of dis-allowed times.
+For some, it is easier to specify the negation of a small number of allowed
+times. */
static unsigned int cond_forbids[] = {
0, /* acl */
@@ -391,7 +392,7 @@
~(1<<ACL_WHERE_MIME), /* decode */
#endif
- 0, /* delay */
+ (1<<ACL_WHERE_NOTQUIT), /* delay */
#ifdef WITH_OLD_DEMIME
(unsigned int)
Index: expand.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/expand.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- expand.c 27 Jun 2007 11:01:51 -0000 1.88
+++ expand.c 22 Aug 2007 10:10:23 -0000 1.89
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/expand.c,v 1.88 2007/06/27 11:01:51 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/expand.c,v 1.89 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -549,6 +549,7 @@
{ "smtp_command", vtype_stringptr, &smtp_cmd_buffer },
{ "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument },
{ "smtp_count_at_connection_start", vtype_int, &smtp_accept_count },
+ { "smtp_notquit_reason", vtype_stringptr, &smtp_notquit_reason },
{ "sn0", vtype_filter_int, &filter_sn[0] },
{ "sn1", vtype_filter_int, &filter_sn[1] },
{ "sn2", vtype_filter_int, &filter_sn[2] },
Index: functions.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/functions.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- functions.h 13 Apr 2007 15:13:47 -0000 1.37
+++ functions.h 22 Aug 2007 10:10:23 -0000 1.38
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/functions.h,v 1.37 2007/04/13 15:13:47 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/functions.h,v 1.38 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -210,7 +210,7 @@
extern void readconf_rest(BOOL);
extern uschar *readconf_retry_error(uschar *, uschar *, int *, int *);
extern void read_message_body(BOOL);
-extern void receive_bomb_out(uschar *);
+extern void receive_bomb_out(uschar *, uschar *);
extern BOOL receive_check_fs(int);
extern BOOL receive_check_set_sender(uschar *);
extern BOOL receive_msg(BOOL);
@@ -277,6 +277,7 @@
extern void smtp_message_code(uschar **, int *, uschar **, uschar **);
extern BOOL smtp_read_response(smtp_inblock *, uschar *, int, int, int);
extern void smtp_respond(uschar *, int, BOOL, uschar *);
+extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
extern void smtp_send_prohibition_message(int, uschar *);
extern int smtp_setup_msg(void);
extern BOOL smtp_start_session(void);
Index: globals.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/globals.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -r1.76 -r1.77
--- globals.c 27 Jun 2007 11:01:52 -0000 1.76
+++ globals.c 22 Aug 2007 10:10:23 -0000 1.77
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/globals.c,v 1.76 2007/06/27 11:01:52 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/globals.c,v 1.77 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -172,11 +172,13 @@
header_line *acl_added_headers = NULL;
tree_node *acl_anchor = NULL;
+
uschar *acl_not_smtp = NULL;
#ifdef WITH_CONTENT_SCAN
uschar *acl_not_smtp_mime = NULL;
#endif
uschar *acl_not_smtp_start = NULL;
+
uschar *acl_smtp_auth = NULL;
uschar *acl_smtp_connect = NULL;
uschar *acl_smtp_data = NULL;
@@ -188,11 +190,13 @@
#ifdef WITH_CONTENT_SCAN
uschar *acl_smtp_mime = NULL;
#endif
+uschar *acl_smtp_notquit = NULL;
uschar *acl_smtp_predata = NULL;
uschar *acl_smtp_quit = NULL;
uschar *acl_smtp_rcpt = NULL;
uschar *acl_smtp_starttls = NULL;
uschar *acl_smtp_vrfy = NULL;
+
BOOL acl_temp_details = FALSE;
tree_node *acl_var_c = NULL;
tree_node *acl_var_m = NULL;
@@ -215,6 +219,7 @@
US"EHLO or HELO",
US"MAILAUTH",
US"non-SMTP-start",
+ US"NOTQUIT",
US"QUIT",
US"STARTTLS",
US"VRFY"
@@ -233,6 +238,7 @@
US"550", /* HELO/EHLO */
US"0", /* MAILAUTH; not relevant */
US"0", /* not SMTP; not relevant */
+ US"0", /* NOTQUIT; not relevant */
US"0", /* QUIT; not relevant */
US"550", /* STARTTLS */
US"252" /* VRFY */
@@ -1087,6 +1093,7 @@
BOOL smtp_etrn_serialize = TRUE;
int smtp_max_synprot_errors= 3;
int smtp_max_unknown_commands = 3;
+uschar *smtp_notquit_reason = NULL;
uschar *smtp_ratelimit_hosts = NULL;
uschar *smtp_ratelimit_mail = NULL;
uschar *smtp_ratelimit_rcpt = NULL;
Index: globals.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/globals.h,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- globals.h 27 Jul 2007 13:56:24 -0000 1.57
+++ globals.h 22 Aug 2007 10:10:23 -0000 1.58
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/globals.h,v 1.57 2007/07/27 13:56:24 magnus Exp $ */
+/* $Cambridge: exim/exim-src/src/globals.h,v 1.58 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -126,6 +126,7 @@
#ifdef WITH_CONTENT_SCAN
extern uschar *acl_smtp_mime; /* ACL run after DATA, before acl_smtp_data, for each MIME part */
#endif
+extern uschar *acl_smtp_notquit; /* ACL run for disconnects */
extern uschar *acl_smtp_predata; /* ACL run for DATA command */
extern uschar *acl_smtp_quit; /* ACL run for QUIT */
extern uschar *acl_smtp_rcpt; /* ACL run for RCPT */
@@ -660,6 +661,7 @@
extern int smtp_mailcmd_count; /* Count of MAIL commands */
extern int smtp_max_synprot_errors;/* Max syntax/protocol errors */
extern int smtp_max_unknown_commands; /* As it says */
+extern uschar *smtp_notquit_reason; /* Global for disconnect reason */
extern FILE *smtp_out; /* Incoming SMTP output file */
extern uschar *smtp_ratelimit_hosts; /* Rate limit these hosts */
extern uschar *smtp_ratelimit_mail; /* Parameters for MAIL limiting */
Index: log.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/log.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- log.c 31 Jan 2007 16:52:12 -0000 1.12
+++ log.c 22 Aug 2007 10:10:23 -0000 1.13
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/log.c,v 1.12 2007/01/31 16:52:12 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/log.c,v 1.13 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -135,9 +135,11 @@
/* This is called when Exim is dying as a result of something going wrong in
the logging, or after a log call with LOG_PANIC_DIE set. Optionally write a
message to debug_file or a stderr file, if they exist. Then, if in the middle
-of accepting a message, throw it away tidily; this will attempt to send an SMTP
-response if appropriate. Otherwise, try to close down an outstanding SMTP call
-tidily.
+of accepting a message, throw it away tidily by calling receive_bomb_out();
+this will attempt to send an SMTP response if appropriate. Passing NULL as the
+first argument stops it trying to run the NOTQUIT ACL (which might try further
+logging and thus cause problems). Otherwise, try to close down an outstanding
+SMTP call tidily.
Arguments:
s1 Error message to write to debug_file and/or stderr and syslog
@@ -155,7 +157,7 @@
if (log_stderr != NULL && log_stderr != debug_file)
fprintf(log_stderr, "%s\n", s1);
}
-if (receive_call_bombout) receive_bomb_out(s2); /* does not return */
+if (receive_call_bombout) receive_bomb_out(NULL, s2); /* does not return */
if (smtp_input) smtp_closedown(s2);
exim_exit(EXIT_FAILURE);
}
Index: macros.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/macros.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- macros.h 27 Jun 2007 11:01:52 -0000 1.35
+++ macros.h 22 Aug 2007 10:10:23 -0000 1.36
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/macros.h,v 1.35 2007/06/27 11:01:52 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/macros.h,v 1.36 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -809,6 +809,7 @@
ACL_WHERE_HELO,
ACL_WHERE_MAILAUTH,
ACL_WHERE_NOTSMTP_START,
+ ACL_WHERE_NOTQUIT,
ACL_WHERE_QUIT,
ACL_WHERE_STARTTLS,
ACL_WHERE_VRFY
Index: readconf.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/readconf.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- readconf.c 4 Jul 2007 11:03:46 -0000 1.31
+++ readconf.c 22 Aug 2007 10:10:23 -0000 1.32
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/readconf.c,v 1.31 2007/07/04 11:03:46 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/readconf.c,v 1.32 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -150,6 +150,7 @@
#ifdef WITH_CONTENT_SCAN
{ "acl_smtp_mime", opt_stringptr, &acl_smtp_mime },
#endif
+ { "acl_smtp_notquit", opt_stringptr, &acl_smtp_notquit },
{ "acl_smtp_predata", opt_stringptr, &acl_smtp_predata },
{ "acl_smtp_quit", opt_stringptr, &acl_smtp_quit },
{ "acl_smtp_rcpt", opt_stringptr, &acl_smtp_rcpt },
Index: receive.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/receive.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- receive.c 29 Jun 2007 09:20:37 -0000 1.39
+++ receive.c 22 Aug 2007 10:10:23 -0000 1.40
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/receive.c,v 1.39 2007/06/29 09:20:37 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/receive.c,v 1.40 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -178,7 +178,7 @@
}
}
-/* We now have the patch; do the business */
+/* We now have the path; do the business */
memset(&statbuf, 0, sizeof(statbuf));
@@ -283,12 +283,14 @@
function if there is an ultimate disaster. That is why it is globally
accessible.
-Arguments: SMTP response to give if in an SMTP session
+Arguments:
+ reason text reason to pass to the not-quit ACL
+ msg default SMTP response to give if in an SMTP session
Returns: it doesn't
*/
void
-receive_bomb_out(uschar *msg)
+receive_bomb_out(uschar *reason, uschar *msg)
{
/* 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
@@ -306,20 +308,16 @@
if (data_file != NULL) (void)fclose(data_file);
else if (data_fd >= 0) (void)close(data_fd);
-/* Attempt to close down an SMTP connection tidily. */
+/* 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 (!smtp_batched_input)
- {
- smtp_printf("421 %s %s - closing connection.\r\n", smtp_active_hostname,
- msg);
- mac_smtp_fflush();
- }
-
- /* Control does not return from moan_smtp_batch(). */
-
- else moan_smtp_batch(NULL, "421 %s - message abandoned", msg);
+ 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) */
@@ -362,7 +360,7 @@
LOG_MAIN, "timed out while reading local message");
}
-receive_bomb_out(msg); /* Does not return */
+receive_bomb_out(US"data-timeout", msg); /* Does not return */
}
@@ -384,7 +382,8 @@
sig = sig; /* Keep picky compilers happy */
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function timed out - "
"message temporarily rejected (size %d)", message_size);
-receive_bomb_out(US"local verification problem"); /* Does not return */
+/* Does not return */
+receive_bomb_out(US"local-scan-timeout", US"local verification problem");
}
@@ -405,7 +404,8 @@
{
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function crashed with "
"signal %d - message temporarily rejected (size %d)", sig, message_size);
-receive_bomb_out(US"local verification problem"); /* Does not return */
+/* Does not return */
+receive_bomb_out(US"local-scan-error", US"local verification problem");
}
@@ -442,7 +442,7 @@
}
}
-receive_bomb_out(msg); /* Does not return */
+receive_bomb_out(US"signal-exit", msg); /* Does not return */
}
Index: smtp_in.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/smtp_in.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -r1.59 -r1.60
--- smtp_in.c 4 Jul 2007 10:37:03 -0000 1.59
+++ smtp_in.c 22 Aug 2007 10:10:23 -0000 1.60
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.59 2007/07/04 10:37:03 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.60 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -123,6 +123,7 @@
static BOOL rcpt_smtp_response_same;
static BOOL rcpt_in_progress;
static int nonmail_command_count;
+static BOOL smtp_exit_function_called = 0;
static int synprot_error_count;
static int unknown_command_count;
static int sync_cmd_limit;
@@ -470,9 +471,8 @@
host_and_ident(FALSE));
if (smtp_batched_input)
moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */
-smtp_printf("421 %s: SMTP command timeout - closing connection\r\n",
- smtp_active_hostname);
-mac_smtp_fflush();
+smtp_notquit_exit(US"command-timeout", US"421",
+ US"%s: SMTP command timeout - closing connection", smtp_active_hostname);
exim_exit(EXIT_FAILURE);
}
@@ -495,8 +495,8 @@
log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info());
if (smtp_batched_input)
moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */
-smtp_printf("421 %s: Service not available - closing connection\r\n",
- smtp_active_hostname);
+smtp_notquit_exit(US"signal-exit", US"421",
+ US"%s: Service not available - closing connection", smtp_active_hostname);
exim_exit(EXIT_FAILURE);
}
@@ -702,7 +702,9 @@
except QUIT. The existence of an SMTP call is detected by the non-NULLness of
smtp_in.
-Argument: SMTP reply string to send, excluding the code
+Arguments:
+ message SMTP reply string to send, excluding the code
+
Returns: nothing
*/
@@ -1344,6 +1346,7 @@
pipelining_advertised = FALSE;
pipelining_enable = TRUE;
sync_cmd_limit = NON_SYNC_CMD_NON_PIPELINING;
+smtp_exit_function_called = FALSE; /* For avoiding loop in not-quit exit */
memset(sender_host_cache, 0, sizeof(sender_host_cache));
@@ -2266,6 +2269,12 @@
log_write(L_smtp_connection, LOG_MAIN, "%s closed by DROP in ACL",
smtp_get_connection_info());
+
+/* Run the not-quit ACL, but without any custom messages. This should not be a
+problem, because we get here only if some other ACL has issued "drop", and
+in that case, *its* custom messages will have been used above. */
+
+smtp_notquit_exit(US"acl-drop", NULL, NULL);
return 2;
}
@@ -2273,6 +2282,86 @@
/*************************************************
+* Handle SMTP exit when QUIT is not given *
+*************************************************/
+
+/* This function provides a logging/statistics hook for when an SMTP connection
+is dropped on the floor or the other end goes away. It's a global function
+because it's called from receive.c as well as this module. As well as running
+the NOTQUIT ACL, if there is one, this function also outputs a final SMTP
+response, either with a custom message from the ACL, or using a default. There
+is one case, however, when no message is output - after "drop". In that case,
+the ACL that obeyed "drop" has already supplied the custom message, and NULL is
+passed to this function.
+
+In case things go wrong while processing this function, causing an error that
+may re-enter this funtion, there is a recursion check.
+
+Arguments:
+ reason What $smtp_notquit_reason will be set to in the ACL;
+ if NULL, the ACL is not run
+ code The error code to return as part of the response
+ defaultrespond The default message if there's no user_msg
+
+Returns: Nothing
+*/
+
+void
+smtp_notquit_exit(uschar *reason, uschar *code, uschar *defaultrespond, ...)
+{
+int rc;
+uschar *user_msg = NULL;
+uschar *log_msg = NULL;
+
+/* Check for recursive acll */
+
+if (smtp_exit_function_called)
+ {
+ log_write(0, LOG_PANIC, "smtp_notquit_exit() called more than once (%s)",
+ reason);
+ return;
+ }
+smtp_exit_function_called = TRUE;
+
+/* Call the not-QUIT ACL, if there is one, unless no reason is given. */
+
+if (acl_smtp_notquit != NULL && reason != NULL)
+ {
+ smtp_notquit_reason = reason;
+ rc = acl_check(ACL_WHERE_NOTQUIT, NULL, acl_smtp_notquit, &user_msg,
+ &log_msg);
+ if (rc == ERROR)
+ log_write(0, LOG_MAIN|LOG_PANIC, "ACL for not-QUIT returned ERROR: %s",
+ log_msg);
+ }
+
+/* Write an SMTP response if we are expected to give one. As the default
+responses are all internal, they should always fit in the buffer, but code a
+warning, just in case. Note that string_vformat() still leaves a complete
+string, even if it is incomplete. */
+
+if (code != NULL && defaultrespond != NULL)
+ {
+ if (user_msg == NULL)
+ {
+ uschar buffer[128];
+ va_list ap;
+ va_start(ap, defaultrespond);
+ if (!string_vformat(buffer, sizeof(buffer), CS defaultrespond, ap))
+ log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_notquit_exit()");
+ smtp_printf("%s %s\r\n", code, buffer);
+ va_end(ap);
+ }
+ else
+ smtp_respond(code, 3, TRUE, user_msg);
+ mac_smtp_fflush();
+ }
+}
+
+
+
+
+/*************************************************
* Verify HELO argument *
*************************************************/
@@ -3786,11 +3875,29 @@
case EOF_CMD:
log_write(L_smtp_connection, LOG_MAIN, "%s closed by EOF",
smtp_get_connection_info());
+ smtp_notquit_exit(US"tls-failed", NULL, NULL);
done = 2;
break;
+ /* It is perhaps arguable as to which exit ACL should be called here,
+ but as it is probably a situtation that almost never arises, it
+ probably doesn't matter. We choose to call the real QUIT ACL, which in
+ some sense is perhaps "right". */
+
case QUIT_CMD:
- smtp_printf("221 %s closing connection\r\n", smtp_active_hostname);
+ user_msg = NULL;
+ if (acl_smtp_quit != NULL)
+ {
+ rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg,
+ &log_msg);
+ if (rc == ERROR)
+ log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
+ log_msg);
+ }
+ if (user_msg == NULL)
+ smtp_printf("221 %s closing connection\r\n", smtp_active_hostname);
+ else
+ smtp_respond(US"221", 3, TRUE, user_msg);
log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT",
smtp_get_connection_info());
done = 2;
@@ -3813,15 +3920,13 @@
case QUIT_CMD:
HAD(SCH_QUIT);
incomplete_transaction_log(US"QUIT");
-
if (acl_smtp_quit != NULL)
{
- rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit,&user_msg,&log_msg);
+ rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg, &log_msg);
if (rc == ERROR)
log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
log_msg);
}
-
if (user_msg == NULL)
smtp_printf("221 %s closing connection\r\n", smtp_active_hostname);
else
@@ -3882,7 +3987,8 @@
case EOF_CMD:
incomplete_transaction_log(US"connection lost");
- smtp_printf("421 %s lost input connection\r\n", smtp_active_hostname);
+ smtp_notquit_exit(US"connection-lost", US"421",
+ US"%s lost input connection", smtp_active_hostname);
/* Don't log by default unless in the middle of a message, as some mailers
just drop the call rather than sending QUIT, and it clutters up the logs.
@@ -4088,7 +4194,8 @@
pipelining_advertised? "" : " not",
smtp_cmd_buffer, host_and_ident(TRUE),
string_printing(smtp_inptr));
- smtp_printf("554 SMTP synchronization error\r\n");
+ smtp_notquit_exit(US"synchronization-error", US"554",
+ US"SMTP synchronization error");
done = 1; /* Pretend eof - drops connection */
break;
@@ -4100,7 +4207,7 @@
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"nonmail commands (last was \"%.*s\")", host_and_ident(FALSE),
s - smtp_cmd_buffer, smtp_cmd_buffer);
- smtp_printf("554 Too many nonmail commands\r\n");
+ smtp_notquit_exit(US"bad-commands", US"554", US"Too many nonmail commands");
done = 1; /* Pretend eof - drops connection */
break;
@@ -4113,7 +4220,8 @@
string_printing(smtp_cmd_buffer), host_and_ident(TRUE),
US"unrecognized command");
incomplete_transaction_log(US"unrecognized command");
- smtp_printf("500 Too many unrecognized commands\r\n");
+ smtp_notquit_exit(US"bad-commands", US"500",
+ US"Too many unrecognized commands");
done = 2;
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"unrecognized commands (last was \"%s\")", host_and_ident(FALSE),
Index: 0562
====================================================================
# Exim test configuration 0562
exim_path = EXIM_PATH
host_lookup_order = bydns
primary_hostname = myhost.test.ex
rfc1413_query_timeout = 0s
spool_directory = DIR/spool
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
# ----- Main settings -----
acl_smtp_rcpt = accept
acl_smtp_data = drop
acl_smtp_notquit = notquit
smtp_accept_max_nonmail = 4
smtp_receive_timeout = 1s
# ----- ACLs -----
begin acl
notquit:
accept logwrite = NOTQUIT reason: '$smtp_notquit_reason'
# End
Index: 0562
====================================================================
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 SMTP data timeout (message abandoned) on connection from (abcd) [127.0.0.1] F=<userx@???>
1999-03-02 09:44:33 NOTQUIT reason: 'data-timeout'
1999-03-02 09:44:33 SMTP command timeout on connection from [127.0.0.1]
1999-03-02 09:44:33 NOTQUIT reason: 'command-timeout'
1999-03-02 09:44:33 NOTQUIT reason: 'connection-lost'
1999-03-02 09:44:33 NOTQUIT reason: 'bad-commands'
1999-03-02 09:44:33 SMTP call from [127.0.0.1] dropped: too many unrecognized commands (last was "unknown")
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 SMTP call from [127.0.0.1] dropped: too many nonmail commands (last was "vrfy")
1999-03-02 09:44:33 NOTQUIT reason: 'bad-commands'
1999-03-02 09:44:33 10HmaX-0005vi-00 H=(abcd) [127.0.0.1] F=<userx@???> rejected after DATA
1999-03-02 09:44:33 10HmaX-0005vi-00 NOTQUIT reason: 'acl-drop'
Index: 0562
====================================================================
1999-03-02 09:44:33 SMTP call from [127.0.0.1] dropped: too many unrecognized commands (last was "unknown")
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 H=[127.0.0.1] rejected VRFY
1999-03-02 09:44:33 SMTP call from [127.0.0.1] dropped: too many nonmail commands (last was "vrfy")
1999-03-02 09:44:33 10HmaX-0005vi-00 H=(abcd) [127.0.0.1] F=<userx@???> rejected after DATA
Envelope-from: <userx@???>
Envelope-to: <userx@???>
P Received: from [127.0.0.1] (helo=abcd)
by myhost.test.ex with esmtp (Exim x.yz)
(envelope-from <userx@???>)
id 10HmaX-0005vi-00
for userx@???; Tue, 2 Mar 1999 09:44:33 +0000
Index: 0562
====================================================================
# NOTQUIT ACL
need_ipv4
#
exim -DSERVER=server -bd -oX PORT_D
****
client 127.0.0.1 PORT_D
??? 220
ehlo abcd
??? 250-
??? 250-
??? 250-
??? 250
mail from:<userx@???>\r\nrcpt to:<userx@???>\r\ndata
??? 250
??? 250
??? 354
This is a test message.
+++ 2
****
client 127.0.0.1 PORT_D
??? 220
+++ 2
****
client 127.0.0.1 PORT_D
??? 220
****
client 127.0.0.1 PORT_D
??? 220
unknown
??? 500
unknown
??? 500
unknown
??? 500
unknown
??? 500
****
client 127.0.0.1 PORT_D
??? 220
vrfy
??? 252
vrfy
??? 252
vrfy
??? 252
vrfy
??? 252
vrfy
??? 554
****
client 127.0.0.1 PORT_D
??? 220
ehlo abcd
??? 250-
??? 250-
??? 250-
??? 250
mail from:<userx@???>\r\nrcpt to:<userx@???>\r\ndata
??? 250
??? 250
??? 354
This is a test message.
.
****
sleep 1
killdaemon
Index: 0562
====================================================================
******** SERVER ********
Index: 0562
====================================================================
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
>>> ehlo abcd
??? 250-
<<< 250-myhost.test.ex Hello abcd [127.0.0.1]
??? 250-
<<< 250-SIZE 52428800
??? 250-
<<< 250-PIPELINING
??? 250
<<< 250 HELP
>>> mail from:<userx@???>\r\nrcpt to:<userx@???>\r\ndata
??? 250
<<< 250 OK
??? 250
<<< 250 Accepted
??? 354
<<< 354 Enter message, ending with "." on a line by itself
>>> This is a test message.
+++ 2
End of script
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+++ 2
End of script
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
End of script
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
>>> unknown
??? 500
<<< 500 unrecognized command
>>> unknown
??? 500
<<< 500 unrecognized command
>>> unknown
??? 500
<<< 500 unrecognized command
>>> unknown
??? 500
<<< 500 Too many unrecognized commands
End of script
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
>>> vrfy
??? 252
<<< 252 Administrative prohibition
>>> vrfy
??? 252
<<< 252 Administrative prohibition
>>> vrfy
??? 252
<<< 252 Administrative prohibition
>>> vrfy
??? 252
<<< 252 Administrative prohibition
>>> vrfy
??? 554
<<< 554 Too many nonmail commands
End of script
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
>>> ehlo abcd
??? 250-
<<< 250-myhost.test.ex Hello abcd [127.0.0.1]
??? 250-
<<< 250-SIZE 52428800
??? 250-
<<< 250-PIPELINING
??? 250
<<< 250 HELP
>>> mail from:<userx@???>\r\nrcpt to:<userx@???>\r\ndata
??? 250
<<< 250 OK
??? 250
<<< 250 Accepted
??? 354
<<< 354 Enter message, ending with "." on a line by itself
>>> This is a test message.
>>> .
End of script