Exiscan inclusion - ACL hooks
authorTom Kistner <tom@duncanthrax.net>
Thu, 25 Nov 2004 15:33:54 +0000 (15:33 +0000)
committerTom Kistner <tom@duncanthrax.net>
Thu, 25 Nov 2004 15:33:54 +0000 (15:33 +0000)
src/src/EDITME
src/src/acl.c
src/src/globals.c
src/src/macros.h

index cea00d2c841431c99c2b44b10289a23f77e06a20..0f213aa0ac1fe7f643dd9e36b33ffdaafd00ec9a 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/src/src/EDITME,v 1.4 2004/11/05 12:33:59 ph10 Exp $
+# $Cambridge: exim/src/src/EDITME,v 1.4.2.1 2004/11/25 15:33:54 tom Exp $
 
 ##################################################
 #          The Exim mail transport agent         #
@@ -314,7 +314,14 @@ LOOKUP_LSEARCH=yes
 
 EXIM_MONITOR=eximon.bin
 
+#------------------------------------------------------------------------------
+# Compiling Exim with content scanning support: If you want to compile Exim
+# with support for message body content scanning, set WITH_CONTENT_SCAN to
+# the value "yes". This will give you malware and spam scanning in the DATA ACL,
+# and the MIME ACL. Please read the documentation to learn more about these
+# features.
 
+#WITH_CONTENT_SCAN=yes
 
 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
index 92ebc18ec7d3e785d0339b9f975e65a63eb64d37..ffd7e9451b4c6d3221c91709db19f5c747cb8b1a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.5 2004/11/04 12:19:48 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.5.2.1 2004/11/25 15:33:55 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -34,19 +34,55 @@ static int msgcond[] = { FAIL, OK, OK, FAIL, OK, FAIL, OK };
 /* ACL condition and modifier codes - keep in step with the table that
 follows. */
 
-enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL, ACLC_DELAY,
-  ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS, ACLC_HOSTS,
-  ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE, ACLC_MESSAGE,
-  ACLC_RECIPIENTS, ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET, ACLC_VERIFY };
+enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL,
+#ifdef WITH_CONTENT_SCAN
+       ACLC_DECODE,
+#endif
+       ACLC_DELAY, ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS,
+       ACLC_HOSTS, ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE,
+#ifdef WITH_CONTENT_SCAN
+       ACLC_MALWARE,
+#endif
+       ACLC_MESSAGE,
+#ifdef WITH_CONTENT_SCAN
+       ACLC_MIME_REGEX,
+#endif
+       ACLC_RECIPIENTS,
+#ifdef WITH_CONTENT_SCAN
+       ACLC_REGEX
+#endif
+       ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET,
+#ifdef WITH_CONTENT_SCAN
+       ACLC_SPAM,       
+#endif
+       ACLC_VERIFY };
 
 /* ACL conditions/modifiers: "delay", "control", "endpass", "message",
 "log_message", "logwrite", and "set" are modifiers that look like conditions
 but always return TRUE. They are used for their side effects. */
 
 static uschar *conditions[] = { US"acl", US"authenticated", US"condition",
-  US"control", US"delay", US"dnslists", US"domains", US"encrypted",
+  US"control", 
+#ifdef WITH_CONTENT_SCAN
+  US"decode",
+#endif
+  US"delay", US"dnslists", US"domains", US"encrypted",
   US"endpass", US"hosts", US"local_parts", US"log_message", US"logwrite",
-  US"message", US"recipients", US"sender_domains", US"senders", US"set",
+#ifdef WITH_CONTENT_SCAN
+  US"malware",
+#endif
+  US"message",
+#ifdef WITH_CONTENT_SCAN
+  US"mime_regex",
+#endif
+  US"recipients",
+#ifdef WITH_CONTENT_SCAN
+  US"regex",
+#endif
+  US"sender_domains", US"senders", US"set",
+#ifdef WITH_CONTENT_SCAN
+  US"spam",
+#endif
   US"verify" };
   
 /* ACL control names */
@@ -64,6 +100,9 @@ static uschar cond_expand_at_top[] = {
   FALSE,   /* authenticated */
   TRUE,    /* condition */
   TRUE,    /* control */
+#ifdef WITH_CONTENT_SCAN
+  TRUE,    /* decode */
+#endif
   TRUE,    /* delay */
   TRUE,    /* dnslists */
   FALSE,   /* domains */
@@ -73,11 +112,23 @@ static uschar cond_expand_at_top[] = {
   FALSE,   /* local_parts */
   TRUE,    /* log_message */
   TRUE,    /* logwrite */
+#ifdef WITH_CONTENT_SCAN
+  TRUE,    /* malware */
+#endif
   TRUE,    /* message */
+#ifdef WITH_CONTENT_SCAN
+  TRUE,    /* mime_regex */
+#endif
   FALSE,   /* recipients */
+#ifdef WITH_CONTENT_SCAN
+  TRUE,    /* regex */
+#endif
   FALSE,   /* sender_domains */
   FALSE,   /* senders */
   TRUE,    /* set */
+#ifdef WITH_CONTENT_SCAN
+  TRUE,    /* spam */
+#endif
   TRUE     /* verify */
 };
 
@@ -88,6 +139,9 @@ static uschar cond_modifiers[] = {
   FALSE,   /* authenticated */
   FALSE,   /* condition */
   TRUE,    /* control */
+#ifdef WITH_CONTENT_SCAN
+  FALSE,   /* decode */
+#endif
   TRUE,    /* delay */
   FALSE,   /* dnslists */
   FALSE,   /* domains */
@@ -96,12 +150,24 @@ static uschar cond_modifiers[] = {
   FALSE,   /* hosts */
   FALSE,   /* local_parts */
   TRUE,    /* log_message */
-  TRUE,    /* log_write */
+  TRUE,    /* logwrite */
+#ifdef WITH_CONTENT_SCAN
+  FALSE,   /* malware */
+#endif
   TRUE,    /* message */
+#ifdef WITH_CONTENT_SCAN
+  FALSE,   /* mime_regex */
+#endif
   FALSE,   /* recipients */
+#ifdef WITH_CONTENT_SCAN
+  FALSE,   /* regex */
+#endif
   FALSE,   /* sender_domains */
   FALSE,   /* senders */
   TRUE,    /* set */
+#ifdef WITH_CONTENT_SCAN
+  FALSE,   /* spam */
+#endif
   FALSE    /* verify */
 };
 
@@ -118,6 +184,17 @@ static unsigned int cond_forbids[] = {
   always and check in the control processing itself */
 
   0,                                               /* control */
+
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* decode */
+    (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_PREDATA)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
+    (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+    (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_RCPT),
+#endif
+
   0,                                               /* delay */
   (1<<ACL_WHERE_NOTSMTP),                          /* dnslists */
 
@@ -144,8 +221,29 @@ static unsigned int cond_forbids[] = {
 
   0,                                               /* log_message */
   0,                                               /* logwrite */
+  
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* malware */
+    (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
+    (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+    (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
+#endif
+
   0,                                               /* message */
 
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* mime_regex */
+    (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_PREDATA)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
+    (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+    (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_RCPT),
+#endif
+
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* recipients */
     (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
     (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_PREDATA)|
@@ -154,6 +252,16 @@ static unsigned int cond_forbids[] = {
     (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
     (1<<ACL_WHERE_VRFY),
 
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* regex */
+    (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
+    (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+    (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
+#endif
+
   (1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)|      /* sender_domains */
     (1<<ACL_WHERE_HELO)|
     (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
@@ -168,6 +276,16 @@ static unsigned int cond_forbids[] = {
 
   0,                                               /* set */
 
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* spam */
+    (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
+    (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+    (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
+#endif
+
   /* Certain types of verify are always allowed, so we let it through
   always and check in the verify function itself */
 
@@ -179,7 +297,11 @@ static unsigned int cond_forbids[] = {
 
 enum { CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
   CONTROL_ENFORCE_SYNC, CONTROL_NO_ENFORCE_SYNC, CONTROL_FREEZE,
-  CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION, CONTROL_NO_MULTILINE };
+  CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION,
+#ifdef WITH_CONTENT_SCAN
+  CONTROL_NO_MBOX_UNSPOOL, CONTROL_FAKEREJECT,
+#endif
+  CONTROL_NO_MULTILINE };
 
 /* Bit map vector of which controls are not allowed at certain times. For
 each control, there's a bitmap of dis-allowed times. For some, it is easier to
@@ -202,7 +324,12 @@ static unsigned int control_forbids[] = {
      
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* submission */
     (1<<ACL_WHERE_PREDATA)),                       
-     
+
+#ifdef WITH_CONTENT_SCAN
+  (1<<ACL_WHERE_NOTSMTP),                          /* no_mbox_unspool */
+  (1<<ACL_WHERE_NOTSMTP),                          /* fakereject */
+#endif
+
   (1<<ACL_WHERE_NOTSMTP)                           /* no_multiline */
 };
 
@@ -222,6 +349,10 @@ static control_def controls_list[] = {
   { US"no_enforce_sync",        CONTROL_NO_ENFORCE_SYNC, FALSE},
   { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE},
   { US"queue_only",             CONTROL_QUEUE_ONLY, FALSE},
+#ifdef WITH_CONTENT_SCAN
+  { US"no_mbox_unspool",        CONTROL_NO_MBOX_UNSPOOL, FALSE},
+  { US"fakereject",             CONTROL_FAKEREJECT, TRUE},
+#endif
   { US"submission",             CONTROL_SUBMISSION, TRUE}
   };
 
@@ -1405,10 +1536,22 @@ for (; cb != NULL; cb = cb->next)
       smtp_enforce_sync = FALSE;
       break;
 
+#ifdef WITH_CONTENT_SCAN
+      case CONTROL_NO_MBOX_UNSPOOL:
+      no_mbox_unspool = TRUE;
+      break;
+#endif
+
       case CONTROL_NO_MULTILINE:
       no_multiline_responses = TRUE;
       break;
 
+#ifdef WITH_CONTENT_SCAN
+      case CONTROL_FAKEREJECT:
+      fake_reject = TRUE;
+      break;
+#endif
+
       case CONTROL_FREEZE:
       deliver_freeze = TRUE;
       deliver_frozen_at = time(NULL);
@@ -1446,6 +1589,12 @@ for (; cb != NULL; cb = cb->next)
       }
     break;
 
+#ifdef WITH_CONTENT_SCAN
+    case ACLC_DECODE:
+    rc = mime_decode(&arg);
+    break;
+#endif
+
     case ACLC_DELAY:
       {
       int delay = readconf_readtime(arg, 0, FALSE);
@@ -1548,12 +1697,42 @@ for (; cb != NULL; cb = cb->next)
       log_write(0, logbits, "%s", string_printing(s));
       }
     break;
+    
+#ifdef WITH_CONTENT_SCAN
+    case ACLC_MALWARE:
+      {
+      /* Seperate 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;
+          }
+        }
+      }
+    break;
+
+    case ACLC_MIME_REGEX:
+      rc = mime_regex(&arg);
+    break;
+#endif
 
     case ACLC_RECIPIENTS:
     rc = match_address_list(addr->address, TRUE, TRUE, &arg, NULL, -1, 0,
       &recipient_data);
     break;
 
+#ifdef WITH_CONTENT_SCAN
+   case ACLC_REGEX:
+      rc = regex(&arg);
+    break;
+#endif
+
     case ACLC_SENDER_DOMAINS:
       {
       uschar *sdomain;
@@ -1580,6 +1759,26 @@ for (; cb != NULL; cb = cb->next)
       }
     break;
 
+#ifdef WITH_CONTENT_SCAN
+    case ACLC_SPAM:
+      {
+      /* Seperate the regular expression and any optional parameters. */
+      uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+      /* Run the spam backend. */
+      rc = spam(&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;
+          }
+        }
+      }
+    break;
+#endif
+
     /* If the verb is WARN, discard any user message from verification, because
     such messages are SMTP responses, not header additions. The latter come
     only from explicit "message" modifiers. */
index f51033dcbec7d7241f619eeae9900243fd9ba322..6fc688654a2a02dcb32a60660baccf2f6d51ef92 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.8 2004/11/25 13:54:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.6.2.1 2004/11/25 15:33:55 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -181,6 +181,9 @@ error codes - keep in step with definitions of ACL_WHERE_xxxx in macros.h. */
 uschar *acl_wherenames[]       = { US"RCPT",
                                    US"MAIL",
                                    US"PREDATA",
+#ifdef WITH_CONTENT_SCAN
+                                   US"MIME",
+#endif
                                    US"DATA",
                                    US"non-SMTP",
                                    US"AUTH",
@@ -197,6 +200,9 @@ uschar *acl_wherenames[]       = { US"RCPT",
 int     acl_wherecodes[]       = { 550,     /* RCPT */
                                    550,     /* MAIL */
                                    550,     /* PREDATA */
+#ifdef WITH_CONTENT_SCAN
+                                   550,     /* MIME */
+#endif                                   
                                    550,     /* DATA */
                                    0,       /* not SMTP; not relevant */
                                    503,     /* AUTH */
@@ -476,9 +482,7 @@ uschar *extra_local_interfaces = NULL;
 int     filter_n[FILTER_VARIABLE_COUNT];
 BOOL    filter_running         = FALSE;
 int     filter_sn[FILTER_VARIABLE_COUNT];
-int     filter_test            = FTEST_NONE;
-uschar *filter_test_sfile      = NULL;
-uschar *filter_test_ufile      = NULL;
+uschar *filter_test            = NULL;
 uschar *filter_thisaddress     = NULL;
 int     finduser_retries       = 0;
 uid_t   fixed_never_users[]    = { FIXED_NEVER_USERS };
@@ -603,7 +607,6 @@ bit_table log_options[]        = {
   { US"outgoing_port",                LX_outgoing_port },
   { US"queue_run",                    L_queue_run },
   { US"queue_time",                   LX_queue_time },
-  { US"queue_time_overall",           LX_queue_time_overall },
   { US"received_recipients",          LX_received_recipients },
   { US"received_sender",              LX_received_sender },
   { US"rejected_header",              LX_rejected_header },
index 996e2e089e89ea58b4a3c1bc6611f921fdaa0ca3..94431fc93d5230595e1ea9fc22aebb8c64f23a3e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.4 2004/11/25 13:54:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.2.2.1 2004/11/25 15:33:55 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -227,12 +227,6 @@ enum {
   CEE_EXEC_PANIC            /* Panic-die if exec fails */
 };
 
-/* Bit values for filter_test */
-
-#define FTEST_NONE     0    /* Not filter testing */
-#define FTEST_USER     1    /* Testing user filter */
-#define FTEST_SYSTEM   2    /* Testing system filter */ 
-
 /* Returns from the routing, transport and authentication functions (not all
 apply to all of them). Some other functions also use these convenient values,
 and some additional values are used only by non-driver functions.
@@ -240,10 +234,10 @@ and some additional values are used only by non-driver functions.
 OK, FAIL, DEFER, and ERROR are also declared in local_scan.h for use in the
 local_scan() function. Do not change them unilaterally. */
 
-#define  OK            0    /* Successful match */
-#define  DEFER         1    /* Defer - some problem */
-#define  FAIL          2    /* Matching failed */
-#define  ERROR         3    /* Internal or config error */
+#define  OK            0     /* Successful match */
+#define  DEFER         1     /* Defer - some problem */
+#define  FAIL          2     /* Matching failed */
+#define  ERROR         3     /* Internal or config error */
 /***********/
 #define DECLINE        4    /* Declined to handle the address, pass to next
                                  router unless no_more is set */
@@ -367,17 +361,16 @@ only in the name table to set all options in both bit maps. */
 #define LX_incoming_port               0x80000020
 #define LX_outgoing_port               0x80000040
 #define LX_queue_time                  0x80000080
-#define LX_queue_time_overall          0x80000100
-#define LX_received_sender             0x80000200
-#define LX_received_recipients         0x80000400
-#define LX_rejected_header             0x80000800
-#define LX_return_path_on_delivery     0x80001000
-#define LX_sender_on_delivery          0x80002000
-#define LX_smtp_confirmation           0x80004000
-#define LX_subject                     0x80008000
-#define LX_tls_certificate_verified    0x80010000
-#define LX_tls_cipher                  0x80020000
-#define LX_tls_peerdn                  0x80040000
+#define LX_received_sender             0x80000100
+#define LX_received_recipients         0x80000200
+#define LX_rejected_header             0x80000400
+#define LX_return_path_on_delivery     0x80000800
+#define LX_sender_on_delivery          0x80001000
+#define LX_smtp_confirmation           0x80002000
+#define LX_subject                     0x80004000
+#define LX_tls_certificate_verified    0x80008000
+#define LX_tls_cipher                  0x80010000
+#define LX_tls_peerdn                  0x80020000
 
 #define L_default     (L_connection_reject        | \
                        L_delay_delivery           | \
@@ -744,8 +737,13 @@ with the tables of names and response codes in globals.c. */
 enum { ACL_WHERE_RCPT,       /* Some controls are for RCPT only */
        ACL_WHERE_MAIL,       /* )                                           */
        ACL_WHERE_PREDATA,    /* ) There are several tests for "in message", */
-       ACL_WHERE_DATA,       /* ) implemented by <= WHERE_NOTSMTP           */
-       ACL_WHERE_NOTSMTP,    /* )                                           */
+                             /* ) implemented by <= WHERE_NOTSMTP           */
+                             /* )                                           */
+#ifdef WITH_CONTENT_SCAN
+       ACL_WHERE_MIME,       
+#endif
+       ACL_WHERE_DATA,       
+       ACL_WHERE_NOTSMTP,    
 
        ACL_WHERE_AUTH,       /* These remaining ones are not currently    */
        ACL_WHERE_CONNECT,    /* required to be in a special order so they */