--- orig-Makefile	1998-06-15 03:53:16.000000000 -0700
+++ Makefile	2007-11-20 12:53:56.000000000 -0800
@@ -1365,26 +1365,26 @@
 compile qmail-qmqpd.c auto_qmail.h qmail.h substdio.h received.h \
 sig.h substdio.h readwrite.h exit.h now.h datetime.h fmt.h env.h
 	./compile qmail-qmqpd.c
 
 qmail-qmtpd: \
-load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \
-date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a open.a \
+load qmail-qmtpd.o rcpthosts.o rcptusers.o auto_break.o control.o constmap.o \
+received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a open.a \
 getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \
 str.a fs.a auto_qmail.o
-	./load qmail-qmtpd rcpthosts.o control.o constmap.o \
-	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
+	./load qmail-qmtpd rcpthosts.o rcptusers.o auto_break.o control.o \
+	constmap.o received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
 	datetime.a open.a getln.a sig.a case.a env.a stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a auto_qmail.o 
 
 qmail-qmtpd.0: \
 qmail-qmtpd.8
 	nroff -man qmail-qmtpd.8 > qmail-qmtpd.0
 
 qmail-qmtpd.o: \
 compile qmail-qmtpd.c stralloc.h gen_alloc.h substdio.h qmail.h \
-substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h \
+substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h rcptusers.h \
 auto_qmail.h readwrite.h control.h received.h
 	./compile qmail-qmtpd.c
 
 qmail-qread: \
 load qmail-qread.o fmtqfn.o readsubdir.o date822fmt.o datetime.a \
@@ -1530,17 +1530,17 @@
 auto_uids.h auto_qmail.h auto_break.h auto_patrn.h auto_spawn.h \
 auto_split.h
 	./compile qmail-showctl.c
 
 qmail-smtpd: \
-load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
-timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
-date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
+load qmail-smtpd.o rcpthosts.o rcptusers.o auto_break.o commands.o \
+timeoutread.o timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
+received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
 open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \
 fs.a auto_qmail.o socket.lib
-	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
-	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
+	./load qmail-smtpd rcpthosts.o rcptusers.o auto_break.o commands.o \
+	timeoutread.o timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
 	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
 	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
 	socket.lib`
 
@@ -1551,11 +1551,11 @@
 qmail-smtpd.o: \
 compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
 substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
 error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
 substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
-exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h
+exit.h rcpthosts.h rcptusers.h timeoutread.h timeoutwrite.h commands.h
 	./compile qmail-smtpd.c
 
 qmail-start: \
 load qmail-start.o prot.o fd.a auto_uids.o
 	./load qmail-start prot.o fd.a auto_uids.o 
@@ -1679,10 +1679,15 @@
 rcpthosts.o: \
 compile rcpthosts.c cdb.h uint32.h byte.h open.h error.h control.h \
 constmap.h stralloc.h gen_alloc.h rcpthosts.h
 	./compile rcpthosts.c
 
+rcptusers.o: \
+compile rcptusers.c cdb.h uint32.h byte.h open.h error.h control.h \
+constmap.h stralloc.h gen_alloc.h rcptusers.h auto_break.h
+	./compile rcptusers.c
+
 readsubdir.o: \
 compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \
 auto_split.h
 	./compile readsubdir.c
 
@@ -1781,12 +1786,12 @@
 qmail-start.c qmail-tcpok.c qmail-tcpto.c spawn.c dnscname.c dnsfq.c \
 dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c tcp-env.c \
 sendmail.c qreceipt.c qsmhook.c qbiff.c forward.c preline.c predate.c \
 except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \
 maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \
-datemail.sh mailsubj.sh qlx.h rcpthosts.h rcpthosts.c commands.h \
-commands.c dnsdoe.h dnsdoe.c fmtqfn.h fmtqfn.c gfrom.h gfrom.c \
+datemail.sh mailsubj.sh qlx.h rcpthosts.h rcpthosts.c rcptusers.h rcptusers.c \
+commands.h commands.c dnsdoe.h dnsdoe.c fmtqfn.h fmtqfn.c gfrom.h gfrom.c \
 myctime.h myctime.c newfield.h newfield.c qsutil.h qsutil.c \
 readsubdir.h readsubdir.c received.h received.c tcpto.h tcpto.c \
 tcpto_clean.c trigger.h trigger.c triggerpull.h triggerpull.c \
 trynpbg1.c trysyslog.c conf-cc conf-ld home.sh home+df.sh proc.sh \
 proc+df.sh binm1.sh binm2.sh binm3.sh binm1+df.sh binm2+df.sh \
--- orig-qmail-qmtpd.c	1998-06-15 03:53:16.000000000 -0700
+++ qmail-qmtpd.c	2007-11-20 11:42:56.000000000 -0800
@@ -5,10 +5,11 @@
 #include "str.h"
 #include "fmt.h"
 #include "env.h"
 #include "sig.h"
 #include "rcpthosts.h"
+#include "rcptusers.h"
 #include "auto_qmail.h"
 #include "readwrite.h"
 #include "control.h"
 #include "received.h"
 
@@ -94,10 +95,11 @@
  
   if (chdir(auto_qmail) == -1) resources();
  
   if (control_init() == -1) resources();
   if (rcpthosts_init() == -1) resources();
+  if (rcptusers_init() == -1) resources();
   relayclient = env_get("RELAYCLIENT");
   relayclientlen = relayclient ? str_len(relayclient) : 0;
  
   if (control_readint(&databytes,"control/databytes") == -1) resources();
   x = env_get("DATABYTES");
@@ -212,11 +214,15 @@
         if (relayclient)
           str_copy(buf + len,relayclient);
         else
           switch(rcpthosts(buf,len)) {
             case -1: resources();
-            case 0: failure.s[failure.len - 1] = 'D';
+            case 0:
+              switch(rcptusers(buf,len)) {
+                case -1: resources();
+                case 0: failure.s[failure.len - 1] = 'D';
+              }
           }
  
         if (!failure.s[failure.len - 1]) {
           qmail_to(&qq,buf);
           flagbother = 1;
@@ -254,11 +260,11 @@
       switch(failure.s[i]) {
         case 0:
           substdio_put(&ssout,buf,len);
           break;
         case 'D':
-          substdio_puts(&ssout,"66:Dsorry, that domain isn't in my list of allowed rcpthosts (#5.7.1),");
+          substdio_puts(&ssout,"66:Dsorry, that user/domain isn't in my list of allowed rcptusers/rcpthosts (#5.7.1),");
           break;
         default:
           substdio_puts(&ssout,"46:Dsorry, I can't handle that recipient (#5.1.3),");
           break;
       }
--- orig-qmail-smtpd.c	1998-06-15 03:53:16.000000000 -0700
+++ qmail-smtpd.c	2007-11-20 11:37:40.000000000 -0800
@@ -18,10 +18,11 @@
 #include "case.h"
 #include "env.h"
 #include "now.h"
 #include "exit.h"
 #include "rcpthosts.h"
+#include "rcptusers.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
 
 #define MAXHOPS 100
@@ -48,11 +49,11 @@
 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_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_nogateway() { out("553 sorry, that user/domain isn't in my list of allowed rcptusers/rcpthosts (#5.7.1)\r\n"); }
 void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
 void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); }
 void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); }
 void err_noop() { out("250 ok\r\n"); }
@@ -109,10 +110,11 @@
   if (liphostok == -1) die_control();
   if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
   if (timeout <= 0) timeout = 1;
 
   if (rcpthosts_init() == -1) die_control();
+  if (rcptusers_init() == -1) die_control();
 
   bmfok = control_readfile(&bmf,"control/badmailfrom",0);
   if (bmfok == -1) die_control();
   if (bmfok)
     if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
@@ -211,10 +213,14 @@
 int addrallowed()
 {
   int r;
   r = rcpthosts(addr.s,str_len(addr.s));
   if (r == -1) die_control();
+  if (r) {
+    r = rcptusers(addr.s,str_len(addr.s));
+    if (r == -1) die_control();
+   }
   return r;
 }
 
 
 int seenmail = 0;
--- orig-rcptusers.c	2007-11-20 12:05:14.000000000 -0800
+++ rcptusers.c	2007-11-20 12:52:02.000000000 -0800
@@ -0,0 +1,61 @@
+#include "cdb.h"
+#include "byte.h"
+#include "open.h"
+#include "error.h"
+#include "control.h"
+#include "constmap.h"
+#include "stralloc.h"
+#include "rcptusers.h"
+#include "auto_break.h"
+
+static int flagru = 0;
+static stralloc ru = {0};
+static struct constmap mapru;
+static int fdmru;
+
+int rcptusers_init()
+{
+  flagru = control_readfile(&ru,"control/rcptusers",0);
+  if (flagru != 1) return flagru;
+  if (!constmap_init(&mapru,ru.s,ru.len,0)) return flagru = -1;
+  fdmru = open_read("control/morercptusers.cdb");
+  if (fdmru == -1) if (errno != error_noent) return flagru = -1;
+  return 0;
+}
+
+static stralloc user = {0};
+
+int rcptusers(buf,len)
+char *buf;
+int len;
+{
+  int j;
+
+  if (flagru != 1) return 1;
+
+  len = byte_rchr(buf,len,'@');
+
+  if (!stralloc_copyb(&user,buf,len)) return -1;
+  buf = user.s;
+  case_lowerb(buf,len);
+
+  if (constmap(&mapru,buf,len)) return 1;
+  for (j = 0;j < len;++j)
+    if (!j || (buf[j] == *auto_break))
+      if (constmap(&mapru,buf,j)) return 1;
+
+  if (fdmru != -1) {
+    uint32 dlen;
+    int r;
+
+    r = cdb_seek(fdmru,buf,len,&dlen);
+    if (r) return r;
+    for (j = 0;j < len;++j)
+      if (!j || (buf[j] == *auto_break)) {
+        r = cdb_seek(fdmru,buf,j,&dlen);
+        if (r) return r;
+      }
+  }
+
+  return 0;
+}
--- orig-rcptusers.h	2007-11-20 12:05:14.000000000 -0800
+++ rcptusers.h	2007-11-20 11:35:41.000000000 -0800
@@ -0,0 +1,7 @@
+#ifndef RCPTUSERS_H
+#define RCPTUSERS_H
+
+extern int rcptusers_init();
+extern int rcptusers();
+
+#endif
