Download | Plain Text | No Line Numbers
- http://code.dogmap.org./qmail/#realrcptto
-
- Changes in version 2009.01.31 (manuel mausz):
- - userlookup + set DTUSER environment variable for quotacheck plugin
-
- Changes in version 2006.12.10:
- - For QMAILRRTENYALL, use error code 554 after DATA, not 550. Thanks to
- ... sorry, I lost track of who found this.
- - Log stat() errors for .qmail files. Thanks to Chris Bensend for suggesting
- this.
-
- Changes in version 2006.10.26:
- - Logging uses substdio_puts() and substdio_flush() instead of
- substdio_putsflush(). This makes log entries less likely to be
- interleaved. Thanks to Matthew Dempsky for finding this.
-
- Changes in version 2004.09.14:
- - Strict syntax fix: a variable declaration was accidentally put among
- statements instead of at the beginning of the block.
-
- Changes in version 2004.08.30:
- - Added QMAILRRTDENYALL.
- - Cleanup: missing "break" for some switch statements (no visible behavior
- changes AFAICT). Thanks to Markus Stumpf for finding these.
-
- Changes in version 2004.02.05:
- - Short-circuit speedup when "dash" is empty.
- - Move duplicated code into realrcptto.c.
- - Add logging of rejected addresses.
- - Verified inter-patchability with netqmail-1.05 and Russell Nelson's
- qmail-smtpd-viruscan patch.
-
- diff -Naur Makefile.orig Makefile
- --- Makefile.orig 1998-06-15 06:52:55.000000000 -0400
- +++ Makefile 2006-12-08 03:21:25.000000000 -0500
- @@ -1447,15 +1447,15 @@
- ./compile qmail-qmqpd.c
-
- qmail-qmtpd: \
- -load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \
- +load qmail-qmtpd.o realrcptto.o slurpclose.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 \
- getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \
- -str.a fs.a auto_qmail.o dns.o ip.o ipalloc.o ipme.o byte_diff.o
- - ./load qmail-qmtpd rcpthosts.o control.o constmap.o \
- +str.a fs.a auto_qmail.o dns.o ip.o ipalloc.o ipme.o byte_diff.o auto_break.o auto_usera.o
- + ./load qmail-qmtpd realrcptto.o slurpclose.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 getln.a sig.a case.a env.a stralloc.a \
- - alloc.a substdio.a error.a fs.a auto_qmail.o dns.o \
- + alloc.a substdio.a error.a fs.a auto_qmail.o dns.o auto_break.o auto_usera.o \
- `cat dns.lib` ip.o ipalloc.o ipme.o byte_diff.o str.a
-
- qmail-qmtpd.0: \
- qmail-qmtpd.8
- @@ -1614,18 +1614,18 @@
- ./compile qmail-showctl.c
-
- qmail-smtpd: \
- -load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \
- +load qmail-smtpd.o realrcptto.o slurpclose.o rcpthosts.o qregex.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 strerr.a substdio.a error.a str.a \
- -fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.o ip.o ipalloc.o
- - ./load qmail-smtpd qregex.o rcpthosts.o commands.o timeoutread.o \
- +fs.a auto_qmail.o base64.o qmail-spp.o auto_break.o auto_usera.o socket.lib dns.o ip.o ipalloc.o
- + ./load qmail-smtpd realrcptto.o slurpclose.o qregex.o rcpthosts.o commands.o timeoutread.o \
- timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
- tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
- received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
- datetime.a getln.a open.a sig.a case.a qmail-spp.o env.a stralloc.a \
- - alloc.a strerr.a substdio.a error.a fs.a auto_qmail.o base64.o `cat \
- - socket.lib` dns.o str.a `cat dns.lib`
- + alloc.a strerr.a substdio.a error.a fs.a auto_qmail.o base64.o auto_break.o \
- + auto_usera.o `cat socket.lib` dns.o str.a `cat dns.lib`
-
- qmail-smtpd.0: \
- qmail-smtpd.8
- @@ -1774,6 +1774,11 @@
- auto_split.h
- ./compile readsubdir.c
-
- +realrcptto.o: \
- +compile realrcptto.c auto_break.h auto_usera.h byte.h case.h cdb.h \
- +constmap.h error.h fmt.h open.h str.h stralloc.h uint32.h
- + ./compile realrcptto.c
- +
- received.o: \
- compile received.c fmt.h qmail.h substdio.h now.h datetime.h \
- datetime.h date822fmt.h received.h
- diff -Naur qmail-qmtpd.c.orig qmail-qmtpd.c
- --- qmail-qmtpd.c.orig 1998-06-15 06:52:55.000000000 -0400
- +++ qmail-qmtpd.c 2006-12-08 03:21:25.000000000 -0500
- @@ -14,6 +14,15 @@
-
- void badproto() { _exit(100); }
- void resources() { _exit(111); }
- +void die_nomem() { resources(); }
- +void die_control() { resources(); }
- +void die_cdb() { resources(); }
- +void die_sys() { resources(); }
- +
- +extern void realrcptto_init();
- +extern void realrcptto_start();
- +extern int realrcptto();
- +extern int realrcptto_deny();
-
- int safewrite(fd,buf,len) int fd; char *buf; int len;
- {
- @@ -98,6 +107,8 @@
- if (rcpthosts_init() == -1) resources();
- relayclient = env_get("RELAYCLIENT");
- relayclientlen = relayclient ? str_len(relayclient) : 0;
- +
- + realrcptto_init();
-
- if (control_readint(&databytes,"control/databytes") == -1) resources();
- x = env_get("DATABYTES");
- @@ -114,6 +125,7 @@
- if (!local) local = "unknown";
-
- for (;;) {
- + realrcptto_start();
- if (!stralloc_copys(&failure,"")) resources();
- flagsenderok = 1;
-
- @@ -216,6 +228,10 @@
- case -1: resources();
- case 0: failure.s[failure.len - 1] = 'D';
- }
- +
- + if (!failure.s[failure.len - 1])
- + if (!realrcptto(buf,1))
- + failure.s[failure.len - 1] = 'D';
-
- if (!failure.s[failure.len - 1]) {
- qmail_to(&qq,buf);
- @@ -231,6 +247,7 @@
- result = qmail_close(&qq);
- if (!flagsenderok) result = "Dunacceptable sender (#5.1.7)";
- if (databytes) if (!bytestooverflow) result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
- + if (!relayclient && realrcptto_deny()) result = "Dsorry, no mailbox here by that name. (#5.1.1)\r\n";
-
- if (*result)
- len = str_len(result);
- diff -Naur qmail-smtpd.c.orig qmail-smtpd.c
- --- qmail-smtpd.c.orig 1998-06-15 06:52:55.000000000 -0400
- +++ qmail-smtpd.c 2006-12-09 04:02:00.000000000 -0500
- @@ -111,12 +111,24 @@
- void die_ipme()
- {
- enew(); eout("Unable to figure out my IP addresses!\n");
- out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush();
- eflush(); _exit(1);
- }
- +void die_cdb()
- +{
- + enew(); eout("Unable to read cdb user database!\n");
- + out("421 unable to read cdb user database (#4.3.0)\r\n"); flush();
- + eflush(); _exit(1);
- +}
- +void die_sys()
- +{
- + enew(); eout("Unable to read system user database!\n");
- + out("421 unable to read system user database (#4.3.0)\r\n"); flush();
- + eflush(); _exit(1);
- +}
- void straynewline()
- {
- enew(); eout("Stray newline from "); eout(remoteip); eout(".\n");
- out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush();
- eflush(); _exit(1);
- }
- @@ -161,6 +173,13 @@
- int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; };
- void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); }
-
- +extern void realrcptto_init();
- +extern void realrcptto_start();
- +extern int realrcptto();
- +extern int realrcptto_deny();
- +
- +int flagauth = 0;
- +
- stralloc greeting = {0};
-
- void smtp_greet(code) char *code;
- @@ -259,7 +259,8 @@
- fdmbrt = open_read("control/morebadrcptto.cdb");
- if (fdmbrt == -1) if (errno != error_noent) die_control();
-
-
- + realrcptto_init();
-
- if (control_readint(&databytes,"control/databytes") == -1) die_control();
- x = env_get("DATABYTES");
- @@ -635,7 +635,8 @@
- if (!stralloc_copys(&rcptto,"")) die_nomem();
- if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
- if (!stralloc_0(&mailfrom)) die_nomem();
- + realrcptto_start();
- recipcount = 0;
- out("250 ok\r\n");
- }
- void smtp_rcpt(arg) char *arg; {
- @@ -680,5 +701,9 @@
- flagbrt = 1;
- log_deny("BAD RCPT TO", mailfrom.s,addr.s);
- }
- + if (!flagauth && !relayclient && !realrcptto(addr.s,1)) {
- + out("554 sorry, no mailbox here by that name. (#5.1.1)\r\n");
- + return;
- + }
- if (!(spp_val = spp_rcpt(allowed))) return;
- if (!relayclient && spp_val == 1) {
- @@ -899,6 +899,7 @@
- if (mailfrom.len == 1 && recipcount > 1) { err_badbounce(); return; }
- if (flagbrt) { err_brt(); return; }
- if (!spp_data()) return;
- + if (!relayclient && realrcptto_deny()) { out("550 sorry, no mailbox here by that name. (#5.1.1)\r\n"); return; }
- seenmail = 0;
- if (databytes) bytestooverflow = databytes + 1;
- if (qmail_open(&qqt) == -1) { err_qqt(); return; }
- @@ -961,6 +961,5 @@
- static stralloc slop = {0}; /* b64 challenge */
- #endif
-
- -int flagauth = 0;
- char **childargs;
- char ssauthbuf[512];
- diff -Naur /dev/null realrcptto.c
- --- /dev/null 2006-09-14 17:39:14.000000000 +0200
- +++ realrcptto.c 2009-01-31 01:01:21.000000000 +0100
- @@ -0,0 +1,421 @@
- +#include <sys/types.h>
- +#include <sys/stat.h>
- +#include <unistd.h>
- +#include <pwd.h>
- +#include "auto_break.h"
- +#include "auto_usera.h"
- +#include "byte.h"
- +#include "case.h"
- +#include "cdb.h"
- +#include "constmap.h"
- +#include "error.h"
- +#include "fmt.h"
- +#include "open.h"
- +#include "str.h"
- +#include "stralloc.h"
- +#include "uint32.h"
- +#include "substdio.h"
- +#include "env.h"
- +#include "slurpclose.h"
- +
- +extern void die_nomem();
- +extern void die_control();
- +extern void die_cdb();
- +extern void die_sys();
- +
- +static stralloc envnoathost = {0};
- +static stralloc percenthack = {0};
- +static stralloc locals = {0};
- +static stralloc vdoms = {0};
- +static struct constmap mappercenthack;
- +static struct constmap maplocals;
- +static struct constmap mapvdoms;
- +
- +static char *dash;
- +static char *extension;
- +static char *local;
- +static struct passwd *pw;
- +
- +static char errbuf[128];
- +static struct substdio sserr = SUBSTDIO_FDBUF(write,2,errbuf,sizeof errbuf);
- +
- +static char pidbuf[64];
- +static char remoteipbuf[64]=" ";
- +
- +static int flagdenyall;
- +static int flagdenyany;
- +
- +void realrcptto_init()
- +{
- + char *x;
- +
- + if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1)
- + die_control();
- +
- + if (control_readfile(&locals,"control/locals",1) != 1) die_control();
- + if (!constmap_init(&maplocals,locals.s,locals.len,0)) die_nomem();
- + switch(control_readfile(&percenthack,"control/percenthack",0)) {
- + case -1: die_control();
- + case 0: if (!constmap_init(&mappercenthack,"",0,0)) die_nomem();
- + case 1:
- + if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0))
- + die_nomem();
- + }
- + switch(control_readfile(&vdoms,"control/virtualdomains",0)) {
- + case -1: die_control();
- + case 0: if (!constmap_init(&mapvdoms,"",0,1)) die_nomem();
- + case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) die_nomem();
- + }
- +
- + str_copy(pidbuf + fmt_ulong(pidbuf,getpid())," ");
- + x=env_get("PROTO");
- + if (x) {
- + static char const remoteip[]="REMOTEIP";
- + unsigned int len = str_len(x);
- + if (len <= sizeof remoteipbuf - sizeof remoteip) {
- + byte_copy(remoteipbuf,len,x);
- + byte_copy(remoteipbuf + len,sizeof remoteip,remoteip);
- + x = env_get(remoteipbuf);
- + len = str_len(x);
- + if (len + 1 < sizeof remoteipbuf) {
- + byte_copy(remoteipbuf,len,x);
- + remoteipbuf[len]=' ';
- + remoteipbuf[len + 1]='\0';
- + }
- + }
- + }
- +
- + x = env_get("QMAILRRTDENYALL");
- + flagdenyall = (x && x[0]=='1' && x[1]=='\0');
- +}
- +
- +void realrcptto_start()
- +{
- + flagdenyany = 0;
- +}
- +
- +static int denyaddr(addr, depth)
- +char *addr;
- +int depth;
- +{
- + if (depth == 1)
- + {
- + substdio_puts(&sserr,"realrcptto ");
- + substdio_puts(&sserr,pidbuf);
- + substdio_puts(&sserr,remoteipbuf);
- + substdio_puts(&sserr,addr);
- + substdio_puts(&sserr,"\n");
- + substdio_flush(&sserr);
- + flagdenyany = 1;
- + }
- + return flagdenyall;
- +}
- +
- +static void stat_error(path,error)
- +char* path;
- +int error;
- +{
- + substdio_puts(&sserr,"unable to stat ");
- + substdio_puts(&sserr,path);
- + substdio_puts(&sserr,": ");
- + substdio_puts(&sserr,error_str(error));
- + substdio_puts(&sserr,"\n");
- + substdio_flush(&sserr);
- +}
- +
- +#define GETPW_USERLEN 32
- +
- +static int userext()
- +{
- + char username[GETPW_USERLEN];
- + struct stat st;
- +
- + extension = local + str_len(local);
- + for (;;) {
- + if (extension - local < sizeof(username))
- + if (!*extension || (*extension == *auto_break)) {
- + byte_copy(username,extension - local,local);
- + username[extension - local] = 0;
- + case_lowers(username);
- + errno = 0;
- + pw = getpwnam(username);
- + if (errno == error_txtbsy) die_sys();
- + if (pw)
- + if (pw->pw_uid)
- + if (stat(pw->pw_dir,&st) == 0) {
- + if (st.st_uid == pw->pw_uid) {
- + dash = "";
- + if (*extension) { ++extension; dash = "-"; }
- + return 1;
- + }
- + }
- + else
- + if (error_temp(errno)) die_sys();
- + }
- + if (extension == local) return 0;
- + --extension;
- + }
- +}
- +
- +// max lookups
- +#define MAXRECURSION 5
- +
- +static int handleqme(qme, depth)
- +stralloc *qme;
- +int depth;
- +{
- + stralloc cmds = {0};
- + char *username = NULL;
- + int fd, i, j, k, count;
- +
- + if (depth >= MAXRECURSION) return 0;
- + if (!stralloc_ready(&cmds,0)) die_nomem();
- + cmds.len = 0;
- +
- + fd = open_read(qme->s);
- + if (fd == -1) return 0;
- + if (slurpclose(fd,&cmds,256) == -1) die_nomem();
- + if (!cmds.len || (cmds.s[cmds.len - 1] != '\n'))
- + if (!stralloc_cats(&cmds,"\n")) die_nomem();
- +
- + i = count = 0;
- + for (j = 0;j < cmds.len;++j)
- + {
- + if (cmds.s[j] == '\n')
- + {
- + cmds.s[j] = 0;
- + k = j;
- + while ((k > i) && ((cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t')))
- + cmds.s[--k] = 0;
- + switch(cmds.s[i])
- + {
- + case 0:
- + case '#':
- + case '.':
- + case '/':
- + case '|':
- + case '+':
- + break;
- + case '&':
- + ++i;
- + default:
- + count++;
- + username = cmds.s + i;
- + break;
- + }
- + i = j + 1;
- + }
- + }
- +
- + if (count == 1 && username)
- + realrcptto(username, ++depth);
- +
- + return 1;
- +}
- +
- +int realrcptto(addr, depth)
- +char *addr;
- +int depth;
- +{
- + env_unset("DTUSER");
- + return realrcptto_ex(addr, depth);
- +}
- +
- +int realrcptto_ex(addr, depth)
- +char *addr;
- +int depth;
- +{
- + char *homedir, *username;
- + static stralloc localpart = {0};
- + static stralloc lower = {0};
- + static stralloc nughde = {0};
- + static stralloc wildchars = {0};
- + static stralloc safeext = {0};
- + static stralloc qme = {0};
- + unsigned int i,at;
- +
- + /* Short circuit, or full logging? Short circuit. */
- + if (flagdenyall && flagdenyany) return 1;
- +
- + /* qmail-send:rewrite */
- + if (!stralloc_copys(&localpart,addr)) die_nomem();
- + i = byte_rchr(localpart.s,localpart.len,'@');
- + if (i == localpart.len) {
- + if (!stralloc_cats(&localpart,"@")) die_nomem();
- + if (!stralloc_cat(&localpart,&envnoathost)) die_nomem();
- + }
- + while (constmap(&mappercenthack,localpart.s + i + 1,localpart.len - i - 1)) {
- + unsigned int j = byte_rchr(localpart.s,i,'%');
- + if (j == i) break;
- + localpart.len = i;
- + i = j;
- + localpart.s[i] = '@';
- + }
- + at = byte_rchr(localpart.s,localpart.len,'@');
- + if (constmap(&maplocals,localpart.s + at + 1,localpart.len - at - 1)) {
- + localpart.len = at;
- + localpart.s[at] = '\0';
- + } else {
- + unsigned int xlen,newlen;
- + char *x;
- + for (i = 0;;++i) {
- + if (i > localpart.len) return denyaddr(addr, depth);
- + if (!i || (i == at + 1) || (i == localpart.len) ||
- + ((i > at) && (localpart.s[i] == '.'))) {
- + x = constmap(&mapvdoms,localpart.s + i,localpart.len - i);
- + if (x && i == at + 1) {
- + // set QMAILQUEUE if catch-all
- + char *qmailqueue;
- + qmailqueue = env_get("QMAILQUEUE");
- + if (qmailqueue) {
- + if (!env_put("QMAILQUEUE=bin/qmail-queue")) die_nomem();
- + }
- + }
- + if (x) break;
- + }
- + }
- + if (!*x) return 1;
- + xlen = str_len(x) + 1; /* +1 for '-' */
- + newlen = xlen + at + 1; /* +1 for \0 */
- + if (xlen < 1 || newlen - 1 < xlen || newlen < 1 ||
- + !stralloc_ready(&localpart,newlen))
- + die_nomem();
- + localpart.s[newlen - 1] = '\0';
- + byte_copyr(localpart.s + xlen,at,localpart.s);
- + localpart.s[xlen - 1] = '-';
- + byte_copy(localpart.s,xlen - 1,x);
- + localpart.len = newlen;
- + }
- +
- + /* qmail-lspawn:nughde_get */
- + {
- + int r,fd,flagwild;
- + if (!stralloc_copys(&lower,"!")) die_nomem();
- + if (!stralloc_cats(&lower,localpart.s)) die_nomem();
- + if (!stralloc_0(&lower)) die_nomem();
- + case_lowerb(lower.s,lower.len);
- + if (!stralloc_copys(&nughde,"")) die_nomem();
- + fd = open_read("users/cdb");
- + if (fd == -1) {
- + if (errno != error_noent) die_cdb();
- + } else {
- + uint32 dlen;
- + r = cdb_seek(fd,"",0,&dlen);
- + if (r != 1) die_cdb();
- + if (!stralloc_ready(&wildchars,(unsigned int) dlen)) die_nomem();
- + wildchars.len = dlen;
- + if (cdb_bread(fd,wildchars.s,wildchars.len) == -1) die_cdb();
- + i = lower.len;
- + flagwild = 0;
- + do { /* i > 0 */
- + if (!flagwild || (i == 1) ||
- + (byte_chr(wildchars.s,wildchars.len,lower.s[i - 1])
- + < wildchars.len)) {
- + r = cdb_seek(fd,lower.s,i,&dlen);
- + if (r == -1) die_cdb();
- + if (r == 1) {
- + char *x;
- + if (!stralloc_ready(&nughde,(unsigned int) dlen)) die_nomem();
- + nughde.len = dlen;
- + if (cdb_bread(fd,nughde.s,nughde.len) == -1) die_cdb();
- + if (flagwild)
- + if (!stralloc_cats(&nughde,localpart.s + i - 1)) die_nomem();
- + if (!stralloc_0(&nughde)) die_nomem();
- + close(fd);
- + x=nughde.s;
- + /* skip username */
- + username=x;
- + x += byte_chr(x,nughde.s + nughde.len - x,'\0');
- + if (x == nughde.s + nughde.len) return 1;
- + ++x;
- + /* skip uid */
- + x += byte_chr(x,nughde.s + nughde.len - x,'\0');
- + if (x == nughde.s + nughde.len) return 1;
- + ++x;
- + /* skip gid */
- + x += byte_chr(x,nughde.s + nughde.len - x,'\0');
- + if (x == nughde.s + nughde.len) return 1;
- + ++x;
- + /* skip homedir */
- + homedir=x;
- + x += byte_chr(x,nughde.s + nughde.len - x,'\0');
- + if (x == nughde.s + nughde.len) return 1;
- + ++x;
- + /* skip dash */
- + dash=x;
- + x += byte_chr(x,nughde.s + nughde.len - x,'\0');
- + if (x == nughde.s + nughde.len) return 1;
- + ++x;
- + extension=x;
- + goto got_nughde;
- + }
- + }
- + --i;
- + flagwild = 1;
- + } while (i);
- + close(fd);
- + }
- + }
- +
- + /* qmail-getpw */
- + local = localpart.s;
- + if (!userext()) {
- + extension = local;
- + dash = "-";
- + pw = getpwnam(auto_usera);
- + }
- + if (!pw) return denyaddr(addr, depth);
- + if (!stralloc_copys(&nughde,pw->pw_dir)) die_nomem();
- + if (!stralloc_0(&nughde)) die_nomem();
- + homedir=nughde.s;
- + username=pw->pw_name;
- +
- + got_nughde:
- +
- + /* qmail-local:qmesearch */
- + //if (!*dash) return 1;
- + if (!*dash) { env_put2("DTUSER", username); return 1; }
- + if (!stralloc_copys(&safeext,extension)) die_nomem();
- + case_lowerb(safeext.s,safeext.len);
- + for (i = 0;i < safeext.len;++i)
- + {
- + if (safeext.s[i] == '.')
- + safeext.s[i] = ':';
- + }
- + {
- + struct stat st;
- + int i;
- + if (!stralloc_copys(&qme,homedir)) die_nomem();
- + if (!stralloc_cats(&qme,"/.qmail")) die_nomem();
- + if (!stralloc_cats(&qme,dash)) die_nomem();
- + if (!stralloc_cat(&qme,&safeext)) die_nomem();
- + if (!stralloc_0(&qme)) die_nomem();
- + //if (stat(qme.s,&st) == 0) return 1;
- + if (stat(qme.s,&st) == 0) { handleqme(&qme, depth); return 1; }
- + if (errno != error_noent) {
- + stat_error(qme.s,errno);
- + return 1;
- + }
- + for (i = safeext.len;i >= 0;--i)
- + if (!i || (safeext.s[i - 1] == '-')) {
- + if (!stralloc_copys(&qme,homedir)) die_nomem();
- + if (!stralloc_cats(&qme,"/.qmail")) die_nomem();
- + if (!stralloc_cats(&qme,dash)) die_nomem();
- + if (!stralloc_catb(&qme,safeext.s,i)) die_nomem();
- + if (!stralloc_cats(&qme,"default")) die_nomem();
- + if (!stralloc_0(&qme)) die_nomem();
- + //if (stat(qme.s,&st) == 0) return 1;
- + if (stat(qme.s,&st) == 0) { handleqme(&qme, depth); return 1; }
- + if (errno != error_noent) {
- + stat_error(qme.s,errno);
- + return 1;
- + }
- + }
- + return denyaddr(addr, depth);
- + }
- +}
- +
- +int realrcptto_deny()
- +{
- + return flagdenyall && flagdenyany;
- +}
-