Get TLS SNI server-switching working with GnuTLS.
[exim.git] / src / src / deliver.c
index be588dd7cb17c2018bce2dc41c623fd8271fa1de..10b63397efdadad24bdad409e2562c146b1c6888 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.43 2007/02/06 11:11:40 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* The main code for delivering a message. */
@@ -624,7 +622,7 @@ for (dup = addr_duplicate; dup != NULL; dup = dup->next)
   {
   if (Ustrcmp(addr->unique, dup->unique) == 0)
     {
-    tree_add_nonrecipient(dup->address);
+    tree_add_nonrecipient(dup->unique);
     child_done(dup, now);
     }
   }
@@ -744,17 +742,15 @@ malformed, it won't ever have gone near LDAP.) */
 if (addr->message != NULL)
   {
   addr->message = string_printing(addr->message);
-  if (Ustrstr(addr->message, "failed to expand") != NULL &&
-      (Ustrstr(addr->message, "ldap:") != NULL ||
+  if (((Ustrstr(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) &&
+      (Ustrstr(addr->message, "mysql") != NULL ||
+       Ustrstr(addr->message, "pgsql") != NULL ||
+       Ustrstr(addr->message, "sqlite") != NULL ||
+       Ustrstr(addr->message, "ldap:") != NULL ||
        Ustrstr(addr->message, "ldapdn:") != NULL ||
        Ustrstr(addr->message, "ldapm:") != NULL))
     {
-    uschar *p = Ustrstr(addr->message, "pass=");
-    if (p != NULL)
-      {
-      p += 5;
-      while (*p != 0 && !isspace(*p)) *p++ = 'x';
-      }
+      addr->message = string_sprintf("Temporary internal error");
     }
   }
 
@@ -944,7 +940,8 @@ if (result == OK)
       s = string_append(s, &size, &ptr, 2, US" CV=",
         testflag(addr, af_cert_verified)? "yes":"no");
     if ((log_extra_selector & LX_tls_peerdn) != 0 && addr->peerdn != NULL)
-      s = string_append(s, &size, &ptr, 3, US" DN=\"", addr->peerdn, US"\"");
+      s = string_append(s, &size, &ptr, 3, US" DN=\"",
+        string_printing(addr->peerdn), US"\"");
     #endif
 
     if ((log_extra_selector & LX_smtp_confirmation) != 0 &&
@@ -1726,7 +1723,20 @@ if ((pid = fork()) == 0)
   HP-UX doesn't have RLIMIT_CORE; I don't know how to do this in that
   system. Some experimental/developing systems (e.g. GNU/Hurd) may define
   RLIMIT_CORE but not support it in setrlimit(). For such systems, do not
-  complain if the error is "not supported". */
+  complain if the error is "not supported".
+
+  There are two scenarios where changing the max limit has an effect.  In one,
+  the user is using a .forward and invoking a command of their choice via pipe;
+  for these, we do need the max limit to be 0 unless the admin chooses to
+  permit an increased limit.  In the other, the command is invoked directly by
+  the transport and is under administrator control, thus being able to raise
+  the limit aids in debugging.  So there's no general always-right answer.
+
+  Thus we inhibit core-dumps completely but let individual transports, while
+  still root, re-raise the limits back up to aid debugging.  We make the
+  default be no core-dumps -- few enough people can use core dumps in
+  diagnosis that it's reasonable to make them something that has to be explicitly requested.
+  */
 
   #ifdef RLIMIT_CORE
   struct rlimit rl;
@@ -4806,6 +4816,7 @@ else if (system_filter != NULL && process_recipients != RECIP_FAIL_TIMEOUT)
       RDO_REWRITE,
     NULL,                   /* No :include: restriction (not used in filter) */
     NULL,                   /* No sieve vacation directory (not sieve!) */
+    NULL,                   /* No sieve enotify mailto owner (not sieve!) */
     NULL,                   /* No sieve user address (not sieve!) */
     NULL,                   /* No sieve subaddress (not sieve!) */
     &ugid,                  /* uid/gid data */
@@ -5478,7 +5489,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
 
       if (address_retry_record == NULL)
         {
-        uschar * altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
+        uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
           sender_address);
         address_retry_record = dbfn_read(dbm_file, altkey);
         if (address_retry_record != NULL &&
@@ -5637,12 +5648,16 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
         string_sprintf("R:%s", addr->domain), 0);
 
     /* Otherwise, if there is an existing retry record in the database, add
-    retry items to delete both forms. Since the domain might have been
-    rewritten (expanded to fully qualified) as a result of routing, ensure
-    that the rewritten form is also deleted. */
+    retry items to delete both forms. We must also allow for the possibility
+    of a routing retry that includes the sender address. Since the domain might
+    have been rewritten (expanded to fully qualified) as a result of routing,
+    ensure that the rewritten form is also deleted. */
 
     else if (testflag(addr, af_dr_retry_exists))
       {
+      uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
+        sender_address);
+      retry_add_item(addr, altkey, rf_delete);
       retry_add_item(addr, addr->address_retry_key, rf_delete);
       retry_add_item(addr, addr->domain_retry_key, rf_delete);
       if (Ustrcmp(addr->domain, old_domain) != 0)
@@ -6549,7 +6564,8 @@ if (addr_defer == NULL)
     else
       {
       if (Uunlink(spoolname) < 0)
-        log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s", spoolname);
+        log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
+                 spoolname, strerror(errno));
       }
     }
 
@@ -6557,10 +6573,12 @@ if (addr_defer == NULL)
 
   sprintf(CS spoolname, "%s/input/%s/%s-D", spool_directory, message_subdir, id);
   if (Uunlink(spoolname) < 0)
-    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s", spoolname);
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
+      spoolname, strerror(errno));
   sprintf(CS spoolname, "%s/input/%s/%s-H", spool_directory, message_subdir, id);
   if (Uunlink(spoolname) < 0)
-    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s", spoolname);
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
+      spoolname, strerror(errno));
 
   /* Log the end of this message, with queue time if requested. */