Avoid exposing passwords in log, on failing ldap lookup expansion. Bug 165
[exim.git] / src / src / deliver.c
index 9066a14becd8b13c0a35d5a7d40882f9225055c9..743fc83e81d8ea3a97b79774614c1155516a67c3 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* The main code for delivering a message. */
@@ -703,7 +703,7 @@ if (LOGGING(incoming_interface) && LOGGING(outgoing_interface)
   s = LOGGING(outgoing_port)
     ? string_append(s, sizep, ptrp, 2, US"]:",
        string_sprintf("%d", sending_port))
-    : string_cat(s, sizep, ptrp, US"]", 1);
+    : string_catn(s, sizep, ptrp, US"]", 1);
   }
 return s;
 }
@@ -914,8 +914,7 @@ if (addr->transport->info->local)
     s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name);
   s = d_log_interface(s, &size, &ptr);
   if (addr->shadow_message)
-    s = string_cat(s, &size, &ptr, addr->shadow_message,
-      Ustrlen(addr->shadow_message));
+    s = string_cat(s, &size, &ptr, addr->shadow_message);
   }
 
 /* Remote delivery */
@@ -926,7 +925,7 @@ else
     {
     s = d_hostlog(s, &size, &ptr, addr);
     if (continue_sequence > 1)
-      s = string_cat(s, &size, &ptr, US"*", 1);
+      s = string_catn(s, &size, &ptr, US"*", 1);
 
 #ifndef DISABLE_EVENT
     deliver_host_address = addr->host_used->address;
@@ -1077,21 +1076,9 @@ malformed, it won't ever have gone near LDAP.) */
 if (addr->message)
   {
   const uschar * s = string_printing(addr->message);
-  if (s != addr->message)
-    addr->message = US s;
-    /* deconst cast ok as string_printing known to have alloc'n'copied */
-  if (  (  Ustrstr(s, "failed to expand") != NULL
-       || Ustrstr(s, "expansion of ")    != NULL
-       )
-     && (  Ustrstr(s, "mysql")   != NULL
-        || Ustrstr(s, "pgsql")   != NULL
-       || Ustrstr(s, "redis")   != NULL
-       || Ustrstr(s, "sqlite")  != NULL
-       || Ustrstr(s, "ldap:")   != NULL
-       || Ustrstr(s, "ldapdn:") != NULL
-       || Ustrstr(s, "ldapm:")  != NULL
-     )  )
-    addr->message = string_sprintf("Temporary internal error");
+
+  /* deconst cast ok as string_printing known to have alloc'n'copied */
+  addr->message = expand_hide_passwords(US s);
   }
 
 /* If we used a transport that has one of the "return_output" options set, and
@@ -1278,7 +1265,7 @@ else if (result == DEFER || result == PANIC)
 
     log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
 
-    s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
+    s = string_cat(s, &size, &ptr, log_address);
 
     /* Either driver_name contains something and driver_kind contains
     " router" or " transport" (note the leading space), or driver_name is
@@ -1298,7 +1285,7 @@ else if (result == DEFER || result == PANIC)
       s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
 
     sprintf(CS ss, " defer (%d)", addr->basic_errno);
-    s = string_cat(s, &size, &ptr, ss, Ustrlen(ss));
+    s = string_cat(s, &size, &ptr, ss);
 
     if (addr->basic_errno > 0)
       s = string_append(s, &size, &ptr, 2, US": ",
@@ -1396,7 +1383,7 @@ else
 
   log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
 
-  s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
+  s = string_cat(s, &size, &ptr, log_address);
 
   if (LOGGING(sender_on_delivery))
     s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
@@ -2220,6 +2207,7 @@ for (addr2 = addr; addr2; addr2 = addr2->next)
       if (message_length > 0)
         {
         len = read(pfd[pipe_read], big_buffer, message_length);
+       big_buffer[big_buffer_size-1] = '\0';           /* guard byte */
         if (len > 0) *sptr = string_copy(big_buffer);
         }
       }
@@ -3855,7 +3843,8 @@ static void
 rmt_dlv_checked_write(int fd, char id, char subid, void * buf, int size)
 {
 uschar writebuffer[PIPE_HEADER_SIZE + BIG_BUFFER_SIZE];
-int     header_length;
+int header_length;
+int ret;
 
 /* we assume that size can't get larger then BIG_BUFFER_SIZE which currently is set to 16k */
 /* complain to log if someone tries with buffer sizes we can't handle*/
@@ -3885,8 +3874,7 @@ if (buf && size > 0)
   memcpy(writebuffer + PIPE_HEADER_SIZE, buf, size);
 
 size += PIPE_HEADER_SIZE;
-int ret = write(fd, writebuffer, size);
-if(ret != size)
+if ((ret = write(fd, writebuffer, size)) != size)
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed writing transport result to pipe: %s\n",
     ret == -1 ? strerror(errno) : "short write");
 }
@@ -4243,7 +4231,7 @@ for (delivery_count = 0; addr_remote; delivery_count++)
         addr_fallback = addr;
         }
 
-      else
+      else if (next)
        {
        while (next->next) next = next->next;
        next->next = addr_defer;
@@ -4831,7 +4819,7 @@ if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0)
 para = store_get(size);
 for (;;)
   {
-  para = string_cat(para, &size, &ptr, buffer, Ustrlen(buffer));
+  para = string_cat(para, &size, &ptr, buffer);
   if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0)
     break;
   }
@@ -5226,7 +5214,7 @@ Any failures cause messages to be written to the log, except for missing files
 while queue running - another process probably completed delivery. As part of
 opening the data file, message_subdir gets set. */
 
-if (!spool_open_datafile(id))
+if ((deliver_datafile = spool_open_datafile(id)) < 0)
   return continue_closedown();  /* yields DELIVER_NOT_ATTEMPTED */
 
 /* The value of message_size at this point has been set to the data length,
@@ -8091,8 +8079,17 @@ deliver_get_sender_address (uschar * id)
 int rc;
 uschar * new_sender_address,
        * save_sender_address;
+BOOL save_qr = queue_running;
+
+/* make spool_open_datafile non-noisy on fail */
+
+queue_running = TRUE;
+
+/* Side effect: message_subdir is set for the (possibly split) spool directory */
 
-if (!spool_open_datafile(id))
+deliver_datafile = spool_open_datafile(id);
+queue_running = save_qr;
+if (deliver_datafile < 0)
   return NULL;
 
 /* Save and restore the global sender_address.  I'm not sure if we should