]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/acl.c
Put in some casts for signed/unsigned character strings that Tom forgot
[user/henk/code/exim.git] / src / src / acl.c
index 8125e38c90cde9a4464df69d1193e871ecc92649..980d3ab2dbd03e46319a41967e35bb31b6c02b64 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.34 2005/05/23 16:58:56 fanf2 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.39 2005/06/10 19:27:05 fanf2 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1143,6 +1143,7 @@ Ustrcpy(t->name, domain);
 
 /* Now we are ready to do the actual DNS lookup(s). */
 
+found = domain;
 switch (dns_special_lookup(&dnsa, domain, T_CSA, &found))
   {
   /* If something bad happened (most commonly DNS_AGAIN), defer. */
@@ -1512,6 +1513,11 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
           else if (strcmpic(opt, US"use_postmaster") == 0)
              verify_options |= vopt_callout_recippmaster;
           else if (strcmpic(opt, US"postmaster") == 0) pm_mailfrom = US"";
+          else if (strcmpic(opt, US"fullpostmaster") == 0)
+            {
+            pm_mailfrom = US"";
+            verify_options |= vopt_callout_fullpm;
+            }
 
           else if (strncmpic(opt, US"mailfrom", 8) == 0)
             {
@@ -1915,7 +1921,7 @@ static int
 acl_ratelimit(uschar *arg, uschar **log_msgptr)
 {
 double limit, period;
-uschar *ss, *key = arg;
+uschar *ss, *key;
 int sep = '/';
 BOOL have_key = FALSE, leaky = FALSE, strict = FALSE;
 BOOL per_byte = FALSE, per_cmd = FALSE, per_conn = FALSE, per_mail = FALSE;
@@ -1951,6 +1957,12 @@ if (limit < 0.0 || *ss != 0)
   return ERROR;
   }
 
+/* We use the rest of the argument list following the limit as the
+lookup key, because it doesn't make sense to use the same stored data
+if the period or options are different. */
+
+key = arg;
+
 /* Second is the rate measurement period and exponential smoothing time
 constant. This must be strictly greater than zero, because zero leads to
 run-time division errors. */
@@ -1991,9 +2003,7 @@ if (leaky + strict > 1 || per_byte + per_cmd + per_conn + per_mail > 1)
 if (!strict) leaky = TRUE;
 if (!per_byte && !per_cmd && !per_conn) per_mail = TRUE;
 
-/* We use the whole of the argument list as the lookup key, because it doesn't
-make sense to use the same stored data if any of the arguments are different.
-If there is no explicit key, use the sender_host_address. If there is no
+/* If there is no explicit key, use the sender_host_address. If there is no
 sender_host_address (e.g. -bs or acl_not_smtp) then we simply omit it. */
 
 if (!have_key && sender_host_address != NULL)
@@ -2002,8 +2012,7 @@ if (!have_key && sender_host_address != NULL)
 HDEBUG(D_acl) debug_printf("ratelimit condition limit=%.0f period=%.0f key=%s\n",
   limit, period, key);
 
-/* If we are dealing with rate limits per connection, per message, or per byte,
-see if we have already computed the rate by looking in the relevant tree. For
+/* See if we have already computed the rate by looking in the relevant tree. For
 per-connection rate limiting, store tree nodes and dbdata in the permanent pool
 so that they survive across resets. */
 
@@ -2015,15 +2024,17 @@ if (per_conn)
   anchor = &ratelimiters_conn;
   store_pool = POOL_PERM;
   }
-if (per_mail || per_byte)
+else if (per_mail || per_byte)
   anchor = &ratelimiters_mail;
+else if (per_cmd)
+  anchor = &ratelimiters_cmd;
 
 if (anchor != NULL && (t = tree_search(*anchor, key)) != NULL)
   {
   dbd = t->data.ptr;
   /* The following few lines duplicate some of the code below. */
-  if (dbd->rate > limit) rc = OK;
-    else rc = FAIL;
+  if (dbd->rate < limit) rc = FAIL;
+    else rc = OK;
   store_pool = old_pool;
   sender_rate = string_sprintf("%.1f", dbd->rate);
   HDEBUG(D_acl)
@@ -2130,8 +2141,13 @@ else
     dbd->rate = (1 - a) / i_over_p + a * dbd->rate;
   }
 
-if (dbd->rate > limit) rc = OK;
-  else rc = FAIL;
+/* Clients sending at the limit are considered to be over the limit. This
+matters for edge cases such the first message sent by a client (which gets
+the initial rate of 0.0) when the rate limit is zero (i.e. the client should
+be completely blocked). */
+
+if (dbd->rate < limit) rc = FAIL;
+  else rc = OK;
 
 /* Update the state if the rate is low or if we are being strict. If we
 are in leaky mode and the sender's rate is too high, we do not update
@@ -3311,6 +3327,7 @@ address_item *addr;
 
 *user_msgptr = *log_msgptr = NULL;
 sender_verified_failed = NULL;
+ratelimiters_cmd = NULL;
 
 if (where == ACL_WHERE_RCPT)
   {