*** qmail-1.03.orig/qmail-smtpd.c	Mon Jun 15 06:53:16 1998
--- qmail-1.03/qmail-smtpd.c	Wed Jul 14 13:48:24 2004
***************
*** 23,28 ****
--- 23,29 ----
  #include "timeoutread.h"
  #include "timeoutwrite.h"
  #include "commands.h"
+ #include "wait.h"
  
  #define MAXHOPS 100
  unsigned int databytes = 0;
***************
*** 47,52 ****
--- 48,56 ----
  void die_nomem() { out("421 out of memory (#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 die_fork() { out("421 unable to fork (#4.3.0)\r\n"); flush(); _exit(1); }
+ void die_rcpt() { out("421 unable to verify recipient (#4.3.0)\r\n"); flush(); _exit(1); }
+ void die_rcpt2() { out("421 unable to execute recipient check (#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_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
***************
*** 58,63 ****
--- 62,68 ----
  void err_noop() { out("250 ok\r\n"); }
  void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); }
  void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
+ void err_badrcpt() { out("553 sorry, no mailbox here by that name. (#5.1.1)\r\n"); }
  
  
  stralloc greeting = {0};
***************
*** 81,86 ****
--- 86,92 ----
  char *remoteinfo;
  char *local;
  char *relayclient;
+ static char *rcptcheck[2] = { 0, 0 };
  
  stralloc helohost = {0};
  char *fakehelo; /* pointer into helohost, or 0 */
***************
*** 131,136 ****
--- 137,143 ----
    if (!remotehost) remotehost = "unknown";
    remoteinfo = env_get("TCPREMOTEINFO");
    relayclient = env_get("RELAYCLIENT");
+   rcptcheck[0] = env_get("RCPTCHECK");
    dohelo(remotehost);
  }
  
***************
*** 216,227 ****
    return r;
  }
  
- 
  int seenmail = 0;
  int flagbarf; /* defined if seenmail */
  stralloc mailfrom = {0};
  stralloc rcptto = {0};
  
  void smtp_helo(arg) char *arg;
  {
    smtp_greet("250 "); out("\r\n");
--- 223,258 ----
    return r;
  }
  
  int seenmail = 0;
  int flagbarf; /* defined if seenmail */
  stralloc mailfrom = {0};
  stralloc rcptto = {0};
  
+ int addrvalid()
+ {
+ 	int pid;
+ 	int wstat;
+ 
+ 	if (!rcptcheck[0]) return 1;
+ 
+     switch(pid = fork()) {
+ 	  case -1: die_fork();
+ 	  case 0:
+ 	    if (!env_put2("SENDER",mailfrom.s)) die_nomem();
+ 	    if (!env_put2("RECIPIENT",addr.s)) die_nomem();
+ 	    execv(*rcptcheck,rcptcheck);
+ 		_exit(120);
+     }
+     if (wait_pid(&wstat,pid) == -1) die_rcpt2();
+     if (wait_crashed(wstat)) die_rcpt2();
+     switch(wait_exitcode(wstat)) {
+ 	  case 100: return 0;
+ 	  case 111: die_rcpt();
+ 	  case 120: die_rcpt2();
+     }
+ 	return 1;
+ }
+ 
  void smtp_helo(arg) char *arg;
  {
    smtp_greet("250 "); out("\r\n");
***************
*** 256,263 ****
      if (!stralloc_cats(&addr,relayclient)) die_nomem();
      if (!stralloc_0(&addr)) die_nomem();
    }
!   else
      if (!addrallowed()) { err_nogateway(); return; }
    if (!stralloc_cats(&rcptto,"T")) die_nomem();
    if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
    if (!stralloc_0(&rcptto)) die_nomem();
--- 287,296 ----
      if (!stralloc_cats(&addr,relayclient)) die_nomem();
      if (!stralloc_0(&addr)) die_nomem();
    }
!   else {
      if (!addrallowed()) { err_nogateway(); return; }
+     if (!addrvalid()) { err_badrcpt(); return; }
+   }
    if (!stralloc_cats(&rcptto,"T")) die_nomem();
    if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
    if (!stralloc_0(&rcptto)) die_nomem();
