Avoid potential crash in close of a verify callout
[exim.git] / src / src / verify.c
index 43caac56247de0aa7efdc872f66ce9650e2fffe8..184809fb55ab434f3e6d4387bc106f6832659258 100644 (file)
@@ -140,7 +140,7 @@ if (options & vopt_callout_no_cache)
   {
   HDEBUG(D_verify) debug_printf("callout cache: disabled by no_cache\n");
   }
-else if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE)))
+else if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE)))
   {
   HDEBUG(D_verify) debug_printf("callout cache: not available\n");
   }
@@ -313,7 +313,7 @@ implying some kind of I/O error. We don't want to write the cache in that case.
 Otherwise the value is ccache_accept, ccache_reject, or ccache_reject_mfnull. */
 
 if (dom_rec->result != ccache_unknown)
-  if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE)))
+  if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE)))
     {
     HDEBUG(D_verify) debug_printf("callout cache: not available\n");
     }
@@ -335,7 +335,7 @@ is disabled. */
 if (done  &&  addr_rec->result != ccache_unknown)
   {
   if (!dbm_file)
-    dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE);
+    dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE);
   if (!dbm_file)
     {
     HDEBUG(D_verify) debug_printf("no callout cache available\n");
@@ -985,13 +985,6 @@ no_conn:
        done = TRUE;
        }
        break;
-#endif
-#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS)
-      case ERRNO_REQUIRETLS:
-        addr->user_message = US"530 5.7.4 REQUIRETLS support required";
-       yield = FAIL;
-       done = TRUE;
-       break;
 #endif
       case ECONNREFUSED:
        sx.send_quit = FALSE;
@@ -1110,12 +1103,9 @@ no_conn:
       if (options & vopt_callout_recipsender)
         cancel_cutthrough_connection(TRUE, US"not usable for cutthrough");
       if (sx.send_quit)
-       {
-       (void) smtp_write_command(&sx, SCMD_FLUSH, "QUIT\r\n");
-
-       /* Wait a short time for response, and discard it */
-       smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', 1);
-       }
+       if (smtp_write_command(&sx, SCMD_FLUSH, "QUIT\r\n") != -1)
+         /* Wait a short time for response, and discard it */
+         smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', 1);
 
       if (sx.cctx.sock >= 0)
        {
@@ -2376,13 +2366,13 @@ The original proposed patch did the former, but I have chosen to do the latter,
 because (a) it requires no memory and (b) will use fewer resources when there
 are many addresses in To: and/or Cc: and only one or two envelope recipients.
 
-Arguments:   none
+Arguments:   case_sensitive   true if case sensitive matching should be used
 Returns:     OK    if there are no blind recipients
              FAIL  if there is at least one blind recipient
 */
 
 int
-verify_check_notblind(void)
+verify_check_notblind(BOOL case_sensitive)
 {
 for (int i = 0; i < recipients_count; i++)
   {
@@ -2406,8 +2396,8 @@ for (int i = 0; i < recipients_count; i++)
 
     while (*s)
       {
-      uschar *ss = parse_find_address_end(s, FALSE);
-      uschar *recipient,*errmess;
+      uschar * ss = parse_find_address_end(s, FALSE);
+      uschar * recipient, * errmess;
       int terminator = *ss;
       int start, end, domain;
 
@@ -2419,21 +2409,22 @@ for (int i = 0; i < recipients_count; i++)
       *ss = terminator;
 
       /* If we found a valid recipient that has a domain, compare it with the
-      envelope recipient. Local parts are compared case-sensitively, domains
-      case-insensitively. By comparing from the start with length "domain", we
-      include the "@" at the end, which ensures that we are comparing the whole
-      local part of each address. */
-
-      if (recipient != NULL && domain != 0)
-        {
-        found = Ustrncmp(recipient, address, domain) == 0 &&
-                strcmpic(recipient + domain, address + domain) == 0;
-        if (found) break;
-        }
+      envelope recipient. Local parts are compared with case-sensitivity
+      according to the routine arg, domains case-insensitively.
+      By comparing from the start with length "domain", we include the "@" at
+      the end, which ensures that we are comparing the whole local part of each
+      address. */
+
+      if (recipient && domain != 0)
+        if ((found = (case_sensitive
+               ? Ustrncmp(recipient, address, domain) == 0
+               : strncmpic(recipient, address, domain) == 0)
+             && strcmpic(recipient + domain, address + domain) == 0))
+         break;
 
       /* Advance to the next address */
 
-      s = ss + (terminator? 1:0);
+      s = ss + (terminator ? 1:0);
       while (isspace(*s)) s++;
       }   /* Next address */
 
@@ -3251,7 +3242,7 @@ int
 verify_check_host(uschar **listptr)
 {
 return verify_check_this_host(CUSS listptr, sender_host_cache, NULL,
-  (sender_host_address == NULL)? US"" : sender_host_address, NULL);
+  sender_host_address ? sender_host_address : US"", NULL);
 }