-----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; +}
qmail-ldap-1.03-relaydomains.patch.sig
Description: Binary data