(This version updated from Gerrit Pape's original patch to work with qmail-verify v1.50,
 also calls to nomem() replaced with die_nomem() which I think was the intention)
From: Gerrit Pape <pape@smarden.org>
Subject: [PATCH 3/3] qmail-verify: optionally check aliases.cdb if fastforward is used

If qmail-verify finds ~alias/.qmail-default and the environment variable
VERIFY_FASTFORWARDCDB is set to e.g. /etc/aliases.cdb, instead of allowing
all addresses it will lookup the recipient address in that constant
database, and only allow the address if a matching entry is found.
---
 qmail-verify.c.orig => qmail-verify.c | 54 ++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/qmail-verify.c.orig b/qmail-verify.c
index cc53e60..f03c8ba 100644
--- a/qmail-verify.c.orig
+++ b/qmail-verify.c
@@ -168,6 +168,49 @@ int userext()	/* from qmail-getpw.c */
   }
 }
 
+int verify_aliasescdb(addr, fn)
+char *addr;
+char *fn;
+{
+  int fd;
+  static stralloc key = {};
+  uint32 dlen;
+  int r;
+  int at;
+
+  fd = open_read(fn);
+  if (fd == -1) die_cdb();
+  if (!stralloc_copys(&key,":")) die_nomem();
+  if (!stralloc_cats(&key,addr)) die_nomem();
+  case_lowerb(key.s,key.len);
+
+  r = cdb_seek(fd,key.s,key.len,&dlen);
+  if (r == -1) die_cdb();
+  if (r) { close(fd); return 1; }
+
+  at = str_rchr(addr,'@');
+  if (!addr[at]) { close(fd); return 0; }
+
+  if (!stralloc_copys(&key,":")) die_nomem();
+  if (!stralloc_cats(&key,addr + at)) die_nomem();
+  case_lowerb(key.s,key.len);
+
+  r = cdb_seek(fd,key.s,key.len,&dlen);
+  if (r == -1) die_cdb();
+  if (r) { close(fd); return 1; }
+
+  if (!stralloc_copys(&key,":")) die_nomem();
+  if (!stralloc_catb(&key,addr,at + 1)) die_nomem();
+  case_lowerb(key.s,key.len);
+
+  r = cdb_seek(fd,key.s,key.len,&dlen);
+  if (r == -1) die_cdb();
+  close(fd);
+  if (r) return 1;
+
+  return 0;
+}
+
 static int stat_as(uid, gid, path, sbuf)
 const uid_t uid;
 const gid_t gid;
@@ -399,7 +442,16 @@ char *addr;
         if (!stralloc_cats(&qme,"default")) die_nomem();
         if (!stralloc_0(&qme)) die_nomem();
 /* e.g. homedir/.qmail-[xxx-]default */
-	if (stat_as(uid,gid,qme.s,&st) == 0) return allowaddr(addr,ADDR_OK|QVPOS12);
+        if (stat_as(uid,gid,qme.s,&st) == 0) {
+	  /* if it's ~alias/.qmail-default, optionally check aliases.cdb */
+          if (!i && (quser == auto_usera)) {
+            char *s;
+            if (s = env_get("VERIFY_FASTFORWARDCDB"))
+              if (!verify_aliasescdb(addr, s))
+                return denyaddr(addr,ADDR_NOK|QVPOS12);
+          }
+          return allowaddr(addr,ADDR_OK|QVPOS12);
+        }
         if (errno != error_noent) /* Maybe not running as root so access denied */
           return stat_error(qme.s,errno,STATERR|QVPOS13);
       }
