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;
}