Update upgrade notes and source about use of seteuid()
[exim.git] / src / src / deliver.c
index 238e33accf4b1cafd7442caea88aa40c24c31ed2..4e472ebe6bb8b34056033d577d56364a9f71a46e 100644 (file)
@@ -334,7 +334,7 @@ static int
 open_msglog_file(uschar *filename, int mode, uschar **error)
 {
 if (Ustrstr(filename, US"/../"))
-  log_write(0, LOG_MAIN|LOG_PANIC,
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "Attempt to open msglog file path with upward-traversal: '%s'\n", filename);
 
 for (int i = 2; i > 0; i--)
@@ -521,8 +521,12 @@ while (one && two)
   else if (one->port != two->port)
     return FALSE;
 
-  /* Hosts matched */
+#ifdef SUPPORT_DANE
+  /* DNSSEC equality */
+  if (one->dnssec != two->dnssec) return FALSE;
+#endif
 
+  /* Hosts matched */
   one = one->next;
   two = two->next;
   }
@@ -1269,8 +1273,8 @@ if (  LOGGING(smtp_confirmation)
 /* Time on queue and actual time taken to deliver */
 
 if (LOGGING(queue_time))
-  g = string_append(g, 2, US" QT=",
-    string_timesince(&received_time));
+  g = string_append(g, 2, US" QT=", string_timesince(
+    LOGGING(queue_time_exclusive) ? &received_time_complete : &received_time));
 
 if (LOGGING(deliver_time))
   g = string_append(g, 2, US" DT=", string_timediff(&addr->delivery_time));
@@ -1580,6 +1584,12 @@ if (addr->return_file >= 0 && addr->return_filename)
   (void)close(addr->return_file);
   }
 
+/* Check if the transport notifed continue-conn status explicitly, and
+update our knowlege. */
+
+if (testflag(addr, af_new_conn))       continue_sequence = 1;
+else if (testflag(addr, af_cont_conn)) continue_sequence++;
+
 /* The success case happens only after delivery by a transport. */
 
 if (result == OK)
@@ -2087,9 +2097,9 @@ return FALSE;
 
 /* Each local delivery is performed in a separate process which sets its
 uid and gid as specified. This is a safer way than simply changing and
-restoring using seteuid(); there is a body of opinion that seteuid() cannot be
-used safely. From release 4, Exim no longer makes any use of it. Besides, not
-all systems have seteuid().
+restoring using seteuid(); there is a body of opinion that seteuid()
+cannot be used safely. From release 4, Exim no longer makes any use of
+it for delivery. Besides, not all systems have seteuid().
 
 If the uid/gid are specified in the transport_instance, they are used; the
 transport initialization must ensure that either both or neither are set.
@@ -2878,10 +2888,8 @@ while (addr_local)
   deliveries (e.g. to pipes) can take a substantial time. */
 
   if (!(dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE, TRUE)))
-    {
     DEBUG(D_deliver|D_retry|D_hints_lookup)
       debug_printf("no retry data available\n");
-    }
 
   addr2 = addr;
   addr3 = NULL;
@@ -3571,7 +3579,13 @@ while (!done)
 
       switch (*subid)
        {
-  #ifdef SUPPORT_SOCKS
+       case 3:         /* explicit notification of continued-connection (non)use;
+                       overrides caller's knowlege. */
+         if (*ptr & BIT(1))      setflag(addr, af_new_conn);
+         else if (*ptr & BIT(2)) setflag(addr, af_cont_conn);
+         break;
+
+#ifdef SUPPORT_SOCKS
        case '2':       /* proxy information; must arrive before A0 and applies to that addr XXX oops*/
          proxy_session = TRUE; /*XXX should this be cleared somewhere? */
          if (*ptr == 0)
@@ -3584,9 +3598,9 @@ while (!done)
            ptr += sizeof(proxy_local_port);
            }
          break;
-  #endif
+#endif
 
-  #ifdef EXPERIMENTAL_DSN_INFO
+#ifdef EXPERIMENTAL_DSN_INFO
        case '1':       /* must arrive before A0, and applies to that addr */
                        /* Two strings: smtp_greeting and helo_response */
          addr->smtp_greeting = string_copy(ptr);
@@ -3594,7 +3608,7 @@ while (!done)
          addr->helo_response = string_copy(ptr);
          while(*ptr++);
          break;
-  #endif
+#endif
 
        case '0':
          DEBUG(D_deliver) debug_printf("A0 %s tret %d\n", addr->address, *ptr);
@@ -4885,6 +4899,14 @@ all pipes, so I do not see a reason to use non-blocking IO here
         rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer);
         }
 
+      if (testflag(addr, af_new_conn) || testflag(addr, af_cont_conn))
+       {
+       DEBUG(D_deliver) debug_printf("%scontinued-connection\n",
+         testflag(addr, af_new_conn) ? "non-" : "");
+       big_buffer[0] = testflag(addr, af_new_conn) ? BIT(1) : BIT(2);
+        rmt_dlv_checked_write(fd, 'A', '3', big_buffer, 1);
+       }
+
 #ifdef SUPPORT_SOCKS
       if (LOGGING(proxy) && proxy_session)
        {
@@ -6814,7 +6836,7 @@ while (addr_new)           /* Loop until all addresses dealt with */
       addr_route = addr->next;
 
       deliver_domain = addr->domain;  /* set $domain */
-      if ((rc = match_isinlist(addr->domain, (const uschar **)&queue_domains, 0,
+      if ((rc = match_isinlist(addr->domain, CUSS &queue_domains, 0,
             &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
               != OK)
         if (rc == DEFER)
@@ -8416,7 +8438,7 @@ else if (addr_defer != (address_item *)(+1))
   /* If this was a first delivery attempt, unset the first time flag, and
   ensure that the spool gets updated. */
 
-  if (f.deliver_firsttime)
+  if (f.deliver_firsttime && !f.queue_2stage)
     {
     f.deliver_firsttime = FALSE;
     update_spool = TRUE;
@@ -8549,52 +8571,9 @@ f.tcp_fastopen_ok = TRUE;
 }
 
 
-uschar *
-deliver_get_sender_address (uschar * id)
-{
-int rc;
-uschar * new_sender_address,
-       * save_sender_address;
-BOOL save_qr = f.queue_running;
-uschar * spoolname;
-
-/* make spool_open_datafile non-noisy on fail */
-
-f.queue_running = TRUE;
-
-/* Side effect: message_subdir is set for the (possibly split) spool directory */
-
-deliver_datafile = spool_open_datafile(id);
-f.queue_running = save_qr;
-if (deliver_datafile < 0)
-  return NULL;
-
-/* Save and restore the global sender_address.  I'm not sure if we should
-not save/restore all the other global variables too, because
-spool_read_header() may change all of them. But OTOH, when this
-deliver_get_sender_address() gets called, the current message is done
-already and nobody needs the globals anymore. (HS12, 2015-08-21) */
-
-spoolname = string_sprintf("%s-H", id);
-save_sender_address = sender_address;
-
-rc = spool_read_header(spoolname, TRUE, TRUE);
-
-new_sender_address = sender_address;
-sender_address = save_sender_address;
-
-if (rc != spool_read_OK)
-  return NULL;
-
-assert(new_sender_address);
-
-(void)close(deliver_datafile);
-deliver_datafile = -1;
-
-return new_sender_address;
-}
-
 
+/* Called from a commandline, or from the daemon, to do a delivery.
+We need to regain privs; do this by exec of the exim binary. */
 
 void
 delivery_re_exec(int exec_type)