Added acl_not_smtp_mime. This involved a bit of refactoring of the
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 4 Apr 2005 10:33:49 +0000 (10:33 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 4 Apr 2005 10:33:49 +0000 (10:33 +0000)
content scanning code. Also, updated doc/OptionList.txt with all the
content-scanning options (none had been added.)

doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/mime.c
src/src/readconf.c
src/src/receive.c

index cf31d4690deb86cedde8d74d6dc6bae5c4ce86aa..87e001f27e6376ca023b526a6faef6598799239d 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.106 2005/03/29 15:53:12 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.107 2005/04/04 10:33:49 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -117,6 +117,8 @@ PH/20 When checking for unexpected SMTP input at connect time (before writing
       There were reports of junk text (parts of files, etc) appearing after
       "input=".
 
       There were reports of junk text (parts of files, etc) appearing after
       "input=".
 
+PH/21 Added acl_not_smtp_mime to allow for MIME scanning for non-SMTP messages.
+
 
 A note about Exim versions 4.44 and 4.50
 ----------------------------------------
 
 A note about Exim versions 4.44 and 4.50
 ----------------------------------------
index 51ac28c3798bb878dcf0162f692b178b61e30a6a..6f3ac86d1b3952403b917334ad77777636444e92 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.31 2005/03/29 14:19:21 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.32 2005/04/04 10:33:49 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -96,6 +96,10 @@ PH/03 There is a new value for RADIUS_LIB_TYPE that can be set in
       in use from radiusclient 0.4.0 onwards, be used. It does not appear to be
       possible to detect the different versions automatically.
 
       in use from radiusclient 0.4.0 onwards, be used. It does not appear to be
       possible to detect the different versions automatically.
 
+PH/04 There is a new option called acl_not_smtp_mime that allows you to scan
+      MIME parts in non-SMTP messages. It operates in exactly the same way as
+      acl_smtp_mime
+
 
 Version 4.50
 ------------
 
 Version 4.50
 ------------
index 49b76b3d66ab8c8664a5e98053494b129aec36a1..ba727b0bbff920f6f7d54d463ca202d87c89dbed 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.6 2005/03/03 08:54:59 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.7 2005/04/04 10:33:49 ph10 Exp $
 
 LISTS OF EXIM OPTIONS
 ---------------------
 
 LISTS OF EXIM OPTIONS
 ---------------------
@@ -52,6 +52,7 @@ in fact some of them were inherited from earlier versions.
 -----------------------------------------------------------------------------------------
 accept_8bitmime                      boolean         false         main              1.60
 acl_not_smtp                         string*         unset         main              4.11
 -----------------------------------------------------------------------------------------
 accept_8bitmime                      boolean         false         main              1.60
 acl_not_smtp                         string*         unset         main              4.11
+acl_not_smtp_mime                    string*         unset         main              4.51 with content scan
 acl_smtp_auth                        string*         unset         main              4.00
 acl_smtp_connect                     string*         unset         main              4.11
 acl_smtp_data                        string*         unset         main              4.00
 acl_smtp_auth                        string*         unset         main              4.00
 acl_smtp_connect                     string*         unset         main              4.11
 acl_smtp_data                        string*         unset         main              4.00
@@ -60,6 +61,7 @@ acl_smtp_expn                        string*         unset         main
 acl_smtp_helo                        string*         unset         main              4.20
 acl_smtp_mail                        string*         unset         main              4.11
 acl_smtp_mailauth                    string*         unset         main              4.21
 acl_smtp_helo                        string*         unset         main              4.20
 acl_smtp_mail                        string*         unset         main              4.11
 acl_smtp_mailauth                    string*         unset         main              4.21
+acl_smtp_mime                        string*         unset         main              4.50 with content scan
 acl_smtp_predata                     string*         unset         main              4.43
 acl_smtp_quit                        string*         unset         main              4.43
 acl_smtp_rcpt                        string*         unset         main              4.00
 acl_smtp_predata                     string*         unset         main              4.43
 acl_smtp_quit                        string*         unset         main              4.43
 acl_smtp_rcpt                        string*         unset         main              4.00
@@ -83,6 +85,7 @@ auth_advertise_hosts                 host list       "*"           main
 authenticated_sender                 string*         unset         smtp              4.14
 authenticate_hosts                   host list       unset         smtp              3.13
 auto_thaw                            time            0s            main
 authenticated_sender                 string*         unset         smtp              4.14
 authenticate_hosts                   host list       unset         smtp              3.13
 auto_thaw                            time            0s            main
+av_scanner                           string*         +             main              4.50 with content scan
 batch_id                             string          unset         appendfile        4.00
                                                      unset         lmtp              4.00
                                                      unset         pipe              4.00
 batch_id                             string          unset         appendfile        4.00
                                                      unset         lmtp              4.00
                                                      unset         pipe              4.00
@@ -466,6 +469,7 @@ smtp_receive_timeout                 time            5m            main
 smtp_reserve_hosts                   host list       unset         main
 smtp_return_error_details            boolean         false         main              4.11
 socket                               string*         unset         lmtp              4.11
 smtp_reserve_hosts                   host list       unset         main
 smtp_return_error_details            boolean         false         main              4.11
 socket                               string*         unset         lmtp              4.11
+spamd_address                        string          +             main              4.50 with content scan
 split_spool_directory                boolean         false         main              1.70
 spool_directory                      string          ++            main
 srv_fail_domains                     domain list     unset         dnslookup         4.43
 split_spool_directory                boolean         false         main              1.70
 spool_directory                      string          ++            main
 srv_fail_domains                     domain list     unset         dnslookup         4.43
index 88bc53d74f259121899fe58e8ab5d55230ee4600..1563a55c3bc673eb106c9bafb7b7b49191a18d1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.12 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.13 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -152,8 +152,8 @@ extern void    md5_start(md5 *);
 extern void    millisleep(int);
 #ifdef WITH_CONTENT_SCAN
 struct mime_boundary_context;
 extern void    millisleep(int);
 #ifdef WITH_CONTENT_SCAN
 struct mime_boundary_context;
-extern int     mime_acl_check(FILE *f, struct mime_boundary_context *,
-                              uschar **, uschar **);
+extern int     mime_acl_check(uschar *acl, FILE *f,
+                 struct mime_boundary_context *, uschar **, uschar **);
 extern int     mime_decode(uschar **);
 extern int     mime_regex(uschar **);
 #endif
 extern int     mime_decode(uschar **);
 extern int     mime_regex(uschar **);
 #endif
index 2324e40723a99f27581c95c18b44ea1a8fc903c3..5fe414b43cfd7e8946b7911bf89275fb66105586 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.20 2005/03/22 14:11:54 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.21 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -160,6 +160,9 @@ int address_expansions_count = sizeof(address_expansions)/sizeof(uschar **);
 
 tree_node *acl_anchor          = NULL;
 uschar *acl_not_smtp           = NULL;
 
 tree_node *acl_anchor          = NULL;
 uschar *acl_not_smtp           = NULL;
+#ifdef WITH_CONTENT_SCAN
+uschar *acl_not_smtp_mime      = NULL;
+#endif
 uschar *acl_smtp_auth          = NULL;
 uschar *acl_smtp_connect       = NULL;
 uschar *acl_smtp_data          = NULL;
 uschar *acl_smtp_auth          = NULL;
 uschar *acl_smtp_connect       = NULL;
 uschar *acl_smtp_data          = NULL;
index 404838126e355c8901c31f913de462b5e2cde7f9..37faa9d50bedc949eb7d294cbc99ce523efc4b06 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.13 2005/03/22 14:11:54 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.14 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -102,6 +102,9 @@ extern uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT];
 extern BOOL    accept_8bitmime;        /* Allow *BITMIME incoming */
 extern tree_node *acl_anchor;          /* Tree of named ACLs */
 extern uschar *acl_not_smtp;           /* ACL run for non-SMTP messages */
 extern BOOL    accept_8bitmime;        /* Allow *BITMIME incoming */
 extern tree_node *acl_anchor;          /* Tree of named ACLs */
 extern uschar *acl_not_smtp;           /* ACL run for non-SMTP messages */
+#ifdef WITH_CONTENT_SCAN
+extern uschar *acl_not_smtp_mime;      /* For MIME parts of ditto */
+#endif
 extern uschar *acl_smtp_auth;          /* ACL run for AUTH */
 extern uschar *acl_smtp_connect;       /* ACL run on SMTP connection */
 extern uschar *acl_smtp_data;          /* ACL run after DATA received */
 extern uschar *acl_smtp_auth;          /* ACL run for AUTH */
 extern uschar *acl_smtp_connect;       /* ACL run on SMTP connection */
 extern uschar *acl_smtp_data;          /* ACL run after DATA received */
index f97d25abb3748885f700a579a4a16bba0c305df1..05b6e3e2a00bcfe11b74f6dc98ce003bcfb93915 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/mime.c,v 1.6 2005/03/08 16:57:28 ph10 Exp $ */
+/* $Cambridge: exim/src/src/mime.c,v 1.7 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -502,8 +502,8 @@ int mime_get_header(FILE *f, uschar *header) {
 }
 
 
 }
 
 
-int mime_acl_check(FILE *f, struct mime_boundary_context *context, uschar
-                   **user_msgptr, uschar **log_msgptr) {
+int mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *context,
+                   uschar **user_msgptr, uschar **log_msgptr) {
   int rc = OK;
   uschar *header = NULL;
   struct mime_boundary_context nested_context;
   int rc = OK;
   uschar *header = NULL;
   struct mime_boundary_context nested_context;
@@ -512,7 +512,7 @@ int mime_acl_check(FILE *f, struct mime_boundary_context *context, uschar
   header = (uschar *)malloc(MIME_MAX_HEADER_SIZE+1);
   if (header == NULL) {
     log_write(0, LOG_PANIC,
   header = (uschar *)malloc(MIME_MAX_HEADER_SIZE+1);
   if (header == NULL) {
     log_write(0, LOG_PANIC,
-                 "acl_smtp_mime: can't allocate %d bytes of memory.", MIME_MAX_HEADER_SIZE+1);
+                 "MIME ACL: can't allocate %d bytes of memory.", MIME_MAX_HEADER_SIZE+1);
     return DEFER;
   };
 
     return DEFER;
   };
 
@@ -659,7 +659,7 @@ int mime_acl_check(FILE *f, struct mime_boundary_context *context, uschar
     mime_is_coverletter = !(context && context->context == MBC_ATTACHMENT);
 
     /* call ACL handling function */
     mime_is_coverletter = !(context && context->context == MBC_ATTACHMENT);
 
     /* call ACL handling function */
-    rc = acl_check(ACL_WHERE_MIME, NULL, acl_smtp_mime, user_msgptr, log_msgptr);
+    rc = acl_check(ACL_WHERE_MIME, NULL, acl, user_msgptr, log_msgptr);
 
     mime_stream = NULL;
     mime_current_boundary = NULL;
 
     mime_stream = NULL;
     mime_current_boundary = NULL;
@@ -680,7 +680,7 @@ int mime_acl_check(FILE *f, struct mime_boundary_context *context, uschar
       else
         nested_context.context = MBC_COVERLETTER_ONESHOT;
 
       else
         nested_context.context = MBC_COVERLETTER_ONESHOT;
 
-      rc = mime_acl_check(f, &nested_context, user_msgptr, log_msgptr);
+      rc = mime_acl_check(acl, f, &nested_context, user_msgptr, log_msgptr);
       if (rc != OK) break;
     }
     else if ( (mime_content_type != NULL) &&
       if (rc != OK) break;
     }
     else if ( (mime_content_type != NULL) &&
index 302255ddf20af55db1e0ef8825c0acac335a1913..0fe00cf6bcf2df4c7112bff2172c8aa84607e052 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.5 2005/02/17 11:58:26 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.6 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -135,6 +135,9 @@ static optionlist optionlist_config[] = {
   { "*set_system_filter_user",  opt_bool|opt_hidden, &system_filter_uid_set },
   { "accept_8bitmime",          opt_bool,        &accept_8bitmime },
   { "acl_not_smtp",             opt_stringptr,   &acl_not_smtp },
   { "*set_system_filter_user",  opt_bool|opt_hidden, &system_filter_uid_set },
   { "accept_8bitmime",          opt_bool,        &accept_8bitmime },
   { "acl_not_smtp",             opt_stringptr,   &acl_not_smtp },
+#ifdef WITH_CONTENT_SCAN
+  { "acl_not_smtp_mime",        opt_stringptr,   &acl_not_smtp_mime },
+#endif
   { "acl_smtp_auth",            opt_stringptr,   &acl_smtp_auth },
   { "acl_smtp_connect",         opt_stringptr,   &acl_smtp_connect },
   { "acl_smtp_data",            opt_stringptr,   &acl_smtp_data },
   { "acl_smtp_auth",            opt_stringptr,   &acl_smtp_auth },
   { "acl_smtp_connect",         opt_stringptr,   &acl_smtp_connect },
   { "acl_smtp_data",            opt_stringptr,   &acl_smtp_data },
index e4ce9cb233862b775ad5c4c83c782cca0cb73948..325544643b08c2e43bb1e05d07058614b9f5df12 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.12 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.13 2005/04/04 10:33:49 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -510,7 +510,7 @@ for (count = 0; count < recipients_count; count++)
     {
     if ((--recipients_count - count) > 0)
       memmove(recipients_list + count, recipients_list + count + 1,
     {
     if ((--recipients_count - count) > 0)
       memmove(recipients_list + count, recipients_list + count + 1,
-              (recipients_count - count)*sizeof(recipient_item));
+        (recipients_count - count)*sizeof(recipient_item));
     return TRUE;
     }
   }
     return TRUE;
     }
   }
@@ -1008,6 +1008,146 @@ return s;
 
 
 
 
 
 
+/*************************************************
+*       Run the MIME ACL on a message            *
+*************************************************/
+
+/* This code is in a subroutine so that it can be used for both SMTP
+and non-SMTP messages. It is called with a non-NULL ACL pointer.
+
+Arguments:
+  acl                The ACL to run (acl_smtp_mime or acl_not_smtp_mime)
+  smtp_yield_ptr     Set FALSE to kill messages after dropped connection
+  smtp_reply_ptr     Where SMTP reply is being built
+  blackholed_by_ptr  Where "blackholed by" message is being built
+
+Returns:             TRUE to carry on; FALSE to abandon the message
+*/
+
+static BOOL
+run_mime_acl(uschar *acl, BOOL *smtp_yield_ptr, uschar **smtp_reply_ptr,
+  uschar **blackholed_by_ptr)
+{
+FILE *mbox_file;
+uschar rfc822_file_path[2048];
+unsigned long mbox_size;
+header_line *my_headerlist;
+uschar *user_msg, *log_msg;
+int mime_part_count_buffer = -1;
+int rc;
+
+memset(CS rfc822_file_path,0,2048);
+
+/* check if it is a MIME message */
+my_headerlist = header_list;
+while (my_headerlist != NULL) {
+  /* skip deleted headers */
+  if (my_headerlist->type == '*') {
+    my_headerlist = my_headerlist->next;
+    continue;
+  };
+  if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0) {
+    DEBUG(D_receive) debug_printf("Found Content-Type: header - executing acl_smtp_mime.\n");
+    goto DO_MIME_ACL;
+  };
+  my_headerlist = my_headerlist->next;
+};
+
+DEBUG(D_receive) debug_printf("No Content-Type: header - presumably not a MIME message.\n");
+return TRUE;
+
+DO_MIME_ACL:
+/* make sure the eml mbox file is spooled up */
+mbox_file = spool_mbox(&mbox_size);
+if (mbox_file == NULL) {
+  /* error while spooling */
+  log_write(0, LOG_MAIN|LOG_PANIC,
+         "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
+  Uunlink(spool_name);
+  unspool_mbox();
+  smtp_respond(451, TRUE, US"temporary local problem");
+  message_id[0] = 0;            /* Indicate no message accepted */
+  *smtp_reply_ptr = US"";       /* Indicate reply already sent */
+  return FALSE;                 /* Indicate skip to end of receive function */
+};
+
+mime_is_rfc822 = 0;
+
+MIME_ACL_CHECK:
+mime_part_count = -1;
+rc = mime_acl_check(acl, mbox_file, NULL, &user_msg, &log_msg);
+fclose(mbox_file);
+
+if (Ustrlen(rfc822_file_path) > 0) {
+  mime_part_count = mime_part_count_buffer;
+
+  if (unlink(CS rfc822_file_path) == -1) {
+    log_write(0, LOG_PANIC,
+         "acl_smtp_mime: can't unlink RFC822 spool file, skipping.");
+      goto END_MIME_ACL;
+  };
+};
+
+/* check if we must check any message/rfc822 attachments */
+if (rc == OK) {
+  uschar temp_path[1024];
+  int n;
+  struct dirent *entry;
+  DIR *tempdir;
+
+  snprintf(CS temp_path, 1024, "%s/scan/%s", spool_directory, message_id);
+
+ tempdir = opendir(CS temp_path);
+ n = 0;
+ do {
+   entry = readdir(tempdir);
+   if (entry == NULL) break;
+    if (strncmpic(US entry->d_name,US"__rfc822_",9) == 0) {
+      snprintf(CS rfc822_file_path, 2048,"%s/scan/%s/%s", spool_directory, message_id, entry->d_name);
+     debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path);
+     break;
+    };
+ } while (1);
+ closedir(tempdir);
+
+  if (entry != NULL) {
+    mbox_file = Ufopen(rfc822_file_path,"r");
+    if (mbox_file == NULL) {
+      log_write(0, LOG_PANIC,
+         "acl_smtp_mime: can't open RFC822 spool file, skipping.");
+      unlink(CS rfc822_file_path);
+      goto END_MIME_ACL;
+    };
+    /* set RFC822 expansion variable */
+    mime_is_rfc822 = 1;
+    mime_part_count_buffer = mime_part_count;
+    goto MIME_ACL_CHECK;
+  };
+};
+
+END_MIME_ACL:
+add_acl_headers(US"MIME");
+if (rc == DISCARD)
+  {
+  recipients_count = 0;
+  *blackholed_by_ptr = US"MIME ACL";
+  }
+else if (rc != OK)
+  {
+  Uunlink(spool_name);
+  unspool_mbox();
+  if (smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0)
+    *smtp_yield_ptr = FALSE;    /* No more messsages after dropped connection */
+  *smtp_reply_ptr = US"";       /* Indicate reply already sent */
+  message_id[0] = 0;            /* Indicate no message accepted */
+  return FALSE;                 /* Cause skip to end of receive function */
+  };
+
+return TRUE;
+}
+
+
+
 /*************************************************
 *                 Receive message                *
 *************************************************/
 /*************************************************
 *                 Receive message                *
 *************************************************/
@@ -2754,127 +2894,13 @@ else
 #endif
 
 #ifdef WITH_CONTENT_SCAN
 #endif
 
 #ifdef WITH_CONTENT_SCAN
-     /* MIME ACL hook */
-    if (acl_smtp_mime != NULL && recipients_count > 0)
-      {
-      FILE *mbox_file;
-      uschar rfc822_file_path[2048];
-      unsigned long mbox_size;
-      header_line *my_headerlist;
-      uschar *user_msg, *log_msg;
-      int mime_part_count_buffer = -1;
-
-      memset(CS rfc822_file_path,0,2048);
-
-      /* check if it is a MIME message */
-      my_headerlist = header_list;
-      while (my_headerlist != NULL) {
-        /* skip deleted headers */
-        if (my_headerlist->type == '*') {
-          my_headerlist = my_headerlist->next;
-          continue;
-        };
-        if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0) {
-          DEBUG(D_receive) debug_printf("Found Content-Type: header - executing acl_smtp_mime.\n");
-          goto DO_MIME_ACL;
-        };
-        my_headerlist = my_headerlist->next;
-      };
-
-      DEBUG(D_receive) debug_printf("No Content-Type: header - presumably not a MIME message.\n");
-      goto NO_MIME_ACL;
-
-      DO_MIME_ACL:
-      /* make sure the eml mbox file is spooled up */
-      mbox_file = spool_mbox(&mbox_size);
-      if (mbox_file == NULL) {
-        /* error while spooling */
-        log_write(0, LOG_MAIN|LOG_PANIC,
-               "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
-        Uunlink(spool_name);
-        unspool_mbox();
-        smtp_respond(451, TRUE, US"temporary local problem");
-        message_id[0] = 0;            /* Indicate no message accepted */
-        smtp_reply = US"";            /* Indicate reply already sent */
-        goto TIDYUP;                  /* Skip to end of function */
-      };
-
-      mime_is_rfc822 = 0;
-
-      MIME_ACL_CHECK:
-      mime_part_count = -1;
-      rc = mime_acl_check(mbox_file, NULL, &user_msg, &log_msg);
-      fclose(mbox_file);
-
-      if (Ustrlen(rfc822_file_path) > 0) {
-        mime_part_count = mime_part_count_buffer;
-
-        if (unlink(CS rfc822_file_path) == -1) {
-          log_write(0, LOG_PANIC,
-               "acl_smtp_mime: can't unlink RFC822 spool file, skipping.");
-            goto END_MIME_ACL;
-        };
-      };
-
-      /* check if we must check any message/rfc822 attachments */
-      if (rc == OK) {
-        uschar temp_path[1024];
-        int n;
-        struct dirent *entry;
-        DIR *tempdir;
-
-        snprintf(CS temp_path, 1024, "%s/scan/%s", spool_directory, message_id);
-
-       tempdir = opendir(CS temp_path);
-       n = 0;
-       do {
-         entry = readdir(tempdir);
-         if (entry == NULL) break;
-          if (strncmpic(US entry->d_name,US"__rfc822_",9) == 0) {
-            snprintf(CS rfc822_file_path, 2048,"%s/scan/%s/%s", spool_directory, message_id, entry->d_name);
-           debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path);
-           break;
-          };
-       } while (1);
-       closedir(tempdir);
-
-        if (entry != NULL) {
-          mbox_file = Ufopen(rfc822_file_path,"r");
-          if (mbox_file == NULL) {
-            log_write(0, LOG_PANIC,
-               "acl_smtp_mime: can't open RFC822 spool file, skipping.");
-            unlink(CS rfc822_file_path);
-            goto END_MIME_ACL;
-          };
-          /* set RFC822 expansion variable */
-          mime_is_rfc822 = 1;
-          mime_part_count_buffer = mime_part_count;
-          goto MIME_ACL_CHECK;
-        };
-      };
-
-      END_MIME_ACL:
-      add_acl_headers(US"MIME");
-      if (rc == DISCARD)
-        {
-        recipients_count = 0;
-        blackholed_by = US"MIME ACL";
-        }
-      else if (rc != OK)
-        {
-        Uunlink(spool_name);
-        unspool_mbox();
-        if (smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0)
-          smtp_yield = FALSE;    /* No more messsages 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 */
-        };
-      }
-
-    NO_MIME_ACL:
+    if (acl_smtp_mime != NULL &&
+        !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by))
+      goto TIDYUP;
 #endif /* WITH_CONTENT_SCAN */
 
 #endif /* WITH_CONTENT_SCAN */
 
+    /* Check the recipients count again, as the MIME ACL might have changed
+    them. */
 
     if (acl_smtp_data != NULL && recipients_count > 0)
       {
 
     if (acl_smtp_data != NULL && recipients_count > 0)
       {
@@ -2906,39 +2932,56 @@ else
   /* Handle non-SMTP and batch SMTP (i.e. non-interactive) messages. Note that
   we cannot take different actions for permanent and temporary rejections. */
 
   /* Handle non-SMTP and batch SMTP (i.e. non-interactive) messages. Note that
   we cannot take different actions for permanent and temporary rejections. */
 
-  else if (acl_not_smtp != NULL)
+  else
     {
     {
-    uschar *user_msg, *log_msg;
-    rc = acl_check(ACL_WHERE_NOTSMTP, NULL, acl_not_smtp, &user_msg, &log_msg);
-    if (rc == DISCARD)
-      {
-      recipients_count = 0;
-      blackholed_by = US"non-SMTP ACL";
-      if (log_msg != NULL) blackhole_log_msg = string_sprintf(": %s", log_msg);
-      }
-    else if (rc != OK)
+
+#ifdef WITH_CONTENT_SCAN
+    if (acl_not_smtp_mime != NULL &&
+        !run_mime_acl(acl_not_smtp_mime, &smtp_yield, &smtp_reply,
+          &blackholed_by))
+      goto TIDYUP;
+#endif /* WITH_CONTENT_SCAN */
+
+    if (acl_not_smtp != NULL)
       {
       {
-      Uunlink(spool_name);
-      log_write(0, LOG_MAIN|LOG_REJECT, "F=<%s> rejected by non-SMTP ACL: %s",
-        sender_address, log_msg);
-      if (user_msg == NULL) user_msg = US"local configuration problem";
-      if (smtp_batched_input)
+      uschar *user_msg, *log_msg;
+      rc = acl_check(ACL_WHERE_NOTSMTP, NULL, acl_not_smtp, &user_msg, &log_msg);
+      if (rc == DISCARD)
         {
         {
-        moan_smtp_batch(NULL, "%d %s", 550, user_msg);
-        /* Does not return */
+        recipients_count = 0;
+        blackholed_by = US"non-SMTP ACL";
+        if (log_msg != NULL)
+          blackhole_log_msg = string_sprintf(": %s", log_msg);
         }
         }
-      else
+      else if (rc != OK)
         {
         {
-        fseek(data_file, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET);
-        give_local_error(ERRMESS_LOCAL_ACL, user_msg,
-          US"message rejected by non-SMTP ACL: ", error_rc, data_file,
-            header_list);
-        /* Does not return */
+        Uunlink(spool_name);
+#ifdef WITH_CONTENT_SCAN
+        unspool_mbox();
+#endif
+        log_write(0, LOG_MAIN|LOG_REJECT, "F=<%s> rejected by non-SMTP ACL: %s",
+          sender_address, log_msg);
+        if (user_msg == NULL) user_msg = US"local configuration problem";
+        if (smtp_batched_input)
+          {
+          moan_smtp_batch(NULL, "%d %s", 550, user_msg);
+          /* Does not return */
+          }
+        else
+          {
+          fseek(data_file, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET);
+          give_local_error(ERRMESS_LOCAL_ACL, user_msg,
+            US"message rejected by non-SMTP ACL: ", error_rc, data_file,
+              header_list);
+          /* Does not return */
+          }
         }
         }
+      add_acl_headers(US"non-SMTP");
       }
       }
-    add_acl_headers(US"non-SMTP");
     }
 
     }
 
+  /* The applicable ACLs have been run */
+
   if (deliver_freeze) frozen_by = US"ACL";     /* for later logging */
   if (queue_only_policy) queued_by = US"ACL";
 
   if (deliver_freeze) frozen_by = US"ACL";     /* for later logging */
   if (queue_only_policy) queued_by = US"ACL";