diff --git a/postfix/HISTORY b/postfix/HISTORY
index cba26c8b1..408259629 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -5114,8 +5114,14 @@ Apologies for any names omitted.
Feature: "postsuper -d queueID" deletes one message queue
file; "postsuper -d -" reads zero or more queue IDs from
- standard input. In order to make this operation usable
- with a running Postfix mail system, some routines were made
- more tolerant for sudden queue file disappearances. Files:
- postsuper/postsuper.c, global/deliver_request.c,
- *qmgr/qmgr_move.c.
+ standard input, and deletes one instance of each file.
+ File: postsuper/postsuper.c.
+
+ Code cleanup: in order to make postsuper -d safe with a
+ running Postfix mail system, some routines had to be made
+ tolerant for sudden queue file disappearances. Files:
+ global/deliver_request.c, *qmgr/qmgr_move.c.
+
+ Code cleanup: in order to make postsuper -d more usable,
+ the showq command was extended to safely list the possibly
+ world-writable maildrop directory. File: showq/showq.c.
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index ab932d0e5..47940a31d 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -1,3 +1,26 @@
+Major changes with snapshot-20010502
+====================================
+
+This snapshot release incorporates all the bugfixes of patch 02
+for the official Postfix release 20010228, and adds a few minor
+features.
+
+The Postfix SMTP client now by default randomly shuffles destination
+IP addresses of equal preference (whether obtained via MX lookup
+or otherwise). Reportedly, this is needed for sites that use
+Bernstein's dnscache program. Specify "smtp_randomize_addresses =
+no" to disable this behavior. Based on shuffling code by Aleph1.
+
+"postmap -q -" and "postmap -d -" read key values from standard
+input, which makes it easier to drive them from another program.
+The same feature was added to the postalias command.
+
+The postsuper command now has an option to delete queue files. In
+principle this command can be used while Postfix is running, but
+there is a possibility of deleting the wrong queue file when Postfix
+deletes a queue file and reuses the queue ID for a new message.
+In that case, postsuper will delete the new message.
+
Incompatible changes with snapshot-20010329
===========================================
@@ -103,7 +126,7 @@ been updated from *.vix.com to *.mail-abuse.org.
Major changes with snapshot-20010128
====================================
-Updated nqmgr (experimental queue manager with clever queueing
+Updated nqmgr (experimental queue manager with clever queuing
strategy) by Patrik Rak. This code is still new. Once it stops
changing (for a long time!) it will become part of the non-beta
release.
diff --git a/postfix/html/faq.html b/postfix/html/faq.html
index 294350905..0f2764aca 100644
--- a/postfix/html/faq.html
+++ b/postfix/html/faq.html
@@ -1261,7 +1261,7 @@ Question:
My Postfix server is too slow. When I telnet to the SMTP port
(telnet hostname 25), the response comes after 40 seconds.
-On the other hand, when I telnet to the the POP port (telnet
+On the other hand, when I telnet to the POP port (telnet
hostname 110) the response comes with no delay.
@@ -1614,7 +1614,7 @@ The implementation uses two lookup tables. One table defines what
users are restricted in where they can send mail, and the other
table defines what destinations are local. It is left as an exercise
for the reader to change this into a scheme where only some users
-have permission to send send mail to off-site destinations, and
+have permission to send mail to off-site destinations, and
where most users are restricted.
@@ -2180,7 +2180,7 @@ types Postfix supports, use the command postconf -m.
Execute the command postmap /etc/postfix/virtual whenever
-you edit the the virtual table.
+you edit the virtual table.
@@ -2987,41 +2987,59 @@ Note: be sure to not advertise fax.your.domain in the DNS :-)
Deleting a message from the Postfix queue
-To delete ONE message with queue id ABCDEF (e.g., from mailq
-output) from the Postfix queue, it is not necessary to stop Postfix.
+As of Postfix version 20010502, the postsuper command
+has an option to delete Postfix message queue files. To delete
+the message with queue id ABCDEF, perhaps obtained from mailq
+output, one would use:
+
- # cd /var/spool/postfix
- # find incoming active deferred -name ABCDEF -print | sed 1q | xargs rm
+# postsuper -d ABCDEF
+
-The above command is safe because it deletes at most one file.
-There is no risk of deleting newly arrived mail that happens to get
-the same queue file name.
+To delete a large number of files one would use:
-If you have to delete a large amount of mail, you must stop Postfix
-first.
-
-
+
- # postfix stop
- # cd /var/spool/postfix
- # find incoming active deferred defer -type f -print |
- fgrep -xf /file/with/queue-ids | xargs rm
- # postfix start
+# postsuper -d - < filename-with-queue-ids
+
-Do not use the above find command on a running Postfix
-system, because it can delete files that belong to new mail that
-arrives while you are deleting queue files.
+It is usually safe to do this while the Postfix system is running.
+However, there is a small chance of deleting the wrong queue
+file. The scenario goes like this:
+
+
+
+
+
+- The Postfix queue manager deletes the file that postsuper
+was supposed to delete, because Postfix was finished with the
+message.
+
+
+
+
- New mail arrives, and the new message is given the same queue
+ID as the message that postsuper was supposed to delete.
+The probability for reusing a deleted queue ID is about 1 in
+215 (the number of different microsecond values that
+the system clock can distinguish).
+
+
+
+
- postsuper deletes the new message file, instead of the
+old file that should have been deleted.
+
+
diff --git a/postfix/html/postsuper.1.html b/postfix/html/postsuper.1.html
index 0d2993f8f..562450a29 100644
--- a/postfix/html/postsuper.1.html
+++ b/postfix/html/postsuper.1.html
@@ -12,35 +12,65 @@ POSTSUPER(1) POSTSUPER(1)
postsuper [-d queue_id] [-p] [-s] [-v] [directory ...]
DESCRIPTION
- The postsuper command does small maintenance jobs on the
- named Postfix queue directories (default: all). Directory
- names are relative to the Postfix top-level queue direc-
- tory.
+ The postsuper command does small maintenance jobs. Use of
+ the command is restricted to the super-user.
By default, postsuper performs the operations requested
- with the -s and -p command-line options. postsuper always
- tries to remove objects that are neither files nor direc-
- tories. Use of this command is restricted to the super-
- user.
+ with the -s and -p command-line options on the named Post-
+ fix queue directories (default: all). Directory names are
+ relative to the Postfix top-level queue directory.
Options:
- -d Delete one message queue file with the named queue
+ -d This option ignores any directory argument(s).
+ Delete one message queue file with the named queue
ID. Specify multiple -d options to delete multiple
queue files by name.
Alternatively, if a queue_id of - is specified, the
program reads queue IDs from standard input.
- This operation can be performed safely while the
- mail system is running, although the queue manager
- may issue warnings when a file suddenly disappears.
- The exit status is zero if at least one of the
- named message queue files was found.
+ The postsuper exit status is non-zero when no mes-
+ sage queue file was deleted.
+
+ There is a very small possibility that postsuper
+ deletes the wrong message file when it is executed
+ while the Postfix mail system is running.
+
+ The scenario is as follows:
+
+ o The Postfix queue manager deletes the file
+ that postsuper was supposed to delete,
+ because Postfix was finished with the mes-
+ sage.
+
+ o New mail arrives, and the new message is
+ given the same queue ID as the message that
+ postsuper was supposed to delete. The prob-
+ ability for reusing a deleted queue ID is
+ about 1 in 2**15 (the number of different
+ microsecond values that the system clock can
+ distinguish).
+
+ o postsuper deletes the new message file,
+ instead of the old file that should have
+ been deleted.
-s Structure check. Move queue files that are in the
wrong place in the file system hierarchy and remove
subdirectories that are no longer needed. File
+
+
+
+ 1
+
+
+
+
+
+POSTSUPER(1) POSTSUPER(1)
+
+
rearrangements are necessary after a change in the
hash_queue_names and/or hash_queue_depth configura-
tion parameters. It is highly recommended to run
@@ -59,18 +89,6 @@ POSTSUPER(1) POSTSUPER(1)
CONFIGURATION PARAMETERS
See the Postfix main.cf file for syntax details and for
-
-
-
- 1
-
-
-
-
-
-POSTSUPER(1) POSTSUPER(1)
-
-
default values.
hash_queue_depth
@@ -107,24 +125,6 @@ POSTSUPER(1) POSTSUPER(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/postfix/man/man1/postsuper.1 b/postfix/man/man1/postsuper.1
index 050497aaa..ea22b0a98 100644
--- a/postfix/man/man1/postsuper.1
+++ b/postfix/man/man1/postsuper.1
@@ -14,27 +14,48 @@ Postfix super intendent
.SH DESCRIPTION
.ad
.fi
-The \fBpostsuper\fR command does small maintenance jobs on the named
-Postfix queue directories (default: all).
-Directory names are relative to the Postfix top-level queue directory.
+The \fBpostsuper\fR command does small maintenance jobs. Use of
+the command is restricted to the super-user.
By default, \fBpostsuper\fR performs the operations requested with the
-\fB-s\fR and \fB-p\fR command-line options.
-\fBpostsuper\fR always tries to remove objects that are neither files
-nor directories. Use of this command is restricted to the super-user.
+\fB-s\fR and \fB-p\fR command-line options on the named Postfix queue
+directories (default: all).
+Directory names are relative to the Postfix top-level queue directory.
Options:
.IP \fB-d \fIqueue_id\fR
+This option ignores any \fIdirectory\fR argument(s).
Delete one message queue file with the named queue ID. Specify
multiple \fB-d\fR options to delete multiple queue files by name.
.sp
Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified, the
program reads queue IDs from standard input.
.sp
-This operation can be performed safely while the mail system is
-running, although the queue manager may issue warnings when a
-file suddenly disappears. The exit status is zero if at least one
-of the named message queue files was found.
+The \fBpostsuper\fR exit status is non-zero when no message queue
+file was deleted.
+.sp
+.ft B
+There is a very small possibility that postsuper deletes the
+wrong message file when it is executed while the Postfix mail
+system is running.
+.ft R
+.sp
+The scenario is as follows:
+.RS
+.IP \(bu
+The Postfix queue manager deletes the file that \fBpostsuper\fR
+was supposed to delete, because Postfix was finished with the
+message.
+.IP \(bu
+New mail arrives, and the new message is given the same queue ID
+as the message that \fBpostsuper\fR was supposed to delete.
+The probability for reusing a deleted queue ID is about 1 in 2**15
+(the number of different microsecond values that the system clock
+can distinguish).
+.IP \(bu
+\fBpostsuper\fR deletes the new message file, instead of the
+old file that should have been deleted.
+.RE
.IP \fB-s\fR
Structure check. Move queue files that are in the wrong place
in the file system hierarchy and remove subdirectories that are
diff --git a/postfix/src/global/deliver_request.c b/postfix/src/global/deliver_request.c
index 29a041ea2..3cd4dd848 100644
--- a/postfix/src/global/deliver_request.c
+++ b/postfix/src/global/deliver_request.c
@@ -314,9 +314,11 @@ DELIVER_REQUEST *deliver_request_read(VSTREAM *stream)
/*
* Allocate and read the queue manager's delivery request.
*/
+#define XXX_DEFER_STATUS -1
+
request = deliver_request_alloc();
if (deliver_request_get(stream, request) < 0) {
- deliver_request_free(request);
+ deliver_request_done(stream, request, XXX_DEFER_STATUS);
request = 0;
}
return (request);
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 56c970950..bb1b805ad 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20010501"
+#define DEF_MAIL_VERSION "Snapshot-20010502"
extern char *var_mail_version;
/* LICENSE
diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c
index 6b4896e67..f4fd84517 100644
--- a/postfix/src/postsuper/postsuper.c
+++ b/postfix/src/postsuper/postsuper.c
@@ -8,27 +8,48 @@
/* \fBpostsuper\fR [\fB-d \fIqueue_id\fR] [\fB-p\fR]
/* [\fB-s\fR] [\fB-v\fR] [\fIdirectory ...\fR]
/* DESCRIPTION
-/* The \fBpostsuper\fR command does small maintenance jobs on the named
-/* Postfix queue directories (default: all).
-/* Directory names are relative to the Postfix top-level queue directory.
+/* The \fBpostsuper\fR command does small maintenance jobs. Use of
+/* the command is restricted to the super-user.
/*
/* By default, \fBpostsuper\fR performs the operations requested with the
-/* \fB-s\fR and \fB-p\fR command-line options.
-/* \fBpostsuper\fR always tries to remove objects that are neither files
-/* nor directories. Use of this command is restricted to the super-user.
+/* \fB-s\fR and \fB-p\fR command-line options on the named Postfix queue
+/* directories (default: all).
+/* Directory names are relative to the Postfix top-level queue directory.
/*
/* Options:
/* .IP \fB-d \fIqueue_id\fR
+/* This option ignores any \fIdirectory\fR argument(s).
/* Delete one message queue file with the named queue ID. Specify
/* multiple \fB-d\fR options to delete multiple queue files by name.
/* .sp
/* Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified, the
/* program reads queue IDs from standard input.
/* .sp
-/* This operation can be performed safely while the mail system is
-/* running, although the queue manager may issue warnings when a
-/* file suddenly disappears. The exit status is zero if at least one
-/* of the named message queue files was found.
+/* The \fBpostsuper\fR exit status is non-zero when no message queue
+/* file was deleted.
+/* .sp
+/* .ft B
+/* There is a very small possibility that postsuper deletes the
+/* wrong message file when it is executed while the Postfix mail
+/* system is running.
+/* .ft R
+/* .sp
+/* The scenario is as follows:
+/* .RS
+/* .IP \(bu
+/* The Postfix queue manager deletes the file that \fBpostsuper\fR
+/* was supposed to delete, because Postfix was finished with the
+/* message.
+/* .IP \(bu
+/* New mail arrives, and the new message is given the same queue ID
+/* as the message that \fBpostsuper\fR was supposed to delete.
+/* The probability for reusing a deleted queue ID is about 1 in 2**15
+/* (the number of different microsecond values that the system clock
+/* can distinguish).
+/* .IP \(bu
+/* \fBpostsuper\fR deletes the new message file, instead of the
+/* old file that should have been deleted.
+/* .RE
/* .IP \fB-s\fR
/* Structure check. Move queue files that are in the wrong place
/* in the file system hierarchy and remove subdirectories that are
@@ -96,6 +117,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -140,16 +162,17 @@ static struct queue_info queue_info[] = {
static int delete_one(const char *queue_id)
{
const char *msg_queue_names[] = {
+ MAIL_QUEUE_MAILDROP,
MAIL_QUEUE_INCOMING, /* twice, to avoid */
MAIL_QUEUE_ACTIVE, /* missing a file while */
MAIL_QUEUE_DEFERRED, /* it is being renamed */
MAIL_QUEUE_INCOMING, /* this is not 100% */
MAIL_QUEUE_ACTIVE, /* foolproof but adequate */
- MAIL_QUEUE_DEFERRED,
0,
};
+ struct stat st;
const char **cpp;
- VSTRING *msg_path = vstring_alloc(100);
+ const char *path;
int found = 0;
/*
@@ -158,17 +181,18 @@ static int delete_one(const char *queue_id)
* ID.
*/
for (cpp = msg_queue_names; *cpp != 0; cpp++) {
- (void) mail_queue_path(msg_path, *cpp, queue_id);
- if (unlink(STR(msg_path)) == 0) {
+ if (!mail_open_ok(*cpp, queue_id, &st, &path)) {
+ continue;
+ } else if (unlink(path) == 0) {
found = 1;
- if (msg_verbose)
- msg_info("removed file %s", STR(msg_path));
+ msg_info("removed file %s", path);
break;
} else if (errno != ENOENT) {
- msg_warn("remove file %s: %m", STR(msg_path));
+ msg_warn("remove file %s: %m", path);
+ } else if (msg_verbose) {
+ msg_info("remove file %s: %m", path);
}
}
- vstring_free(msg_path);
return (found);
}
@@ -417,6 +441,8 @@ int main(int argc, char **argv)
* a non-root user limits the damage to the already compromised mail
* owner.
*/
+ if (getuid())
+ msg_fatal("use of this command is reserved for the super-user");
set_ugid(var_owner_uid, var_owner_gid);
/*
diff --git a/postfix/src/showq/showq.c b/postfix/src/showq/showq.c
index 55cab747a..d6a762174 100644
--- a/postfix/src/showq/showq.c
+++ b/postfix/src/showq/showq.c
@@ -92,6 +92,7 @@ int var_dup_filter_limit;
#define STRING_FORMAT "%-10s %8s %-20s %s\n"
#define DATA_FORMAT "%-10s%c%8ld %20.20s %s\n"
+#define DROP_FORMAT "%-10s%c%8ld %20.20s (maildrop queue, sender UID %d)\n"
static void showq_reasons(VSTREAM *, BOUNCE_LOG *, HTABLE *);
@@ -203,7 +204,6 @@ static void showq_reasons(VSTREAM *client, BOUNCE_LOG *bp, HTABLE *dup_filter)
static void showq_service(VSTREAM *client, char *unused_service, char **argv)
{
- char **queue;
VSTREAM *qfile;
const char *path;
int status;
@@ -211,11 +211,17 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
int file_count;
unsigned long queue_size = 0;
struct stat st;
- char *queue_names[] = { /* XXX configurable */
- MAIL_QUEUE_INCOMING,
- MAIL_QUEUE_ACTIVE,
- MAIL_QUEUE_DEFERRED,
- /* No maildrop until we can disable recursive scans. */
+ struct queue_info {
+ char *name; /* queue name */
+ char *(*scan_next) (SCAN_DIR *); /* flat or recursive */
+ };
+ struct queue_info *qp;
+
+ static struct queue_info queue_info[] = {
+ MAIL_QUEUE_MAILDROP, scan_dir_next,
+ MAIL_QUEUE_INCOMING, mail_scan_dir_next,
+ MAIL_QUEUE_ACTIVE, mail_scan_dir_next,
+ MAIL_QUEUE_DEFERRED, mail_scan_dir_next,
0,
};
@@ -231,11 +237,11 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
* mis-configured, and force backoff by raising a fatal error.
*/
file_count = 0;
- for (queue = queue_names; *queue != 0; queue++) {
- SCAN_DIR *scan = scan_dir_open(*queue);
+ for (qp = queue_info; qp->name != 0; qp++) {
+ SCAN_DIR *scan = scan_dir_open(qp->name);
char *saved_id = 0;
- while ((id = mail_scan_dir_next(scan)) != 0) {
+ while ((id = qp->scan_next(scan)) != 0) {
/*
* XXX I have seen showq loop on the same queue id. That would be
@@ -244,13 +250,13 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
*/
if (saved_id) {
if (strcmp(saved_id, id) == 0) {
- msg_warn("readdir loop on queue %s id %s", *queue, id);
+ msg_warn("readdir loop on queue %s id %s", qp->name, id);
break;
}
myfree(saved_id);
}
saved_id = mystrdup(id);
- status = mail_open_ok(*queue, id, &st, &path);
+ status = mail_open_ok(qp->name, id, &st, &path);
if (status == MAIL_OPEN_YES) {
if (file_count == 0)
vstream_fprintf(client, STRING_FORMAT,
@@ -259,19 +265,19 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
"-Sender/Recipient-------");
else
vstream_fprintf(client, "\n");
- if ((qfile = mail_queue_open(*queue, id, O_RDONLY, 0)) != 0) {
+ if ((qfile = mail_queue_open(qp->name, id, O_RDONLY, 0)) != 0) {
queue_size += st.st_size;
- showq_report(client, *queue, id, qfile, (long) st.st_size);
+ showq_report(client, qp->name, id, qfile, (long) st.st_size);
if (vstream_fclose(qfile))
- msg_warn("close file %s %s: %m", *queue, id);
- } else if (strcmp(*queue, MAIL_QUEUE_MAILDROP) == 0) {
+ msg_warn("close file %s %s: %m", qp->name, id);
+ } else if (strcmp(qp->name, MAIL_QUEUE_MAILDROP) == 0) {
queue_size += st.st_size;
- vstream_fprintf(client, DATA_FORMAT, id, ' ',
+ vstream_fprintf(client, DROP_FORMAT, id, ' ',
(long) st.st_size,
asctime(localtime(&st.st_mtime)),
- "(to be determined)");
+ st.st_uid);
} else if (errno != ENOENT)
- msg_fatal("open %s %s: %m", *queue, id);
+ msg_fatal("open %s %s: %m", qp->name, id);
file_count++;
vstream_fflush(client);
}
diff --git a/postfix/src/util/myrand.c b/postfix/src/util/myrand.c
index d86f2bce1..39fcbfd9e 100644
--- a/postfix/src/util/myrand.c
+++ b/postfix/src/util/myrand.c
@@ -12,7 +12,7 @@
/* int myrand()
/* DESCRIPTION
/* This module implements a wrapper for the portable, pseudo-random
-/* number generator.
+/* number generator. The wrapper adds automatic initialization.
/*
/* mysrand() performs initialization. This call may be skipped.
/*