From: Peter Pentchev Date: Wed, 11 Mar 2009 13:15:44 +0000 (+0000) Subject: Add four new patches to bring the Debian package up to date with X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b59d7b1d356d3dbced67c526f67c3e400ed34a7;p=people%2Fms%2Fdma.git Add four new patches to bring the Debian package up to date with my work on trunk and the debian/ branch. --- diff --git a/changelog b/changelog index 9c15d10..218d686 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,15 @@ +dma (0.0.2009.02.11-1~2) unstable; urgency=low + + * Add four new patches: + - lock the newly-created files to prevent double delivery attempts + if "dma -q" is run at just the wrong time; + - provide the proper bounce message on failed deliveries; + - add the FULLBOUNCE option; + - add the MAILNAME and MAILNAMEFILE options and use /etc/mailname + as the MAILNAMEFILE. + + -- Peter Pentchev Wed, 11 Mar 2009 14:48:15 +0200 + dma (0.0.2009.02.11-1~1) unstable; urgency=low * Initial release (Closes: #511410) diff --git a/patches/14-lock-new-files.patch b/patches/14-lock-new-files.patch new file mode 100644 index 0000000..0fe8ac8 --- /dev/null +++ b/patches/14-lock-new-files.patch @@ -0,0 +1,15 @@ +Lock the temporary files after creating them to protect from a "dma -q" +run at just the wrong time causing a double delivery attempt for +the same message. + +--- a/dma.c ++++ b/dma.c +@@ -225,6 +225,8 @@ + fd = mkstemp(fn); + if (fd < 0) + return (-1); ++ if (flock(fd, LOCK_EX) == -1) ++ return (-1); + queue->mailfd = fd; + queue->tmpf = strdup(fn); + if (queue->tmpf == NULL) { diff --git a/patches/15-bounce-message.patch b/patches/15-bounce-message.patch new file mode 100644 index 0000000..1db781c --- /dev/null +++ b/patches/15-bounce-message.patch @@ -0,0 +1,149 @@ +Provide the proper bounce error message on failed deliveries. +This may not be the best solution - the error message buffer has now +turned dynamic, but the only alternative I see is to make it a static +array in net.c... and I'm not quite sure if I want to do that just now. + +--- a/dma.c ++++ b/dma.c +@@ -439,7 +439,7 @@ + } + + static void +-bounce(struct qitem *it, const char *reason) ++bounce(struct qitem *it, char *reason) + { + struct queue bounceq; + struct qitem *bit; +@@ -598,6 +598,7 @@ + VERSION, hostname(), + it->addr, + reason); ++ free(reason); + if (error < 0) + goto fail; + if (fflush(bit->queuef) != 0) +@@ -674,7 +675,7 @@ + #endif + + static int +-deliver_local(struct qitem *it, const char **errmsg) ++deliver_local(struct qitem *it, char **errmsg) + { + char fn[PATH_MAX+1]; + char line[1000]; +@@ -757,7 +758,7 @@ + #ifdef HAVE_LIBLOCKFILE + mailunlock(); + #endif +- *errmsg = "corrupted queue file"; ++ *errmsg = strdup("corrupted queue file"); + error = -1; + goto chop; + } +@@ -800,7 +801,7 @@ + { + int error; + unsigned int backoff = MIN_RETRY; +- const char *errmsg = "unknown bounce reason"; ++ char *errmsg = strdup("unknown bounce reason"); + struct timeval now; + struct stat st; + +@@ -831,12 +832,9 @@ + } + if (gettimeofday(&now, NULL) == 0 && + (now.tv_sec - st.st_mtime > MAX_TIMEOUT)) { +- char *msg; +- +- if (asprintf(&msg, ++ asprintf(&errmsg, + "Could not deliver for the last %d seconds. Giving up.", +- MAX_TIMEOUT) > 0) +- errmsg = msg; ++ MAX_TIMEOUT); + goto bounce; + } + sleep(backoff); +--- a/dma.h ++++ b/dma.h +@@ -163,7 +163,7 @@ + /* net.c */ + extern int read_remote(int, int, char *); + extern ssize_t send_remote_command(int, const char*, ...); +-extern int deliver_remote(struct qitem *, const char **); ++extern int deliver_remote(struct qitem *, char **); + + /* base64.c */ + extern int base64_encode(const void *, int, char **); +--- a/net.c ++++ b/net.c +@@ -314,7 +314,7 @@ + } + + int +-deliver_remote(struct qitem *it, const char **errmsg) ++deliver_remote(struct qitem *it, char **errmsg) + { + struct authuser *a; + char *host, line[1000]; +@@ -323,11 +323,14 @@ + + host = strrchr(it->addr, '@'); + /* Should not happen */ +- if (host == NULL) ++ if (host == NULL) { ++ asprintf(errmsg, "Internal error: badly formed address %s", ++ it->addr); + return(-1); +- else ++ } else { + /* Step over the @ */ + host++; ++ } + + /* Smarthost support? */ + if (config->smarthost != NULL && strlen(config->smarthost) > 0) { +@@ -370,6 +373,8 @@ + if (read_remote(fd, 0, NULL) != 2) { + syslog(LOG_ERR, "%s: remote delivery deferred: " + " EHLO failed: %s", it->queueid, neterr); ++ asprintf(errmsg, "%s did not like our EHLO:\n%s", ++ host, neterr); + return (-1); + } + } +@@ -379,6 +384,8 @@ + if (read_remote(fd, 0, NULL) != 2) { + syslog(LOG_ERR, "%s: remote delivery deferred: " + " EHLO failed: %s", it->queueid, neterr); ++ asprintf(errmsg, "%s did not like our EHLO:\n%s", ++ host, neterr); + return (-1); + } + } +@@ -405,6 +412,7 @@ + if (error < 0) { + syslog(LOG_ERR, "%s: remote delivery failed:" + " SMTP login failed: %m", it->queueid); ++ asprintf(errmsg, "SMTP login to %s failed", host); + return (-1); + } + /* SMTP login is not available, so try without */ +@@ -418,6 +426,8 @@ + if (res == 5) { \ + syslog(LOG_ERR, "%s: remote delivery failed: " \ + c " failed: %s", it->queueid, neterr); \ ++ asprintf(errmsg, "%s did not like our " c ":\n%s", \ ++ host, neterr); \ + return (-1); \ + } else if (res != exp) { \ + syslog(LOG_ERR, "%s: remote delivery deferred: " \ +@@ -447,7 +457,7 @@ + if (linelen == 0 || line[linelen - 1] != '\n') { + syslog(LOG_CRIT, "%s: remote delivery failed:" + "corrupted queue file", it->queueid); +- *errmsg = "corrupted queue file"; ++ *errmsg = strdup("corrupted queue file"); + error = -1; + goto out; + } diff --git a/patches/16-bounce-full.patch b/patches/16-bounce-full.patch new file mode 100644 index 0000000..5b5c975 --- /dev/null +++ b/patches/16-bounce-full.patch @@ -0,0 +1,98 @@ +Add the FULLBOUNCE config option to include the full message in the bounce. + +--- a/conf.c ++++ b/conf.c +@@ -250,6 +250,8 @@ + config->features |= DEFER; + else if (strcmp(word, "INSECURE") == 0) + config->features |= INSECURE; ++ else if (strcmp(word, "FULLBOUNCE") == 0) ++ config->features |= FULLBOUNCE; + } + } + +--- a/dma.8 ++++ b/dma.8 +@@ -237,6 +237,11 @@ + .Ar queueid + .Fl f + .Ar messagefile ++.It Ic FULLBOUNCE Xo ++(boolean, default=commented) ++.Xc ++Uncomment if you want the bounce message to include the complete original ++message, not just the headers. + .El + .Ss virtusertable + The +--- a/dma.c ++++ b/dma.c +@@ -585,7 +585,7 @@ + \n\ + %s\n\ + \n\ +-Message headers follow.\n\ ++%s\n\ + \n\ + ", + bounceq.id, +@@ -597,7 +597,9 @@ + rfc822date(), + VERSION, hostname(), + it->addr, +- reason); ++ reason, ++ config->features & FULLBOUNCE? "Original message follows.": ++ "Message headers follow."); + free(reason); + if (error < 0) + goto fail; +@@ -606,14 +608,20 @@ + + if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0) + goto fail; +- while (!feof(it->queuef)) { +- if (fgets(line, sizeof(line), it->queuef) == NULL) +- break; +- if (line[0] == '\n') +- break; +- if (write(bounceq.mailfd, line, strlen(line)) != strlen(line)) +- goto fail; +- } ++ if (config->features & FULLBOUNCE) ++ while ((pos = fread(line, 1, sizeof(line), it->queuef)) > 0) { ++ if (write(bounceq.mailfd, line, pos) != pos) ++ goto fail; ++ } ++ else ++ while (!feof(it->queuef)) { ++ if (fgets(line, sizeof(line), it->queuef) == NULL) ++ break; ++ if (line[0] == '\n') ++ break; ++ if (write(bounceq.mailfd, line, strlen(line)) != strlen(line)) ++ goto fail; ++ } + if (fsync(bounceq.mailfd) != 0) + goto fail; + if (linkspool(&bounceq) != 0) +--- a/dma.h ++++ b/dma.h +@@ -72,6 +72,7 @@ + #define NOSSL 0x008 /* Do not use SSL */ + #define DEFER 0x010 /* Defer mails */ + #define INSECURE 0x020 /* Allow plain login w/o encryption */ ++#define FULLBOUNCE 0x040 /* Bounce the full message */ + + #define CONF_PATH "/etc/dma/dma.conf" /* Default path to dma.conf */ + +--- a/etc/dma.conf ++++ b/etc/dma.conf +@@ -45,3 +45,7 @@ + # default behavior of simply aborting the delivery, or specify the name or + # full path to a program that will process the double-bounce message. + DBOUNCEPROG dbounce-simple-safecat ++ ++# Uncomment if you want the bounce message to include the complete original ++# message, not just the headers. ++#FULLBOUNCE diff --git a/patches/17-mailname.patch b/patches/17-mailname.patch new file mode 100644 index 0000000..fdc4ac6 --- /dev/null +++ b/patches/17-mailname.patch @@ -0,0 +1,111 @@ +Add the MAILNAME and MAILNAMEFILE config options. +For Debian, use /etc/mailname for the MAILNAMEFILE. + +--- a/conf.c ++++ b/conf.c +@@ -240,6 +240,14 @@ + if (data != NULL) + config->dbounceprog = strdup(data); + } ++ else if (strcmp(word, "MAILNAME") == 0) { ++ if (data != NULL) ++ config->mailname = strdup(data); ++ } ++ else if (strcmp(word, "MAILNAMEFILE") == 0) { ++ if (data != NULL) ++ config->mailnamefile = strdup(data); ++ } + else if (strcmp(word, "VIRTUAL") == 0) + config->features |= VIRTUAL; + else if (strcmp(word, "STARTTLS") == 0) +--- a/dma.8 ++++ b/dma.8 +@@ -242,6 +242,20 @@ + .Xc + Uncomment if you want the bounce message to include the complete original + message, not just the headers. ++.It Ic MAILNAME Xo ++(string, default=empty) ++.Xc ++The name to be used when introducing this host, if different from ++the result of ++.Xr hostname 1 . ++If specified, this option overrides ++.Sq MAILNAMEFILE . ++.It Ic MAILNAMEFILE Xo ++(string, default=empty) ++.Xc ++The name of the file to read the ++.Sq MAILNAME ++from. + .El + .Ss virtusertable + The +--- a/dma.c ++++ b/dma.c +@@ -82,10 +82,38 @@ + hostname(void) + { + static char name[MAXHOSTNAMELEN+1]; +- ++ int initialized = 0; ++ FILE *fp; ++ size_t len; ++ ++ if (initialized) ++ return (name); ++ ++ if (config->mailname != NULL && config->mailname[0] != '\0') { ++ snprintf(name, sizeof(name), "%s", config->mailname); ++ initialized = 1; ++ return (name); ++ } ++ if (config->mailnamefile != NULL && config->mailnamefile[0] != '\0') { ++ fp = fopen(config->mailnamefile, "r"); ++ if (fp != NULL) { ++ if (fgets(name, sizeof(name), fp) != NULL) { ++ len = strlen(name); ++ while (len > 0 && ++ (name[len - 1] == '\r' || ++ name[len - 1] == '\n')) ++ name[--len] = '\0'; ++ if (name[0] != '\0') { ++ initialized = 1; ++ return (name); ++ } ++ } ++ fclose(fp); ++ } ++ } + if (gethostname(name, sizeof(name)) != 0) + strcpy(name, "(unknown hostname)"); +- ++ initialized = 1; + return name; + } + +--- a/dma.h ++++ b/dma.h +@@ -122,6 +122,8 @@ + SSL *ssl; + #endif /* HAVE_CRYPTO */ + char *dbounceprog; ++ char *mailname; ++ char *mailnamefile; + }; + + +--- a/etc/dma.conf ++++ b/etc/dma.conf +@@ -49,3 +49,11 @@ + # Uncomment if you want the bounce message to include the complete original + # message, not just the headers. + #FULLBOUNCE ++ ++# The name to be used when introducing this host, if different from ++# the result of "hostname". If specified, this overrides MAILNAMEFILE. ++#MAILNAME mail.example.net ++ ++# The name of the file to read the MAILNAME from; if this file is not ++# present, the result of "hostname" will be used. ++MAILNAMEFILE /etc/mailname diff --git a/patches/series b/patches/series index 2bba0a0..56668ce 100644 --- a/patches/series +++ b/patches/series @@ -11,3 +11,7 @@ 11-double-bounce.patch 12-man-q-argument.patch 13-hardening.patch +14-lock-new-files.patch +15-bounce-message.patch +16-bounce-full.patch +17-mailname.patch