]> git.ipfire.org Git - people/ms/dma.git/commitdiff
Bring it up to current dma, part I: refresh all patches to
authorPeter Pentchev <roam@ringlet.net>
Fri, 31 Jul 2009 15:45:50 +0000 (15:45 +0000)
committerPeter Pentchev <roam@ringlet.net>
Fri, 31 Jul 2009 15:45:50 +0000 (15:45 +0000)
bring things up to dma-dfly-2009-07-17 plus my Debian branch patches.

24 files changed:
changelog
patches/01-debian-build.patch
patches/02-man-dragonflybsd.patch
patches/03-debian-locations.patch
patches/04-debian-setgid.patch
patches/05-remote-error-messages.patch [deleted file]
patches/06-quit-nonfatal.patch [deleted file]
patches/07-permanent-errors.patch [deleted file]
patches/08-queue-list-all.patch [deleted file]
patches/09-typos.patch
patches/10-liblockfile.patch
patches/11-double-bounce.patch
patches/12-man-q-argument.patch [deleted file]
patches/13-hardening.patch [deleted file]
patches/14-lock-new-files.patch [deleted file]
patches/15-bounce-message.patch
patches/16-bounce-full.patch [deleted file]
patches/17-mailname.patch
patches/18-guess-username.patch [deleted file]
patches/19-ignore-options.patch [deleted file]
patches/20-parse-recipient.patch
patches/21-smtp-auth.patch [deleted file]
patches/22-openfiles.patch
patches/series

index 4c504e112b52268087484debaa5203477ccc6d9f..5359b43b78aea793dca92cb824ec2ab33d111622 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,6 +1,6 @@
-dma (0.0.2009.02.11-1) unstable; urgency=low
+dma (0.0.2009.07.17-1) unstable; urgency=low
 
   * Initial release
     (Closes: #511410, #533458, #533614, #533890, #534101, #534860)
 
- -- Peter Pentchev <roam@ringlet.net>  Mon, 29 Jun 2009 14:31:29 +0300
+ -- Peter Pentchev <roam@ringlet.net>  Fri, 31 Jul 2009 18:41:35 +0300
index 923ef1191691a2110d92f143f7c1529f3733c3fb..3c2623257afc216efcba4f16f6787267850bd1e4 100644 (file)
@@ -1,11 +1,9 @@
 Several fixes to make dma build on Debian:
 - build and install the files in the etc/ subdirectory;
-- disable compiler warnings;
 - generate aliases_parse.h and let the others depend on it;
-- replace open(..., O_EXLOCK) with a new open_locked() routine;
-- use st_mtime instead of st_mtimespec;
-- define the __unused function attribute;
-- do not redefine PATH_MAX.
+- define the __DECONST macro;
+- prototype open_locked() in dma.c, just in case;
+- use mtime instead of mtimespec.
 
 All of these are taken from the Ringlet Subversion repository:
 http://svn.ringlet.net/svn/ringlet/mail/dma/
@@ -19,16 +17,13 @@ http://svn.ringlet.net/cgi-bin/viewvc/viewvc.cgi/ringlet/mail/dma/
  
 +SUBDIR=       etc
 +
- CFLAGS+= -DHAVE_CRYPTO
  CFLAGS+= -I${.CURDIR}
  
-@@ -14,6 +16,25 @@
- BINOWN= root
- BINGRP= mail
+ DPADD=  ${LIBSSL} ${LIBCRYPTO}
+@@ -15,4 +17,23 @@
  BINMODE=2555
--WARNS?=       1
-+#WARNS?=      1
-+
+ WARNS?=       6
 +# The pmake Debian package does not seem to deal properly with y.tab.h
 +
 +DPSRCS+=      aliases_parse.h
@@ -45,96 +40,40 @@ http://svn.ringlet.net/cgi-bin/viewvc/viewvc.cgi/ringlet/mail/dma/
 +
 +aliases_parse.o:      aliases_parse.h
 +aliases_scan.o:       aliases_parse.h
++
  .include <bsd.prog.mk>
 +
 +.include <bsd.subdir.mk>
 --- a/dma.c
 +++ b/dma.c
 @@ -74,6 +74,8 @@
- static int daemonize = 1;
- struct config *config;
+ static struct strlist seenmsg[16][16];
  
 +static int open_locked(const char *, int);
 +
  char *
  hostname(void)
  {
-@@ -542,7 +544,7 @@
-       }
-       /* mailx removes users mailspool file if empty, so open with O_CREAT */
--      mbox = open(fn, O_WRONLY | O_EXLOCK | O_APPEND | O_CREAT);
-+      mbox = open_locked(fn, O_WRONLY | O_APPEND | O_CREAT);
-       if (mbox < 0) {
-               syslog(LOG_ERR, "%s: local delivery deferred: can not open `%s': %m",
-                      it->queueid, fn);
-@@ -639,7 +641,7 @@
+@@ -803,7 +805,7 @@
                        exit(1);
                }
                if (gettimeofday(&now, NULL) == 0 &&
 -                  (now.tv_sec - st.st_mtimespec.tv_sec > MAX_TIMEOUT)) {
 +                  (now.tv_sec - st.st_mtime > MAX_TIMEOUT)) {
-                       char *msg;
-                       if (asprintf(&msg,
-@@ -703,7 +705,7 @@
-                       continue;
-               if (asprintf(&queuefn, "%s/%s", config->spooldir, de->d_name) < 0)
-                       goto fail;
--              fd = open(queuefn, O_RDONLY|O_EXLOCK|O_NONBLOCK);
-+              fd = open_locked(queuefn, O_RDONLY|O_NONBLOCK);
-               if (fd < 0) {
-                       /* Ignore locked files */
-                       if (errno == EWOULDBLOCK)
-@@ -962,3 +964,24 @@
-       /* NOTREACHED */
-       return (0);
- }
-+
-+static int
-+open_locked(const char *fname, int flags)
-+{
-+#ifndef O_EXLOCK
-+      int fd, save_errno;
-+
-+      fd = open(fname, flags, 0);
-+      if (fd < 0)
-+              return(fd);
-+      if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) {
-+              save_errno = errno;
-+              close(fd);
-+              errno = save_errno;
-+              return(-1);
-+      }
-+      return(fd);
-+#else
-+      return(open(fname, flags|O_EXLOCK));
-+#endif
-+}
+                       asprintf(__DECONST(void *, &errmsg),
+                                "Could not deliver for the last %d seconds. Giving up.",
+                                MAX_TIMEOUT);
 --- a/dma.h
 +++ b/dma.h
-@@ -46,6 +46,13 @@
- #include <stdint.h>
- #include <stdio.h>
-+#ifndef __unused
-+#ifdef __GNUC__
-+#define __unused      __attribute__((unused))
-+#else
-+#define __unused
-+#endif  /* __GNUC__ */
-+#endif
+@@ -52,6 +52,10 @@
+ #endif  /* __GNUC__ */
+ #endif
  
++#ifndef __DECONST
++#define       __DECONST(type, var)    ((type)(uintptr_t)(const void *)(var))
++#endif  /* __DECONST */
++
  #define VERSION       "DragonFly Mail Agent"
  
-@@ -53,7 +60,9 @@
- #define MIN_RETRY     300             /* 5 minutes */
- #define MAX_RETRY     (3*60*60)       /* retry at least every 3 hours */
- #define MAX_TIMEOUT   (5*24*60*60)    /* give up after 5 days */
-+#ifndef PATH_MAX
- #define PATH_MAX      1024            /* Max path len */
-+#endif
- #define       SMTP_PORT       25              /* Default SMTP port */
- #define CON_TIMEOUT   120             /* Connection timeout */
+ #define BUF_SIZE      2048
index 46d8cca2f61049b090c8f68939f0954f891675d3..db19d15fc9be5e867ac6da93c2d4e1c88fa670e5 100644 (file)
@@ -3,7 +3,7 @@ not have the ".Dx" macro yet.
 
 --- a/dma.8
 +++ b/dma.8
-@@ -248,7 +248,7 @@
+@@ -269,7 +269,7 @@
  The
  .Nm
  utility first appeared in
index 0c7eb42ebaf017a3c41f7a9a870f63921403cc07..95b64965f1a2c2cdef64440e5b4d95161709f00f 100644 (file)
@@ -4,7 +4,7 @@ Use deferred delivery - the package includes a cron job running the queue.
 
 --- a/dma.8
 +++ b/dma.8
-@@ -141,7 +141,7 @@
+@@ -143,7 +143,7 @@
  .Pa dma.conf .
  .Bl -tag -width 4n
  .It Ic SMARTHOST Xo
@@ -13,7 +13,7 @@ Use deferred delivery - the package includes a cron job running the queue.
  .Xc
  If you want to send outgoing mails via a smarthost, set this variable to
  your smarthosts address.
-@@ -156,7 +156,7 @@
+@@ -158,7 +158,7 @@
  will deliver all mails to this port, regardless of whether a smarthost is set
  or not.
  .It Ic ALIASES Xo
@@ -40,9 +40,12 @@ Use deferred delivery - the package includes a cron job running the queue.
  
  # Path to your spooldir.  Just stay with the default.
  SPOOLDIR /var/spool/dma
-@@ -39,4 +39,4 @@
+@@ -39,7 +39,7 @@
  
  # Uncomment if you want to defer your mails.  This is useful if you are
  # behind a dialup line.  You have to submit your mails manually with dma -q
 -#DEFER
 +DEFER
+ # Uncomment if you want the bounce message to include the complete original
+ # message, not just the headers.
index 042db9a64bb4dfa430ac9040f8bb099f8ebe87e7..ed7626bb2df7e15fca08befa623413ebe3a14dcf 100644 (file)
@@ -3,12 +3,12 @@ to 2755, since removing root write access gains us nothing.
 
 --- a/Makefile
 +++ b/Makefile
-@@ -15,7 +15,7 @@
+@@ -14,7 +14,7 @@
  
  BINOWN= root
  BINGRP= mail
 -BINMODE=2555
 +BINMODE=2755
- #WARNS?=      1
+ WARNS?=       6
  
  # The pmake Debian package does not seem to deal properly with y.tab.h
diff --git a/patches/05-remote-error-messages.patch b/patches/05-remote-error-messages.patch
deleted file mode 100644 (file)
index fc094fd..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-Store the last error or status message received from the remote server in
-the neterr[] buffer and display it instead of the meaningless %m in
-remote delivery syslog messages.
-
---- a/crypto.c
-+++ b/crypto.c
-@@ -122,7 +122,8 @@
-                       send_remote_command(fd, "STARTTLS");
-                       if (read_remote(fd, 0, NULL) != 2) {
-                               syslog(LOG_ERR, "%s: remote delivery failed:"
--                                " STARTTLS not available: %m", it->queueid);
-+                                " STARTTLS not available: %s", it->queueid,
-+                                neterr);
-                               config->features &= ~NOSSL;
-                               return (-1);
-                       }
-@@ -267,7 +268,8 @@
-       send_remote_command(fd, "AUTH CRAM-MD5");
-       if (read_remote(fd, sizeof(buffer), buffer) != 3) {
-               syslog(LOG_ERR, "%s: smarthost authentification:"
--                     " AUTH cram-md5 not available: %m", it->queueid);
-+                     " AUTH cram-md5 not available: %s", it->queueid,
-+                     neterr);
-               /* if cram-md5 is not available */
-               return (-1);
-       }
-@@ -296,7 +298,8 @@
-       send_remote_command(fd, "%s", temp);
-       if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
--                              " AUTH cram-md5 failed: %m", it->queueid);
-+                              " AUTH cram-md5 failed: %s", it->queueid,
-+                              neterr);
-               return (-2);
-       }
---- a/dma.h
-+++ b/dma.h
-@@ -139,6 +139,8 @@
- extern struct aliases aliases;
-+extern char neterr[BUF_SIZE];
-+
- /* aliases_parse.y */
- extern int yyparse(void);
- extern FILE *yyin;
---- a/net.c
-+++ b/net.c
-@@ -48,6 +48,7 @@
- #endif /* HAVE_CRYPTO */
- #include <err.h>
-+#include <errno.h>
- #include <netdb.h>
- #include <setjmp.h>
- #include <signal.h>
-@@ -59,6 +60,7 @@
- extern struct config *config;
- extern struct authusers authusers;
- static jmp_buf timeout_alarm;
-+char neterr[BUF_SIZE];
- static void
- sig_alarm(int signo __unused)
-@@ -99,10 +101,12 @@
-       int done = 0, status = 0, extbufpos = 0;
-       if (signal(SIGALRM, sig_alarm) == SIG_ERR) {
--              syslog(LOG_ERR, "SIGALRM error: %m");
-+              snprintf(neterr, sizeof(neterr), "SIGALRM error: %s",
-+                  strerror(errno));
-+              return (1);
-       }
-       if (setjmp(timeout_alarm) != 0) {
--              syslog(LOG_ERR, "Timeout reached");
-+              snprintf(neterr, sizeof(neterr), "Timeout reached");
-               return (1);
-       }
-       alarm(CON_TIMEOUT);
-@@ -163,6 +167,10 @@
-       }
-       alarm(0);
-+      buff[len] = '\0';
-+      while (len > 0 && (buff[len - 1] == '\r' || buff[len - 1] == '\n'))
-+              buff[--len] = '\0';
-+      snprintf(neterr, sizeof(neterr), "%s", buff);
-       status = atoi(buff);
-       return (status/100);
- }
-@@ -194,7 +202,8 @@
-               send_remote_command(fd, "AUTH LOGIN");
-               if (read_remote(fd, 0, NULL) != 3) {
-                       syslog(LOG_ERR, "%s: remote delivery deferred:"
--                                      " AUTH login not available: %m", it->queueid);
-+                                      " AUTH login not available: %s",
-+                                      it->queueid, neterr);
-                       return (1);
-               }
-@@ -205,7 +214,8 @@
-               send_remote_command(fd, "%s", temp);
-               if (read_remote(fd, 0, NULL) != 3) {
-                       syslog(LOG_ERR, "%s: remote delivery deferred:"
--                                      " AUTH login failed: %m", it->queueid);
-+                                      " AUTH login failed: %s", it->queueid,
-+                                      neterr);
-                       return (-1);
-               }
-@@ -217,11 +227,13 @@
-               res = read_remote(fd, 0, NULL);
-               if (res == 5) {
-                       syslog(LOG_ERR, "%s: remote delivery failed:"
--                                      " Authentication failed: %m", it->queueid);
-+                                      " Authentication failed: %s",
-+                                      it->queueid, neterr);
-                       return (-1);
-               } else if (res != 2) {
-                       syslog(LOG_ERR, "%s: remote delivery failed:"
--                                      " AUTH password failed: %m", it->queueid);
-+                                      " AUTH password failed: %s",
-+                                      it->queueid, neterr);
-                       return (-1);
-               }
-       } else {
-@@ -341,7 +353,7 @@
-               send_remote_command(fd, "EHLO %s", hostname());
-               if (read_remote(fd, 0, NULL) != 2) {
-                       syslog(LOG_ERR, "%s: remote delivery deferred: "
--                             " EHLO failed: %m", it->queueid);
-+                             " EHLO failed: %s", it->queueid, neterr);
-                       return (-1);
-               }
-       }
-@@ -350,7 +362,7 @@
-               send_remote_command(fd, "EHLO %s", hostname());
-               if (read_remote(fd, 0, NULL) != 2) {
-                       syslog(LOG_ERR, "%s: remote delivery deferred: "
--                             " EHLO failed: %m", it->queueid);
-+                             " EHLO failed: %s", it->queueid, neterr);
-                       return (-1);
-               }
-       }
-@@ -388,27 +400,27 @@
-       send_remote_command(fd, "MAIL FROM:<%s>", it->sender);
-       if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
--                     " MAIL FROM failed: %m", it->queueid);
-+                     " MAIL FROM failed: %s", it->queueid, neterr);
-               return (1);
-       }
-       send_remote_command(fd, "RCPT TO:<%s>", it->addr);
-       if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
--                              " RCPT TO failed: %m", it->queueid);
-+                              " RCPT TO failed: %s", it->queueid, neterr);
-               return (1);
-       }
-       send_remote_command(fd, "DATA");
-       if (read_remote(fd, 0, NULL) != 3) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
--                     " DATA failed: %m", it->queueid);
-+                     " DATA failed: %s", it->queueid, neterr);
-               return (1);
-       }
-       if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0) {
--              syslog(LOG_ERR, "%s: remote delivery deferred: cannot seek: %m",
--                     it->queueid);
-+              syslog(LOG_ERR, "%s: remote delivery deferred: cannot seek: %s",
-+                     it->queueid, neterr);
-               return (1);
-       }
-@@ -444,15 +456,15 @@
-       send_remote_command(fd, ".");
-       if (read_remote(fd, 0, NULL) != 2) {
--              syslog(LOG_ERR, "%s: remote delivery deferred: %m",
--                     it->queueid);
-+              syslog(LOG_ERR, "%s: remote delivery deferred: %s",
-+                     it->queueid, neterr);
-               return (1);
-       }
-       send_remote_command(fd, "QUIT");
-       if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_ERR, "%s: remote delivery deferred: "
--                     "QUIT failed: %m", it->queueid);
-+                     "QUIT failed: %s", it->queueid, neterr);
-               return (1);
-       }
- out:
diff --git a/patches/06-quit-nonfatal.patch b/patches/06-quit-nonfatal.patch
deleted file mode 100644 (file)
index b36c3a2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Treat a QUIT error as merely a warning: RFC 2821 only mandates that
-a QUIT error should abort an unfinished transaction, and since we've
-reached this point, the DATA command has succeeded and the message has
-been accepted for delivery by the remote end.  Thus, just warn about it.
-
---- a/net.c
-+++ b/net.c
-@@ -462,11 +462,9 @@
-       }
-       send_remote_command(fd, "QUIT");
--      if (read_remote(fd, 0, NULL) != 2) {
--              syslog(LOG_ERR, "%s: remote delivery deferred: "
-+      if (read_remote(fd, 0, NULL) != 2)
-+              syslog(LOG_WARNING, "%s: remote delivery succeeded but "
-                      "QUIT failed: %s", it->queueid, neterr);
--              return (1);
--      }
- out:
-       close(fd);
diff --git a/patches/07-permanent-errors.patch b/patches/07-permanent-errors.patch
deleted file mode 100644 (file)
index 384cf33..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-Recognize permanent delivery errors on remote deliveries and
-bounce the message immediately.
-
---- a/net.c
-+++ b/net.c
-@@ -397,26 +397,26 @@
-                                       " Try without", it->queueid);
-       }
--      send_remote_command(fd, "MAIL FROM:<%s>", it->sender);
--      if (read_remote(fd, 0, NULL) != 2) {
--              syslog(LOG_ERR, "%s: remote delivery deferred:"
--                     " MAIL FROM failed: %s", it->queueid, neterr);
--              return (1);
-+#define READ_REMOTE_CHECK(c, exp)     \
-+      res = read_remote(fd, 0, NULL); \
-+      if (res == 5) { \
-+              syslog(LOG_ERR, "%s: remote delivery failed: " \
-+                     c " failed: %s", it->queueid, neterr); \
-+              return (-1); \
-+      } else if (res != exp) { \
-+              syslog(LOG_ERR, "%s: remote delivery deferred: " \
-+                     c " failed: %s", it->queueid, neterr); \
-+              return (1); \
-       }
-+      send_remote_command(fd, "MAIL FROM:<%s>", it->sender);
-+      READ_REMOTE_CHECK("MAIL FROM", 2);
-+
-       send_remote_command(fd, "RCPT TO:<%s>", it->addr);
--      if (read_remote(fd, 0, NULL) != 2) {
--              syslog(LOG_ERR, "%s: remote delivery deferred:"
--                              " RCPT TO failed: %s", it->queueid, neterr);
--              return (1);
--      }
-+      READ_REMOTE_CHECK("RCPT TO", 2);
-       send_remote_command(fd, "DATA");
--      if (read_remote(fd, 0, NULL) != 3) {
--              syslog(LOG_ERR, "%s: remote delivery deferred:"
--                     " DATA failed: %s", it->queueid, neterr);
--              return (1);
--      }
-+      READ_REMOTE_CHECK("DATA", 3);
-       if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0) {
-               syslog(LOG_ERR, "%s: remote delivery deferred: cannot seek: %s",
-@@ -455,11 +455,7 @@
-       }
-       send_remote_command(fd, ".");
--      if (read_remote(fd, 0, NULL) != 2) {
--              syslog(LOG_ERR, "%s: remote delivery deferred: %s",
--                     it->queueid, neterr);
--              return (1);
--      }
-+      READ_REMOTE_CHECK("final DATA", 2);
-       send_remote_command(fd, "QUIT");
-       if (read_remote(fd, 0, NULL) != 2)
diff --git a/patches/08-queue-list-all.patch b/patches/08-queue-list-all.patch
deleted file mode 100644 (file)
index 1d517ef..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-When listing the queue, show all messages, even those that are
-currently locked for delivery.  Indicate the lock with a '*' after
-the queue ID.
-
---- a/dma.c
-+++ b/dma.c
-@@ -73,6 +73,7 @@
- struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
- static int daemonize = 1;
- struct config *config;
-+static struct strlist seenmsg[16][16];
- static int open_locked(const char *, int);
-@@ -666,8 +667,66 @@
-       /* NOTREACHED */
- }
-+static int
-+c2x(char c)
-+{
-+      if (c <= '9')
-+              return (c - '0');
-+      else if (c <= 'F')
-+              return (c - 'A' + 10);
-+      else
-+              return (c - 'a' + 10);
-+}
-+
- static void
--load_queue(struct queue *queue)
-+seen_init(void)
-+{
-+      int i, j;
-+
-+      for (i = 0; i < 16; i++)
-+              for (j = 0; j < 16; j++)
-+                      SLIST_INIT(&seenmsg[i][j]);
-+}
-+
-+static int
-+seen(const char *msgid)
-+{
-+      const char *p;
-+      size_t len;
-+      int i, j;
-+      struct stritem *t;
-+
-+      p = strchr(msgid, '.');
-+      if (p == NULL)
-+              return (0);
-+      len = p - msgid;
-+      if (len >= 2) {
-+              i = c2x(msgid[len - 2]);
-+              j = c2x(msgid[len - 1]);
-+      } else if (len == 1) {
-+              i = c2x(msgid[0]);
-+              j = 0;
-+      } else {
-+              i = j = 0;
-+      }
-+      if (i < 0 || i >= 16 || j < 0 || j >= 16)
-+              errx(1, "INTERNAL ERROR: bad seen code for msgid %s", msgid);
-+      SLIST_FOREACH(t, &seenmsg[i][j], next)
-+              if (!strncmp(t->str, msgid, len))
-+                      return (1);
-+      t = malloc(sizeof(*t));
-+      if (t == NULL)
-+              errx(1, "Could not allocate %lu bytes",
-+                  (unsigned long)(sizeof(*t)));
-+      t->str = strdup(msgid);
-+      if (t->str == NULL)
-+              errx(1, "Could not duplicate msgid %s", msgid);
-+      SLIST_INSERT_HEAD(&seenmsg[i][j], t, next);
-+      return (0);
-+}
-+
-+static void
-+load_queue(struct queue *queue, int nolock)
- {
-       struct stat st;
-       struct qitem *it;
-@@ -683,7 +742,7 @@
-       char *queueid;
-       char *queuefn;
-       off_t hdrlen;
--      int fd;
-+      int fd, locked, seenit;
-       LIST_INIT(&queue->queue);
-@@ -691,6 +750,7 @@
-       if (spooldir == NULL)
-               err(1, "reading queue");
-+      seen_init();
-       while ((de = readdir(spooldir)) != NULL) {
-               sender = NULL;
-               queuef = NULL;
-@@ -705,12 +765,19 @@
-                       continue;
-               if (asprintf(&queuefn, "%s/%s", config->spooldir, de->d_name) < 0)
-                       goto fail;
-+              seenit = seen(de->d_name);
-+              locked = 0;
-               fd = open_locked(queuefn, O_RDONLY|O_NONBLOCK);
-               if (fd < 0) {
-                       /* Ignore locked files */
--                      if (errno == EWOULDBLOCK)
-+                      if (errno != EWOULDBLOCK)
-+                              goto skip_item;
-+                      if (!nolock || seenit)
-                               continue;
--                      goto skip_item;
-+                      fd = open(queuefn, O_RDONLY);
-+                      if (fd < 0)
-+                              goto skip_item;
-+                      locked = 1;
-               }
-               queuef = fdopen(fd, "r");
-@@ -751,6 +818,7 @@
-                       it->queuef = queuef;
-                       it->queueid = queueid;
-                       it->queuefn = fn;
-+                      it->locked = locked;
-                       fn = NULL;
-               }
-               if (LIST_EMPTY(&itmqueue.queue)) {
-@@ -810,9 +878,9 @@
-       LIST_FOREACH(it, &queue->queue, next) {
-               printf("\
--ID\t: %s\n\
-+ID\t: %s%s\n\
- From\t: %s\n\
--To\t: %s\n--\n", it->queueid, it->sender, it->addr);
-+To\t: %s\n--\n", it->queueid, it->locked? "*": "", it->sender, it->addr);
-       }
- }
-@@ -914,7 +982,7 @@
-               if (argc != 0)
-                       errx(1, "sending mail and displaying queue is"
-                               " mutually exclusive");
--              load_queue(&lqueue);
-+              load_queue(&lqueue, 1);
-               show_queue(&lqueue);
-               return (0);
-       }
-@@ -922,7 +990,7 @@
-       if (doqueue) {
-               if (argc != 0)
-                       errx(1, "sending mail and queue pickup is mutually exclusive");
--              load_queue(&lqueue);
-+              load_queue(&lqueue, 0);
-               run_queue(&lqueue);
-               return (0);
-       }
---- a/dma.h
-+++ b/dma.h
-@@ -97,6 +97,7 @@
-       FILE *queuef;
-       off_t hdrlen;
-       int remote;
-+      int locked;
- };
- LIST_HEAD(queueh, qitem);
index af470f3bac4f561e147b6569f5ed9903e92e7192..dc26c459f212a5a55371eb394a32fb0e511f70b5 100644 (file)
@@ -1,31 +1,13 @@
-Fix two typos and a word order problem.
+Fix a typo.
 
 --- a/crypto.c
 +++ b/crypto.c
-@@ -155,7 +155,7 @@
-       error = SSL_connect(config->ssl);
-       if (error < 0) {
-               syslog(LOG_ERR, "%s: remote delivery failed:"
--                     " SSL handshake fataly failed: %m", it->queueid);
-+                     " SSL handshake failed fatally: %m", it->queueid);
-               return (-1);
-       }
-@@ -163,7 +163,7 @@
-       cert = SSL_get_peer_certificate(config->ssl);
-       if (cert == NULL) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
--                     " Peer did not provied certificate: %m", it->queueid);
-+                     " Peer did not provide certificate: %m", it->queueid);
-       }
-       X509_free(cert);
-@@ -267,7 +267,7 @@
+@@ -271,7 +271,7 @@
        /* Send AUTH command according to RFC 2554 */
        send_remote_command(fd, "AUTH CRAM-MD5");
        if (read_remote(fd, sizeof(buffer), buffer) != 3) {
--              syslog(LOG_ERR, "%s: smarthost authentification:"
-+              syslog(LOG_ERR, "%s: smarthost authentication:"
+-              syslog(LOG_DEBUG, "%s: smarthost authentification:"
++              syslog(LOG_DEBUG, "%s: smarthost authentication:"
                       " AUTH cram-md5 not available: %s", it->queueid,
                       neterr);
                /* if cram-md5 is not available */
index b84b6a4a727de0eb31440fffa03512fce66f7679..539e58fa161812515d619ad995d0bca5ce472312 100644 (file)
@@ -3,10 +3,10 @@ liblockfile, as mandated by Debian Policy.
 
 --- a/Makefile
 +++ b/Makefile
-@@ -4,10 +4,11 @@
+@@ -3,10 +3,11 @@
  SUBDIR=       etc
  
- CFLAGS+= -DHAVE_CRYPTO
 +CFLAGS+= -DHAVE_LIBLOCKFILE
  CFLAGS+= -I${.CURDIR}
  
@@ -19,7 +19,7 @@ liblockfile, as mandated by Debian Policy.
  SRCS= base64.c conf.c crypto.c net.c dma.c aliases_scan.l aliases_parse.y
 --- a/dma.c
 +++ b/dma.c
-@@ -60,9 +60,11 @@
+@@ -56,9 +56,11 @@
  #include <syslog.h>
  #include <unistd.h>
  
@@ -33,7 +33,7 @@ liblockfile, as mandated by Debian Policy.
  
  static void deliver(struct qitem *);
  static int add_recp(struct queue *, const char *, const char *, int);
-@@ -526,6 +528,47 @@
+@@ -689,6 +691,47 @@
        exit(1);
  }
  
@@ -42,7 +42,7 @@ liblockfile, as mandated by Debian Policy.
 +liblockfile_strerror(int res)
 +{
 +      static char buf[512];
-+      
++
 +      switch (res) {
 +              case L_SUCCESS:
 +                      snprintf(buf, sizeof(buf), "No error");
@@ -81,7 +81,7 @@ liblockfile, as mandated by Debian Policy.
  static int
  deliver_local(struct qitem *it, const char **errmsg)
  {
-@@ -536,6 +579,10 @@
+@@ -699,6 +742,10 @@
        int error;
        off_t mboxlen;
        time_t now = time(NULL);
@@ -92,13 +92,13 @@ liblockfile, as mandated by Debian Policy.
  
        error = snprintf(fn, sizeof(fn), "%s/%s", _PATH_MAILDIR, it->addr);
        if (error < 0 || (size_t)error >= sizeof(fn)) {
-@@ -545,17 +592,42 @@
+@@ -708,17 +755,42 @@
        }
  
        /* mailx removes users mailspool file if empty, so open with O_CREAT */
 -      mbox = open_locked(fn, O_WRONLY | O_APPEND | O_CREAT);
 -      if (mbox < 0) {
--              syslog(LOG_ERR, "%s: local delivery deferred: can not open `%s': %m",
+-              syslog(LOG_NOTICE, "%s: local delivery deferred: can not open `%s': %m",
 -                     it->queueid, fn);
 -              return (1);
 +#ifdef HAVE_LIBLOCKFILE
@@ -107,7 +107,7 @@ liblockfile, as mandated by Debian Policy.
 +#endif
 +              mbox = open_locked(fn, O_WRONLY | O_APPEND | O_CREAT);
 +              if (mbox < 0) {
-+                      syslog(LOG_ERR, "%s: local delivery deferred: can not open `%s': %m",
++                      syslog(LOG_NOTICE, "%s: local delivery deferred: can not open `%s': %m",
 +                             it->queueid, fn);
 +                      return (1);
 +              }
@@ -116,15 +116,15 @@ liblockfile, as mandated by Debian Policy.
 +              if (res == L_SUCCESS)
 +                      break;
 +              else
-+                      syslog(LOG_WARNING, "%s: could not dot-lock `%s': %s",
++                      syslog(LOG_NOTICE, "%s: could not dot-lock `%s': %s",
 +                             it->queueid, fn, liblockfile_strerror(res));
 +              close(mbox);
 +              if (try++ >= 5) {
-+                      syslog(LOG_ERR, "%s: local delivery deferred: can not dot-lock `%s'",
++                      syslog(LOG_NOTICE, "%s: local delivery deferred: can not dot-lock `%s'",
 +                             it->queueid, fn);
 +                      return (1);
 +              }
-+              syslog(LOG_WARNING, "%s: sleeping to retry the dot-lock",
++              syslog(LOG_NOTICE, "%s: sleeping to retry the dot-lock",
 +                     it->queueid);
 +              sleep(5 * try);
        }
@@ -132,7 +132,7 @@ liblockfile, as mandated by Debian Policy.
        mboxlen = lseek(mbox, 0, SEEK_CUR);
  
        if (fseek(it->queuef, it->hdrlen, SEEK_SET) != 0) {
-               syslog(LOG_ERR, "%s: local delivery deferred: can not seek: %m",
+               syslog(LOG_NOTICE, "%s: local delivery deferred: can not seek: %m",
                       it->queueid);
 +#ifdef HAVE_LIBLOCKFILE
 +              mailunlock();
@@ -140,9 +140,9 @@ liblockfile, as mandated by Debian Policy.
                return (1);
        }
  
-@@ -563,6 +635,9 @@
+@@ -726,6 +798,9 @@
        if (error < 0 || (size_t)error >= sizeof(line)) {
-               syslog(LOG_ERR, "%s: local delivery deferred: can not write header: %m",
+               syslog(LOG_NOTICE, "%s: local delivery deferred: can not write header: %m",
                       it->queueid);
 +#ifdef HAVE_LIBLOCKFILE
 +              mailunlock();
@@ -150,7 +150,7 @@ liblockfile, as mandated by Debian Policy.
                return (1);
        }
        if (write(mbox, line, error) != error)
-@@ -575,6 +650,9 @@
+@@ -738,6 +813,9 @@
                if (linelen == 0 || line[linelen - 1] != '\n') {
                        syslog(LOG_CRIT, "%s: local delivery failed: corrupted queue file",
                               it->queueid);
@@ -160,7 +160,7 @@ liblockfile, as mandated by Debian Policy.
                        *errmsg = "corrupted queue file";
                        error = -1;
                        goto chop;
-@@ -592,6 +670,9 @@
+@@ -755,6 +833,9 @@
        line[0] = '\n';
        if (write(mbox, line, 1) != 1)
                goto wrerror;
@@ -170,7 +170,7 @@ liblockfile, as mandated by Debian Policy.
        close(mbox);
        return (0);
  
-@@ -603,6 +684,9 @@
+@@ -766,6 +847,9 @@
        if (ftruncate(mbox, mboxlen) != 0)
                syslog(LOG_WARNING, "%s: error recovering mbox `%s': %m",
                       it->queueid, fn);
index 9d4af1a76c78a8ef02083b0f849a97617ec7c17c..f3ff7ed558a0a1a8d5aba63f14c6b6bf4fa64bee 100644 (file)
@@ -5,7 +5,7 @@ helper installed by the package.
 
 --- a/conf.c
 +++ b/conf.c
-@@ -233,6 +233,10 @@
+@@ -238,6 +238,10 @@
                                if (data != NULL)
                                        config->certfile = strdup(data);
                        }
@@ -13,12 +13,12 @@ helper installed by the package.
 +                              if (data != NULL)
 +                                      config->dbounceprog = strdup(data);
 +                      }
-                       else if (strcmp(word, "VIRTUAL") == 0)
-                               config->features |= VIRTUAL;
-                       else if (strcmp(word, "STARTTLS") == 0)
+                       else if (strcmp(word, "MAILNAME") == 0) {
+                               if (data != NULL)
+                                       config->mailname = strdup(data);
 --- a/dma.8
 +++ b/dma.8
-@@ -215,6 +215,26 @@
+@@ -217,6 +217,26 @@
  .Fl q
  option.
  This option is handy if you are behind a dialup line.
@@ -42,27 +42,29 @@ helper installed by the package.
 +.Ar queueid
 +.Fl f
 +.Ar messagefile
- .El
- .Ss virtusertable
- The
+ .It Ic FULLBOUNCE Xo
+ (boolean, default=commented)
+ .Xc
 --- a/dma.c
 +++ b/dma.c
-@@ -444,12 +444,114 @@
+@@ -595,14 +595,115 @@
+       struct queue bounceq;
        struct qitem *bit;
        char line[1000];
+-      size_t pos;
        int error;
 +      int pipefd[2];
 +      pid_t child;
 +      char *buf;
 +      size_t i, pos, bufsize;
 +      ssize_t n;
-+      int stat;
++      int status;
 +      struct sigaction sa;
  
        /* Don't bounce bounced mails */
        if (it->sender[0] == 0) {
--              syslog(LOG_CRIT, "%s: delivery panic: can't bounce a bounce",
-+              syslog(LOG_ERR, "%s: bounce delivery failed, double-bouncing",
+-              syslog(LOG_INFO, "%s: can not bounce a bounce message, discarding",
++              syslog(LOG_INFO, "%s: bounce delivery failed, double-bouncing",
                       it->queueid);
 -              exit(1);
 +              if (config->dbounceprog == NULL) {
@@ -139,21 +141,21 @@ helper installed by the package.
 +               */
 +              buf[pos] = '\0';
 +
-+              if (waitpid(child, &stat, 0) == -1) {
++              if (waitpid(child, &status, 0) == -1) {
 +                      syslog(LOG_ERR, "%s: double-bounce deferred: could not fetch the result from child process %ld: %m; child process output: %s",
 +                             it->queueid, (long)child, buf);
 +                      exit(1);
-+              } else if (WIFSIGNALED(stat)) {
++              } else if (WIFSIGNALED(status)) {
 +                      syslog(LOG_ERR, "%s: double-bounce deferred: child process %ld died from signal %d; child process output: %s",
-+                             it->queueid, (long)child, WTERMSIG(stat), buf);
++                             it->queueid, (long)child, WTERMSIG(status), buf);
 +                      exit(1);
-+              } else if (!WIFEXITED(stat)) {
++              } else if (!WIFEXITED(status)) {
 +                      syslog(LOG_ERR, "%s: double-bounce deferred: child process %ld got an unexpected waitpid code of %d; child process output: %s",
-+                             it->queueid, (long)child, stat, buf);
++                             it->queueid, (long)child, status, buf);
 +                      exit(1);
-+              } else if (WEXITSTATUS(stat) != 0) {
++              } else if (WEXITSTATUS(status) != 0) {
 +                      syslog(LOG_ERR, "%s: double-bounce deferred: child process %ld exited with code %d; child process output: %s",
-+                             it->queueid, (long)child, (int)WEXITSTATUS(stat), buf);
++                             it->queueid, (long)child, (int)WEXITSTATUS(status), buf);
 +                      exit(1);
 +              }
 +              syslog(LOG_ERR, "%s: double-bounce succeeded, message passed to handler `%s': %s",
@@ -166,22 +168,25 @@ helper installed by the package.
        syslog(LOG_ERR, "%s: delivery failed, bouncing",
 --- a/dma.h
 +++ b/dma.h
-@@ -120,6 +120,7 @@
- #ifdef HAVE_CRYPTO
+@@ -121,6 +121,7 @@
+       char *certfile;
+       int features;
        SSL *ssl;
- #endif /* HAVE_CRYPTO */
 +      char *dbounceprog;
+       char *mailname;
+       char *mailnamefile;
  };
 --- a/etc/dma.conf
 +++ b/etc/dma.conf
-@@ -40,3 +40,8 @@
- # Uncomment if you want to defer your mails.  This is useful if you are
+@@ -41,6 +41,11 @@
  # behind a dialup line.  You have to submit your mails manually with dma -q
  DEFER
-+
 +# The double-bounce handler program.  Leave this blank if you like dma's
 +# 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/12-man-q-argument.patch b/patches/12-man-q-argument.patch
deleted file mode 100644 (file)
index dfded9a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Note that the -q option requires an unused argument.
-
---- a/dma.8
-+++ b/dma.8
-@@ -39,13 +39,14 @@
- .Nd DragonFly Mail Agent
- .Sh SYNOPSIS
- .Nm
--.Op Fl DiOq
-+.Op Fl DiO
- .Op Fl A Ar mode
- .Op Fl b Ar mode
- .Op Fl f Ar sender
- .Op Fl L Ar tag
- .Op Fl o Ar option
- .Op Fl r Ar sender
-+.Op Fl q Ar arg
- .Op Ar recipient ...
- .Sh DESCRIPTION
- .Nm
-@@ -95,8 +96,9 @@
- is synonymous to
- .Fl i .
- All other options are ignored.
--.It Fl q
-+.It Fl q Ar arg
- Process saved messages in the queue.
-+The argument is required for compatibility with sendmail, and ignored.
- .It Fl r Ar sender
- Same as
- .Fl f .
diff --git a/patches/13-hardening.patch b/patches/13-hardening.patch
deleted file mode 100644 (file)
index 6a6b204..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-Appease the Debian hardening wrapper:
-- check the result of fgets()
-- loop the network writes until the whole thing is sent
-- check one more write() result
-
---- a/conf.c
-+++ b/conf.c
-@@ -106,7 +106,8 @@
-               return (-1);
-       while (!feof(v)) {
--              fgets(line, sizeof(line), v);
-+              if (fgets(line, sizeof(line), v) == NULL)
-+                      break;
-               /* We hit a comment */
-               if (strchr(line, '#'))
-                       *strchr(line, '#') = 0;
-@@ -162,7 +163,8 @@
-               return (1);
-       while (!feof(a)) {
--              fgets(line, sizeof(line), a);
-+              if (fgets(line, sizeof(line), a) == NULL)
-+                      break;
-               /* We hit a comment */
-               if (strchr(line, '#'))
-                       *strchr(line, '#') = 0;
-@@ -199,7 +201,8 @@
-       config->features = 0;
-       while (!feof(conf)) {
--              fgets(line, sizeof(line), conf);
-+              if (fgets(line, sizeof(line), conf) == NULL)
-+                      break;
-               /* We hit a comment */
-               if (strchr(line, '#'))
-                       *strchr(line, '#') = 0;
---- a/net.c
-+++ b/net.c
-@@ -73,23 +73,39 @@
- {
-       va_list va;
-       char cmd[4096];
--      ssize_t len = 0;
-+      size_t len, pos;
-+      int s;
-+      ssize_t n;
-       va_start(va, fmt);
--      vsprintf(cmd, fmt, va);
-+      s = vsnprintf(cmd, sizeof(cmd) - 2, fmt, va);
-+      va_end(va);
-+      if (s == sizeof(cmd) - 2 || s < 0)
-+              errx(1, "Internal error: oversized command string");
-+      /* We *know* there are at least two more bytes available */
-+      strcat(cmd, "\r\n");
-+      len = strlen(cmd);
-       if (((config->features & SECURETRANS) != 0) &&
-           ((config->features & NOSSL) == 0)) {
--              len = SSL_write(config->ssl, (const char*)cmd, strlen(cmd));
--              SSL_write(config->ssl, "\r\n", 2);
-+              while ((s = SSL_write(config->ssl, (const char*)cmd, len)) <= 0) {
-+                      s = SSL_get_error(config->ssl, s);
-+                      if (s != SSL_ERROR_WANT_READ &&
-+                          s != SSL_ERROR_WANT_WRITE)
-+                              return (-1);
-+              }
-       }
-       else {
--              len = write(fd, cmd, strlen(cmd));
--              write(fd, "\r\n", 2);
-+              pos = 0;
-+              while (pos < len) {
-+                      n = write(fd, cmd + pos, len - pos);
-+                      if (n < 0)
-+                              return (-1);
-+                      pos += n;
-+              }
-       }
--      va_end(va);
--      return (len+2);
-+      return (len);
- }
- int
---- a/dma.c
-+++ b/dma.c
-@@ -609,7 +609,8 @@
-                       break;
-               if (line[0] == '\n')
-                       break;
--              write(bounceq.mailfd, line, strlen(line));
-+              if (write(bounceq.mailfd, line, strlen(line)) != strlen(line))
-+                      goto fail;
-       }
-       if (fsync(bounceq.mailfd) != 0)
-               goto fail;
diff --git a/patches/14-lock-new-files.patch b/patches/14-lock-new-files.patch
deleted file mode 100644 (file)
index 3ff6628..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
-@@ -226,6 +226,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) {
index 3e2161fe23d2ff1502e073fe4bda89e760a94729..178b0fd9759f637e0881a29743755a03e4b0b6f9 100644 (file)
@@ -1,11 +1,13 @@
-Provide the proper bounce error message on failed deliveries.
+Make the bounce error message buffer dynamic.  The rest of this comment
+is left over from when this read "Provide the proper bounce error message".
+
 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
-@@ -440,7 +440,7 @@
+@@ -590,7 +590,7 @@
  }
  
  static void
@@ -14,15 +16,15 @@ array in net.c... and I'm not quite sure if I want to do that just now.
  {
        struct queue bounceq;
        struct qitem *bit;
-@@ -599,6 +599,7 @@
-               VERSION, hostname(),
-               it->addr,
-               reason);
+@@ -751,6 +751,7 @@
+               config->features & FULLBOUNCE ?
+                   "Original message follows." :
+                   "Message headers follow.");
 +      free(reason);
        if (error < 0)
                goto fail;
        if (fflush(bit->queuef) != 0)
-@@ -675,7 +676,7 @@
+@@ -834,7 +835,7 @@
  #endif
  
  static int
@@ -31,7 +33,7 @@ array in net.c... and I'm not quite sure if I want to do that just now.
  {
        char fn[PATH_MAX+1];
        char line[1000];
-@@ -758,7 +759,7 @@
+@@ -917,7 +918,7 @@
  #ifdef HAVE_LIBLOCKFILE
                        mailunlock();
  #endif
@@ -40,7 +42,7 @@ array in net.c... and I'm not quite sure if I want to do that just now.
                        error = -1;
                        goto chop;
                }
-@@ -801,7 +802,7 @@
+@@ -960,7 +961,7 @@
  {
        int error;
        unsigned int backoff = MIN_RETRY;
@@ -49,25 +51,10 @@ array in net.c... and I'm not quite sure if I want to do that just now.
        struct timeval now;
        struct stat st;
  
-@@ -832,12 +833,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 */
+@@ -165,7 +165,7 @@
+ extern char *ssl_errstr(void);
  extern int read_remote(int, int, char *);
  extern ssize_t send_remote_command(int, const char*, ...);
 -extern int deliver_remote(struct qitem *, const char **);
@@ -77,7 +64,7 @@ array in net.c... and I'm not quite sure if I want to do that just now.
  extern int base64_encode(const void *, int, char **);
 --- a/net.c
 +++ b/net.c
-@@ -314,7 +314,7 @@
+@@ -347,7 +347,7 @@
  }
  
  int
@@ -86,59 +73,7 @@ array in net.c... and I'm not quite sure if I want to do that just now.
  {
        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 @@
+@@ -474,7 +474,7 @@
                if (linelen == 0 || line[linelen - 1] != '\n') {
                        syslog(LOG_CRIT, "%s: remote delivery failed:"
                                "corrupted queue file", it->queueid);
diff --git a/patches/16-bounce-full.patch b/patches/16-bounce-full.patch
deleted file mode 100644 (file)
index 5dae966..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-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
-@@ -586,7 +586,7 @@
- \n\
- %s\n\
- \n\
--Message headers follow.\n\
-+%s\n\
- \n\
- ",
-               bounceq.id,
-@@ -598,7 +598,9 @@
-               rfc822date(),
-               VERSION, hostname(),
-               it->addr,
--              reason);
-+              reason,
-+              config->features & FULLBOUNCE? "Original message follows.":
-+              "Message headers follow.");
-       free(reason);
-       if (error < 0)
-               goto fail;
-@@ -607,14 +609,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
index 437f2d7b09f4a8b638418f8dbebef8d940ae318e..ff8f99987212d279bd494d31b896b6f457c2a84d 100644 (file)
-Add the MAILNAME and MAILNAMEFILE config options.
+Fix a file descriptor leak in the MAILNAMEFILE code.
+Fix a mistake in my patch submitted to DFBSD - "initialized" should be static!
 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
-@@ -83,10 +83,40 @@
+@@ -82,8 +82,9 @@
  hostname(void)
  {
        static char name[MAXHOSTNAMELEN+1];
+-      int initialized = 0;
 +      static int initialized = 0;
-+      FILE *fp;
+       FILE *fp;
 +      char *res;
-+      size_t len;
-+
-+      if (initialized)
-+              return (name);
+       size_t len;
  
-+      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 (initialized)
+@@ -97,7 +98,9 @@
+       if (config->mailnamefile != NULL && config->mailnamefile[0] != '\0') {
+               fp = fopen(config->mailnamefile, "r");
+               if (fp != NULL) {
+-                      if (fgets(name, sizeof(name), fp) != NULL) {
 +                      res = fgets(name, sizeof(name), fp);
 +                      fclose(fp);
 +                      if (res != 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);
-+                              }
-+                      }
-+              }
-+      }
+                               len = strlen(name);
+                               while (len > 0 &&
+                                   (name[len - 1] == '\r' ||
+@@ -108,7 +111,6 @@
+                                       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.
+@@ -56,4 +56,4 @@
+ # 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
 +MAILNAMEFILE /etc/mailname
diff --git a/patches/18-guess-username.patch b/patches/18-guess-username.patch
deleted file mode 100644 (file)
index af30c73..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-Apply better logic to guess the username when getlogin(3) is not
-available for some reason, e.g. no login session at all, no access
-to utmp/wtmp, etc.
-
---- a/dma.c
-+++ b/dma.c
-@@ -75,6 +75,8 @@
- struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
- static int daemonize = 1;
- struct config *config;
-+static const char *username;
-+static uid_t uid;
- static struct strlist seenmsg[16][16];
- static int open_locked(const char *, int);
-@@ -120,6 +122,45 @@
-       return name;
- }
-+static const char *
-+check_username(const char *username, uid_t uid)
-+{
-+      struct passwd *pwd;
-+
-+      if (username == NULL)
-+              return (NULL);
-+      pwd = getpwnam(username);
-+      if (pwd == NULL || pwd->pw_uid != uid)
-+              return (NULL);
-+      return (username);
-+}
-+
-+static void
-+set_username(void)
-+{
-+      struct passwd *pwd;
-+      char *u;
-+
-+      uid = getuid();
-+      username = check_username(getlogin(), uid);
-+      if (username == NULL)
-+              username = check_username(getenv("LOGNAME"), uid);
-+      if (username == NULL)
-+              username = check_username(getenv("USER"), uid);
-+      if (username == NULL) {
-+              pwd = getpwuid(uid);
-+              if (pwd != NULL && pwd->pw_name != NULL &&
-+                  pwd->pw_name[0] != '\0')
-+                      username = check_username(strdup(pwd->pw_name), uid);
-+      }
-+      if (username == NULL) {
-+              asprintf(&u, "%ld", (long)uid);
-+              username = u;
-+      }
-+      if (username == NULL)
-+              username = "unknown-or-invalid-username";
-+}
-+
- static char *
- set_from(const char *osender)
- {
-@@ -128,7 +169,7 @@
-       if ((config->features & VIRTUAL) != 0) {
-               SLIST_FOREACH(v, &virtusers, next) {
--                      if (strcmp(v->login, getlogin()) == 0) {
-+                      if (strcmp(v->login, username) == 0) {
-                               sender = strdup(v->address);
-                               if (sender == NULL)
-                                       return(NULL);
-@@ -142,7 +183,7 @@
-               if (sender == NULL)
-                       return (NULL);
-       } else {
--              if (asprintf(&sender, "%s@%s", getlogin(), hostname()) <= 0)
-+              if (asprintf(&sender, "%s@%s", username, hostname()) <= 0)
-                       return (NULL);
-       }
-@@ -370,7 +411,7 @@
- \tid %"PRIxMAX"\n\
- \tby %s (%s)\n\
- \t%s\n",
--              getlogin(), getuid(),
-+              username, uid,
-               sender,
-               queue->id,
-               hostname(), VERSION,
-@@ -1184,6 +1225,7 @@
-       opterr = 1;
-       openlog(tag, LOG_PID | LOG_PERROR, LOG_MAIL);
-+      set_username();
-       config = malloc(sizeof(struct config));
-       if (config == NULL)
diff --git a/patches/19-ignore-options.patch b/patches/19-ignore-options.patch
deleted file mode 100644 (file)
index 61ddfcf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-Ignore a whole slew of sendmail options.  Probably some more left.
-
---- a/dma.c
-+++ b/dma.c
-@@ -1174,7 +1174,7 @@
-       snprintf(tag, 254, "dma");
-       opterr = 0;
--      while ((ch = getopt(argc, argv, "A:b:Df:iL:o:O:q:r:")) != -1) {
-+      while ((ch = getopt(argc, argv, "A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:UV:vX:")) != -1) {
-               switch (ch) {
-               case 'A':
-                       /* -AX is being ignored, except for -A{c,m} */
-@@ -1216,6 +1216,21 @@
-                       doqueue = 1;
-                       break;
-+              /* Ignored options */
-+              case 'B':
-+              case 'C':
-+              case 'd':
-+              case 'F':
-+              case 'h':
-+              case 'N':
-+              case 'n':
-+              case 'R':
-+              case 'U':
-+              case 'V':
-+              case 'v':
-+              case 'X':
-+                      break;
-+
-               default:
-                       exit(1);
-               }
index e37608f5023de4252294bf823fe31c4ce786367c..dabe714da3ca5cda0ab4f30e85906c31b6a3f222 100644 (file)
@@ -23,21 +23,20 @@ to obtain the recipient addresses.
  .Nm
 --- a/dma.c
 +++ b/dma.c
-@@ -77,6 +77,7 @@
+@@ -73,6 +73,7 @@
  struct config *config;
  static const char *username;
  static uid_t uid;
 +static FILE *scanfile;
  static struct strlist seenmsg[16][16];
  
- static int open_locked(const char *, int);
-@@ -399,11 +400,307 @@
+@@ -429,6 +430,300 @@
  }
  
  static int
 +parse_header_line(struct queue *queue, const char *sender, const char *line)
 +{
-+      size_t len;
 +      const char *p;
 +      enum dma_header_state st;
 +      char buf[1000];
@@ -330,16 +329,18 @@ to obtain the recipient addresses.
 +}
 +
 +static int
readmail(struct queue *queue, const char *sender, int nodot)
strprefixcmp(const char *str, const char *prefix)
  {
+       return (strncasecmp(str, prefix, strlen(prefix)));
+@@ -440,6 +735,7 @@
        char line[1000];        /* by RFC2822 */
        size_t linelen;
        int error;
 +      FILE *infile;
-       error = snprintf(line, sizeof(line), "\
- Received: from %s (uid %d)\n\
-@@ -421,8 +718,12 @@
+       int had_headers = 0;
+       int had_from = 0;
+       int had_messagid = 0;
+@@ -461,8 +757,12 @@
        if (write(queue->mailfd, line, error) != error)
                return (-1);
  
@@ -354,7 +355,7 @@ to obtain the recipient addresses.
                        break;
                linelen = strlen(line);
                if (linelen == 0 || line[linelen - 1] != '\n') {
-@@ -436,6 +737,8 @@
+@@ -504,6 +804,8 @@
        }
        if (fsync(queue->mailfd) != 0)
                return (-1);
@@ -363,7 +364,7 @@ to obtain the recipient addresses.
        return (0);
  }
  
-@@ -1167,14 +1470,14 @@
+@@ -1252,7 +1554,7 @@
        struct queue queue;
        struct queue lqueue;
        int i, ch;
@@ -372,7 +373,8 @@ to obtain the recipient addresses.
  
        atexit(deltmp);
        LIST_INIT(&queue.queue);
-       snprintf(tag, 254, "dma");
+@@ -1267,7 +1569,7 @@
+       }
  
        opterr = 0;
 -      while ((ch = getopt(argc, argv, "A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:UV:vX:")) != -1) {
@@ -380,7 +382,7 @@ to obtain the recipient addresses.
                switch (ch) {
                case 'A':
                        /* -AX is being ignored, except for -A{c,m} */
-@@ -1216,6 +1519,10 @@
+@@ -1309,6 +1611,10 @@
                        doqueue = 1;
                        break;
  
@@ -391,8 +393,8 @@ to obtain the recipient addresses.
                /* Ignored options */
                case 'B':
                case 'C':
-@@ -1288,12 +1595,19 @@
-                       errx(1, "invalid recipient `%s'\n", argv[i]);
+@@ -1382,12 +1688,19 @@
+                       errx(1, "invalid recipient `%s'", argv[i]);
        }
  
 -      if (LIST_EMPTY(&queue.queue))
@@ -400,7 +402,7 @@ to obtain the recipient addresses.
                errx(1, "no recipients");
  
        if (gentempf(&queue) != 0)
-               err(1, "create temp file");
+               err(1, "can not create temp file");
  
 +      if (headerrecips) {
 +              if (scanmail(&queue, sender) != 0)
@@ -410,7 +412,7 @@ to obtain the recipient addresses.
 +      }
 +
        if (preparespool(&queue, sender) != 0)
-               err(1, "creating spools (1)");
+               err(1, "can not create spools (1)");
  
 --- a/dma.h
 +++ b/dma.h
diff --git a/patches/21-smtp-auth.patch b/patches/21-smtp-auth.patch
deleted file mode 100644 (file)
index 2b0c1bf..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-Unbreak SMTP authentication with or without encrypted connections:
-- always send an EHLO command at the start of the "real" negotiation;
-- allow LOGIN authentication over an SSL link if CRAM-MD5 fails.
-
---- a/net.c
-+++ b/net.c
-@@ -213,7 +213,9 @@
-       }
- #endif /* HAVE_CRYPTO */
--      if ((config->features & INSECURE) != 0) {
-+      if ((config->features & INSECURE) != 0 ||
-+          ((config->features & SECURETRANS) != 0 &&
-+           (config->features & NOSSL) == 0)) {
-               /* Send AUTH command according to RFC 2554 */
-               send_remote_command(fd, "AUTH LOGIN");
-               if (read_remote(fd, 0, NULL) != 3) {
-@@ -363,6 +365,7 @@
-                       goto out;
-       }
-+#if 0
-       /*
-        * If the user doesn't want STARTTLS, but SSL encryption, we
-        * have to enable SSL first, then send EHLO
-@@ -378,8 +381,11 @@
-                       return (-1);
-               }
-       }
-+#endif
- #endif /* HAVE_CRYPTO */
-+#if 0
-       if (((config->features & SECURETRANS) == 0)) {
-+#endif
-               send_remote_command(fd, "EHLO %s", hostname());
-               if (read_remote(fd, 0, NULL) != 2) {
-                       syslog(LOG_ERR, "%s: remote delivery deferred: "
-@@ -388,7 +394,9 @@
-                           host, neterr);
-                       return (-1);
-               }
-+#if 0
-       }
-+#endif
-       /*
-        * Use SMTP authentication if the user defined an entry for the remote
index ddbcd99c3264e603ba1494b1b07e02321aec2428..b1a0cffa2d1fe1e7ebcafc2c41233f778eeb9271 100644 (file)
@@ -2,15 +2,16 @@ Handle the "too many open files" error gracefully, retrying.
 
 --- a/dma.c
 +++ b/dma.c
-@@ -79,6 +79,7 @@
+@@ -75,7 +75,7 @@
  static uid_t uid;
  static FILE *scanfile;
  static struct strlist seenmsg[16][16];
+-
 +static int morefiles;
  
  static int open_locked(const char *, int);
  
-@@ -1311,15 +1312,21 @@
+@@ -1392,15 +1392,21 @@
        char *queueid;
        char *queuefn;
        off_t hdrlen;
@@ -34,7 +35,7 @@ Handle the "too many open files" error gracefully, retrying.
        while ((de = readdir(spooldir)) != NULL) {
                sender = NULL;
                queuef = NULL;
-@@ -1335,12 +1342,22 @@
+@@ -1416,12 +1422,22 @@
                if (asprintf(&queuefn, "%s/%s", config->spooldir, de->d_name) < 0)
                        goto fail;
                seenit = seen(de->d_name);
@@ -55,10 +56,10 @@ Handle the "too many open files" error gracefully, retrying.
 +                              }
                                goto skip_item;
 +                      }
-                       if (!nolock || seenit)
+                       if (!ignorelock || seenit)
                                continue;
                        fd = open(queuefn, O_RDONLY);
-@@ -1425,12 +1442,15 @@
+@@ -1506,12 +1522,15 @@
  static void
  run_queue(struct queue *queue)
  {
@@ -75,16 +76,16 @@ Handle the "too many open files" error gracefully, retrying.
        deliver(it);
        /* NOTREACHED */
  }
-@@ -1450,6 +1470,8 @@
- ID\t: %s%s\n\
- From\t: %s\n\
To\t: %s\n--\n", it->queueid, it->locked? "*": "", it->sender, it->addr);
+@@ -1534,6 +1553,8 @@
+                      it->queueid,
+                      it->locked ? "*" : "",
                     it->sender, it->addr);
 +              if (it->queuef != NULL)
 +                      close(fileno(it->queuef));
        }
  }
  
-@@ -1571,16 +1593,21 @@
+@@ -1664,16 +1685,21 @@
                if (argc != 0)
                        errx(1, "sending mail and displaying queue is"
                                " mutually exclusive");
index ce0e157094a63df9c6cea857d16b80c000f9a494..b487785eea7dc0d9d7a63be5dde50fb957e0dd62 100644 (file)
@@ -2,21 +2,10 @@
 02-man-dragonflybsd.patch
 03-debian-locations.patch
 04-debian-setgid.patch
-05-remote-error-messages.patch
-06-quit-nonfatal.patch
-07-permanent-errors.patch
-08-queue-list-all.patch
 09-typos.patch
 10-liblockfile.patch
 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
-18-guess-username.patch
-19-ignore-options.patch
 20-parse-recipient.patch
-21-smtp-auth.patch
 22-openfiles.patch