Added $sender_verify_failure and $recipient_verify_failure to
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Fri, 5 Nov 2004 16:53:28 +0000 (16:53 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Fri, 5 Nov 2004 16:53:28 +0000 (16:53 +0000)
distinguish in more detail what has failed (e.g. MAIL vs RCPT in a
callout).

doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/verify.c

index 9ae2962..f946cd0 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.17 2004/11/05 14:59:12 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.18 2004/11/05 16:53:28 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -65,6 +65,9 @@ Exim version 4.44
 17. A "Completed" log line is now written for messages that are removed from
     the spool by the -Mrm option.
 
+18. New variables $sender_verify_failure and $recipient_verify_failure contain
+    information about exactly what failed.
+
 
 Exim version 4.43
 -----------------
index 79e3476..5ed1661 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.6 2004/11/04 12:19:48 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.7 2004/11/05 16:53:28 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -41,6 +41,27 @@ Version 4.44
 
     If not specified, it defaults to the general timeout value.
 
+ 7. The new variables $sender_verify_failure and $recipient_verify_failure
+    contain information about exactly what failed. In an ACL, after one of
+    these failures, the relevant variable contains one of the following words:
+
+      qualify       the address was unqualified (no domain), and the message
+                    was neither local nor came from an exempted host;
+
+      route         routing failed;
+
+      mail          routing succeeded, and a callout was attempted; rejection
+                    occurred at or before the MAIL command (that is, on initial
+                    connection, HELO, or MAIL);
+
+      recipient     the RCPT command in a callout was rejected;
+
+      postmaster    the postmaster check in a callout was rejected.
+
+    The main use of these variables is expected to be to distinguish between
+    rejections of MAIL and rejections of RCPT.
+
+
 
 Version 4.43
 ------------
index afe57f9..2575247 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.2 2004/10/19 13:40:39 ph10 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.3 2004/11/05 16:53:28 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -387,6 +387,7 @@ static var_entry var_table[] = {
   { "received_for",        vtype_stringptr,   &received_for },
   { "received_protocol",   vtype_stringptr,   &received_protocol },
   { "recipient_data",      vtype_stringptr,   &recipient_data },
+  { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, 
   { "recipients",          vtype_recipients,  NULL },
   { "recipients_count",    vtype_int,         &recipients_count },
   { "reply_address",       vtype_reply,       NULL },
@@ -407,6 +408,7 @@ static var_entry var_table[] = {
   { "sender_host_port",    vtype_int,         &sender_host_port },
   { "sender_ident",        vtype_stringptr,   &sender_ident },
   { "sender_rcvhost",      vtype_stringptr,   &sender_rcvhost },
+  { "sender_verify_failure",vtype_stringptr,  &sender_verify_failure }, 
   { "smtp_command_argument", vtype_stringptr, &smtp_command_argument },
   { "sn0",                 vtype_filter_int,  &filter_sn[0] },
   { "sn1",                 vtype_filter_int,  &filter_sn[1] },
index 58ae517..0794e03 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.4 2004/10/19 13:40:39 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.5 2004/11/05 16:53:28 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -742,6 +742,7 @@ uschar *received_protocol      = NULL;
 int     received_time          = 0;
 uschar *recipient_data         = NULL;
 uschar *recipient_unqualified_hosts = NULL;
+uschar *recipient_verify_failure = NULL;
 int     recipients_count       = 0;
 BOOL    recipients_discarded   = FALSE;
 recipient_item  *recipients_list = NULL;
@@ -879,6 +880,7 @@ BOOL    sender_local           = FALSE;
 uschar *sender_rcvhost         = NULL;
 BOOL    sender_set_untrusted   = FALSE;
 uschar *sender_unqualified_hosts = NULL;
+uschar *sender_verify_failure = NULL;
 address_item *sender_verified_list  = NULL;
 address_item *sender_verified_failed = NULL;
 int     sender_verified_rc     = -1;
index c9106b9..eaf192e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.4 2004/10/19 13:40:39 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.5 2004/11/05 16:53:28 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -453,6 +453,7 @@ extern int     received_headers_max;   /* Max count of Received: headers */
 extern int     received_time;          /* Time the message was received */
 extern uschar *recipient_data;         /* lookup data for recipients */
 extern uschar *recipient_unqualified_hosts; /* Permitted unqualified recipients */
+extern uschar *recipient_verify_failure; /* What went wrong */
 extern BOOL    recipients_discarded;   /* By an ACL */
 extern int     recipients_list_max;    /* Maximum number fitting in list */
 extern int     recipients_max;         /* Max permitted */
@@ -505,6 +506,7 @@ extern BOOL    sender_local;           /* TRUE for local senders */
 extern uschar *sender_rcvhost;         /* Host data for Received: */
 extern BOOL    sender_set_untrusted;   /* Sender set by untrusted caller */
 extern uschar *sender_unqualified_hosts; /* Permitted unqualified senders */
+extern uschar *sender_verify_failure;  /* What went wrong */
 extern address_item *sender_verified_list; /* Saved chain of sender verifies */
 extern address_item *sender_verified_failed; /* The one that caused denial */
 extern volatile BOOL sigalrm_seen;     /* Flag for sigalrm_handler */
index 8b24fb4..45a4c81 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/verify.c,v 1.2 2004/11/04 12:19:48 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.3 2004/11/05 16:53:28 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -151,6 +151,8 @@ BOOL done = FALSE;
 uschar *address_key;
 uschar *from_address;
 uschar *random_local_part = NULL;
+uschar **failure_ptr = is_recipient? 
+  &recipient_verify_failure : &sender_verify_failure;
 open_db dbblock;
 open_db *dbm_file = NULL;
 dbdata_callout_cache new_domain_record;
@@ -236,6 +238,7 @@ if (dbm_file != NULL)
       setflag(addr, af_verify_nsfail);
       addr->user_message = US"(result of an earlier callout reused).";
       yield = FAIL;
+      *failure_ptr = US"mail"; 
       goto END_CALLOUT;
       }
 
@@ -282,6 +285,7 @@ if (dbm_file != NULL)
           debug_printf("callout cache: domain does not accept "
             "RCPT TO:<postmaster@domain>\n");
         yield = FAIL;
+        *failure_ptr = US"postmaster"; 
         setflag(addr, af_verify_pmfail);
         addr->user_message = US"(result of earlier verification reused).";
         goto END_CALLOUT;
@@ -330,6 +334,7 @@ if (dbm_file != NULL)
       HDEBUG(D_verify)
         debug_printf("callout cache: address record is negative\n");
       addr->user_message = US"Previous (cached) callout verification failure";
+      *failure_ptr = US"recipient"; 
       yield = FAIL;
       }
     goto END_CALLOUT;
@@ -476,6 +481,7 @@ for (host = host_list; host != NULL && !done; host = host->next)
 
   if (!done)
     {
+    *failure_ptr = US"mail"; 
     if (errno == 0 && responsebuffer[0] == '5')
       {
       setflag(addr, af_verify_nsfail);
@@ -550,7 +556,10 @@ for (host = host_list; host != NULL && !done; host = host->next)
       if (done)
         new_address_record.result = ccache_accept;
       else if (errno == 0 && responsebuffer[0] == '5')
+        {
+        *failure_ptr = US"recipient";  
         new_address_record.result = ccache_reject;
+        } 
 
       /* Do postmaster check if requested */
 
@@ -577,6 +586,7 @@ for (host = host_list; host != NULL && !done; host = host->next)
           new_domain_record.postmaster_result = ccache_accept;
         else if (errno == 0 && responsebuffer[0] == '5')
           {
+          *failure_ptr = US"postmaster"; 
           setflag(addr, af_verify_pmfail);
           new_domain_record.postmaster_result = ccache_reject;
           }
@@ -810,7 +820,6 @@ BOOL allok = TRUE;
 BOOL full_info = (f == NULL)? FALSE : (debug_selector != 0);
 BOOL is_recipient = (options & vopt_is_recipient) != 0;
 BOOL expn         = (options & vopt_expn) != 0;
-
 int i;
 int yield = OK;
 int verify_type = expn? v_expn :
@@ -821,11 +830,17 @@ address_item *addr_new = NULL;
 address_item *addr_remote = NULL;
 address_item *addr_local = NULL;
 address_item *addr_succeed = NULL;
+uschar **failure_ptr = is_recipient? 
+  &recipient_verify_failure : &sender_verify_failure;
 uschar *ko_prefix, *cr;
 uschar *address = vaddr->address;
 uschar *save_sender;
 uschar null_sender[] = { 0 };             /* Ensure writeable memory */
 
+/* Clear, just in case */
+
+*failure_ptr = NULL;
+
 /* Set up a prefix and suffix for error message which allow us to use the same
 output statements both in EXPN mode (where an SMTP response is needed) and when
 debugging with an output file. */
@@ -846,6 +861,7 @@ if (parse_find_at(address) == NULL)
     if (f != NULL)
       fprintf(f, "%sA domain is required for \"%s\"%s\n", ko_prefix, address,
         cr);
+    *failure_ptr = US"qualify";     
     return FAIL;
     }
   address = rewrite_address_qualify(address, is_recipient);
@@ -1044,7 +1060,8 @@ while (addr_new != NULL)
           }
         }
 
-      /* Can only do a callout if we have at least one host! */
+      /* Can only do a callout if we have at least one host! If the callout 
+      fails, it will have set ${sender,recipient}_verify_failure. */
 
       if (host_list != NULL)
         {
@@ -1068,6 +1085,10 @@ while (addr_new != NULL)
         }
       }
     }
+    
+  /* Otherwise, any failure is a routing failure */
+  
+  else *failure_ptr = US"route"; 
 
   /* A router may return REROUTED if it has set up a child address as a result
   of a change of domain name (typically from widening). In this case we always
@@ -1255,7 +1276,10 @@ else for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
     }
   }
 
-return yield;  /* Will be DEFER or FAIL if any one address has */
+/* Will be DEFER or FAIL if any one address has, only for full_info (which is 
+the -bv or -bt case). */
+
+return yield;  
 }