Re: [exim] Multiple spamd servers.

Top Page
Delete this message
Reply to this message
Author: Michael Haardt
Date:  
To: exim-users
Subject: Re: [exim] Multiple spamd servers.
On Wed, Nov 09, 2005 at 10:28:22AM +0200, Ian FREISLICH wrote:
> The only other way that I can think of is to allow exim to have
> sets of spamd_address options so that I could scan submitted mail
> with a spamd using a particular configuration and incoming SMTP on
> a different spamd. This will mean some changes to the semantics
> of the spam condition.


Sounds very familiar to me.

> I envisage something like:
>
>     deny    message    = Spam detected
>         !authenticated    = *
>         spam    = incoming-$primary_hostname/servers=spamd1 783 : \
>             spamd2 783 : ...


Indeed it would be nice to get rid of the global option and specify the
spamd server entirely in "spam". I suggested that long ago, because I
run multiple *different* spamd servers since some years now. But the
result of the discussion was: Unless it stays compatible with the awkward
syntax, there will be no change. When Tom finally introduced multiple
servers, it was just for load balancing, missing the point.

> Altenatively, making the spamd_address configuration option expanded,
> rather than a string could have the desired effect:
>
> spamd_address= $acl_m0


Right, just as ugly as when using virus scanners, but compatible.

> This might be the easier and smaller change to make.
>
> So, before I go ahead and patch, I'd like to know what others think
> and which form (if any) is more likely to be adopted into the source.


The second. I got tired of maintaining my own spam.c interface and
switched to the second way. I appended a part of my patches. Most likely
it will not apply to the plain source, but you get the point.

Seeing that there are still external variables in spool_mbox.c instead
of a decent interface to the scanners to invalidate their caches, I gave
up on hoping for a nice and clean interface towards the admin. View the
source below as a hack on top of a hack.

Michael
----------------------------------------------------------------------
--- src/spam.c.orig    2005-10-04 10:55:28.000000000 +0200
+++ src/spam.c    2005-10-21 18:15:55.000000000 +0200
@@ -24,6 +24,7 @@
 int spam(uschar **listptr) {
   int sep = 0;
   uschar *list = *listptr;
+  uschar *spamd_address_work = spamd_address;
   uschar *user_name;
   uschar user_name_buffer[128];
   unsigned long mbox_size;
@@ -47,6 +48,22 @@
   /* stop compiler warning */
   result = result;


+  /* if spamd_address starts with a dollar, expand it first */
+  if (*spamd_address == '$') {
+    spamd_address_work = expand_string(spamd_address);
+    if (spamd_address_work == NULL) {
+      log_write(0, LOG_MAIN|LOG_PANIC,
+           "spam acl condition: spamd_address starts with $, but expansion failed: %s", expand_string_message);
+      return DEFER;
+    }
+    else {
+      debug_printf("Expanded spamd_address global: %s\n", spamd_address_work);
+      /* disable result caching in this case */
+      prev_user_name[0] = '\0';
+      spam_ok = 0;
+    };
+  }
+
   /* find the username from the option list */
   if ((user_name = string_nextinlist(&list, &sep,
                                      user_name_buffer,
@@ -87,13 +104,13 @@


   start = time(NULL);
   /* socket does not start with '/' -> network socket */
-  if (*spamd_address != '/') {
+  if (*spamd_address_work != '/') {
     time_t now = time(NULL);
     int num_servers = 0;
     int current_server = 0;
     int start_server = 0;
     uschar *address = NULL;
-    uschar *spamd_address_list_ptr = spamd_address;
+    uschar *spamd_address_list_ptr = spamd_address_work;
     uschar address_buffer[256];
     spamd_address_container * spamd_address_vector[32];


@@ -181,12 +198,12 @@
     }


     server.sun_family = AF_UNIX;
-    Ustrcpy(server.sun_path, spamd_address);
+    Ustrcpy(server.sun_path, spamd_address_work);


     if (connect(spamd_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
       log_write(0, LOG_MAIN|LOG_PANIC,
                 "malware acl condition: spamd: unable to connect to UNIX socket %s (%s)",
-                spamd_address, strerror(errno) );
+                spamd_address_work, strerror(errno) );
       (void)fclose(mbox_file);
       (void)close(spamd_sock);
       return DEFER;
@@ -292,7 +310,7 @@
   /* error handling */
   if((i <= 0) && (errno != 0)) {
     log_write(0, LOG_MAIN|LOG_PANIC,
-         "spam acl condition: error reading from spamd socket: %s", strerror(errno));
+         "spam acl condition: error reading from spamd socket %s: %s", spamd_address_work, strerror(errno));
     (void)close(spamd_sock);
     return DEFER;
   }