Add NFSv4 spool file patch
[users/heiko/exim.git] / src / src / receive.c
index d14409c5897db96c071d50bf499aeef4e579272c..bda0f79bf0803efb7be62075faa788eb78e4ff5a 100644 (file)
@@ -1034,6 +1034,7 @@ for (;;)
     unsigned len = MAX(chunking_data_left, thismessage_size_limit - message_size + 1);
     uschar * buf = bdat_getbuf(&len);
 
+    if (!buf) return END_EOF;
     message_size += len;
     if (fout && fwrite(buf, len, 1, fout) != 1) return END_WERROR;
     }
@@ -1616,8 +1617,8 @@ int  i;
 int  rc = FAIL;
 int  msg_size = 0;
 int  process_info_len = Ustrlen(process_info);
-int  error_rc = (error_handling == ERRORS_SENDER)?
-       errors_sender_rc : EXIT_FAILURE;
+int  error_rc = error_handling == ERRORS_SENDER
+       errors_sender_rc : EXIT_FAILURE;
 int  header_size = 256;
 int  start, end, domain;
 int  id_resolution;
@@ -3038,9 +3039,22 @@ if ((data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE)) < 0)
 because the group setting doesn't always get set automatically. */
 
 if (fchown(data_fd, exim_uid, exim_gid))
-  log_write(0, LOG_MAIN|LOG_PANIC_DIE,
-    "Failed setting ownership on spool file %s: %s",
-    spool_name, strerror(errno));
+{
+  int chown_errno = errno;
+  struct stat buf;
+
+  /* On NFSv4 with UID mapping the above fchown() might fail. If the
+  file is owned by the proper uid and gid, we won't report this failure. */
+  if (fstat(data_fd, &buf))
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+      "Failed to stat on spool file %s: %s",
+      spool_name, strerror(errno));
+
+  if (buf.st_uid != exim_uid || buf.st_gid != exim_gid)
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+      "Failed setting ownership on spool file %s: %s",
+      spool_name, strerror(chown_errno));
+}
 (void)fchmod(data_fd, SPOOL_MODE);
 
 /* We now have data file open. Build a stream for it and lock it. We lock only
@@ -3571,15 +3585,16 @@ else
       goto TIDYUP;
 #endif /* WITH_CONTENT_SCAN */
 
-    if (acl_not_smtp != NULL)
+    if (acl_not_smtp)
       {
       uschar *user_msg, *log_msg;
+      authentication_local = TRUE;
       rc = acl_check(ACL_WHERE_NOTSMTP, NULL, acl_not_smtp, &user_msg, &log_msg);
       if (rc == DISCARD)
         {
         recipients_count = 0;
         blackholed_by = US"non-SMTP ACL";
-        if (log_msg != NULL)
+        if (log_msg)
           blackhole_log_msg = string_sprintf(": %s", log_msg);
         }
       else if (rc != OK)
@@ -3594,11 +3609,11 @@ else
         /* The ACL can specify where rejections are to be logged, possibly
         nowhere. The default is main and reject logs. */
 
-        if (log_reject_target != 0)
+        if (log_reject_target)
           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 (!user_msg) user_msg = US"local configuration problem";
         if (smtp_batched_input)
           {
           moan_smtp_batch(NULL, "%d %s", 550, user_msg);
@@ -3960,6 +3975,10 @@ if (LOGGING(8bitmime))
 #ifndef DISABLE_DKIM
 if (LOGGING(dkim) && dkim_verify_overall)
   g = string_append(g, 2, US" DKIM=", dkim_verify_overall);
+# ifdef EXPERIMENTAL_ARC
+if (LOGGING(dkim) && arc_state && Ustrcmp(arc_state, "pass") == 0)
+  g = string_catn(g, US" ARC", 4);
+# endif
 #endif
 
 if (LOGGING(receive_time))
@@ -4151,9 +4170,11 @@ if(cutthrough.fd >= 0 && cutthrough.delivery)
     case '4':  /* Temp-reject. Keep spoolfiles and accept, unless defer-pass mode.
                ... for which, pass back the exact error */
       if (cutthrough.defer_pass) smtp_reply = string_copy_malloc(msg);
-      /*FALLTRHOUGH*/
+      cutthrough_done = TMP_REJ;               /* Avoid the usual immediate delivery attempt */
+      break;                                   /* message_id needed for SMTP accept below */
 
     default:   /* Unknown response, or error.  Treat as temp-reject.         */
+      if (cutthrough.defer_pass) smtp_reply = US"450 Onward transmission not accepted";
       cutthrough_done = TMP_REJ;               /* Avoid the usual immediate delivery attempt */
       break;                                   /* message_id needed for SMTP accept below */
 
@@ -4180,7 +4201,7 @@ if(!smtp_reply)
   if (deliver_freeze) log_write(0, LOG_MAIN, "frozen by %s", frozen_by);
   if (queue_only_policy) log_write(L_delay_delivery, LOG_MAIN,
     "no immediate delivery: queued%s%s by %s",
-    *queue_name ? " in " : "", *queue_name ? CS queue_name : "",       
+    *queue_name ? " in " : "", *queue_name ? CS queue_name : "",
     queued_by);
   }
 receive_call_bombout = FALSE;