[Greylist-users] qmail implementation - correct this time, I hope

Tony Arcieri tarcieri at atmos.colostate.edu
Thu Jun 26 12:02:14 PDT 2003


On Thu, 26 Jun 2003, Eirik Oeverby wrote:

> Hi,
>
> I just gave your patch a go.
> If the qmail-env-scan script/program does not exist, qmail-smtpd will
> fail with a permanent envelope error. According to what you wrote in
> earlier posts, this is not the intended behaviour. I think I can fix it
> myself, but as I'm not really a C coder, I think it's best if you make
> another update to the patch.

I posted this patch to the qmail mailing list yesterday and together
picked out a number of errors with the original author.

My original intention was that the envelope scanner not be a point of
failure in the system, so my intention was that if qmail-env-scan does not
exist messages would simply be passed.  Unfortunately I was using the
wrong return values, which resulted in the opposite behaviour (permanent
failure)

An amended patch is attached to this post.  As I said earlier, I will have
to first set up a non-production system before I can begin testing of this
patch for myself, unfortunately.  My two systems running qmail provide
mail service for over 50 people each.

> May I also add that when using the FreeBSD ports system to download and
> unpack the source, your patch will not apply cleanly - in fact it will
> not apply at all. I had to manually patch my source file, though I have
> *no* idea why it didn't want to patch it automatically (patch <
> qmail-env-scanner.patch). All hunks were rejected.

Be sure to patch with -p1.  I successfully patched the source in the ports
tree using the patch attached to this message.

Tony Arcieri
-------------- next part --------------
--- qmail-1.03/qmail-smtpd.c	Mon Jun 15 04:53:16 1998
+++ qmail-1.03-scanenv/qmail-smtpd.c	Thu Jun 26 10:57:41 2003
@@ -19,6 +19,8 @@
 #include "env.h"
 #include "now.h"
 #include "exit.h"
+#include "fork.h"
+#include "wait.h"
 #include "rcpthosts.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
@@ -45,10 +47,12 @@
 void die_read() { _exit(1); }
 void die_alarm() { out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1); }
 void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); }
+void die_tempfail() { out("421 message temporarily rejected (#4.3.0)\r\n"); flush(); _exit(1); } 
 void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); }
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
 void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
 
+void err_permfail() { out("553 message permanently rejected (#5.7.1)\r\n"); }
 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
 void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
@@ -222,6 +226,44 @@
 stralloc mailfrom = {0};
 stralloc rcptto = {0};
 
+int env_scanner()
+{
+  int child;
+  int wstat;
+  char *env_scannerarg[] = { "bin/qmail-env-scanner", mailfrom.s, addr.s, 0 };
+  
+  switch(child = vfork()) {
+    case -1:
+      return 1;
+    case 0:
+      execv(*env_scannerarg,env_scannerarg);
+      _exit(111);
+  }
+
+  wait_pid(&wstat,child);
+  if (wait_crashed(wstat)) {
+    /* Can't call log1 here? */
+    /* log1("warning: envelope scanner crashed\n"); */   
+    return 1;
+  }
+  
+  switch(wait_exitcode(wstat)) {
+    case 0:
+      return 1; 
+    case 100:
+      die_tempfail();
+    case 101:
+      return 0;
+    case 111:
+      /* Can't call log1 here? */
+      /* log1("warning: cannot execute envelope scanner\n"); */
+      return 1;
+    default:
+      /* log1("warning: envelope scanner exited with error code\n"); */
+      return 1;
+  }
+}
+
 void smtp_helo(arg) char *arg;
 {
   smtp_greet("250 "); out("\r\n");
@@ -261,6 +303,7 @@
   if (!stralloc_cats(&rcptto,"T")) die_nomem();
   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
   if (!stralloc_0(&rcptto)) die_nomem();
+  if(!env_scanner()) { err_permfail(); return; }
   out("250 ok\r\n");
 }
 


More information about the Greylist-users mailing list