Make $smtp_command_argument available for all SMTP commands.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Aug 2005 14:01:37 +0000 (14:01 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Aug 2005 14:01:37 +0000 (14:01 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/globals.h
src/src/smtp_in.c

index 7ab667a281f48595c4d1fc68a5531b1c28163dcb..81029b4cab372a0c7bb83b7c9438b6c8bcdae5ff 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.206 2005/08/22 10:49:04 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.207 2005/08/22 14:01:37 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -103,6 +103,10 @@ TK/04 MIME ACL: Fix buffer underrun that occurs when EOF condition is met
 PH/24 Include config.h inside local_scan.h so that configuration settings are
       available.
 
 PH/24 Include config.h inside local_scan.h so that configuration settings are
       available.
 
+PH/25 Make $smtp_command_argument available after all SMTP commands. This means
+      that in an ACL for RCPT (for example), you can examine exactly what was
+      received.
+
 
 Exim version 4.52
 -----------------
 
 Exim version 4.52
 -----------------
index 575d269d76b1f9cffc09d2b2bc04d1f4dc11c9a2..c7e7fb8ba3c99c6702b105b6438b7bbdd797a5d0 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.63 2005/08/09 13:31:52 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.64 2005/08/22 14:01:37 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -102,6 +102,10 @@ PH/06 It is now possible to specify a port number along with a host name or
 
            route_list = *  dom1.tld/mx::1225
 
 
            route_list = *  dom1.tld/mx::1225
 
+PH/07 $smtp_command_argument is now set for all SMTP commands, not just the
+      non-message ones. This makes it possible to inspect the complete command
+      for RCPT commands, for example.
+
 
 Exim version 4.52
 -----------------
 
 Exim version 4.52
 -----------------
index f4788d19e55b94a8c575c688f96530a6900391e1..4a73957ac57ceebc8dc6e4dfe6fb18bca2cab7ad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.43 2005/08/02 15:19:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.44 2005/08/22 14:01:37 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -3331,7 +3331,7 @@ acl_check_internal() to do the actual work.
 
 Arguments:
   where        ACL_WHERE_xxxx indicating where called from
 
 Arguments:
   where        ACL_WHERE_xxxx indicating where called from
-  data_string  RCPT address, or SMTP command argument, or NULL
+  recipient    RCPT address for RCPT check, else NULL
   s            the input string; NULL is the same as an empty ACL => DENY
   user_msgptr  where to put a user error (for SMTP response)
   log_msgptr   where to put a logging message (not for SMTP response)
   s            the input string; NULL is the same as an empty ACL => DENY
   user_msgptr  where to put a user error (for SMTP response)
   log_msgptr   where to put a logging message (not for SMTP response)
@@ -3345,12 +3345,12 @@ Returns:       OK         access is granted by an ACCEPT verb
 */
 
 int
 */
 
 int
-acl_check(int where, uschar *data_string, uschar *s, uschar **user_msgptr,
+acl_check(int where, uschar *recipient, uschar *s, uschar **user_msgptr,
   uschar **log_msgptr)
 {
 int rc;
 address_item adb;
   uschar **log_msgptr)
 {
 int rc;
 address_item adb;
-address_item *addr;
+address_item *addr = NULL;
 
 *user_msgptr = *log_msgptr = NULL;
 sender_verified_failed = NULL;
 
 *user_msgptr = *log_msgptr = NULL;
 sender_verified_failed = NULL;
@@ -3360,7 +3360,7 @@ if (where == ACL_WHERE_RCPT)
   {
   adb = address_defaults;
   addr = &adb;
   {
   adb = address_defaults;
   addr = &adb;
-  addr->address = data_string;
+  addr->address = recipient;
   if (deliver_split_address(addr) == DEFER)
     {
     *log_msgptr = US"defer in percent_hack_domains check";
   if (deliver_split_address(addr) == DEFER)
     {
     *log_msgptr = US"defer in percent_hack_domains check";
@@ -3369,16 +3369,11 @@ if (where == ACL_WHERE_RCPT)
   deliver_domain = addr->domain;
   deliver_localpart = addr->local_part;
   }
   deliver_domain = addr->domain;
   deliver_localpart = addr->local_part;
   }
-else
-  {
-  addr = NULL;
-  smtp_command_argument = data_string;
-  }
 
 rc = acl_check_internal(where, addr, s, 0, user_msgptr, log_msgptr);
 
 
 rc = acl_check_internal(where, addr, s, 0, user_msgptr, log_msgptr);
 
-smtp_command_argument = deliver_domain =
-  deliver_localpart = deliver_address_data = sender_address_data = NULL;
+deliver_domain = deliver_localpart = deliver_address_data =
+  sender_address_data = NULL;
 
 /* A DISCARD response is permitted only for message ACLs, excluding the PREDATA
 ACL, which is really in the middle of an SMTP command. */
 
 /* A DISCARD response is permitted only for message ACLs, excluding the PREDATA
 ACL, which is really in the middle of an SMTP command. */
index 3126f276b430698943407b4e87ea71062b6f1ee7..6becb6b390deb6186c69162bfb69171eb93dbbd9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.25 2005/08/08 10:48:27 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.26 2005/08/22 14:01:37 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -618,7 +618,7 @@ extern uschar *smtp_active_hostname;   /* Hostname for this message */
 extern BOOL    smtp_authenticated;     /* Sending client has authenticated */
 extern uschar *smtp_banner;            /* Banner string (to be expanded) */
 extern BOOL    smtp_check_spool_space; /* TRUE to check SMTP SIZE value */
 extern BOOL    smtp_authenticated;     /* Sending client has authenticated */
 extern uschar *smtp_banner;            /* Banner string (to be expanded) */
 extern BOOL    smtp_check_spool_space; /* TRUE to check SMTP SIZE value */
-extern uschar *smtp_command_argument;  /* When running certain ACLs */
+extern uschar *smtp_command_argument;  /* For all SMTP commands */
 extern int     smtp_connect_backlog;   /* Max backlog permitted */
 extern double  smtp_delay_mail;        /* Current MAIL delay */
 extern double  smtp_delay_rcpt;        /* Current RCPT delay */
 extern int     smtp_connect_backlog;   /* Max backlog permitted */
 extern double  smtp_delay_mail;        /* Current MAIL delay */
 extern double  smtp_delay_rcpt;        /* Current RCPT delay */
index 9a736a4b7bb68af059af192b7a0beaffd1283905..f6a2af89c94671108eb27623f665406d27f7b29d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.22 2005/08/02 15:19:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.23 2005/08/22 14:01:37 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -119,8 +119,6 @@ static int  unknown_command_count;
 static int  sync_cmd_limit;
 static int  smtp_write_error = 0;
 
 static int  sync_cmd_limit;
 static int  smtp_write_error = 0;
 
-static uschar *smtp_data;
-
 static uschar *cmd_buffer;
 
 /* We need to know the position of RSET, HELO, EHLO, AUTH, and STARTTLS. Their
 static uschar *cmd_buffer;
 
 /* We need to know the position of RSET, HELO, EHLO, AUTH, and STARTTLS. Their
@@ -535,7 +533,7 @@ for (p = cmd_list; p < cmd_list_end; p++)
     the following test, so that if it fails, the command name can easily be
     logged. */
 
     the following test, so that if it fails, the command name can easily be
     logged. */
 
-    smtp_data = cmd_buffer + p->len;
+    smtp_command_argument = cmd_buffer + p->len;
 
     /* Count non-mail commands from those hosts that are controlled in this
     way. The default is all hosts. We don't waste effort checking the list
 
     /* Count non-mail commands from those hosts that are controlled in this
     way. The default is all hosts. We don't waste effort checking the list
@@ -553,11 +551,11 @@ for (p = cmd_list; p < cmd_list_end; p++)
         return TOO_MANY_NONMAIL_CMD;
       }
 
         return TOO_MANY_NONMAIL_CMD;
       }
 
-    /* Get the data pointer over leading spaces and return; if there is no data
-    for a command that expects it, we give the error centrally here. */
+    /* Get the data pointer over leading spaces and return; if there is data
+    for a command that does not expect it, give the error centrally here. */
 
 
-    while (isspace(*smtp_data)) smtp_data++;
-    return (p->has_arg || *smtp_data == 0)? p->cmd : BADARG_CMD;
+    while (isspace(*smtp_command_argument)) smtp_command_argument++;
+    return (p->has_arg || *smtp_command_argument == 0)? p->cmd : BADARG_CMD;
     }
   }
 
     }
   }
 
@@ -745,7 +743,7 @@ return yield;
 *         Extract SMTP command option            *
 *************************************************/
 
 *         Extract SMTP command option            *
 *************************************************/
 
-/* This function picks the next option setting off the end of smtp_data. It
+/* This function picks the next option setting off the end of smtp_command_argument. It
 is called for MAIL FROM and RCPT TO commands, to pick off the optional ESMTP
 things that can appear there.
 
 is called for MAIL FROM and RCPT TO commands, to pick off the optional ESMTP
 things that can appear there.
 
@@ -760,11 +758,11 @@ static BOOL
 extract_option(uschar **name, uschar **value)
 {
 uschar *n;
 extract_option(uschar **name, uschar **value)
 {
 uschar *n;
-uschar *v = smtp_data + Ustrlen(smtp_data) -1;
+uschar *v = smtp_command_argument + Ustrlen(smtp_command_argument) -1;
 while (isspace(*v)) v--;
 v[1] = 0;
 
 while (isspace(*v)) v--;
 v[1] = 0;
 
-while (v > smtp_data && *v != '=' && !isspace(*v)) v--;
+while (v > smtp_command_argument && *v != '=' && !isspace(*v)) v--;
 if (*v != '=') return FALSE;
 
 n = v;
 if (*v != '=') return FALSE;
 
 n = v;
@@ -926,7 +924,7 @@ while (done <= 0)
     case HELO_CMD:
     case EHLO_CMD:
 
     case HELO_CMD:
     case EHLO_CMD:
 
-    check_helo(smtp_data);
+    check_helo(smtp_command_argument);
     /* Fall through */
 
     case RSET_CMD:
     /* Fall through */
 
     case RSET_CMD:
@@ -946,7 +944,7 @@ while (done <= 0)
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "503 Sender already given");
 
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "503 Sender already given");
 
-    if (smtp_data[0] == 0)
+    if (smtp_command_argument[0] == 0)
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "501 MAIL FROM must have an address operand");
 
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "501 MAIL FROM must have an address operand");
 
@@ -957,8 +955,8 @@ while (done <= 0)
     /* Apply SMTP rewrite */
 
     raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
     /* Apply SMTP rewrite */
 
     raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
-      rewrite_one(smtp_data, rewrite_smtp|rewrite_smtp_sender, NULL, FALSE,
-        US"", global_rewrite_rules) : smtp_data;
+      rewrite_one(smtp_command_argument, rewrite_smtp|rewrite_smtp_sender, NULL, FALSE,
+        US"", global_rewrite_rules) : smtp_command_argument;
 
     /* Extract the address; the TRUE flag allows <> as valid */
 
 
     /* Extract the address; the TRUE flag allows <> as valid */
 
@@ -1001,7 +999,7 @@ while (done <= 0)
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "503 No sender yet given");
 
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "503 No sender yet given");
 
-    if (smtp_data[0] == 0)
+    if (smtp_command_argument[0] == 0)
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "501 RCPT TO must have an address operand");
 
       /* The function moan_smtp_batch() does not return. */
       moan_smtp_batch(cmd_buffer, "501 RCPT TO must have an address operand");
 
@@ -1016,8 +1014,8 @@ while (done <= 0)
     recipient address */
 
     recipient = ((rewrite_existflags & rewrite_smtp) != 0)?
     recipient address */
 
     recipient = ((rewrite_existflags & rewrite_smtp) != 0)?
-      rewrite_one(smtp_data, rewrite_smtp, NULL, FALSE, US"",
-        global_rewrite_rules) : smtp_data;
+      rewrite_one(smtp_command_argument, rewrite_smtp, NULL, FALSE, US"",
+        global_rewrite_rules) : smtp_command_argument;
 
     /* rfc821_domains = TRUE; << no longer needed */
     recipient = parse_extract_address(recipient, &errmess, &start, &end,
 
     /* rfc821_domains = TRUE; << no longer needed */
     recipient = parse_extract_address(recipient, &errmess, &start, &end,
@@ -1546,8 +1544,7 @@ if (acl_smtp_connect != NULL)
   {
   int rc;
   uschar *user_msg, *log_msg;
   {
   int rc;
   uschar *user_msg, *log_msg;
-  smtp_data = US"in \"connect\" ACL";    /* For logged failure message */
-  rc = acl_check(ACL_WHERE_CONNECT, US"", acl_smtp_connect, &user_msg,
+  rc = acl_check(ACL_WHERE_CONNECT, NULL, acl_smtp_connect, &user_msg,
     &log_msg);
   if (rc != OK)
     {
     &log_msg);
   if (rc != OK)
     {
@@ -1816,12 +1813,15 @@ int code = acl_wherecodes[where];
 BOOL drop = rc == FAIL_DROP;
 uschar *lognl;
 uschar *sender_info = US"";
 BOOL drop = rc == FAIL_DROP;
 uschar *lognl;
 uschar *sender_info = US"";
-uschar *what = (where == ACL_WHERE_PREDATA)? US"DATA" :
+uschar *what =
 #ifdef WITH_CONTENT_SCAN
 #ifdef WITH_CONTENT_SCAN
-               (where == ACL_WHERE_MIME)? US"during MIME ACL checks" :
+  (where == ACL_WHERE_MIME)? US"during MIME ACL checks" :
 #endif
 #endif
-               (where == ACL_WHERE_DATA)? US"after DATA" :
-  string_sprintf("%s %s", acl_wherenames[where], smtp_data);
+  (where == ACL_WHERE_PREDATA)? US"DATA" :
+  (where == ACL_WHERE_DATA)? US"after DATA" :
+  (smtp_command_argument == NULL)?
+    string_sprintf("%s in \"connect\" ACL", acl_wherenames[where]) :
+    string_sprintf("%s %s", acl_wherenames[where], smtp_command_argument);
 
 if (drop) rc = FAIL;
 
 
 if (drop) rc = FAIL;
 
@@ -2179,8 +2179,7 @@ while (done <= 0)
 
     if (acl_smtp_auth != NULL)
       {
 
     if (acl_smtp_auth != NULL)
       {
-      rc = acl_check(ACL_WHERE_AUTH, smtp_data, acl_smtp_auth, &user_msg,
-        &log_msg);
+      rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth, &user_msg, &log_msg);
       if (rc != OK)
         {
         done = smtp_handle_acl_fail(ACL_WHERE_AUTH, rc, user_msg, log_msg);
       if (rc != OK)
         {
         done = smtp_handle_acl_fail(ACL_WHERE_AUTH, rc, user_msg, log_msg);
@@ -2190,8 +2189,8 @@ while (done <= 0)
 
     /* Find the name of the requested authentication mechanism. */
 
 
     /* Find the name of the requested authentication mechanism. */
 
-    s = smtp_data;
-    while ((c = *smtp_data) != 0 && !isspace(c))
+    s = smtp_command_argument;
+    while ((c = *smtp_command_argument) != 0 && !isspace(c))
       {
       if (!isalnum(c) && c != '-' && c != '_')
         {
       {
       if (!isalnum(c) && c != '-' && c != '_')
         {
@@ -2199,16 +2198,16 @@ while (done <= 0)
           US"invalid character in authentication mechanism name");
         goto COMMAND_LOOP;
         }
           US"invalid character in authentication mechanism name");
         goto COMMAND_LOOP;
         }
-      smtp_data++;
+      smtp_command_argument++;
       }
 
     /* If not at the end of the line, we must be at white space. Terminate the
     name and move the pointer on to any data that may be present. */
 
       }
 
     /* If not at the end of the line, we must be at white space. Terminate the
     name and move the pointer on to any data that may be present. */
 
-    if (*smtp_data != 0)
+    if (*smtp_command_argument != 0)
       {
       {
-      *smtp_data++ = 0;
-      while (isspace(*smtp_data)) smtp_data++;
+      *smtp_command_argument++ = 0;
+      while (isspace(*smtp_command_argument)) smtp_command_argument++;
       }
 
     /* Search for an authentication mechanism which is configured for use
       }
 
     /* Search for an authentication mechanism which is configured for use
@@ -2238,7 +2237,7 @@ while (done <= 0)
     expand_nmax = 0;
     expand_nlength[0] = 0;   /* $0 contains nothing */
 
     expand_nmax = 0;
     expand_nlength[0] = 0;   /* $0 contains nothing */
 
-    c = (au->info->servercode)(au, smtp_data);
+    c = (au->info->servercode)(au, smtp_command_argument);
     if (au->set_id != NULL) set_id = expand_string(au->set_id);
     expand_nmax = -1;        /* Reset numeric variables */
 
     if (au->set_id != NULL) set_id = expand_string(au->set_id);
     expand_nmax = -1;        /* Reset numeric variables */
 
@@ -2354,14 +2353,14 @@ while (done <= 0)
     /* Reject the HELO if its argument was invalid or non-existent. A
     successful check causes the argument to be saved in malloc store. */
 
     /* Reject the HELO if its argument was invalid or non-existent. A
     successful check causes the argument to be saved in malloc store. */
 
-    if (!check_helo(smtp_data))
+    if (!check_helo(smtp_command_argument))
       {
       smtp_printf("501 Syntactically invalid %s argument(s)\r\n", hello);
 
       log_write(0, LOG_MAIN|LOG_REJECT, "rejected %s from %s: syntactically "
         "invalid argument(s): %s", hello, host_and_ident(FALSE),
       {
       smtp_printf("501 Syntactically invalid %s argument(s)\r\n", hello);
 
       log_write(0, LOG_MAIN|LOG_REJECT, "rejected %s from %s: syntactically "
         "invalid argument(s): %s", hello, host_and_ident(FALSE),
-        (*smtp_data == 0)? US"(no argument given)" :
-                           string_printing(smtp_data));
+        (*smtp_command_argument == 0)? US"(no argument given)" :
+                           string_printing(smtp_command_argument));
 
       if (++synprot_error_count > smtp_max_synprot_errors)
         {
 
       if (++synprot_error_count > smtp_max_synprot_errors)
         {
@@ -2384,7 +2383,7 @@ while (done <= 0)
     if (!sender_host_unknown)
       {
       BOOL old_helo_verified = helo_verified;
     if (!sender_host_unknown)
       {
       BOOL old_helo_verified = helo_verified;
-      uschar *p = smtp_data;
+      uschar *p = smtp_command_argument;
 
       while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
       *p = 0;
 
       while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
       *p = 0;
@@ -2443,8 +2442,7 @@ while (done <= 0)
 
     if (acl_smtp_helo != NULL)
       {
 
     if (acl_smtp_helo != NULL)
       {
-      rc = acl_check(ACL_WHERE_HELO, smtp_data, acl_smtp_helo, &user_msg,
-        &log_msg);
+      rc = acl_check(ACL_WHERE_HELO, NULL, acl_smtp_helo, &user_msg, &log_msg);
       if (rc != OK)
         {
         done = smtp_handle_acl_fail(ACL_WHERE_HELO, rc, user_msg, log_msg);
       if (rc != OK)
         {
         done = smtp_handle_acl_fail(ACL_WHERE_HELO, rc, user_msg, log_msg);
@@ -2660,7 +2658,7 @@ while (done <= 0)
       break;
       }
 
       break;
       }
 
-    if (smtp_data[0] == 0)
+    if (smtp_command_argument[0] == 0)
       {
       done = synprot_error(L_smtp_protocol_error, 501, NULL,
         US"MAIL must have an address operand");
       {
       done = synprot_error(L_smtp_protocol_error, 501, NULL,
         US"MAIL must have an address operand");
@@ -2819,8 +2817,8 @@ while (done <= 0)
     TRUE flag allows "<>" as a sender address. */
 
     raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
     TRUE flag allows "<>" as a sender address. */
 
     raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
-      rewrite_one(smtp_data, rewrite_smtp, NULL, FALSE, US"",
-        global_rewrite_rules) : smtp_data;
+      rewrite_one(smtp_command_argument, rewrite_smtp, NULL, FALSE, US"",
+        global_rewrite_rules) : smtp_command_argument;
 
     /* rfc821_domains = TRUE; << no longer needed */
     raw_sender =
 
     /* rfc821_domains = TRUE; << no longer needed */
     raw_sender =
@@ -2830,7 +2828,7 @@ while (done <= 0)
 
     if (raw_sender == NULL)
       {
 
     if (raw_sender == NULL)
       {
-      done = synprot_error(L_smtp_syntax_error, 501, smtp_data, errmess);
+      done = synprot_error(L_smtp_syntax_error, 501, smtp_command_argument, errmess);
       break;
       }
 
       break;
       }
 
@@ -2890,7 +2888,7 @@ while (done <= 0)
       else
         {
         smtp_printf("501 %s: sender address must contain a domain\r\n",
       else
         {
         smtp_printf("501 %s: sender address must contain a domain\r\n",
-          smtp_data);
+          smtp_command_argument);
         log_write(L_smtp_syntax_error,
           LOG_MAIN|LOG_REJECT,
           "unqualified sender rejected: <%s> %s%s",
         log_write(L_smtp_syntax_error,
           LOG_MAIN|LOG_REJECT,
           "unqualified sender rejected: <%s> %s%s",
@@ -2958,7 +2956,7 @@ while (done <= 0)
 
     /* Check for an operand */
 
 
     /* Check for an operand */
 
-    if (smtp_data[0] == 0)
+    if (smtp_command_argument[0] == 0)
       {
       done = synprot_error(L_smtp_syntax_error, 501, NULL,
         US"RCPT must have an address operand");
       {
       done = synprot_error(L_smtp_syntax_error, 501, NULL,
         US"RCPT must have an address operand");
@@ -2970,8 +2968,8 @@ while (done <= 0)
     as a recipient address */
 
     recipient = ((rewrite_existflags & rewrite_smtp) != 0)?
     as a recipient address */
 
     recipient = ((rewrite_existflags & rewrite_smtp) != 0)?
-      rewrite_one(smtp_data, rewrite_smtp, NULL, FALSE, US"",
-        global_rewrite_rules) : smtp_data;
+      rewrite_one(smtp_command_argument, rewrite_smtp, NULL, FALSE, US"",
+        global_rewrite_rules) : smtp_command_argument;
 
     /* rfc821_domains = TRUE; << no longer needed */
     recipient = parse_extract_address(recipient, &errmess, &start, &end,
 
     /* rfc821_domains = TRUE; << no longer needed */
     recipient = parse_extract_address(recipient, &errmess, &start, &end,
@@ -2980,7 +2978,7 @@ while (done <= 0)
 
     if (recipient == NULL)
       {
 
     if (recipient == NULL)
       {
-      done = synprot_error(L_smtp_syntax_error, 501, smtp_data, errmess);
+      done = synprot_error(L_smtp_syntax_error, 501, smtp_command_argument, errmess);
       rcpt_fail_count++;
       break;
       }
       rcpt_fail_count++;
       break;
       }
@@ -3010,7 +3008,7 @@ while (done <= 0)
         {
         rcpt_fail_count++;
         smtp_printf("501 %s: recipient address must contain a domain\r\n",
         {
         rcpt_fail_count++;
         smtp_printf("501 %s: recipient address must contain a domain\r\n",
-          smtp_data);
+          smtp_command_argument);
         log_write(L_smtp_syntax_error,
           LOG_MAIN|LOG_REJECT, "unqualified recipient rejected: "
           "<%s> %s%s", recipient, host_and_ident(TRUE),
         log_write(L_smtp_syntax_error,
           LOG_MAIN|LOG_REJECT, "unqualified recipient rejected: "
           "<%s> %s%s", recipient, host_and_ident(TRUE),
@@ -3084,7 +3082,7 @@ while (done <= 0)
         "discarded by %s ACL%s%s", host_and_ident(TRUE),
         (sender_address_unrewritten != NULL)?
         sender_address_unrewritten : sender_address,
         "discarded by %s ACL%s%s", host_and_ident(TRUE),
         (sender_address_unrewritten != NULL)?
         sender_address_unrewritten : sender_address,
-        smtp_data, recipients_discarded? "MAIL" : "RCPT",
+        smtp_command_argument, recipients_discarded? "MAIL" : "RCPT",
         (log_msg == NULL)? US"" : US": ",
         (log_msg == NULL)? US"" : log_msg);
       }
         (log_msg == NULL)? US"" : US": ",
         (log_msg == NULL)? US"" : log_msg);
       }
@@ -3158,8 +3156,7 @@ while (done <= 0)
 
 
     case VRFY_CMD:
 
 
     case VRFY_CMD:
-    rc = acl_check(ACL_WHERE_VRFY, smtp_data, acl_smtp_vrfy, &user_msg,
-      &log_msg);
+    rc = acl_check(ACL_WHERE_VRFY, NULL, acl_smtp_vrfy, &user_msg, &log_msg);
     if (rc != OK)
       done = smtp_handle_acl_fail(ACL_WHERE_VRFY, rc, user_msg, log_msg);
     else
     if (rc != OK)
       done = smtp_handle_acl_fail(ACL_WHERE_VRFY, rc, user_msg, log_msg);
     else
@@ -3168,7 +3165,7 @@ while (done <= 0)
       uschar *s = NULL;
 
       /* rfc821_domains = TRUE; << no longer needed */
       uschar *s = NULL;
 
       /* rfc821_domains = TRUE; << no longer needed */
-      address = parse_extract_address(smtp_data, &errmess, &start, &end,
+      address = parse_extract_address(smtp_command_argument, &errmess, &start, &end,
         &recipient_domain, FALSE);
       /* rfc821_domains = FALSE; << no longer needed */
 
         &recipient_domain, FALSE);
       /* rfc821_domains = FALSE; << no longer needed */
 
@@ -3195,7 +3192,7 @@ while (done <= 0)
             string_sprintf("550 <%s> %s", address, addr->message) :
             string_sprintf("550 <%s> is not deliverable", address);
           log_write(0, LOG_MAIN, "VRFY failed for %s %s",
             string_sprintf("550 <%s> %s", address, addr->message) :
             string_sprintf("550 <%s> is not deliverable", address);
           log_write(0, LOG_MAIN, "VRFY failed for %s %s",
-            smtp_data, host_and_ident(TRUE));
+            smtp_command_argument, host_and_ident(TRUE));
           break;
           }
         }
           break;
           }
         }
@@ -3206,17 +3203,16 @@ while (done <= 0)
 
 
     case EXPN_CMD:
 
 
     case EXPN_CMD:
-    rc = acl_check(ACL_WHERE_EXPN, smtp_data, acl_smtp_expn, &user_msg,
-      &log_msg);
+    rc = acl_check(ACL_WHERE_EXPN, NULL, acl_smtp_expn, &user_msg, &log_msg);
     if (rc != OK)
       done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
     else
       {
       BOOL save_log_testing_mode = log_testing_mode;
       address_test_mode = log_testing_mode = TRUE;
     if (rc != OK)
       done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
     else
       {
       BOOL save_log_testing_mode = log_testing_mode;
       address_test_mode = log_testing_mode = TRUE;
-      (void) verify_address(deliver_make_addr(smtp_data, FALSE), smtp_out,
-        vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, -1, NULL, NULL,
-        NULL);
+      (void) verify_address(deliver_make_addr(smtp_command_argument, FALSE),
+        smtp_out, vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, -1,
+        NULL, NULL, NULL);
       address_test_mode = FALSE;
       log_testing_mode = save_log_testing_mode;    /* true for -bh */
       }
       address_test_mode = FALSE;
       log_testing_mode = save_log_testing_mode;    /* true for -bh */
       }
@@ -3343,7 +3339,7 @@ while (done <= 0)
 
     if (acl_smtp_quit != NULL)
       {
 
     if (acl_smtp_quit != NULL)
       {
-      rc = acl_check(ACL_WHERE_QUIT, US"", 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 (rc == ERROR)
         log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
           log_msg);
@@ -3432,11 +3428,10 @@ while (done <= 0)
       break;
       }
 
       break;
       }
 
-    log_write(L_etrn, LOG_MAIN, "ETRN %s received from %s", smtp_data,
+    log_write(L_etrn, LOG_MAIN, "ETRN %s received from %s", smtp_command_argument,
       host_and_ident(FALSE));
 
       host_and_ident(FALSE));
 
-    rc = acl_check(ACL_WHERE_ETRN, smtp_data, acl_smtp_etrn, &user_msg,
-      &log_msg);
+    rc = acl_check(ACL_WHERE_ETRN, NULL, acl_smtp_etrn, &user_msg, &log_msg);
     if (rc != OK)
       {
       done = smtp_handle_acl_fail(ACL_WHERE_ETRN, rc, user_msg, log_msg);
     if (rc != OK)
       {
       done = smtp_handle_acl_fail(ACL_WHERE_ETRN, rc, user_msg, log_msg);
@@ -3445,7 +3440,7 @@ while (done <= 0)
 
     /* Compute the serialization key for this command. */
 
 
     /* Compute the serialization key for this command. */
 
-    etrn_serialize_key = string_sprintf("etrn-%s\n", smtp_data);
+    etrn_serialize_key = string_sprintf("etrn-%s\n", smtp_command_argument);
 
     /* If a command has been specified for running as a result of ETRN, we
     permit any argument to ETRN. If not, only the # standard form is permitted,
 
     /* If a command has been specified for running as a result of ETRN, we
     permit any argument to ETRN. If not, only the # standard form is permitted,
@@ -3457,7 +3452,7 @@ while (done <= 0)
       uschar *error;
       BOOL rc;
       etrn_command = smtp_etrn_command;
       uschar *error;
       BOOL rc;
       etrn_command = smtp_etrn_command;
-      deliver_domain = smtp_data;
+      deliver_domain = smtp_command_argument;
       rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
         US"ETRN processing", &error);
       deliver_domain = NULL;
       rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
         US"ETRN processing", &error);
       deliver_domain = NULL;
@@ -3474,7 +3469,7 @@ while (done <= 0)
 
     else
       {
 
     else
       {
-      if (*smtp_data++ != '#')
+      if (*smtp_command_argument++ != '#')
         {
         done = synprot_error(L_smtp_syntax_error, 501, NULL,
           US"argument must begin with #");
         {
         done = synprot_error(L_smtp_syntax_error, 501, NULL,
           US"argument must begin with #");
@@ -3482,7 +3477,7 @@ while (done <= 0)
         }
       etrn_command = US"exim -R";
       argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
         }
       etrn_command = US"exim -R";
       argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
-        smtp_data);
+        smtp_command_argument);
       }
 
     /* If we are host-testing, don't actually do anything. */
       }
 
     /* If we are host-testing, don't actually do anything. */
@@ -3504,7 +3499,7 @@ while (done <= 0)
 
     if (smtp_etrn_serialize && !enq_start(etrn_serialize_key))
       {
 
     if (smtp_etrn_serialize && !enq_start(etrn_serialize_key))
       {
-      smtp_printf("458 Already processing %s\r\n", smtp_data);
+      smtp_printf("458 Already processing %s\r\n", smtp_command_argument);
       break;
       }
 
       break;
       }
 
@@ -3613,7 +3608,7 @@ while (done <= 0)
     incomplete_transaction_log(US"too many non-mail commands");
     log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
       "nonmail commands (last was \"%.*s\")",  host_and_ident(FALSE),
     incomplete_transaction_log(US"too many non-mail commands");
     log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
       "nonmail commands (last was \"%.*s\")",  host_and_ident(FALSE),
-      smtp_data - cmd_buffer, cmd_buffer);
+      smtp_command_argument - cmd_buffer, cmd_buffer);
     smtp_printf("554 Too many nonmail commands\r\n");
     done = 1;   /* Pretend eof - drops connection */
     break;
     smtp_printf("554 Too many nonmail commands\r\n");
     done = 1;   /* Pretend eof - drops connection */
     break;