-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi everybody,

        While setting up a Secondary MX for a friend of mine, he
asked if it was possible to take the same approach of postfix,
listing valid e-mail address and dropping connection if the RCPT
TO is invalid.

        I checked the mail list archive and found the concerns
about how to properly do that because of the lack of LDAP and
the idea that Primary MX wouldn't be available for a query. So,
the idea of this patch is to address a use case where people
want to list valid e-mail address (even with wildcards) that
are accepted.

        It introduces two new control file:

        control/relaydomains:
                List the domains that you want RCPTCHECK

        control/relaymailaddr:
                List valid e-mail addresses for relays


        I changed two files, rcpthosts.c and qmail-smtpd.c based
on some references from other patches, the idea is to check if
the domain is listed in relaydomains then it should check if the
RCPT TO exists in relaymailaddr, it seems to work fine so far.

        I'm not sure if this is suitable for inclusion in
qmail-ldap but I would love to get some feedback from people (and
specially qmail-ldap upstream) about potential problems of the
patch and if I should take another approach.

        I really want to stay with qmail-ldap "pristine" as much
as possible, my other changes in the patch were just to make it
easier, so I added relaydomains.cdb in Makefile.cdb. I hope
that there are some interest from other people, I remember that
somebody was using a stock-qmail with validrcptto and qmail-ldap,
I don't know it this patch addresses the same issue, if it does,
hopefully it is easier.

        Patch: qmail-ldap-1.03-relaydomains.patch
        Keywords: Secondary MX, Backup MX, Relay MX
        Description: add support to list valid recipients when
                     acting as a secondary MX, the domain is
                     not listed in control/locals only in
                     control/rcpthosts.

Kind regards,
- --
Felipe Augusto van de Wiel <[EMAIL PROTECTED]>
Coordenadoria de Tecnologia da Informação (CTI) - SEDU/PARANACIDADE
http://www.paranacidade.org.br/           Phone: (+55 41 3350 3300)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHOFmpCj65ZxU4gPQRCJCCAJ9ED7dA0VIimuu9x6TTeqB1ONQHqQCfUYKG
83czkjzrrMB7XCyepsQzR4s=
=2dTd
-----END PGP SIGNATURE-----
diff -Nru qmail-1.03-ldap/Makefile.cdb qmail-1.03-relay/Makefile.cdb
--- qmail-1.03-ldap/Makefile.cdb	2007-11-12 06:42:55.000000000 -0600
+++ qmail-1.03-relay/Makefile.cdb	2007-11-12 07:27:05.000000000 -0600
@@ -38,8 +38,8 @@
 TCPRULES=tcprules
 QMAILRULES="%QMAIL%/bin/qmail-cdb"
 
-FILES=	locals.cdb rcpthosts.cdb qmail-smtpd.cdb qmail-qmqpd.cdb \
-	qmail-pop3d.cdb qmail-imapd.cdb
+FILES=	locals.cdb rcpthosts.cdb relaydomains.cdb qmail-smtpd.cdb \
+	qmail-qmqpd.cdb qmail-pop3d.cdb qmail-imapd.cdb
 
 TMPFILE=rules.tmp
 
@@ -55,6 +55,9 @@
 rcpthosts.cdb: rcpthosts
 	$(QMAILRULES) rcpthosts.cdb $(TMPFILE) < rcpthosts
 
+relaydomains.cdb: relaydomains
+	$(QMAILRULES) relaydomains.cdb $(TMPFILE) < relaydomains
+
 .rules.cdb:
 	$(TCPRULES) $@ $(TMPFILE) < $<
 
diff -Nru qmail-1.03-ldap/qmail-smtpd.c qmail-1.03-relay/qmail-smtpd.c
--- qmail-1.03-ldap/qmail-smtpd.c	2007-11-12 06:42:56.000000000 -0600
+++ qmail-1.03-relay/qmail-smtpd.c	2007-11-12 07:23:05.000000000 -0600
@@ -274,6 +274,9 @@
 int gmaok = 0;
 stralloc gma = {0};
 struct constmap mapgma;
+int rmaok = 0;
+stralloc rma = {0};
+struct constmap maprma;
 int rblok = 0;
 int rbloh = 0;
 int errdisconnect = 0;
@@ -375,6 +378,11 @@
   if (gmaok)
     if (!constmap_init(&mapgma,gma.s,gma.len,0)) die_nomem();
 
+  rmaok = control_readfile(&rma,"control/relaymailaddr",0);
+  if (rmaok == -1) die_control();
+  if (rmaok)
+    if (!constmap_init(&maprma,rma.s,rma.len,0)) die_nomem();
+
   if (env_get("RBL")) {
     rblok = rblinit();
     if (rblok == -1) die_control();
@@ -687,6 +695,15 @@
   return r;
 }
 
+int addrrelays(void)
+{
+  int r;
+
+  r = relaydomains(addr.s,addr.len - 1);
+  if (r == -1) die_control();
+  return r;
+}
+
 int addrlocals(void)
 {
   int r;
@@ -759,6 +776,56 @@
   return 0;
 }
 
+stralloc rmaddr;
+
+int relaymailaddr(void)
+{
+  unsigned int at;
+#ifdef DASH_EXT
+  unsigned int ext;
+  int extcnt;
+#endif
+
+  if (!rmaok) return 0;
+  if (constmap(&maprma, addr.s, addr.len - 1)) return 1;
+  at = byte_rchr(addr.s,addr.len,'@');
+  if (at < addr.len) {
+    if (constmap(&maprma, addr.s + at, addr.len - at - 1))
+      return 1;
+    if (constmap(&maprma, addr.s, at + 1))
+      return 1;
+#ifdef DASH_EXT
+    /* [EMAIL PROTECTED] */
+    for (ext = 0, extcnt = 1; ext < at && extcnt <= DASH_EXT_LEVELS; ext++)
+      if (addr.s[ext] == *auto_break)
+	extcnt++;
+    for (;;) {
+      if (addr.s[ext] == *auto_break) {
+	if (!stralloc_copyb(&rmaddr, addr.s, ext + 1))
+	  die_nomem();
+	if (!stralloc_cats(&rmaddr, LDAP_CATCH_ALL))
+	  die_nomem();
+	if (!stralloc_catb(&rmaddr, addr.s + at, addr.len - at - 1))
+	  die_nomem();
+	if (constmap(&maprma, rmaddr.s, rmaddr.len))
+	  return 1;
+      }
+      if (ext == 0)
+	break;
+      ext--;
+    }
+#endif
+    /* [EMAIL PROTECTED] */
+    if (!stralloc_copys(&rmaddr, LDAP_CATCH_ALL))
+      die_nomem();
+    if (!stralloc_catb(&rmaddr, addr.s + at, addr.len - at - 1))
+      die_nomem();
+    if (constmap(&maprma, rmaddr.s, rmaddr.len))
+      return 1;
+  }
+  return 0;
+}
+
 struct call ccverify;
 stralloc verifyresponse;
 int flagverify = 0;
@@ -1178,7 +1245,14 @@
             if (errdisconnect) err_quit();
             return;
         }
-      } /* else this is relaying, don't do anything */
+      } else { /* else this is relaying, just check valid relays */
+      	if (addrrelays() && !relaymailaddr()) {
+      	  logline(4,"recipient verify, recipient not in relaymailaddr");
+    	  err_badrcptto();
+          logline2(3,"'rcpt to' denied via badrcptto: ",addr.s);
+          if (errdisconnect) err_quit();
+        }
+      }
     }
   }
 
diff -Nru qmail-1.03-ldap/rcpthosts.c qmail-1.03-relay/rcpthosts.c
--- qmail-1.03-ldap/rcpthosts.c	2007-11-12 06:42:56.000000000 -0600
+++ qmail-1.03-relay/rcpthosts.c	2007-11-12 07:33:53.000000000 -0600
@@ -14,11 +14,15 @@
 static int fdlo;
 static int fdrh;
 static int fdmrh;
+static int fdrd;
 static struct cdb cdblo;
 static struct cdb cdbrh;
 static struct cdb cdbmrh;
+static struct cdb cdbrd;
 static stralloc locals = {0};
+static stralloc rd = {0};
 static struct constmap maplocals;
+static struct constmap maprd;
 
 int rcpthosts_init(void)
 {
@@ -131,3 +135,34 @@
 	return 0;
 }
 
+int relaydomains(char *buf, unsigned int len)
+{
+	unsigned int j;
+	uint32 dlen;
+
+	fdrd = open_read("control/relaydomains.cdb");
+	if (fdrd == -1) {
+		if (errno != error_noent)
+			return -1;
+		if (control_readfile(&rd,"control/relaydomains",1) != 1)
+			return -1;
+		if (!constmap_init(&maprd,rd.s,rd.len,0))
+			return -1;
+	} else
+		cdb_init(&cdbrd, fdrd);
+
+	j = byte_rchr(buf,len,'@');
+	if (j >= len) return 0; /* envnoathost is not acceptable */
+	++j; buf += j; len -= j;
+
+	if (!stralloc_copyb(&host,buf,len)) return -1;
+	buf = host.s;
+	case_lowerb(buf,len);
+
+	/* if relaydomains.cdb available use this as source */
+	if (fdrd != -1) 
+		return cdb_seek(&cdbrd, buf, len, &dlen);
+	else   
+		if (constmap(&maprd, buf, len)) return 1;
+	return 0;
+}

Attachment: qmail-ldap-1.03-relaydomains.patch.sig
Description: Binary data

Reply via email to