Add log_reject_target as an ACL modifier.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 25 Sep 2006 10:14:20 +0000 (10:14 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 25 Sep 2006 10:14:20 +0000 (10:14 +0000)
14 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/globals.c
src/src/globals.h
src/src/receive.c
src/src/smtp_in.c
test/confs/0539 [new file with mode: 0644]
test/log/0539 [new file with mode: 0644]
test/paniclog/0539 [new file with mode: 0644]
test/rejectlog/0539 [new file with mode: 0644]
test/scripts/0000-Basic/0539 [new file with mode: 0644]
test/stderr/0539 [new file with mode: 0644]
test/stdout/0539 [new file with mode: 0644]

index eebf9122d8f2236493098a1a63b79103763b2806..ba67b731549ed972e5bd82c6b7ce4d9f603c29cc 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.396 2006/09/22 08:41:59 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.397 2006/09/25 10:14:20 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -52,6 +52,10 @@ JJ/01 exipick 20060919.0, allow for arbitrary acl_ variables introduced
 JJ/02 exipick 20060919.0, --show-vars args can now be regular expressions,
       miscellaneous code fixes
 
+PH/10 Added the log_reject_target ACL modifier to specify where to log
+      rejections.
+
+
 
 Exim version 4.63
 -----------------
index 6ee8f6bdcb69bd44b4393f150d7bc1a7cfd7ad6a..ae4043cc178454f87df5bda0624b955d1135b815 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.110 2006/09/19 14:31:06 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.111 2006/09/25 10:14:20 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -37,6 +37,19 @@ Version 4.64
    used, spool files written by the new release can be read by earlier
    releases.
 
+2. There is a new ACL modifier called log_reject_target. It makes it possible
+   to specify which logs are used for messages about ACL rejections. Its
+   argument is a list of words which can be "main", "reject", or "panic". The
+   default is "main:reject". The list may be empty, in which case a rejection
+   is not logged at all. For example, this ACL fragment writes no logging
+   information when access is denied:
+
+     deny <some conditions>
+          log_reject_target =
+
+   The modifier can be used in SMTP and non-SMTP ACLs. It applies to both
+   permanent and temporary rejections.
+
 
 Version 4.63
 ------------
index 5709a11aba41dfca9e3cf09c0b204da510810257..8274e0c73f00704467b8d985284ecb25ce82d736 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.65 2006/09/19 14:31:06 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.66 2006/09/25 10:14:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -65,6 +65,7 @@ enum { ACLC_ACL,
        ACLC_HOSTS,
        ACLC_LOCAL_PARTS,
        ACLC_LOG_MESSAGE,
+       ACLC_LOG_REJECT_TARGET,
        ACLC_LOGWRITE,
 #ifdef WITH_CONTENT_SCAN
        ACLC_MALWARE,
@@ -90,8 +91,9 @@ enum { ACLC_ACL,
        ACLC_VERIFY };
 
 /* ACL conditions/modifiers: "delay", "control", "endpass", "message",
-"log_message", "logwrite", and "set" are modifiers that look like conditions
-but always return TRUE. They are used for their side effects. */
+"log_message", "log_reject_target", "logwrite", and "set" are modifiers that
+look like conditions but always return TRUE. They are used for their side
+effects. */
 
 static uschar *conditions[] = {
   US"acl",
@@ -117,8 +119,15 @@ static uschar *conditions[] = {
   US"dk_senders",
   US"dk_status",
 #endif
-  US"dnslists", US"domains", US"encrypted",
-  US"endpass", US"hosts", US"local_parts", US"log_message", US"logwrite",
+  US"dnslists",
+  US"domains",
+  US"encrypted",
+  US"endpass",
+  US"hosts",
+  US"local_parts",
+  US"log_message",
+  US"log_reject_target",
+  US"logwrite",
 #ifdef WITH_CONTENT_SCAN
   US"malware",
 #endif
@@ -232,6 +241,7 @@ static uschar cond_expand_at_top[] = {
   FALSE,   /* hosts */
   FALSE,   /* local_parts */
   TRUE,    /* log_message */
+  TRUE,    /* log_reject_target */
   TRUE,    /* logwrite */
 #ifdef WITH_CONTENT_SCAN
   TRUE,    /* malware */
@@ -290,6 +300,7 @@ static uschar cond_modifiers[] = {
   FALSE,   /* hosts */
   FALSE,   /* local_parts */
   TRUE,    /* log_message */
+  TRUE,    /* log_reject_target */
   TRUE,    /* logwrite */
 #ifdef WITH_CONTENT_SCAN
   FALSE,   /* malware */
@@ -433,6 +444,8 @@ static unsigned int cond_forbids[] = {
 
   0,                                               /* log_message */
 
+  0,                                               /* log_reject_target */
+
   0,                                               /* logwrite */
 
   #ifdef WITH_CONTENT_SCAN
@@ -2844,6 +2857,29 @@ for (; cb != NULL; cb = cb->next)
       &deliver_localpart_data);
     break;
 
+    case ACLC_LOG_REJECT_TARGET:
+      {
+      int logbits = 0;
+      int sep = 0;
+      uschar *s = arg;
+      uschar *ss;
+      while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size))
+              != NULL)
+        {
+        if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN;
+        else if (Ustrcmp(ss, "panic") == 0) logbits |= LOG_PANIC;
+        else if (Ustrcmp(ss, "reject") == 0) logbits |= LOG_REJECT;
+        else
+          {
+          logbits |= LOG_MAIN|LOG_REJECT;
+          log_write(0, LOG_MAIN|LOG_PANIC, "unknown log name \"%s\" in "
+            "\"log_reject_target\" in %s ACL", ss, acl_wherenames[where]);
+          }
+        }
+      log_reject_target = logbits;
+      }
+    break;
+
     case ACLC_LOGWRITE:
       {
       int logbits = 0;
@@ -2870,6 +2906,8 @@ for (; cb != NULL; cb = cb->next)
         s++;
         }
       while (isspace(*s)) s++;
+
+
       if (logbits == 0) logbits = LOG_MAIN;
       log_write(0, logbits, "%s", string_printing(s));
       }
@@ -2878,7 +2916,7 @@ for (; cb != NULL; cb = cb->next)
     #ifdef WITH_CONTENT_SCAN
     case ACLC_MALWARE:
       {
-      /* Seperate the regular expression and any optional parameters. */
+      /* Separate the regular expression and any optional parameters. */
       uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
       /* Run the malware backend. */
       rc = malware(&ss);
@@ -3513,6 +3551,7 @@ address_item *addr = NULL;
 *user_msgptr = *log_msgptr = NULL;
 sender_verified_failed = NULL;
 ratelimiters_cmd = NULL;
+log_reject_target = LOG_MAIN|LOG_REJECT;
 
 if (where == ACL_WHERE_RCPT)
   {
index a694053c56d5f9de238cea11cd5f5a510a92dbad..7c3f8e9f1011babe7971ad8b7f9c534a8d73f09d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.58 2006/09/19 11:28:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.59 2006/09/25 10:14:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -703,11 +703,12 @@ bit_table log_options[]        = {
 };
 
 int     log_options_count      = sizeof(log_options)/sizeof(bit_table);
-unsigned int log_write_selector= L_default;
+int     log_reject_target      = 0;
 uschar *log_selector_string    = NULL;
 FILE   *log_stderr             = NULL;
 BOOL    log_testing_mode       = FALSE;
 BOOL    log_timezone           = FALSE;
+unsigned int log_write_selector= L_default;
 uschar *login_sender_address   = NULL;
 int     lookup_open_max        = 25;
 uschar *lookup_value           = NULL;
index cd5fb4e36407a2a2e338e635d5370b61a1ace660..0bafda666cc23f98d116460e0f99d7ab21c9171a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.40 2006/09/19 11:28:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.41 2006/09/25 10:14:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -404,11 +404,12 @@ extern unsigned int log_extra_selector;/* Bit map of logging options other than
 extern uschar *log_file_path;          /* If unset, use default */
 extern bit_table log_options[];        /* Table of options */
 extern int     log_options_count;      /* Size of table */
-extern unsigned int log_write_selector;/* Bit map of logging options for log_write() */
+extern int     log_reject_target;      /* Target log for ACL rejections */
 extern uschar *log_selector_string;    /* As supplied in the config */
 extern FILE   *log_stderr;             /* Copy of stderr for log use, or NULL */
 extern BOOL    log_testing_mode;       /* TRUE in various testing modes */
 extern BOOL    log_timezone;           /* TRUE to include the timezone in log lines */
+extern unsigned int log_write_selector;/* Bit map of logging options for log_write() */
 extern uschar *login_sender_address;   /* The actual sender address */
 extern lookup_info lookup_list[];      /* Vector of available lookups */
 extern int     lookup_list_count;      /* Number of entries in the list */
index 3f430f1aa20ff3f47a836ec266e88e5db2369ad6..797444ca1b3b6963c5a2cbecfc45e6be9c9ae96f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.28 2006/07/13 13:53:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.29 2006/09/25 10:14:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2985,8 +2985,13 @@ else
 #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);
+        /* The ACL can specify where rejections are to be logged, possibly
+        nowhere. The default is main and reject logs. */
+
+        if (log_reject_target != 0)
+          log_write(0, log_reject_target, "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)
           {
index 614a3ffe0fb49f15db057e2770c031dc71186b0b..36c4c3021d921a7f8540ab3ded2f898d45d8bada 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.43 2006/09/19 11:28:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.44 2006/09/25 10:14:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2002,12 +2002,15 @@ else
       US"Temporary local problem - please try later");
   }
 
-/* Log the incident. If the connection is not forcibly to be dropped, return 0.
-Otherwise, log why it is closing if required and return 2.  */
+/* Log the incident to the logs that are specified by log_reject_target
+(default main, reject). This can be empty to suppress logging of rejections. If
+the connection is not forcibly to be dropped, return 0. Otherwise, log why it
+is closing if required and return 2.  */
 
-log_write(0, LOG_MAIN|LOG_REJECT, "%s %s%srejected %s%s",
-  host_and_ident(TRUE),
-  sender_info, (rc == FAIL)? US"" : US"temporarily ", what, log_msg);
+if (log_reject_target != 0)
+  log_write(0, log_reject_target, "%s %s%srejected %s%s",
+    host_and_ident(TRUE),
+    sender_info, (rc == FAIL)? US"" : US"temporarily ", what, log_msg);
 
 if (!drop) return 0;
 
diff --git a/test/confs/0539 b/test/confs/0539
new file mode 100644 (file)
index 0000000..02b7a26
--- /dev/null
@@ -0,0 +1,59 @@
+# Exim test configuration 0539
+
+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_not_smtp = not_smtp
+acl_smtp_mail = check_mail
+acl_smtp_rcpt = check_rcpt
+acl_smtp_predata = predata
+
+
+# ----- ACLs -----
+
+begin acl
+
+check_mail:
+  deny  senders = main@test.ex
+        log_reject_target = main
+  deny  senders = reject@test.ex
+        log_reject_target = reject
+  deny  senders = both@test.ex
+        log_reject_target = <, main, reject
+  deny  senders = panic@test.ex
+        log_reject_target = panic
+  deny  senders = none@test.ex
+        log_reject_target =
+  accept
+
+check_rcpt:
+  deny  local_parts = main
+        log_reject_target = main
+  deny  local_parts = reject
+        log_reject_target = reject
+  deny  local_parts = both
+        log_reject_target = <, main, reject
+  deny  local_parts = panic
+        log_reject_target = panic
+  deny  local_parts = none
+        log_reject_target =
+  accept
+
+predata:
+  deny  log_reject_target = main
+        log_message = Not today
+
+not_smtp:
+  deny  log_reject_target = reject
+        log_message = Nyet
+
+
+# End
diff --git a/test/log/0539 b/test/log/0539
new file mode 100644 (file)
index 0000000..b6787e7
--- /dev/null
@@ -0,0 +1,5 @@
+1999-03-02 09:44:33 U=CALLER rejected MAIL <main@test.ex>
+1999-03-02 09:44:33 U=CALLER rejected MAIL <both@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <main@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <both@test.ex>
+1999-03-02 09:44:33 U=CALLER rejected DATA: Not today
diff --git a/test/paniclog/0539 b/test/paniclog/0539
new file mode 100644 (file)
index 0000000..84edf4d
--- /dev/null
@@ -0,0 +1,2 @@
+1999-03-02 09:44:33 U=CALLER rejected MAIL <panic@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <panic@test.ex>
diff --git a/test/rejectlog/0539 b/test/rejectlog/0539
new file mode 100644 (file)
index 0000000..74da8e6
--- /dev/null
@@ -0,0 +1,14 @@
+1999-03-02 09:44:33 U=CALLER rejected MAIL <reject@test.ex>
+1999-03-02 09:44:33 U=CALLER rejected MAIL <both@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <reject@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <both@test.ex>
+1999-03-02 09:44:33 10HmaX-0005vi-00 F=<CALLER@myhost.test.ex> rejected by non-SMTP ACL: Nyet
+Envelope-from: <CALLER@myhost.test.ex>
+Envelope-to: <userx@test.ex>
+P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@myhost.test.ex>)
+       id 10HmaX-0005vi-00
+       for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+I Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+F From: CALLER_NAME <CALLER@myhost.test.ex>
+  Date: Tue, 2 Mar 1999 09:44:33 +0000
diff --git a/test/scripts/0000-Basic/0539 b/test/scripts/0000-Basic/0539
new file mode 100644 (file)
index 0000000..193047a
--- /dev/null
@@ -0,0 +1,20 @@
+# log_reject_target
+exim -bs
+mail from:<main@test.ex>
+mail from:<reject@test.ex>
+mail from:<both@test.ex>
+mail from:<panic@test.ex>
+mail from:<none@test.ex>
+mail from:<ok@test.ex>
+rcpt to:<main@test.ex>
+rcpt to:<reject@test.ex>
+rcpt to:<both@test.ex>
+rcpt to:<panic@test.ex>
+rcpt to:<none@test.ex>
+rcpt to:<ok@test.ex>
+data
+quit
+****
+1
+exim -oep userx@test.ex
+****
diff --git a/test/stderr/0539 b/test/stderr/0539
new file mode 100644 (file)
index 0000000..00e0000
--- /dev/null
@@ -0,0 +1,3 @@
+1999-03-02 09:44:33 U=CALLER rejected MAIL <panic@test.ex>
+1999-03-02 09:44:33 U=CALLER F=<ok@test.ex> rejected RCPT <panic@test.ex>
+exim: message rejected by non-SMTP ACL: local configuration problem
diff --git a/test/stdout/0539 b/test/stdout/0539
new file mode 100644 (file)
index 0000000..d260b66
--- /dev/null
@@ -0,0 +1,15 @@
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+250 OK\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
+250 Accepted\r
+550 Administrative prohibition\r
+221 myhost.test.ex closing connection\r