Support timeout option on malware=
[exim.git] / src / src / acl.c
index e8a0657f2f6787fa4719b1392fcabd7fd7b715aa..8fdae039074a29ccffef64cdec4a2503ee1b72fc 100644 (file)
@@ -491,7 +491,7 @@ static unsigned int cond_forbids[] = {
 
   (unsigned int)
   ~((1<<ACL_WHERE_RCPT)                             /* local_parts */
-  #ifdef EXPERIMENTAL_PRDR
+  #ifndef DISABLE_PRDR
     |(1<<ACL_WHERE_PRDR)
   #endif
     ),
@@ -1550,7 +1550,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
   assertion: legitimate SMTP clients are all explicitly authorized with CSA
   SRV records of their own. */
 
-  if (found != domain)
+  if (Ustrcmp(found, domain) != 0)
     {
     if (port & 1)
       return t->data.val = CSA_FAIL_EXPLICIT;
@@ -2352,7 +2352,10 @@ rate measurement as opposed to rate limiting. */
 
 sender_rate_limit = string_nextinlist(&arg, &sep, NULL, 0);
 if (sender_rate_limit == NULL)
+  {
   limit = -1.0;
+  ss = NULL;   /* compiler quietening */
+  }
 else
   {
   limit = Ustrtod(sender_rate_limit, &ss);
@@ -2979,7 +2982,7 @@ uschar *debug_opts = NULL;
 uschar *p = NULL;
 int rc = OK;
 #ifdef WITH_CONTENT_SCAN
-int sep = '/';
+int sep = -'/';
 #endif
 
 for (; cb != NULL; cb = cb->next)
@@ -3580,21 +3583,28 @@ for (; cb != NULL; cb = cb->next)
     break;
 
     #ifdef WITH_CONTENT_SCAN
-    case ACLC_MALWARE:
+    case ACLC_MALWARE:                 /* Run the malware backend. */
       {
       /* Separate the regular expression and any optional parameters. */
       uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
-      /* Run the malware backend. */
-      rc = malware(&ss);
-      /* Modify return code based upon the existance of options. */
-      while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
-            != NULL) {
-        if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
-          {
-          /* FAIL so that the message is passed to the next ACL */
-          rc = FAIL;
-          }
-        }
+      uschar *opt;
+      BOOL defer_ok = FALSE;
+      int timeout = 0;
+
+      while ((opt = string_nextinlist(&arg, &sep, NULL, 0)))
+        if (strcmpic(opt, US"defer_ok") == 0)
+         defer_ok = TRUE;
+       else if (  strncmpic(opt, US"tmo=", 4) == 0
+               && (timeout = readconf_readtime(opt+4, '\0', FALSE)) < 0
+               )
+         {
+         *log_msgptr = string_sprintf("bad timeout value in '%s'", opt);
+         return ERROR;
+         }
+
+      rc = malware(ss, timeout);
+      if (rc == DEFER && defer_ok)
+       rc = FAIL;      /* FAIL so that the message is passed to the next ACL */
       }
     break;
 
@@ -4129,7 +4139,11 @@ while (acl != NULL)
   switch(acl->verb)
     {
     case ACL_ACCEPT:
-    if (cond == OK || cond == DISCARD) return cond;
+    if (cond == OK || cond == DISCARD)
+      {
+      HDEBUG(D_acl) debug_printf("end of %s: ACCEPT\n", acl_name);
+      return cond;
+      }
     if (endpass_seen)
       {
       HDEBUG(D_acl) debug_printf("accept: endpass encountered - denying access\n");
@@ -4140,17 +4154,26 @@ while (acl != NULL)
     case ACL_DEFER:
     if (cond == OK)
       {
+      HDEBUG(D_acl) debug_printf("end of %s: DEFER\n", acl_name);
       acl_temp_details = TRUE;
       return DEFER;
       }
     break;
 
     case ACL_DENY:
-    if (cond == OK) return FAIL;
+    if (cond == OK)
+      {
+      HDEBUG(D_acl) debug_printf("end of %s: DENY\n", acl_name);
+      return FAIL;
+      }
     break;
 
     case ACL_DISCARD:
-    if (cond == OK || cond == DISCARD) return DISCARD;
+    if (cond == OK || cond == DISCARD)
+      {
+      HDEBUG(D_acl) debug_printf("end of %s: DISCARD\n", acl_name);
+      return DISCARD;
+      }
     if (endpass_seen)
       {
       HDEBUG(D_acl) debug_printf("discard: endpass encountered - denying access\n");
@@ -4159,11 +4182,19 @@ while (acl != NULL)
     break;
 
     case ACL_DROP:
-    if (cond == OK) return FAIL_DROP;
+    if (cond == OK)
+      {
+      HDEBUG(D_acl) debug_printf("end of %s: DROP\n", acl_name);
+      return FAIL_DROP;
+      }
     break;
 
     case ACL_REQUIRE:
-    if (cond != OK) return cond;
+    if (cond != OK)
+      {
+      HDEBUG(D_acl) debug_printf("end of %s: not OK\n", acl_name);
+      return cond;
+      }
     break;
 
     case ACL_WARN: