7 /* Postfix superintendent
10 /* \fBpostsuper\fR [\fB-psv\fR]
11 /* [\fB-c \fIconfig_dir\fR] [\fB-d \fIqueue_id\fR]
12 /* [\fB-h \fIqueue_id\fR] [\fB-H \fIqueue_id\fR]
13 /* [\fB-r \fIqueue_id\fR] [\fIdirectory ...\fR]
15 /* The \fBpostsuper\fR(1) command does maintenance jobs on the Postfix
16 /* queue. Use of the command is restricted to the superuser.
17 /* See the \fBpostqueue\fR(1) command for unprivileged queue operations
18 /* such as listing or flushing the mail queue.
20 /* By default, \fBpostsuper\fR(1) performs the operations
22 /* \fB-s\fR and \fB-p\fR command-line options on all Postfix queue
23 /* directories - this includes the \fBincoming\fR, \fBactive\fR and
24 /* \fBdeferred\fR directories with mail files and the \fBbounce\fR,
25 /* \fBdefer\fR, \fBtrace\fR and \fBflush\fR directories with log files.
28 /* .IP "\fB-c \fIconfig_dir\fR"
29 /* The \fBmain.cf\fR configuration file is in the named directory
30 /* instead of the default configuration directory. See also the
31 /* MAIL_CONFIG environment setting below.
32 /* .IP "\fB-d \fIqueue_id\fR"
33 /* Delete one message with the named queue ID from the named
34 /* mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
37 /* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
38 /* queue IDs from standard input. For example, to delete all mail
39 /* with exactly one recipient \fBuser@example.com\fR:
42 /* mailq | tail +2 | grep -v '^ *(' | awk \'BEGIN { RS = "" }
43 /* # $7=sender, $8=recipient1, $9=recipient2
44 /* { if ($8 == "user@example.com" && $9 == "")
46 /* \' | tr -d '*!' | postsuper -d -
49 /* Specify "\fB-d ALL\fR" to remove all messages; for example, specify
50 /* "\fB-d ALL deferred\fR" to delete all mail in the \fBdeferred\fR queue.
51 /* As a safety measure, the word \fBALL\fR must be specified in upper
54 /* Warning: Postfix queue IDs are reused.
55 /* There is a very small possibility that postsuper deletes the
56 /* wrong message file when it is executed while the Postfix mail
57 /* system is delivering mail.
59 /* The scenario is as follows:
62 /* The Postfix queue manager deletes the message that \fBpostsuper\fR(1)
63 /* is asked to delete, because Postfix is finished with the
64 /* message (it is delivered, or it is returned to the sender).
66 /* New mail arrives, and the new message is given the same queue ID
67 /* as the message that \fBpostsuper\fR(1) is supposed to delete.
68 /* The probability for reusing a deleted queue ID is about 1 in 2**15
69 /* (the number of different microsecond values that the system clock
70 /* can distinguish within a second).
72 /* \fBpostsuper\fR(1) deletes the new message, instead of the old
73 /* message that it should have deleted.
75 /* .IP "\fB-h \fIqueue_id\fR"
76 /* Put mail "on hold" so that no attempt is made to deliver it.
77 /* Move one message with the named queue ID from the named
78 /* mail queue(s) (default: \fBincoming\fR, \fBactive\fR and
79 /* \fBdeferred\fR) to the \fBhold\fR queue.
81 /* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
82 /* queue IDs from standard input.
84 /* Specify "\fB-h ALL\fR" to hold all messages; for example, specify
85 /* "\fB-h ALL deferred\fR" to hold all mail in the \fBdeferred\fR queue.
86 /* As a safety measure, the word \fBALL\fR must be specified in upper
89 /* Note: while mail is "on hold" it will not expire when its
90 /* time in the queue exceeds the \fBmaximal_queue_lifetime\fR
91 /* or \fBbounce_queue_lifetime\fR setting. It becomes subject to
92 /* expiration after it is released from "hold".
94 /* This feature is available in Postfix 2.0 and later.
95 /* .IP "\fB-H \fIqueue_id\fR"
96 /* Release mail that was put "on hold".
97 /* Move one message with the named queue ID from the named
98 /* mail queue(s) (default: \fBhold\fR) to the \fBdeferred\fR queue.
100 /* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
101 /* queue IDs from standard input.
103 /* Note: specify "\fBpostsuper -r\fR" to release mail that was kept on
104 /* hold for a significant fraction of \fB$maximal_queue_lifetime\fR
105 /* or \fB$bounce_queue_lifetime\fR, or longer.
107 /* Specify "\fB-H ALL\fR" to release all mail that is "on hold".
108 /* As a safety measure, the word \fBALL\fR must be specified in upper
111 /* This feature is available in Postfix 2.0 and later.
113 /* Purge old temporary files that are left over after system or
115 /* .IP "\fB-r \fIqueue_id\fR"
116 /* Requeue the message with the named queue ID from the named
117 /* mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
119 /* To requeue multiple messages, specify multiple \fB-r\fR
120 /* command-line options.
122 /* Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified,
123 /* the program reads queue IDs from standard input.
125 /* Specify "\fB-r ALL\fR" to requeue all messages. As a safety
126 /* measure, the word \fBALL\fR must be specified in upper case.
128 /* A requeued message is moved to the \fBmaildrop\fR queue,
129 /* from where it is copied by the \fBpickup\fR(8) and
130 /* \fBcleanup\fR(8) daemons to a new queue file. In many
131 /* respects its handling differs from that of a new local
135 /* The message is not subjected to the smtpd_milters or
136 /* non_smtpd_milters settings. When mail has passed through
137 /* an external content filter, this would produce incorrect
138 /* results with Milter applications that depend on original
139 /* SMTP connection state information.
141 /* The message is subjected again to mail address rewriting
142 /* and substitution. This is useful when rewriting rules or
143 /* virtual mappings have changed.
145 /* The address rewriting context (local or remote) is the same
146 /* as when the message was received.
148 /* The message is subjected to the same content_filter settings
149 /* (if any) as used for new local mail submissions. This is
150 /* useful when content_filter settings have changed.
153 /* Warning: Postfix queue IDs are reused.
154 /* There is a very small possibility that \fBpostsuper\fR(1) requeues
155 /* the wrong message file when it is executed while the Postfix mail
156 /* system is running, but no harm should be done.
158 /* This feature is available in Postfix 1.1 and later.
160 /* Structure check and structure repair. This should be done once
161 /* before Postfix startup.
164 /* Rename files whose name does not match the message file inode
165 /* number. This operation is necessary after restoring a mail queue
166 /* from a different machine, or from backup media.
168 /* Move queue files that are in the wrong place in the file system
169 /* hierarchy and remove subdirectories that are no longer needed.
170 /* File position rearrangements are necessary after a change in the
171 /* \fBhash_queue_names\fR and/or \fBhash_queue_depth\fR
172 /* configuration parameters.
175 /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
176 /* options make the software increasingly verbose.
178 /* Problems are reported to the standard error stream and to
181 /* \fBpostsuper\fR(1) reports the number of messages deleted with \fB-d\fR,
182 /* the number of messages requeued with \fB-r\fR, and the number of
183 /* messages whose queue file name was fixed with \fB-s\fR. The report
184 /* is written to the standard error stream and to \fBsyslogd\fR(8).
189 /* Directory with the \fBmain.cf\fR file.
191 /* Mail that is not sanitized by Postfix (i.e. mail in the \fBmaildrop\fR
192 /* queue) cannot be placed "on hold".
193 /* CONFIGURATION PARAMETERS
196 /* The following \fBmain.cf\fR parameters are especially relevant to
198 /* The text below provides only a parameter summary. See
199 /* \fBpostconf\fR(5) for more details including examples.
200 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
201 /* The default location of the Postfix main.cf and master.cf
202 /* configuration files.
203 /* .IP "\fBhash_queue_depth (1)\fR"
204 /* The number of subdirectory levels for queue directories listed with
205 /* the hash_queue_names parameter.
206 /* .IP "\fBhash_queue_names (deferred, defer)\fR"
207 /* The names of queue directories that are split across multiple
208 /* subdirectory levels.
209 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
210 /* The location of the Postfix top-level queue directory.
211 /* .IP "\fBsyslog_facility (mail)\fR"
212 /* The syslog facility of Postfix logging.
213 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
214 /* The mail system name that is prepended to the process name in syslog
215 /* records, so that "smtpd" becomes, for example, "postfix/smtpd".
217 /* sendmail(1), Sendmail-compatible user interface
218 /* postqueue(1), unprivileged queue operations
222 /* The Secure Mailer license must be distributed with this software.
225 /* IBM T.J. Watson Research
227 /* Yorktown Heights, NY 10598, USA
230 /* System library. */
232 #include <sys_defs.h>
233 #include <sys/stat.h>
239 #include <stdio.h> /* remove() */
242 /* Utility library. */
244 #include <mymalloc.h>
246 #include <msg_syslog.h>
248 #include <msg_vstream.h>
249 #include <scan_dir.h>
252 #include <set_ugid.h>
254 #include <vstring_vstream.h>
255 #include <sane_fsops.h>
257 /* Global library. */
259 #include <mail_task.h>
260 #include <mail_conf.h>
261 #include <mail_params.h>
262 #include <mail_version.h>
263 #include <mail_queue.h>
264 #include <mail_open_ok.h>
266 /* Application-specific. */
268 #define MAX_TEMP_AGE (60 * 60 * 24) /* temp file maximal age */
269 #define STR vstring_str /* silly little macro */
271 #define ACTION_STRUCT (1<<0) /* fix file organization */
272 #define ACTION_PURGE (1<<1) /* purge old temp files */
273 #define ACTION_DELETE_ONE (1<<2) /* delete named queue file(s) */
274 #define ACTION_DELETE_ALL (1<<3) /* delete all queue file(s) */
275 #define ACTION_REQUEUE_ONE (1<<4) /* requeue named queue file(s) */
276 #define ACTION_REQUEUE_ALL (1<<5) /* requeue all queue file(s) */
277 #define ACTION_HOLD_ONE (1<<6) /* put named queue file(s) on hold */
278 #define ACTION_HOLD_ALL (1<<7) /* put all messages on hold */
279 #define ACTION_RELEASE_ONE (1<<8) /* release named queue file(s) */
280 #define ACTION_RELEASE_ALL (1<<9) /* release all "on hold" mail */
282 #define ACTION_DEFAULT (ACTION_STRUCT | ACTION_PURGE)
285 * Actions that operate on individually named queue files. These must never
286 * be done when queue file names are changed to match their inode number.
288 #define ACTIONS_BY_QUEUE_ID (ACTION_DELETE_ONE | ACTION_REQUEUE_ONE \
289 | ACTION_HOLD_ONE | ACTION_RELEASE_ONE)
292 * Mass rename operations that are postponed to a second pass after queue
293 * file names are changed to match their inode number.
295 #define ACTIONS_AFTER_INUM_FIX (ACTION_REQUEUE_ALL | ACTION_HOLD_ALL \
296 | ACTION_RELEASE_ALL)
299 * Information about queue directories and what we expect to do there. If a
300 * file has unexpected owner permissions and is older than some threshold,
301 * the file is discarded. We don't step into maildrop subdirectories - if
302 * maildrop is writable, we might end up in the wrong place, deleting the
306 char *name
; /* directory name */
307 int perms
; /* expected permissions */
308 int flags
; /* see below */
311 #define RECURSE (1<<0) /* step into subdirectories */
312 #define DONT_RECURSE 0 /* don't step into directories */
314 static struct queue_info queue_info
[] = {
315 MAIL_QUEUE_MAILDROP
, MAIL_QUEUE_STAT_READY
, DONT_RECURSE
,
316 MAIL_QUEUE_INCOMING
, MAIL_QUEUE_STAT_READY
, RECURSE
,
317 MAIL_QUEUE_ACTIVE
, MAIL_QUEUE_STAT_READY
, RECURSE
,
318 MAIL_QUEUE_DEFERRED
, MAIL_QUEUE_STAT_READY
, RECURSE
,
319 MAIL_QUEUE_HOLD
, MAIL_QUEUE_STAT_READY
, RECURSE
,
320 MAIL_QUEUE_TRACE
, 0600, RECURSE
,
321 MAIL_QUEUE_DEFER
, 0600, RECURSE
,
322 MAIL_QUEUE_BOUNCE
, 0600, RECURSE
,
323 MAIL_QUEUE_FLUSH
, 0600, RECURSE
,
328 * Directories with per-message meta files.
330 const char *log_queue_names
[] = {
338 * Cruft that we append to a file name when a queue ID is named after the
339 * message file inode number. This cruft must not pass mail_queue_id_ok() so
340 * that the queue manager will ignore it, should people be so unwise as to
341 * run this operation on a live mail system.
343 #define SUFFIX "#FIX"
347 * Grr. These counters are global, because C only has clumsy ways to return
348 * multiple results from a function.
350 static int message_requeued
= 0; /* requeued messages */
351 static int message_held
= 0; /* messages put on hold */
352 static int message_released
= 0; /* messages released from hold */
353 static int message_deleted
= 0; /* deleted messages */
354 static int inode_fixed
= 0; /* queue id matched to inode number */
355 static int inode_mismatch
= 0; /* queue id inode mismatch */
356 static int position_mismatch
= 0; /* file position mismatch */
359 * Silly little macros. These translate arcane expressions into something
360 * more at a conceptual level.
362 #define MESSAGE_QUEUE(qp) ((qp)->perms == MAIL_QUEUE_STAT_READY)
363 #define READY_MESSAGE(st) (((st).st_mode & S_IRWXU) == MAIL_QUEUE_STAT_READY)
365 /* find_queue_info - look up expected permissions field by queue name */
367 static struct queue_info
*find_queue_info(const char *queue_name
)
369 struct queue_info
*qp
;
371 for (qp
= queue_info
; qp
->name
; qp
++)
372 if (strcmp(queue_name
, qp
->name
) == 0)
374 msg_fatal("invalid directory name: %s", queue_name
);
377 /* postremove - remove file with extreme prejudice */
379 static int postremove(const char *path
)
383 if ((ret
= remove(path
)) < 0) {
385 msg_fatal("remove file %s: %m", path
);
388 msg_info("removed file %s", path
);
393 /* postrename - rename file with extreme prejudice */
395 static int postrename(const char *old
, const char *new)
399 if ((ret
= sane_rename(old
, new)) < 0) {
401 || mail_queue_mkdirs(new) < 0
402 || sane_rename(old
, new) < 0)
404 msg_fatal("rename file %s as %s: %m", old
, new);
407 msg_info("renamed file %s as %s", old
, new);
412 /* postrmdir - remove directory with extreme prejudice */
414 static int postrmdir(const char *path
)
418 if ((ret
= rmdir(path
)) < 0) {
420 msg_fatal("remove directory %s: %m", path
);
423 msg_info("remove directory %s", path
);
428 /* delete_one - delete one message instance and all its associated files */
430 static int delete_one(const char **queue_names
, const char *queue_id
)
433 const char **msg_qpp
;
434 const char **log_qpp
;
435 const char *msg_path
;
436 VSTRING
*log_path_buf
;
441 * Sanity check. No early returns beyond this point.
443 if (!mail_queue_id_ok(queue_id
)) {
444 msg_warn("invalid mail queue id: %s", queue_id
);
447 log_path_buf
= vstring_alloc(100);
450 * Skip meta file directories. Delete trace/defer/bounce logfiles before
451 * deleting the corresponding message file, and only if the message file
452 * exists. This minimizes but does not eliminate a race condition with
453 * queue ID reuse which results in deleting the wrong files.
455 for (found
= 0, tries
= 0; found
== 0 && tries
< 2; tries
++) {
456 for (msg_qpp
= queue_names
; *msg_qpp
!= 0; msg_qpp
++) {
457 if (!MESSAGE_QUEUE(find_queue_info(*msg_qpp
)))
459 if (mail_open_ok(*msg_qpp
, queue_id
, &st
, &msg_path
) != MAIL_OPEN_YES
)
461 for (log_qpp
= log_queue_names
; *log_qpp
!= 0; log_qpp
++)
462 postremove(mail_queue_path(log_path_buf
, *log_qpp
, queue_id
));
463 if (postremove(msg_path
) == 0) {
465 msg_info("%s: removed", queue_id
);
467 } /* else: maybe lost a race */
470 vstring_free(log_path_buf
);
474 /* requeue_one - requeue one message instance and delete its logfiles */
476 static int requeue_one(const char **queue_names
, const char *queue_id
)
479 const char **msg_qpp
;
480 const char *old_path
;
481 VSTRING
*new_path_buf
;
487 * Sanity check. No early returns beyond this point.
489 if (!mail_queue_id_ok(queue_id
)) {
490 msg_warn("invalid mail queue id: %s", queue_id
);
493 new_path_buf
= vstring_alloc(100);
496 * Skip meta file directories. Like the mass requeue operation, we not
497 * delete defer or bounce logfiles, to avoid losing a race where the
498 * queue manager decides to bounce mail after all recipients have been
501 for (found
= 0, tries
= 0; found
== 0 && tries
< 2; tries
++) {
502 for (msg_qpp
= queue_names
; *msg_qpp
!= 0; msg_qpp
++) {
503 if (strcmp(*msg_qpp
, MAIL_QUEUE_MAILDROP
) == 0)
505 if (!MESSAGE_QUEUE(find_queue_info(*msg_qpp
)))
507 if (mail_open_ok(*msg_qpp
, queue_id
, &st
, &old_path
) != MAIL_OPEN_YES
)
509 (void) mail_queue_path(new_path_buf
, MAIL_QUEUE_MAILDROP
, queue_id
);
510 if (postrename(old_path
, STR(new_path_buf
)) == 0) {
511 tbuf
.actime
= tbuf
.modtime
= time((time_t *) 0);
512 if (utime(STR(new_path_buf
), &tbuf
) < 0)
513 msg_warn("%s: reset time stamps: %m", STR(new_path_buf
));
514 msg_info("%s: requeued", queue_id
);
517 } /* else: maybe lost a race */
520 vstring_free(new_path_buf
);
524 /* hold_one - put "on hold" one message instance */
526 static int hold_one(const char **queue_names
, const char *queue_id
)
529 const char **msg_qpp
;
530 const char *old_path
;
531 VSTRING
*new_path_buf
;
536 * Sanity check. No early returns beyond this point.
538 if (!mail_queue_id_ok(queue_id
)) {
539 msg_warn("invalid mail queue id: %s", queue_id
);
542 new_path_buf
= vstring_alloc(100);
545 * Skip meta file directories. Like the mass requeue operation, we not
546 * delete defer or bounce logfiles, to avoid losing a race where the
547 * queue manager decides to bounce mail after all recipients have been
550 * XXX We must not put maildrop mail on hold because that would mix already
551 * sanitized mail with mail that still needs to be sanitized.
553 for (found
= 0, tries
= 0; found
== 0 && tries
< 2; tries
++) {
554 for (msg_qpp
= queue_names
; *msg_qpp
!= 0; msg_qpp
++) {
555 if (strcmp(*msg_qpp
, MAIL_QUEUE_MAILDROP
) == 0)
557 if (strcmp(*msg_qpp
, MAIL_QUEUE_HOLD
) == 0)
559 if (!MESSAGE_QUEUE(find_queue_info(*msg_qpp
)))
561 if (mail_open_ok(*msg_qpp
, queue_id
, &st
, &old_path
) != MAIL_OPEN_YES
)
563 (void) mail_queue_path(new_path_buf
, MAIL_QUEUE_HOLD
, queue_id
);
564 if (postrename(old_path
, STR(new_path_buf
)) == 0) {
565 msg_info("%s: placed on hold", queue_id
);
568 } /* else: maybe lost a race */
571 vstring_free(new_path_buf
);
575 /* release_one - release one message instance that was placed "on hold" */
577 static int release_one(const char **queue_names
, const char *queue_id
)
580 const char **msg_qpp
;
581 const char *old_path
;
582 VSTRING
*new_path_buf
;
586 * Sanity check. No early returns beyond this point.
588 if (!mail_queue_id_ok(queue_id
)) {
589 msg_warn("invalid mail queue id: %s", queue_id
);
592 new_path_buf
= vstring_alloc(100);
595 * Skip inapplicable directories. This can happen when -H is combined
596 * with other operations.
599 for (msg_qpp
= queue_names
; *msg_qpp
!= 0; msg_qpp
++) {
600 if (strcmp(*msg_qpp
, MAIL_QUEUE_HOLD
) != 0)
602 if (mail_open_ok(*msg_qpp
, queue_id
, &st
, &old_path
) != MAIL_OPEN_YES
)
604 (void) mail_queue_path(new_path_buf
, MAIL_QUEUE_DEFERRED
, queue_id
);
605 if (postrename(old_path
, STR(new_path_buf
)) == 0) {
606 msg_info("%s: released from hold", queue_id
);
611 vstring_free(new_path_buf
);
615 /* operate_stream - operate on queue IDs given on stream */
617 static int operate_stream(VSTREAM
*fp
,
618 int (*operator) (const char **, const char *),
621 VSTRING
*buf
= vstring_alloc(20);
624 while (vstring_get_nonl(buf
, fp
) != VSTREAM_EOF
)
625 found
+= operator(queues
, STR(buf
));
631 /* fix_queue_id - make message queue ID match inode number */
633 static int fix_queue_id(const char *actual_path
, const char *actual_queue
,
634 const char *actual_id
, ino_t inum
)
636 VSTRING
*old_path
= vstring_alloc(10);
637 VSTRING
*new_path
= vstring_alloc(10);
638 VSTRING
*new_id
= vstring_alloc(10);
639 const char **log_qpp
;
643 * Create the new queue ID from the existing time digits and from the new
644 * inode number. Since we are renaming multiple files, the new name must
645 * be deterministic so that we can recover even when the renaming
646 * operation is interrupted in the middle.
648 vstring_sprintf(new_id
, "%.5s%lX", actual_id
, (unsigned long) inum
);
651 * Rename logfiles before renaming the message file, so that we can
652 * recover when a previous attempt was interrupted.
654 for (log_qpp
= log_queue_names
; *log_qpp
; log_qpp
++) {
655 mail_queue_path(old_path
, *log_qpp
, actual_id
);
656 mail_queue_path(new_path
, *log_qpp
, STR(new_id
));
657 vstring_strcat(new_path
, SUFFIX
);
658 postrename(STR(old_path
), STR(new_path
));
662 * Rename the message file last, so that we know that we are done with
663 * this message and with all its logfiles.
665 mail_queue_path(new_path
, actual_queue
, STR(new_id
));
666 vstring_strcat(new_path
, SUFFIX
);
667 ret
= postrename(actual_path
, STR(new_path
));
672 vstring_free(old_path
);
673 vstring_free(new_path
);
674 vstring_free(new_id
);
679 /* super - check queue structure, clean up, do wild-card operations */
681 static void super(const char **queues
, int action
)
683 ARGV
*hash_queue_names
= argv_split(var_hash_queue_names
, " \t\r\n,");
684 VSTRING
*actual_path
= vstring_alloc(10);
685 VSTRING
*wanted_path
= vstring_alloc(10);
687 const char *queue_name
;
693 struct queue_info
*qp
;
697 * Make sure every file is in the right place, clean out stale files, and
698 * remove non-file/non-directory objects.
700 while ((queue_name
= *queues
++) != 0) {
703 msg_info("queue: %s", queue_name
);
706 * Look up queue-specific properties: desired hashing depth, what
707 * file permissions to look for, and whether or not it is desirable
708 * to step into subdirectories.
710 qp
= find_queue_info(queue_name
);
711 for (cpp
= hash_queue_names
->argv
; /* void */ ; cpp
++) {
716 if (strcmp(*cpp
, queue_name
) == 0) {
717 wanted_depth
= var_hash_queue_depth
;
723 * Sanity check. Some queues just cannot be recursive.
725 if (wanted_depth
> 0 && (qp
->flags
& RECURSE
) == 0)
726 msg_fatal("%s queue must not be hashed", queue_name
);
729 * Other per-directory initialization.
731 info
= scan_dir_open(queue_name
);
737 * If we reach the end of a subdirectory, return to its parent.
738 * Delete subdirectories that are no longer needed.
740 if ((path
= scan_dir_next(info
)) == 0) {
741 if (actual_depth
== 0)
743 if (actual_depth
> wanted_depth
)
744 postrmdir(scan_dir_path(info
));
751 * If we stumble upon a subdirectory, enter it, if it is
752 * considered safe to do so. Otherwise, try to remove the
753 * subdirectory at a later stage.
755 if (strlen(path
) == 1 && (qp
->flags
& RECURSE
) != 0) {
757 scan_dir_push(info
, path
);
762 * From here on we need to keep track of operations that
763 * invalidate or revalidate the actual_path and path variables,
764 * otherwise we can hit the wrong files.
766 vstring_sprintf(actual_path
, "%s/%s", scan_dir_path(info
), path
);
767 if (stat(STR(actual_path
), &st
) < 0)
771 * Remove alien directories. If maildrop is compromised, then we
772 * cannot abort just because we cannot remove someone's
775 if (S_ISDIR(st
.st_mode
)) {
776 if (rmdir(STR(actual_path
)) < 0) {
778 msg_warn("remove subdirectory %s: %m", STR(actual_path
));
781 msg_info("remove subdirectory %s", STR(actual_path
));
783 /* No further work on this object is possible. */
788 * Mass deletion. We count the deletion of mail that this system
789 * has taken responsibility for. XXX This option does not use
790 * mail_queue_remove(), so that it can avoid having to first move
791 * queue files to the "right" subdirectory level.
793 if (action
& ACTION_DELETE_ALL
) {
794 if (postremove(STR(actual_path
)) == 0)
795 if (MESSAGE_QUEUE(qp
) && READY_MESSAGE(st
))
797 /* No further work on this object is possible. */
802 * Remove non-file objects and old temporary files. Be careful
803 * not to delete bounce or defer logs just because they are more
804 * than a couple days old.
806 if (!S_ISREG(st
.st_mode
)
807 || ((action
& ACTION_PURGE
) != 0
809 && !READY_MESSAGE(st
)
810 && time((time_t *) 0) > st
.st_mtime
+ MAX_TEMP_AGE
)) {
811 (void) postremove(STR(actual_path
));
812 /* No further work on this object is possible. */
817 * Fix queueid#FIX names that were left from a previous pass over
818 * the queue where message queue file names were matched to their
819 * inode number. We strip the suffix and move the file into the
820 * proper subdirectory level. Make sure that the name minus
821 * suffix is well formed and that the name matches the file inode
824 if ((action
& ACTION_STRUCT
)
825 && strcmp(path
+ (strlen(path
) - SUFFIX_LEN
), SUFFIX
) == 0) {
826 path
[strlen(path
) - SUFFIX_LEN
] = 0; /* XXX */
827 if (!mail_queue_id_ok(path
)) {
828 msg_warn("bogus file name: %s", STR(actual_path
));
831 if (MESSAGE_QUEUE(qp
)) {
832 if (sscanf(path
+ 5, "%lx", &inum
) != 1) {
833 msg_warn("bogus file name: %s", STR(actual_path
));
836 if (inum
!= (unsigned long) st
.st_ino
) {
837 msg_warn("name/inode mismatch: %s", STR(actual_path
));
841 (void) mail_queue_path(wanted_path
, queue_name
, path
);
842 if (postrename(STR(actual_path
), STR(wanted_path
)) < 0) {
843 /* No further work on this object is possible. */
846 if (MESSAGE_QUEUE(qp
))
848 vstring_strcpy(actual_path
, STR(wanted_path
));
849 /* At this point, path and actual_path are revalidated. */
854 * Skip over files with illegal names. The library routines
855 * refuse to operate on them.
857 if (!mail_queue_id_ok(path
)) {
858 msg_warn("bogus file name: %s", STR(actual_path
));
863 * See if the file name matches the file inode number. Skip meta
864 * file directories. This option requires that meta files be put
865 * into their proper place before queue files, so that we can
866 * rename queue files and meta files at the same time. Mis-named
867 * files are renamed to newqueueid#FIX on the first pass, and
868 * upon the second pass the #FIX is stripped off the name. Of
869 * course we have to be prepared that the program is interrupted
870 * before it completes, so any left-over newqueueid#FIX files
871 * have to be handled properly. XXX This option cannot use
872 * mail_queue_rename(), because the queue file name violates
873 * normal queue file syntax.
875 if ((action
& ACTION_STRUCT
) != 0 && MESSAGE_QUEUE(qp
)) {
876 if (sscanf(path
+ 5, "%lx", &inum
) != 1) {
877 msg_warn("bogus file name: %s", STR(actual_path
));
880 if (inum
!= (unsigned long) st
.st_ino
) {
881 inode_mismatch
++; /* before we fix */
882 action
&= ~ACTIONS_AFTER_INUM_FIX
;
883 fix_queue_id(STR(actual_path
), queue_name
, path
, st
.st_ino
);
884 /* At this point, path and actual_path are invalidated. */
890 * Mass requeuing. The pickup daemon will copy requeued mail to a
891 * new queue file, so that address rewriting is applied again.
892 * XXX This option does not use mail_queue_rename(), so that it
893 * can avoid having to first move queue files to the "right"
894 * subdirectory level. Like the requeue_one() routine, this code
895 * does not touch logfiles.
897 if ((action
& ACTION_REQUEUE_ALL
)
899 && strcmp(queue_name
, MAIL_QUEUE_MAILDROP
) != 0) {
900 (void) mail_queue_path(wanted_path
, MAIL_QUEUE_MAILDROP
, path
);
901 if (postrename(STR(actual_path
), STR(wanted_path
)) == 0)
903 /* At this point, path and actual_path are invalidated. */
908 * Mass renaming to the "on hold" queue. XXX This option does not
909 * use mail_queue_rename(), so that it can avoid having to first
910 * move queue files to the "right" subdirectory level. Like the
911 * hold_one() routine, this code does not touch logfiles, and
912 * must not touch files in the maildrop queue, because maildrop
913 * files contain data that has not yet been sanitized and
914 * therefore must not be mixed with already sanitized mail.
916 if ((action
& ACTION_HOLD_ALL
)
918 && strcmp(queue_name
, MAIL_QUEUE_MAILDROP
) != 0
919 && strcmp(queue_name
, MAIL_QUEUE_HOLD
) != 0) {
920 (void) mail_queue_path(wanted_path
, MAIL_QUEUE_HOLD
, path
);
921 if (postrename(STR(actual_path
), STR(wanted_path
)) == 0)
923 /* At this point, path and actual_path are invalidated. */
928 * Mass release from the "on hold" queue. XXX This option does
929 * not use mail_queue_rename(), so that it can avoid having to
930 * first move queue files to the "right" subdirectory level. Like
931 * the release_one() routine, this code must not touch logfiles.
933 if ((action
& ACTION_RELEASE_ALL
)
934 && strcmp(queue_name
, MAIL_QUEUE_HOLD
) == 0) {
935 (void) mail_queue_path(wanted_path
, MAIL_QUEUE_DEFERRED
, path
);
936 if (postrename(STR(actual_path
), STR(wanted_path
)) == 0)
938 /* At this point, path and actual_path are invalidated. */
943 * See if this file sits in the right place in the file system
944 * hierarchy. Its place may be wrong after a change to the
945 * hash_queue_{names,depth} parameter settings. This requires
946 * that the bounce/defer logfiles be at the right subdirectory
947 * level first, otherwise we would fail to properly rename
948 * bounce/defer logfiles.
950 if (action
& ACTION_STRUCT
) {
951 (void) mail_queue_path(wanted_path
, queue_name
, path
);
952 if (strcmp(STR(actual_path
), STR(wanted_path
)) != 0) {
953 position_mismatch
++; /* before we fix */
954 (void) postrename(STR(actual_path
), STR(wanted_path
));
955 /* At this point, path and actual_path are invalidated. */
960 scan_dir_close(info
);
966 vstring_free(wanted_path
);
967 vstring_free(actual_path
);
968 argv_free(hash_queue_names
);
971 /* interrupted - signal handler */
973 static void interrupted(int sig
)
977 * This commands requires root privileges. We therefore do not worry
978 * about hostile signals, and report problems via msg_warn().
980 * We use the in-kernel SIGINT handler address as an atomic variable to
981 * prevent nested interrupted() calls. For this reason, main() must
982 * configure interrupted() as SIGINT handler before other signal handlers
983 * are allowed to invoke interrupted(). See also similar code in
986 if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
) {
987 (void) signal(SIGQUIT
, SIG_IGN
);
988 (void) signal(SIGTERM
, SIG_IGN
);
989 (void) signal(SIGHUP
, SIG_IGN
);
990 if (inode_mismatch
> 0 || inode_fixed
> 0 || position_mismatch
> 0)
991 msg_warn("OPERATION INCOMPLETE -- RERUN COMMAND TO FIX THE QUEUE FIRST");
997 /* fatal_warning - print warning if queue fix is incomplete */
999 static void fatal_warning(void)
1004 MAIL_VERSION_STAMP_DECLARE
;
1006 int main(int argc
, char **argv
)
1012 const char **queues
;
1014 ARGV
*requeue_names
= 0;
1015 ARGV
*delete_names
= 0;
1016 ARGV
*hold_names
= 0;
1017 ARGV
*release_names
= 0;
1021 * Defaults. The structural checks must fix the directory levels of "log
1022 * file" directories (bounce, defer) before doing structural checks on
1023 * the "message file" directories, so that we can find the logfiles in
1024 * the right place when message files need to be renamed to match their
1027 static char *default_queues
[] = {
1028 MAIL_QUEUE_DEFER
, /* before message directories */
1029 MAIL_QUEUE_BOUNCE
, /* before message directories */
1030 MAIL_QUEUE_MAILDROP
,
1031 MAIL_QUEUE_INCOMING
,
1033 MAIL_QUEUE_DEFERRED
,
1038 static char *default_hold_queues
[] = {
1039 MAIL_QUEUE_INCOMING
,
1041 MAIL_QUEUE_DEFERRED
,
1044 static char *default_release_queues
[] = {
1050 * Fingerprint executables and core dumps.
1052 MAIL_VERSION_STAMP_ALLOCATE
;
1055 * Be consistent with file permissions.
1060 * To minimize confusion, make sure that the standard file descriptors
1061 * are open before opening anything else. XXX Work around for 44BSD where
1062 * fstat can return EBADF on an open file descriptor.
1064 for (fd
= 0; fd
< 3; fd
++)
1065 if (fstat(fd
, &st
) == -1
1066 && (close(fd
), open("/dev/null", O_RDWR
, 0)) != fd
)
1067 msg_fatal("open /dev/null: %m");
1070 * Process this environment option as early as we can, to aid debugging.
1072 if (safe_getenv(CONF_ENV_VERB
))
1076 * Initialize logging.
1078 if ((slash
= strrchr(argv
[0], '/')) != 0 && slash
[1])
1079 argv
[0] = slash
+ 1;
1080 msg_vstream_init(argv
[0], VSTREAM_ERR
);
1081 msg_syslog_init(mail_task(argv
[0]), LOG_PID
, LOG_FACILITY
);
1082 set_mail_conf_str(VAR_PROCNAME
, var_procname
= mystrdup(argv
[0]));
1085 * Disallow unsafe practices, and refuse to run set-uid (or as the child
1086 * of a set-uid process). Whenever a privileged wrapper program is
1087 * needed, it must properly sanitize the real/effective/saved UID/GID,
1088 * the secondary groups, the process environment, and so on. Otherwise,
1089 * accidents can happen. If not with Postfix, then with other software.
1092 msg_fatal("this postfix command must not run as a set-uid process");
1094 msg_fatal("use of this command is reserved for the superuser");
1099 while ((c
= GETOPT(argc
, argv
, "c:d:h:H:pr:sv")) > 0) {
1102 msg_fatal("usage: %s "
1104 "[-d queue_id (delete)] "
1105 "[-h queue_id (hold)] [-H queue_id (un-hold)] "
1106 "[-p (purge temporary files)] [-r queue_id (requeue)] "
1107 "[-s (structure fix)] [-v (verbose)] "
1108 "[queue...]", argv
[0]);
1111 msg_fatal("-c requires absolute pathname");
1112 if (setenv(CONF_ENV_PATH
, optarg
, 1) < 0)
1113 msg_fatal("setenv: %m");
1116 if (delete_names
== 0)
1117 delete_names
= argv_alloc(1);
1118 argv_add(delete_names
, optarg
, (char *) 0);
1119 action
|= (strcmp(optarg
, "ALL") == 0 ?
1120 ACTION_DELETE_ALL
: ACTION_DELETE_ONE
);
1123 if (hold_names
== 0)
1124 hold_names
= argv_alloc(1);
1125 argv_add(hold_names
, optarg
, (char *) 0);
1126 action
|= (strcmp(optarg
, "ALL") == 0 ?
1127 ACTION_HOLD_ALL
: ACTION_HOLD_ONE
);
1130 if (release_names
== 0)
1131 release_names
= argv_alloc(1);
1132 argv_add(release_names
, optarg
, (char *) 0);
1133 action
|= (strcmp(optarg
, "ALL") == 0 ?
1134 ACTION_RELEASE_ALL
: ACTION_RELEASE_ONE
);
1137 action
|= ACTION_PURGE
;
1140 if (requeue_names
== 0)
1141 requeue_names
= argv_alloc(1);
1142 argv_add(requeue_names
, optarg
, (char *) 0);
1143 action
|= (strcmp(optarg
, "ALL") == 0 ?
1144 ACTION_REQUEUE_ALL
: ACTION_REQUEUE_ONE
);
1147 action
|= ACTION_STRUCT
;
1156 * Read the global configuration file and extract configuration
1157 * information. The -c command option can override the default
1158 * configuration directory location.
1161 if (strcmp(var_syslog_name
, DEF_SYSLOG_NAME
) != 0)
1162 msg_syslog_init(mail_task(argv
[0]), LOG_PID
, LOG_FACILITY
);
1163 if (chdir(var_queue_dir
))
1164 msg_fatal("chdir %s: %m", var_queue_dir
);
1167 * All file/directory updates must be done as the mail system owner. This
1168 * is because Postfix daemons manipulate the queue with those same
1169 * privileges, so directories must be created with the right ownership.
1171 * Running as a non-root user is also required for security reasons. When
1172 * the Postfix queue hierarchy is compromised, an attacker could trick us
1173 * into entering other file hierarchies and afflicting damage. Running as
1174 * a non-root user limits the damage to the already compromised mail
1177 set_ugid(var_owner_uid
, var_owner_gid
);
1180 * Be sure to log a warning if we do not finish structural repair. Maybe
1181 * we should have an fsck-style "clean" flag so Postfix will not start
1182 * with a broken queue.
1184 * Set up signal handlers after permanently dropping super-user privileges,
1185 * so that signal handlers will always run with the correct privileges.
1187 * XXX Don't enable SIGHUP or SIGTERM if it was ignored by the parent.
1189 * interrupted() uses the in-kernel SIGINT handler address as an atomic
1190 * variable to prevent nested interrupted() calls. For this reason, the
1191 * SIGINT handler must be configured before other signal handlers are
1192 * allowed to invoke interrupted(). See also similar code in postdrop.
1194 signal(SIGINT
, interrupted
);
1195 signal(SIGQUIT
, interrupted
);
1196 if (signal(SIGTERM
, SIG_IGN
) == SIG_DFL
)
1197 signal(SIGTERM
, interrupted
);
1198 if (signal(SIGHUP
, SIG_IGN
) == SIG_DFL
)
1199 signal(SIGHUP
, interrupted
);
1200 msg_cleanup(fatal_warning
);
1205 if ((action
& ACTION_DELETE_ALL
) && (action
& ACTION_DELETE_ONE
)) {
1206 msg_warn("option \"-d ALL\" will ignore other command line queue IDs");
1207 action
&= ~ACTION_DELETE_ONE
;
1209 if ((action
& ACTION_REQUEUE_ALL
) && (action
& ACTION_REQUEUE_ONE
)) {
1210 msg_warn("option \"-r ALL\" will ignore other command line queue IDs");
1211 action
&= ~ACTION_REQUEUE_ONE
;
1213 if ((action
& ACTION_HOLD_ALL
) && (action
& ACTION_HOLD_ONE
)) {
1214 msg_warn("option \"-h ALL\" will ignore other command line queue IDs");
1215 action
&= ~ACTION_HOLD_ONE
;
1217 if ((action
& ACTION_RELEASE_ALL
) && (action
& ACTION_RELEASE_ONE
)) {
1218 msg_warn("option \"-H ALL\" will ignore other command line queue IDs");
1219 action
&= ~ACTION_RELEASE_ONE
;
1223 * Execute the explicitly specified (or default) action, on the
1224 * explicitly specified (or default) queues.
1226 * XXX Work around gcc const brain damage.
1228 * XXX The file name/inode number fix should always run over all message
1229 * file directories, and should always be preceded by a subdirectory
1230 * level check of the bounce and defer logfile directories.
1233 action
= ACTION_DEFAULT
;
1234 if (argv
[optind
] != 0)
1235 queues
= (const char **) argv
+ optind
;
1236 else if (action
== ACTION_HOLD_ALL
)
1237 queues
= (const char **) default_hold_queues
;
1238 else if (action
== ACTION_RELEASE_ALL
)
1239 queues
= (const char **) default_release_queues
;
1241 queues
= (const char **) default_queues
;
1244 * Basic queue maintenance, as well as mass deletion, mass requeuing, and
1245 * mass name-to-inode fixing. This ensures that queue files are in the
1246 * right place before the file-by-name operations are done.
1248 if (action
& ~ACTIONS_BY_QUEUE_ID
)
1249 super(queues
, action
);
1252 * If any file names needed changing to match the message file inode
1253 * number, those files were named newqeueid#FIX. We need a second pass to
1254 * strip the suffix from the new queue ID, and to complete any requested
1255 * operations that had to be skipped in the first pass.
1257 if (inode_mismatch
> 0)
1258 super(queues
, action
);
1261 * Don't do actions by queue file name if any queue files changed name
1262 * because they did not match the queue file inode number. We could be
1263 * acting on the wrong queue file and lose mail.
1265 if ((action
& ACTIONS_BY_QUEUE_ID
)
1266 && (inode_mismatch
> 0 || inode_fixed
> 0)) {
1267 msg_error("QUEUE FILE NAMES WERE CHANGED TO MATCH INODE NUMBERS");
1268 msg_fatal("CHECK YOUR QUEUE IDS AND RE-ISSUE THE COMMAND");
1272 * Delete queue files by name. This must not be done when queue file
1273 * names have changed names as a result of inode number mismatches,
1274 * because we could be deleting the wrong message.
1276 if (action
& ACTION_DELETE_ONE
) {
1277 argv_terminate(delete_names
);
1278 queues
= (const char **)
1279 (argv
[optind
] ? argv
+ optind
: default_queues
);
1280 for (cpp
= delete_names
->argv
; *cpp
; cpp
++) {
1281 if (strcmp(*cpp
, "ALL") == 0)
1283 if (strcmp(*cpp
, "-") == 0)
1285 operate_stream(VSTREAM_IN
, delete_one
, queues
);
1287 message_deleted
+= delete_one(queues
, *cpp
);
1292 * Requeue queue files by name. This must not be done when queue file
1293 * names have changed names as a result of inode number mismatches,
1294 * because we could be requeuing the wrong message.
1296 if (action
& ACTION_REQUEUE_ONE
) {
1297 argv_terminate(requeue_names
);
1298 queues
= (const char **)
1299 (argv
[optind
] ? argv
+ optind
: default_queues
);
1300 for (cpp
= requeue_names
->argv
; *cpp
; cpp
++) {
1301 if (strcmp(*cpp
, "ALL") == 0)
1303 if (strcmp(*cpp
, "-") == 0)
1305 operate_stream(VSTREAM_IN
, requeue_one
, queues
);
1307 message_requeued
+= requeue_one(queues
, *cpp
);
1312 * Put on hold queue files by name. This must not be done when queue file
1313 * names have changed names as a result of inode number mismatches,
1314 * because we could put on hold the wrong message.
1316 if (action
& ACTION_HOLD_ONE
) {
1317 argv_terminate(hold_names
);
1318 queues
= (const char **)
1319 (argv
[optind
] ? argv
+ optind
: default_hold_queues
);
1320 for (cpp
= hold_names
->argv
; *cpp
; cpp
++) {
1321 if (strcmp(*cpp
, "ALL") == 0)
1323 if (strcmp(*cpp
, "-") == 0)
1325 operate_stream(VSTREAM_IN
, hold_one
, queues
);
1327 message_held
+= hold_one(queues
, *cpp
);
1332 * Take "off hold" queue files by name. This must not be done when queue
1333 * file names have changed names as a result of inode number mismatches,
1334 * because we could take off hold the wrong message.
1336 if (action
& ACTION_RELEASE_ONE
) {
1337 argv_terminate(release_names
);
1338 queues
= (const char **)
1339 (argv
[optind
] ? argv
+ optind
: default_release_queues
);
1340 for (cpp
= release_names
->argv
; *cpp
; cpp
++) {
1341 if (strcmp(*cpp
, "ALL") == 0)
1343 if (strcmp(*cpp
, "-") == 0)
1345 operate_stream(VSTREAM_IN
, release_one
, queues
);
1347 message_released
+= release_one(queues
, *cpp
);
1354 if (message_requeued
> 0)
1355 msg_info("Requeued: %d message%s", message_requeued
,
1356 message_requeued
> 1 ? "s" : "");
1357 if (message_deleted
> 0)
1358 msg_info("Deleted: %d message%s", message_deleted
,
1359 message_deleted
> 1 ? "s" : "");
1360 if (message_held
> 0)
1361 msg_info("Placed on hold: %d message%s",
1362 message_held
, message_held
> 1 ? "s" : "");
1363 if (message_released
> 0)
1364 msg_info("Released from hold: %d message%s",
1365 message_released
, message_released
> 1 ? "s" : "");
1366 if (inode_fixed
> 0)
1367 msg_info("Renamed to match inode number: %d message%s", inode_fixed
,
1368 inode_fixed
> 1 ? "s" : "");
1369 if (inode_mismatch
> 0 || inode_fixed
> 0)
1370 msg_warn("QUEUE FILE NAMES WERE CHANGED TO MATCH INODE NUMBERS");
1376 argv_free(requeue_names
);
1378 argv_free(delete_names
);
1380 argv_free(hold_names
);
1382 argv_free(release_names
);