diff --git a/postfix/HISTORY b/postfix/HISTORY index 0e388c942..ac1b98e6a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -16685,6 +16685,22 @@ Apologies for any names omitted. src/global/dict_ldap.c src/global/cfg_parser.h src/global/cfg_parser.c. +20110320 + + Feature: specify "enable_long_queue_ids = yes" to enable + support for non-repeating queue IDs (also used as queue + file names). These queue IDs encode the time and inode + number with a safe alphabet of the 52 characters 0-9B-Zb-z. + The alphabet excludes vowels (AEIOUaeiou) to avoid creating + real words. The queue ID format is: time in seconds, time + in microseconds, 'z', inode number (the inode number is + encoded without using the 'z' character of the safe alphabet). + Turning on long queue IDs changes the width of the first + output column of the mailq (postqueue -p) command, and + changes the appearance of Postfix Message-ID headers to + queueID@myhostname. Files: global/file_id.[hc], + global/safe_ultostr.[hc], global/mail_queue.[hc], + postsuper/postsuper.c, showq/showq.c 20110311 Feature: Base 32 encoder/decoder per RFC 4648. This code @@ -16693,11 +16709,19 @@ Apologies for any names omitted. 20110313 - Bugfix (introduced Postfix 2.8): number the postscreen DNSBL - requests, so that delayed results for an old session are - not added to the score when the same remote SMTP client has - reconnected in the mean time. Files: postscreen/postscreen_dnsbl.c, - dnsblog/dnsblog.c. + Bugfix (introduced Postfix 2.8): postscreen DNSBL scoring + error. When a client disconnected and then reconnected + before all DNSBL results for the earlier session arrived, + DNSBL results for the earlier session would be added to the + score for the later session. Problem report by Larry Vaden. + Files: dnsblog/dnsblog.c, postscreen/postscreen_dnsbl.c. Cleanup: protocol description in dnsblog(8) manpage. File: dnsblog/dnsblog.c. + +20110314 + + Portability: the SUN compiler had trouble with a pointer + expression of the form ``("text1" "text2") + constant'' so + we don't try to be so clever. Fix by Victor Duchovni. File: + global/mail_params.h. diff --git a/postfix/README_FILES/POSTSCREEN_README b/postfix/README_FILES/POSTSCREEN_README index 4b68315a1..19df31b0a 100644 --- a/postfix/README_FILES/POSTSCREEN_README +++ b/postfix/README_FILES/POSTSCREEN_README @@ -604,8 +604,9 @@ Notes: * Some postscreen(8) configuration parameters implement stress-dependent behavior. This is supported only when the default value is stress-dependent - (that is, it looks like ${stress?X}${stress:Y}). Other parameters always - evaluate as if the stress value is the empty string. + (that is, "postconf -d parametername" output shows "parametername = $ + {stress?something}${stress:something}"). Other parameters always evaluate + as if the stress value is the empty string. * See "Tests before the 220 SMTP server greeting" for details about the logging from these postscreen(8) tests. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 01d988efb..b51bc4593 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -14,6 +14,47 @@ specifies the release date of a stable release or snapshot release. If you upgrade from Postfix 2.7 or earlier, read RELEASE_NOTES-2.8 before proceeding. +Incompatible changes with snapshot 20110320 +=========================================== + +If you enable support for long queue file names, you need to be +aware that these file names are not compatible with Postfix <= 2.8. +If you must migrate to Postfix <= 2.8, you must first convert all +long queue file names into short names, otherwise the old Postfix +version will complain. + +The conversion procedure before migration to Postfix <= 2.8 is: + + # postfix stop + # postconf enable_long_queue_ids=no + # postsuper + +Run the postsuper command repeatedly until it no longer reports +queue file name changes. + +Major changes with snapshot 20110320 +==================================== + +Support for long, non-repeating, queue IDs (queue file names). The +benefit of non-repeating names is simpler logfile analysis, and +easier queue migration (there is no need to run "postsuper" to +change queue file names that don't match their message file inode +number). + +Specify "enable_long_queue_ids = yes" to enable the feature. This +does not change the names of existing queue files. See postconf(5) +or postconf.5.html#enable_long_queue_ids for a detailed description +of the differences with the old short queue IDs. + +This changes new Postfix queue IDs from the short form 0FCEE9247A9 +into the longer form 3Ps0FS1Zhtz1PFjb, and changes new Message-ID +header values from YYMMDDHHMMSS.queueid@myhostname into the shorter +form queueid@myhostname. + +See the note on "Incompatible changes" for a backwards migration +procedure to convert long queue file names into a form that is +compatible with Postfix <= 2.8. + Incompatible changes with snapshot 20110313 =========================================== diff --git a/postfix/WISHLIST b/postfix/WISHLIST index fa63f559d..bf1570fd3 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -11,9 +11,6 @@ Wish list: Don't forget Apple's code donation for fetching mail from IMAP server. - Use queue ID (file name) based on inode number and enough - (time or random) bits to avoid repetition in 10+ years. - Simplify postscreen logic: set the noforward flag if the client made an unforgivable error. Individual "fail" flags are needed only to avoid logging the same offense multiple diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index 2264a2c75..ca28c9319 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -458,7 +458,12 @@ unknown_local_recipient_reject_code = 550 # the main.cf file, otherwise the SMTP server will reject mail for # non-UNIX accounts with "User unknown in local recipient table". # -#mailbox_transport = lmtp:unix:/file/name +# Cyrus IMAP over LMTP. Specify ``lmtpunix cmd="lmtpd" +# listen="/var/imap/socket/lmtp" prefork=0'' in cyrus.conf. +#mailbox_transport = lmtp:unix:/var/imap/socket/lmtp +# +# Cyrus IMAP via command line. Uncomment the "cyrus...pipe" and +# subsequent line in master.cf. #mailbox_transport = cyrus # The fallback_transport specifies the optional transport in master.cf diff --git a/postfix/html/POSTSCREEN_README.html b/postfix/html/POSTSCREEN_README.html index 369fbf2a8..d20d13672 100644 --- a/postfix/html/POSTSCREEN_README.html +++ b/postfix/html/POSTSCREEN_README.html @@ -837,7 +837,9 @@ Postfix version 2.8.

  • Some postscreen(8) configuration parameters implement stress-dependent behavior. This is supported only when the default -value is stress-dependent (that is, it looks like ${stress?X}${stress:Y}). +value is stress-dependent (that is, "postconf -d parametername" +output shows "parametername = +${stress?something}${stress:something}"). Other parameters always evaluate as if the stress value is the empty string.

    diff --git a/postfix/html/cleanup.8.html b/postfix/html/cleanup.8.html index 70e5e4098..1071b1efa 100644 --- a/postfix/html/cleanup.8.html +++ b/postfix/html/cleanup.8.html @@ -80,8 +80,7 @@ CLEANUP(8) CLEANUP(8) postconf(5) for more details including examples. COMPATIBILITY CONTROLS - undisclosed_recipients_header (To: undisclosed-recipi- - ents:;) + undisclosed_recipients_header (see 'postconf -d' output) Message header that the Postfix cleanup(8) server inserts when a message contains no To: or Cc: mes- sage header. @@ -103,41 +102,47 @@ CLEANUP(8) CLEANUP(8) Always add (Resent-) From:, To:, Date: or Message- ID: headers when not present. + Available in Postfix version 2.9 and later: + + enable_long_queue_ids (no) + Enable long, non-repeating, queue IDs (queue file + names). + BUILT-IN CONTENT FILTERING CONTROLS - Postfix built-in content filtering is meant to stop a - flood of worms or viruses. It is not a general content + Postfix built-in content filtering is meant to stop a + flood of worms or viruses. It is not a general content filter. body_checks (empty) - Optional lookup tables for content inspection as + Optional lookup tables for content inspection as specified in the body_checks(5) manual page. header_checks (empty) - Optional lookup tables for content inspection of - primary non-MIME message headers, as specified in + Optional lookup tables for content inspection of + primary non-MIME message headers, as specified in the header_checks(5) manual page. Available in Postfix version 2.0 and later: body_checks_size_limit (51200) How much text in a message body segment (or attach- - ment, if you prefer to use that term) is subjected + ment, if you prefer to use that term) is subjected to body_checks inspection. mime_header_checks ($header_checks) - Optional lookup tables for content inspection of - MIME related message headers, as described in the + Optional lookup tables for content inspection of + MIME related message headers, as described in the header_checks(5) manual page. nested_header_checks ($header_checks) - Optional lookup tables for content inspection of - non-MIME message headers in attached messages, as + Optional lookup tables for content inspection of + non-MIME message headers in attached messages, as described in the header_checks(5) manual page. Available in Postfix version 2.3 and later: message_reject_characters (empty) - The set of characters that Postfix will reject in + The set of characters that Postfix will reject in message content. message_strip_characters (empty) @@ -146,24 +151,24 @@ CLEANUP(8) CLEANUP(8) BEFORE QUEUE MILTER CONTROLS As of version 2.3, Postfix supports the Sendmail version 8 - Milter (mail filter) protocol. When mail is not received - via the smtpd(8) server, the cleanup(8) server will simu- - late SMTP events to the extent that this is possible. For + Milter (mail filter) protocol. When mail is not received + via the smtpd(8) server, the cleanup(8) server will simu- + late SMTP events to the extent that this is possible. For details see the MILTER_README document. non_smtpd_milters (empty) A list of Milter (mail filter) applications for new - mail that does not arrive via the Postfix smtpd(8) + mail that does not arrive via the Postfix smtpd(8) server. milter_protocol (6) - The mail filter protocol version and optional pro- - tocol extensions for communication with a Milter - application; prior to Postfix 2.6 the default pro- + The mail filter protocol version and optional pro- + tocol extensions for communication with a Milter + application; prior to Postfix 2.6 the default pro- tocol is 2. milter_default_action (tempfail) - The default action when a Milter (mail filter) + The default action when a Milter (mail filter) application is unavailable or mis-configured. milter_macro_daemon_name ($myhostname) @@ -175,62 +180,62 @@ CLEANUP(8) CLEANUP(8) cations. milter_connect_timeout (30s) - The time limit for connecting to a Milter (mail - filter) application, and for negotiating protocol + The time limit for connecting to a Milter (mail + filter) application, and for negotiating protocol options. milter_command_timeout (30s) - The time limit for sending an SMTP command to a + The time limit for sending an SMTP command to a Milter (mail filter) application, and for receiving the response. milter_content_timeout (300s) - The time limit for sending message content to a + The time limit for sending message content to a Milter (mail filter) application, and for receiving the response. milter_connect_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) - applications after completion of an SMTP connec- + The macros that are sent to Milter (mail filter) + applications after completion of an SMTP connec- tion. milter_helo_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) + The macros that are sent to Milter (mail filter) applications after the SMTP HELO or EHLO command. milter_mail_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) + The macros that are sent to Milter (mail filter) applications after the SMTP MAIL FROM command. milter_rcpt_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) + The macros that are sent to Milter (mail filter) applications after the SMTP RCPT TO command. milter_data_macros (see 'postconf -d' output) - The macros that are sent to version 4 or higher - Milter (mail filter) applications after the SMTP + The macros that are sent to version 4 or higher + Milter (mail filter) applications after the SMTP DATA command. milter_unknown_command_macros (see 'postconf -d' output) - The macros that are sent to version 3 or higher - Milter (mail filter) applications after an unknown + The macros that are sent to version 3 or higher + Milter (mail filter) applications after an unknown SMTP command. milter_end_of_data_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) + The macros that are sent to Milter (mail filter) applications after the message end-of-data. Available in Postfix version 2.5 and later: milter_end_of_header_macros (see 'postconf -d' output) - The macros that are sent to Milter (mail filter) + The macros that are sent to Milter (mail filter) applications after the end of the message header. Available in Postfix version 2.7 and later: milter_header_checks (empty) - Optional lookup tables for content inspection of - message headers that are produced by Milter appli- + Optional lookup tables for content inspection of + message headers that are produced by Milter appli- cations. MIME PROCESSING CONTROLS @@ -248,27 +253,27 @@ CLEANUP(8) CLEANUP(8) will handle. strict_8bitmime (no) - Enable both strict_7bit_headers and strict_8bit- + Enable both strict_7bit_headers and strict_8bit- mime_body. strict_7bit_headers (no) Reject mail with 8-bit text in message headers. strict_8bitmime_body (no) - Reject 8-bit message body text without 8-bit MIME + Reject 8-bit message body text without 8-bit MIME content encoding information. strict_mime_encoding_domain (no) Reject mail with invalid Content-Transfer-Encoding: - information for the message/* or multipart/* MIME + information for the message/* or multipart/* MIME content types. Available in Postfix version 2.5 and later: detect_8bit_encoding_header (yes) Automatically detect 8BITMIME body content by look- - ing at Content-Transfer-Encoding: message headers; - historically, this behavior was hard-coded to be + ing at Content-Transfer-Encoding: message headers; + historically, this behavior was hard-coded to be "always on". AUTOMATIC BCC RECIPIENT CONTROLS @@ -276,31 +281,31 @@ CLEANUP(8) CLEANUP(8) mail enters the mail system: always_bcc (empty) - Optional address that receives a "blind carbon + Optional address that receives a "blind carbon copy" of each message that is received by the Post- fix mail system. Available in Postfix version 2.1 and later: sender_bcc_maps (empty) - Optional BCC (blind carbon-copy) address lookup + Optional BCC (blind carbon-copy) address lookup tables, indexed by sender address. recipient_bcc_maps (empty) - Optional BCC (blind carbon-copy) address lookup + Optional BCC (blind carbon-copy) address lookup tables, indexed by recipient address. ADDRESS TRANSFORMATION CONTROLS - Address rewriting is delegated to the trivial-rewrite(8) - daemon. The cleanup(8) server implements table driven + Address rewriting is delegated to the trivial-rewrite(8) + daemon. The cleanup(8) server implements table driven address mapping. empty_address_recipient (MAILER-DAEMON) - The recipient of mail addressed to the null + The recipient of mail addressed to the null address. canonical_maps (empty) - Optional address mapping lookup tables for message + Optional address mapping lookup tables for message headers and envelopes. recipient_canonical_maps (empty) @@ -311,49 +316,49 @@ CLEANUP(8) CLEANUP(8) Optional address mapping lookup tables for envelope and header sender addresses. - masquerade_classes (envelope_sender, header_sender, + masquerade_classes (envelope_sender, header_sender, header_recipient) What addresses are subject to address masquerading. masquerade_domains (empty) - Optional list of domains whose subdomain structure + Optional list of domains whose subdomain structure will be stripped off in email addresses. masquerade_exceptions (empty) - Optional list of user names that are not subjected - to address masquerading, even when their address + Optional list of user names that are not subjected + to address masquerading, even when their address matches $masquerade_domains. propagate_unmatched_extensions (canonical, virtual) - What address lookup tables copy an address exten- + What address lookup tables copy an address exten- sion from the lookup key to the lookup result. Available before Postfix version 2.0: virtual_maps (empty) Optional lookup tables with a) names of domains for - which all addresses are aliased to addresses in - other local or remote domains, and b) addresses - that are aliased to addresses in other local or + which all addresses are aliased to addresses in + other local or remote domains, and b) addresses + that are aliased to addresses in other local or remote domains. Available in Postfix version 2.0 and later: virtual_alias_maps ($virtual_maps) - Optional lookup tables that alias specific mail - addresses or domains to other local or remote + Optional lookup tables that alias specific mail + addresses or domains to other local or remote address. Available in Postfix version 2.2 and later: - canonical_classes (envelope_sender, envelope_recipient, + canonical_classes (envelope_sender, envelope_recipient, header_sender, header_recipient) - What addresses are subject to canonical_maps + What addresses are subject to canonical_maps address mapping. recipient_canonical_classes (envelope_recipient, header_recipient) - What addresses are subject to recipient_canoni- + What addresses are subject to recipient_canoni- cal_maps address mapping. sender_canonical_classes (envelope_sender, header_sender) @@ -361,15 +366,15 @@ CLEANUP(8) CLEANUP(8) address mapping. remote_header_rewrite_domain (empty) - Don't rewrite message headers from remote clients + Don't rewrite message headers from remote clients at all when this parameter is empty; otherwise, re- - write message headers and append the specified + write message headers and append the specified domain name to incomplete addresses. RESOURCE AND RATE CONTROLS duplicate_filter_limit (1000) - The maximal number of addresses remembered by the - address duplicate filter for aliases(5) or vir- + The maximal number of addresses remembered by the + address duplicate filter for aliases(5) or vir- tual(5) alias expansion, or for showq(8) queue dis- plays. @@ -378,16 +383,16 @@ CLEANUP(8) CLEANUP(8) message header. hopcount_limit (50) - The maximal number of Received: message headers + The maximal number of Received: message headers that is allowed in the primary message headers. in_flow_delay (1s) - Time to pause before accepting a new message, when + Time to pause before accepting a new message, when the message arrival rate exceeds the message deliv- ery rate. message_size_limit (10240000) - The maximal size in bytes of a message, including + The maximal size in bytes of a message, including envelope information. Available in Postfix version 2.0 and later: @@ -405,35 +410,35 @@ CLEANUP(8) CLEANUP(8) will handle. queue_file_attribute_count_limit (100) - The maximal number of (name=value) attributes that + The maximal number of (name=value) attributes that may be stored in a Postfix queue file. Available in Postfix version 2.1 and later: virtual_alias_expansion_limit (1000) - The maximal number of addresses that virtual alias + The maximal number of addresses that virtual alias expansion produces from each original recipient. virtual_alias_recursion_limit (1000) - The maximal nesting depth of virtual alias expan- + The maximal nesting depth of virtual alias expan- sion. MISCELLANEOUS CONTROLS config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. daemon_timeout (18000s) - How much time a Postfix daemon process may take to - handle a request before it is terminated by a + How much time a Postfix daemon process may take to + handle a request before it is terminated by a built-in watchdog timer. delay_logging_resolution_limit (2) - The maximal number of digits after the decimal + The maximal number of digits after the decimal point when logging sub-second delay values. delay_warning_time (0h) - The time after which the sender receives the mes- + The time after which the sender receives the mes- sage headers of mail that is still queued. ipc_timeout (3600s) @@ -441,13 +446,13 @@ CLEANUP(8) CLEANUP(8) over an internal communication channel. max_idle (100s) - The maximum amount of time that an idle Postfix - daemon process waits for an incoming connection + The maximum amount of time that an idle Postfix + daemon process waits for an incoming connection before terminating voluntarily. max_use (100) - The maximal number of incoming connections that a - Postfix daemon process will service before termi- + The maximal number of incoming connections that a + Postfix daemon process will service before termi- nating voluntarily. myhostname (see 'postconf -d' output) @@ -455,19 +460,19 @@ CLEANUP(8) CLEANUP(8) myorigin ($myhostname) The domain name that locally-posted mail appears to - come from, and that locally posted mail is deliv- + come from, and that locally posted mail is deliv- ered to. process_id (read-only) - The process ID of a Postfix command or daemon + The process ID of a Postfix command or daemon process. process_name (read-only) - The process name of a Postfix command or daemon + The process name of a Postfix command or daemon process. queue_directory (see 'postconf -d' output) - The location of the Postfix top-level queue direc- + The location of the Postfix top-level queue direc- tory. soft_bounce (no) @@ -478,14 +483,14 @@ CLEANUP(8) CLEANUP(8) The syslog facility of Postfix logging. syslog_name (see 'postconf -d' output) - The mail system name that is prepended to the - process name in syslog records, so that "smtpd" + The mail system name that is prepended to the + process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". Available in Postfix version 2.1 and later: enable_original_recipient (yes) - Enable support for the X-Original-To message + Enable support for the X-Original-To message header. FILES @@ -509,7 +514,7 @@ CLEANUP(8) CLEANUP(8) CONTENT_INSPECTION_README content inspection LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 891ea211d..e0123aa12 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -2688,6 +2688,80 @@ turned off by default with Postfix version 2.1, and is always turned on with older Postfix versions).

    + + +
    enable_long_queue_ids +(default: no)
    + +

    Enable long, non-repeating, queue IDs (queue file names). The +benefit of non-repeating names is simpler logfile analysis and +easier queue migration (there is no need to run "postsuper" to +change queue file names that don't match their message file inode +number).

    + +

    Note: see below for how to prepare long queue file names +for migration to Postfix ≤ 2.8.

    + +

    Changing the parameter value to "yes" has the following effects: +

    + + + +

    Changing the parameter value to "no" has the following effects: +

    + + + +

    Before migration to Postfix ≤ 2.8, the following commands +are required to convert long queue file names into short names:

    + +
    +# postfix stop
    +# postconf enable_long_queue_ids=no
    +# postsuper
    +
    + +

    Repeat the postsuper command until it reports no more queue file +name changes.

    + +
    enable_original_recipient diff --git a/postfix/html/postsuper.1.html b/postfix/html/postsuper.1.html index bb819abd0..1421c48eb 100644 --- a/postfix/html/postsuper.1.html +++ b/postfix/html/postsuper.1.html @@ -10,7 +10,7 @@ POSTSUPER(1) POSTSUPER(1) postsuper - Postfix superintendent SYNOPSIS - postsuper [-psv] [-c config_dir] [-d queue_id] + postsuper [-psSv] [-c config_dir] [-d queue_id] [-h queue_id] [-H queue_id] [-r queue_id] [directory ...] @@ -180,7 +180,9 @@ POSTSUPER(1) POSTSUPER(1) o Rename files whose name does not match the message file inode number. This operation is necessary after restoring a mail queue from - a different machine, or from backup media. + a different machine or from backup, when + queue files were created with Postfix <= 2.8 + or with "enable_long_queue_ids = no". o Move queue files that are in the wrong place in the file system hierarchy and remove sub- @@ -189,6 +191,22 @@ POSTSUPER(1) POSTSUPER(1) a change in the hash_queue_names and/or hash_queue_depth configuration parameters. + o Rename queue files created with + "enable_long_queue_ids = yes" to short + names, for migration to Postfix <= 2.8. The + procedure is as follows: + + # postfix stop + # postconf enable_long_queue_ids=no + # postsuper + + Run postsuper(1) repeatedly until it stops + reporting file name changes. + + -S A redundant version of -s that requires that long + file names also match the message file inode num- + ber. This option exists for testing purposes. + -v Enable verbose logging for debugging purposes. Mul- tiple -v options make the software increasingly verbose. @@ -241,12 +259,18 @@ POSTSUPER(1) POSTSUPER(1) process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". + Available in Postfix version 2.9 and later: + + enable_long_queue_ids (no) + Enable long, non-repeating, queue IDs (queue file + names). + SEE ALSO sendmail(1), Sendmail-compatible user interface postqueue(1), unprivileged queue operations LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/showq.8.html b/postfix/html/showq.8.html index c399c68ec..b03b6d722 100644 --- a/postfix/html/showq.8.html +++ b/postfix/html/showq.8.html @@ -95,6 +95,12 @@ SHOWQ(8) SHOWQ(8) process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". + Available in Postfix version 2.9 and later: + + enable_long_queue_ids (no) + Enable long, non-repeating, queue IDs (queue file + names). + FILES /var/spool/postfix, queue directories @@ -107,7 +113,7 @@ SHOWQ(8) SHOWQ(8) syslogd(8), system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/man/man1/postsuper.1 b/postfix/man/man1/postsuper.1 index 9b292a987..093315de3 100644 --- a/postfix/man/man1/postsuper.1 +++ b/postfix/man/man1/postsuper.1 @@ -9,7 +9,7 @@ Postfix superintendent .na .nf .fi -\fBpostsuper\fR [\fB-psv\fR] +\fBpostsuper\fR [\fB-psSv\fR] [\fB-c \fIconfig_dir\fR] [\fB-d \fIqueue_id\fR] [\fB-h \fIqueue_id\fR] [\fB-H \fIqueue_id\fR] [\fB-r \fIqueue_id\fR] [\fIdirectory ...\fR] @@ -166,15 +166,36 @@ before Postfix startup. .RS .IP \(bu Rename files whose name does not match the message file inode -number. This operation is necessary after restoring a mail queue -from a different machine, or from backup media. +number. This operation is necessary after restoring a mail +queue from a different machine or from backup, when queue +files were created with Postfix <= 2.8 or with +"enable_long_queue_ids = no". .IP \(bu Move queue files that are in the wrong place in the file system hierarchy and remove subdirectories that are no longer needed. File position rearrangements are necessary after a change in the \fBhash_queue_names\fR and/or \fBhash_queue_depth\fR configuration parameters. +.IP \(bu +Rename queue files created with "enable_long_queue_ids = +yes" to short names, for migration to Postfix <= 2.8. The +procedure is as follows: +.sp +.nf +.na +# postfix stop +# postconf enable_long_queue_ids=no +# postsuper +.ad +.fi +.sp +Run \fBpostsuper\fR(1) repeatedly until it stops reporting +file name changes. .RE +.IP \fB-S\fR +A redundant version of \fB-s\fR that requires that long +file names also match the message file inode number. This +option exists for testing purposes. .IP \fB-v\fR Enable verbose logging for debugging purposes. Multiple \fB-v\fR options make the software increasingly verbose. @@ -225,6 +246,10 @@ The syslog facility of Postfix logging. .IP "\fBsyslog_name (see 'postconf -d' output)\fR" The mail system name that is prepended to the process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". +.PP +Available in Postfix version 2.9 and later: +.IP "\fBenable_long_queue_ids (no)\fR" +Enable long, non-repeating, queue IDs (queue file names). .SH "SEE ALSO" .na .nf diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index b07bbd1df..f245f0ab4 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1509,6 +1509,68 @@ non-standard Errors-To: message header, instead of the envelope sender address (this feature is removed with Postfix version 2.2, is turned off by default with Postfix version 2.1, and is always turned on with older Postfix versions). +.SH enable_long_queue_ids (default: no) +Enable long, non-repeating, queue IDs (queue file names). The +benefit of non-repeating names is simpler logfile analysis and +easier queue migration (there is no need to run "postsuper" to +change queue file names that don't match their message file inode +number). +.PP +Note: see below for how to prepare long queue file names +for migration to Postfix <= 2.8. +.PP +Changing the parameter value to "yes" has the following effects: +.IP \(bu +Existing queue file names are not affected. +.IP \(bu +New queue files are created with names such as 3Pt2mN2VXxznjll. +These are encoded in a 52-character alphabet that contains digits +(0-9), upper-case letters (B-Z) and lower-case letters (b-z). For +safety reasons the vowels (AEIOUaeiou) are excluded from the alphabet. +The name format is: 6 or more characters for the time in seconds, +4 characters for the time in microseconds, the 'z'; the remainder +is the file inode number encoded in the first 51 characters of the +52-character alphabet. +.IP \(bu +New messages have a Message-ID header with +\fIqueueID\fR@\fImyhostname\fR. +.IP \(bu +The mailq (postqueue -p) output has a wider Queue ID column. +The number of whitespace-separated fields is not changed. +.PP +Changing the parameter value to "no" has the following effects: +.IP \(bu +Existing long queue file names are renamed to the short +form (while running "postfix reload" or "postsuper"). +.IP \(bu +New queue files are created with names such as C3CD21F3E90 +from a hexadecimal alphabet that contains digits (0-9) and upper-case +letters (A-F). The name format is: 5 characters for the time in +microseconds; the remainder is the file inode number. +.IP \(bu +New messages have a Message-ID header with +\fIYYYYMMDDHHMMSS.queueid\fR@\fImyhostname\fR, where +\fIYYYYMMDDHHMMSS\fR are the year, month, day, hour, minute and +second. +.IP \(bu +The mailq (postqueue -p) output has the same format as +with Postfix <= 2.8. +.PP +Before migration to Postfix <= 2.8, the following commands +are required to convert long queue file names into short names: +.PP +.nf +.na +.ft C +# postfix stop +# postconf enable_long_queue_ids=no +# postsuper +.fi +.ad +.ft R +.PP +Repeat the postsuper command until it reports no more queue file +name changes. .SH enable_original_recipient (default: yes) Enable support for the X-Original-To message header. This header is needed for multi-recipient mailboxes. diff --git a/postfix/man/man8/cleanup.8 b/postfix/man/man8/cleanup.8 index 5407ab075..d789450c5 100644 --- a/postfix/man/man8/cleanup.8 +++ b/postfix/man/man8/cleanup.8 @@ -84,7 +84,7 @@ The text below provides only a parameter summary. See .nf .ad .fi -.IP "\fBundisclosed_recipients_header (To: undisclosed-recipients:;)\fR" +.IP "\fBundisclosed_recipients_header (see 'postconf -d' output)\fR" Message header that the Postfix \fBcleanup\fR(8) server inserts when a message contains no To: or Cc: message header. .PP @@ -100,6 +100,10 @@ Available in Postfix version 2.6 and later: .IP "\fBalways_add_missing_headers (no)\fR" Always add (Resent-) From:, To:, Date: or Message-ID: headers when not present. +.PP +Available in Postfix version 2.9 and later: +.IP "\fBenable_long_queue_ids (no)\fR" +Enable long, non-repeating, queue IDs (queue file names). .SH "BUILT-IN CONTENT FILTERING CONTROLS" .na .nf diff --git a/postfix/man/man8/showq.8 b/postfix/man/man8/showq.8 index 389b29e78..a200429e8 100644 --- a/postfix/man/man8/showq.8 +++ b/postfix/man/man8/showq.8 @@ -81,6 +81,10 @@ The syslog facility of Postfix logging. .IP "\fBsyslog_name (see 'postconf -d' output)\fR" The mail system name that is prepended to the process name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". +.PP +Available in Postfix version 2.9 and later: +.IP "\fBenable_long_queue_ids (no)\fR" +Enable long, non-repeating, queue IDs (queue file names). .SH "FILES" .na .nf diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 387d95255..eb1baec77 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -689,6 +689,7 @@ while (<>) { s;\bfrozen_delivered_to\b;$&;g; s;\breset_owner_alias\b;$&;g; + s;\benable_long_queue_ids\b;$&;g; # Transport-dependent magical parameters. diff --git a/postfix/proto/POSTSCREEN_README.html b/postfix/proto/POSTSCREEN_README.html index 0d31c7d46..a86a7fd48 100644 --- a/postfix/proto/POSTSCREEN_README.html +++ b/postfix/proto/POSTSCREEN_README.html @@ -837,7 +837,9 @@ Postfix version 2.8.

  • Some postscreen(8) configuration parameters implement stress-dependent behavior. This is supported only when the default -value is stress-dependent (that is, it looks like ${stress?X}${stress:Y}). +value is stress-dependent (that is, "postconf -d parametername" +output shows "parametername = +${stress?something}${stress:something}"). Other parameters always evaluate as if the stress value is the empty string.

    diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 023051d99..fddc672f3 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -14080,3 +14080,73 @@ talking to a Postfix SMTP server process.

    This feature is available in Postfix 2.9 and later.

    + +%PARAM enable_long_queue_ids no + +

    Enable long, non-repeating, queue IDs (queue file names). The +benefit of non-repeating names is simpler logfile analysis and +easier queue migration (there is no need to run "postsuper" to +change queue file names that don't match their message file inode +number).

    + +

    Note: see below for how to prepare long queue file names +for migration to Postfix ≤ 2.8.

    + +

    Changing the parameter value to "yes" has the following effects: +

    + +
      + +
    • Existing queue file names are not affected.

      + +
    • New queue files are created with names such as 3Pt2mN2VXxznjll. +These are encoded in a 52-character alphabet that contains digits +(0-9), upper-case letters (B-Z) and lower-case letters (b-z). For +safety reasons the vowels (AEIOUaeiou) are excluded from the alphabet. +The name format is: 6 or more characters for the time in seconds, +4 characters for the time in microseconds, the 'z'; the remainder +is the file inode number encoded in the first 51 characters of the +52-character alphabet.

      + +
    • New messages have a Message-ID header with +queueID@myhostname.

      + +
    • The mailq (postqueue -p) output has a wider Queue ID column. +The number of whitespace-separated fields is not changed.

      + +

    + +

    Changing the parameter value to "no" has the following effects: +

    + +
      + +
    • Existing long queue file names are renamed to the short +form (while running "postfix reload" or "postsuper").

      + +
    • New queue files are created with names such as C3CD21F3E90 +from a hexadecimal alphabet that contains digits (0-9) and upper-case +letters (A-F). The name format is: 5 characters for the time in +microseconds; the remainder is the file inode number.

      + +
    • New messages have a Message-ID header with +YYYYMMDDHHMMSS.queueid@myhostname, where +YYYYMMDDHHMMSS are the year, month, day, hour, minute and +second. + +

    • The mailq (postqueue -p) output has the same format as +with Postfix ≤ 2.8.

      + +

    + +

    Before migration to Postfix ≤ 2.8, the following commands +are required to convert long queue file names into short names:

    + +
    +# postfix stop
    +# postconf enable_long_queue_ids=no
    +# postsuper
    +
    + +

    Repeat the postsuper command until it reports no more queue file +name changes.

    diff --git a/postfix/src/cleanup/cleanup.c b/postfix/src/cleanup/cleanup.c index c5b71e9d8..0f8df6616 100644 --- a/postfix/src/cleanup/cleanup.c +++ b/postfix/src/cleanup/cleanup.c @@ -68,7 +68,7 @@ /* COMPATIBILITY CONTROLS /* .ad /* .fi -/* .IP "\fBundisclosed_recipients_header (To: undisclosed-recipients:;)\fR" +/* .IP "\fBundisclosed_recipients_header (see 'postconf -d' output)\fR" /* Message header that the Postfix \fBcleanup\fR(8) server inserts when a /* message contains no To: or Cc: message header. /* .PP @@ -84,6 +84,10 @@ /* .IP "\fBalways_add_missing_headers (no)\fR" /* Always add (Resent-) From:, To:, Date: or Message-ID: headers /* when not present. +/* .PP +/* Available in Postfix version 2.9 and later: +/* .IP "\fBenable_long_queue_ids (no)\fR" +/* Enable long, non-repeating, queue IDs (queue file names). /* BUILT-IN CONTENT FILTERING CONTROLS /* .ad /* .fi diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 4de1aa530..08f694ad2 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -636,14 +636,21 @@ static void cleanup_header_done_callback(void *context) if ((state->hdr_rewrite_context || var_always_add_hdrs) && (state->headers_seen & (1 << (state->resent[0] ? HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) { - tv = state->handle->ctime.tv_sec; - tp = gmtime(&tv); - strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp); - cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>", - state->resent, time_stamp, state->queue_id, var_myhostname); - msg_info("%s: %smessage-id=<%s.%s@%s>", + if (var_long_queue_ids) { + vstring_sprintf(state->temp1, "%s@%s", + state->queue_id, var_myhostname); + } else { + tv = state->handle->ctime.tv_sec; + tp = gmtime(&tv); + strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp); + vstring_sprintf(state->temp1, "%s.%s@%s", + time_stamp, state->queue_id, var_myhostname); + } + cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s>", + state->resent, vstring_str(state->temp1)); + msg_info("%s: %smessage-id=<%s>", state->queue_id, *state->resent ? "resent-" : "", - time_stamp, state->queue_id, var_myhostname); + vstring_str(state->temp1)); state->headers_seen |= (1 << (state->resent[0] ? HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID)); } diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 1a3511412..123944275 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -30,7 +30,7 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \ verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \ fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \ match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \ - smtp_reply_footer.c + smtp_reply_footer.c safe_ultostr.c OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \ clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \ @@ -62,7 +62,7 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \ fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \ match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \ - smtp_reply_footer.o + smtp_reply_footer.o safe_ultostr.o HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \ conv_time.h db_common.h debug_peer.h debug_process.h defer.h \ @@ -87,7 +87,7 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ trace.h user_acl.h valid_mailhost_addr.h verify.h verify_clnt.h \ verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \ fold_addr.h header_body_checks.h data_redirect.h match_service.h \ - addr_match_list.h smtp_reply_footer.h + addr_match_list.h smtp_reply_footer.h safe_ultostr.h TESTSRC = rec2stream.c stream2rec.c recdump.c DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) CFLAGS = $(DEBUG) $(OPT) $(DEFS) @@ -100,7 +100,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \ quote_821_local mail_conf_time mime_state strip_addr \ verify_clnt xtext anvil_clnt scache ehlo_mask \ valid_mailhost_addr own_inet_addr header_body_checks \ - data_redirect + data_redirect addr_match_list safe_ultostr LIBS = ../../lib/libutil.a LIB_DIR = ../../lib @@ -286,6 +286,9 @@ data_redirect: data_redirect.c $(LIB) $(LIBS) addr_match_list: addr_match_list.c $(LIB) $(LIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) +safe_ultostr: safe_ultostr.c $(LIB) $(LIBS) + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) + tests: tok822_test mime_tests strip_addr_test tok822_limit_test \ xtext_test scache_multi_test ehlo_mask_test \ namadr_list_test mail_conf_time_test header_body_checks_tests @@ -978,9 +981,12 @@ ext_prop.o: mail_params.h file_id.o: ../../include/msg.h file_id.o: ../../include/sys_defs.h file_id.o: ../../include/vbuf.h +file_id.o: ../../include/vstream.h file_id.o: ../../include/vstring.h file_id.o: file_id.c file_id.o: file_id.h +file_id.o: mail_queue.h +file_id.o: safe_ultostr.h flush_clnt.o: ../../include/attr.h flush_clnt.o: ../../include/iostuff.h flush_clnt.o: ../../include/match_list.h @@ -1352,6 +1358,7 @@ mail_queue.o: file_id.h mail_queue.o: mail_params.h mail_queue.o: mail_queue.c mail_queue.o: mail_queue.h +mail_queue.o: safe_ultostr.h mail_run.o: ../../include/msg.h mail_run.o: ../../include/mymalloc.h mail_run.o: ../../include/stringops.h @@ -1799,6 +1806,13 @@ rewrite_clnt.o: quote_822_local.h rewrite_clnt.o: quote_flags.h rewrite_clnt.o: rewrite_clnt.c rewrite_clnt.o: rewrite_clnt.h +safe_ultostr.o: ../../include/msg.h +safe_ultostr.o: ../../include/mymalloc.h +safe_ultostr.o: ../../include/sys_defs.h +safe_ultostr.o: ../../include/vbuf.h +safe_ultostr.o: ../../include/vstring.h +safe_ultostr.o: safe_ultostr.c +safe_ultostr.o: safe_ultostr.h scache.o: ../../include/argv.h scache.o: ../../include/events.h scache.o: ../../include/msg.h diff --git a/postfix/src/global/file_id.c b/postfix/src/global/file_id.c index e130087db..c482017ae 100644 --- a/postfix/src/global/file_id.c +++ b/postfix/src/global/file_id.c @@ -6,26 +6,37 @@ /* SYNOPSIS /* #include /* +/* const char *get_file_id_fd(fd, long_flag) +/* int fd; +/* int long_flag; +/* +/* const char *get_file_id_st(st, long_flag) +/* struct stat *st; +/* int long_flag; +/* /* const char *get_file_id(fd) /* int fd; -/* -/* int check_file_id(fd, id) -/* int fd; -/* const char *id; /* DESCRIPTION -/* get_file_id() queries the operating system for the unique identifier -/* for the specified file and returns a printable representation. -/* The result is volatile. Make a copy if it is to be used for any -/* appreciable amount of time. +/* get_file_id_fd() queries the operating system for the unique +/* file identifier for the specified file descriptor and returns +/* a printable representation. The result is volatile. Make +/* a copy if it is to be used for any appreciable amount of +/* time. /* -/* check_file_id() tests if an open file matches the given -/* printable FILE ID representation. +/* get_file_id_st() returns the unique identifier for the +/* specified file status information. +/* +/* get_file_id() provides binary compatibility for old programs. +/* This function should not be used by new programs. /* /* Arguments: /* .IP fd /* A valid file descriptor that is associated with an open file. -/* .IP id -/* Printable file ID. +/* .IP st +/* The result from e.g., stat(2) or fstat(2). +/* .IP long_flag +/* Encode the result as appropriate for long or short queue +/* identifiers. /* DIAGNOSTICS /* All errors are fatal. /* LICENSE @@ -52,26 +63,38 @@ /* Global library. */ +#define MAIL_QUEUE_INTERNAL +#include #include "file_id.h" -/* get_file_id - lookup file ID, convert to printable form */ +/* get_file_id - binary compatibility */ const char *get_file_id(int fd) { - static VSTRING *result; + return (get_file_id_fd(fd, 0)); +} + +/* get_file_id_fd - return printable file identifier for file descriptor */ + +const char *get_file_id_fd(int fd, int long_flag) +{ struct stat st; + if (fstat(fd, &st) < 0) + msg_fatal("fstat: %m"); + return (get_file_id_st(&st, long_flag)); +} + +/* get_file_id_st - return printable file identifier for file status */ + +const char *get_file_id_st(struct stat * st, int long_flag) +{ + static VSTRING *result; + if (result == 0) result = vstring_alloc(1); - if (fstat(fd, &st) < 0) - msg_fatal("fstat: %m"); - vstring_sprintf(result, "%lX", (long) st.st_ino); - return (vstring_str(result)); -} - -/* check_file_id - make sure file name matches ID */ - -int check_file_id(int fd, const char *name) -{ - return (strcmp(get_file_id(fd), name)); + if (long_flag) + return (MQID_LG_ENCODE_INUM(result, st->st_ino)); + else + return (MQID_SH_ENCODE_INUM(result, st->st_ino)); } diff --git a/postfix/src/global/file_id.h b/postfix/src/global/file_id.h index c954e36bc..a20b0abfa 100644 --- a/postfix/src/global/file_id.h +++ b/postfix/src/global/file_id.h @@ -11,10 +11,18 @@ /* DESCRIPTION /* .nf + /* +System library. +*/ +#include + /* External interface. */ +extern const char *get_file_id_fd(int, int); +extern const char *get_file_id_st(struct stat *, int); + + /* Legacy interface. */ extern const char *get_file_id(int); -extern int check_file_id(int, const char *); /* LICENSE /* .ad diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index dc744cf7a..009beb49b 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -117,6 +117,7 @@ /* char *var_multi_group; /* char *var_multi_name; /* bool var_multi_enable; +/* bool var_long_queue_ids; /* /* void mail_params_init() /* @@ -302,6 +303,7 @@ char *var_multi_wrapper; char *var_multi_group; char *var_multi_name; bool var_multi_enable; +bool var_long_queue_ids; const char null_format_string[1] = ""; @@ -627,6 +629,7 @@ void mail_params_init() VAR_HELPFUL_WARNINGS, DEF_HELPFUL_WARNINGS, &var_helpful_warnings, VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid, VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable, + VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids, 0, }; const char *cp; diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 169a9100a..ebd3c2c7b 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -910,6 +910,14 @@ extern char *var_hash_queue_names; #define DEF_HASH_QUEUE_DEPTH 1 extern int var_hash_queue_depth; + /* + * Short queue IDs contain the time in microseconds and file inode number. + * Long queue IDs also contain the time in seconds. + */ +#define VAR_LONG_QUEUE_IDS "enable_long_queue_ids" +#define DEF_LONG_QUEUE_IDS 0 +extern bool var_long_queue_ids; + /* * Multi-protocol support. */ @@ -2988,33 +2996,20 @@ extern char *var_tls_eecdh_ultra; #define DEF_TLS_PREEMPT_CLIST 0 extern bool var_tls_preempt_clist; -#ifdef USE_TLS - - /* - * The tweak for CVE-2005-2969 is needed in some versions prior to 1.0.0 - */ + /* The tweak for CVE-2010-4180 is needed in some versions prior to 1.0.1 */ + /* The tweak for CVE-2005-2969 is needed in some versions prior to 1.0.0 */ +#if defined(USE_TLS) && (OPENSSL_VERSION_NUMBER < 0x1000100fL) #if (OPENSSL_VERSION_NUMBER < 0x1000000fL) -#define TLS_BUG_TWEAK_A " CVE-2005-2969" +#define TLS_BUG_TWEAKS "CVE-2005-2969 CVE-2010-4180" #else -#define TLS_BUG_TWEAK_A "" +#define TLS_BUG_TWEAKS "CVE-2010-4180" #endif - - /* - * The tweak for CVE-2010-4180 is needed in some versions prior to 1.0.1 - */ -#if (OPENSSL_VERSION_NUMBER < 0x1000100fL) -#define TLS_BUG_TWEAK_B " CVE-2010-4180" #else -#define TLS_BUG_TWEAK_B " " +#define TLS_BUG_TWEAKS "" #endif -#else /* USE_TLS */ -#define TLS_BUG_TWEAK_A "" -#define TLS_BUG_TWEAK_B " " -#endif /* USE_TLS */ - #define VAR_TLS_BUG_TWEAKS "tls_disable_workarounds" -#define DEF_TLS_BUG_TWEAKS ((TLS_BUG_TWEAK_A TLS_BUG_TWEAK_B)+1) +#define DEF_TLS_BUG_TWEAKS TLS_BUG_TWEAKS extern char *var_tls_bug_tweaks; /* diff --git a/postfix/src/global/mail_queue.c b/postfix/src/global/mail_queue.c index 0d997080c..820b682a9 100644 --- a/postfix/src/global/mail_queue.c +++ b/postfix/src/global/mail_queue.c @@ -135,6 +135,7 @@ #include "file_id.h" #include "mail_params.h" +#define MAIL_QUEUE_INTERNAL #include "mail_queue.h" #define STR vstring_str @@ -311,6 +312,8 @@ VSTREAM *mail_queue_enter(const char *queue_name, mode_t mode, struct timeval * tp) { const char *myname = "mail_queue_enter"; + static VSTRING *sec_buf; + static VSTRING *usec_buf; static VSTRING *id_buf; static int pid; static VSTRING *path_buf; @@ -326,6 +329,8 @@ VSTREAM *mail_queue_enter(const char *queue_name, mode_t mode, */ if (id_buf == 0) { pid = getpid(); + sec_buf = vstring_alloc(10); + usec_buf = vstring_alloc(10); id_buf = vstring_alloc(10); path_buf = vstring_alloc(10); temp_path = vstring_alloc(100); @@ -366,7 +371,7 @@ VSTREAM *mail_queue_enter(const char *queue_name, mode_t mode, * * If someone is racing against us, try to win. */ - file_id = get_file_id(fd); + file_id = get_file_id_fd(fd, var_long_queue_ids); /* * XXX Some systems seem to have clocks that correlate with process @@ -377,7 +382,16 @@ VSTREAM *mail_queue_enter(const char *queue_name, mode_t mode, */ for (count = 0;; count++) { GETTIMEOFDAY(tp); - vstring_sprintf(id_buf, "%05X%s", (int) tp->tv_usec, file_id); + if (var_long_queue_ids) { + vstring_sprintf(id_buf, "%s%s%c%s", + MQID_LG_ENCODE_SEC(sec_buf, tp->tv_sec), + MQID_LG_ENCODE_USEC(usec_buf, tp->tv_usec), + MQID_LG_INUM_SEP, file_id); + } else { + vstring_sprintf(id_buf, "%s%s", + MQID_SH_ENCODE_USEC(usec_buf, tp->tv_usec), + file_id); + } mail_queue_path(path_buf, queue_name, STR(id_buf)); if (sane_rename(STR(temp_path), STR(path_buf)) == 0) /* success */ break; diff --git a/postfix/src/global/mail_queue.h b/postfix/src/global/mail_queue.h index 47cb61bdf..a1a0e8b9e 100644 --- a/postfix/src/global/mail_queue.h +++ b/postfix/src/global/mail_queue.h @@ -61,6 +61,105 @@ extern int mail_queue_mkdirs(const char *); extern int mail_queue_name_ok(const char *); extern int mail_queue_id_ok(const char *); + /* + * MQID - Mail Queue ID format definitions. Needed only by code that creates + * or parses queue ID strings. + */ +#ifdef MAIL_QUEUE_INTERNAL + + /* + * System library. + */ +#include + + /* + * Global library. + */ +#include + + /* + * The long non-repeating queue ID is encoded in an alphabet of 10 digits, + * 21 upper-case characters, and 21 or fewer lower-case characters. The + * alphabet is made "safe" by removing all the vowels (AEIOUaeiou). The ID + * is the concatenation of: + * + * - the time in seconds (base 52 encoded, six or more chars), + * + * - the time in microseconds (base 52 encoded, exactly four chars), + * + * - the 'z' character to separate the time and inode information, + * + * - the inode number (base 51 encoded so that it contains no 'z'). + */ +#define MQID_LG_SEC_BASE 52 /* seconds safe alphabet base */ +#define MQID_LG_SEC_PAD 6 /* seconds minumum field width */ +#define MQID_LG_USEC_BASE 52 /* microseconds safe alphabet base */ +#define MQID_LG_USEC_PAD 4 /* microseconds exact field width */ +#define MQID_LG_TIME_PAD (MQID_LG_SEC_PAD + MQID_LG_USEC_PAD) +#define MQID_LG_INUM_SEP 'z' /* time-inode separator */ +#define MQID_LG_INUM_BASE 51 /* inode safe alphabet base */ +#define MQID_LG_INUM_PAD 0 /* no padding needed */ + +#define MQID_FIND_LG_INUM_SEPARATOR(cp, path) \ + ((cp) = strrchr((path), MQID_LG_INUM_SEP)) != 0 \ + && ((cp) - (path) >= MQID_LG_TIME_PAD) + +#define MQID_GET_INUM(path, inum, long_form, error) do { \ + char *_cp; \ + if (((long_form) = MQID_FIND_LG_INUM_SEPARATOR(_cp, (path))) != 0) { \ + MQID_LG_DECODE_INUM(_cp + 1, (inum), (error)); \ + } else { \ + MQID_SH_DECODE_INUM((path) + MQID_SH_USEC_PAD, (inum), (error)); \ + } \ + } while (0) + +#define MQID_LG_ENCODE_SEC(buf, val) \ + MQID_LG_ENCODE((buf), (val), MQID_LG_SEC_BASE, MQID_LG_SEC_PAD) + +#define MQID_LG_ENCODE_USEC(buf, val) \ + MQID_LG_ENCODE((buf), (val), MQID_LG_USEC_BASE, MQID_LG_USEC_PAD) + +#define MQID_LG_ENCODE_INUM(buf, val) \ + MQID_LG_ENCODE((buf), (val), MQID_LG_INUM_BASE, MQID_LG_INUM_PAD) + +#define MQID_LG_DECODE_INUM(str, ulval, error) \ + MQID_LG_DECODE((str), (ulval), MQID_LG_INUM_BASE, (error)) + +#define MQID_LG_ENCODE(buf, val, base, padlen) \ + safe_ultostr((buf), (unsigned long) (val), (base), (padlen), '0') + +#define MQID_LG_DECODE(str, ulval, base, error) do { \ + char *_end; \ + errno = 0; \ + (ulval) = safe_strtoul((str), &_end, (base)); \ + (error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \ + } while (0) + + /* + * The short repeating queue ID is encoded in upper-case hexadecimal, and is + * the concatenation of: + * + * - the time in microseconds (exactly five chars), + * + * - the inode number. + */ +#define MQID_SH_USEC_PAD 5 /* microseconds exact field width */ + +#define MQID_SH_ENCODE_USEC(buf, usec) \ + vstring_str(vstring_sprintf((buf), "%05X", (int) (usec))) + +#define MQID_SH_ENCODE_INUM(buf, inum) \ + vstring_str(vstring_sprintf((buf), "%lX", (unsigned long) (inum))) + +#define MQID_SH_DECODE_INUM(str, ulval, error) do { \ + char *_end; \ + errno = 0; \ + (ulval) = strtoul((str), &_end, 16); \ + (error) = (*_end != 0 || ((ulval) == ULONG_MAX && errno == ERANGE)); \ + } while (0) + +#endif /* MAIL_QUEUE_INTERNAL */ + /* LICENSE /* .ad /* .fi @@ -72,4 +171,4 @@ extern int mail_queue_id_ok(const char *); /* Yorktown Heights, NY 10598, USA /*--*/ -#endif +#endif /* _MAIL_QUEUE_H_INCLUDED_ */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index b6924097d..692f46cca 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20110313" +#define MAIL_RELEASE_DATE "20110320" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/safe_ultostr.c b/postfix/src/global/safe_ultostr.c new file mode 100644 index 000000000..a16e87bd1 --- /dev/null +++ b/postfix/src/global/safe_ultostr.c @@ -0,0 +1,239 @@ +/*++ +/* NAME +/* safe_ultostr 3 +/* SUMMARY +/* convert unsigned long to safe string +/* SYNOPSIS +/* #include +/* +/* char *safe_ultostr(result, ulval, base, padlen, padchar) +/* VSTRING *result; +/* unsigned long ulval; +/* int base; +/* int padlen; +/* int padchar; +/* +/* unsigned long safe_strtoul(start, end, base) +/* const char *start; +/* char **end; +/* int base; +/* DESCRIPTION +/* The functions in this module perform conversions between +/* unsigned long values and "safe" alphanumerical strings +/* (strings with digits, uppercase letters and lowercase +/* letters, but without the vowels AEIOUaeiou). Specifically, +/* the characters B-Z represent the numbers 10-30, and b-z +/* represent 31-51. +/* +/* safe_ultostr() converts an unsigned long value to a safe +/* alphanumerical string. This is the reverse of safe_strtoul(). +/* +/* safe_strtoul() implements similar functionality as strtoul() +/* except that it uses a safe alphanumerical string as input, +/* and that it supports no signs or 0/0x prefixes. +/* +/* Arguments: +/* .IP result +/* Buffer for storage of the result of conversion to string. +/* .IP ulval +/* Unsigned long value. +/* .IP base +/* Value between 2 and 52 inclusive. +/* .IP padlen +/* .IP padchar +/* Left-pad a short result with padchar characters to the +/* specified length. Specify padlen=0 to disable padding. +/* DIAGNOSTICS +/* Fatal: out of memory. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include +#include +#include +#include + +/* Utility library. */ + +#include +#include +#include + +/* Global library. */ + +#include + +/* Application-specific. */ + +#define STR vstring_str +#define END vstring_end +#define SWAP(type, a, b) { type temp; temp = a; a = b; b = temp; } + +static unsigned char safe_chars[] = +"0123456789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"; + +#define SAFE_MAX_BASE (sizeof(safe_chars) - 1) +#define SAFE_MIN_BASE (2) + +/* safe_ultostr - convert unsigned long to safe alphanumerical string */ + +char *safe_ultostr(VSTRING *buf, unsigned long ulval, int base, + int padlen, int padchar) +{ + const char *myname = "safe_ultostr"; + char *start; + char *last; + int i; + + /* + * Sanity check. + */ + if (base < SAFE_MIN_BASE || base > SAFE_MAX_BASE) + msg_panic("%s: bad base: %d", myname, base); + + /* + * First accumulate the result, backwards. + */ + VSTRING_RESET(buf); + while (ulval != 0) { + VSTRING_ADDCH(buf, safe_chars[ulval % base]); + ulval /= base; + } + while (VSTRING_LEN(buf) < padlen) + VSTRING_ADDCH(buf, padchar); + VSTRING_TERMINATE(buf); + + /* + * Then, reverse the result. + */ + start = STR(buf); + last = END(buf) - 1; + for (i = 0; i < VSTRING_LEN(buf) / 2; i++) + SWAP(int, start[i], last[-i]); + return (STR(buf)); +} + +/* safe_strtoul - convert safe alphanumerical string to unsigned long */ + +unsigned long safe_strtoul(char *start, char **end, int base) +{ + const char *myname = "safe_strtoul"; + static unsigned char *char_map = 0; + unsigned char *cp; + unsigned long sum; + unsigned long div_limit; + unsigned long mod_limit; + int char_val; + + /* + * Sanity check. + */ + if (base < SAFE_MIN_BASE || base > SAFE_MAX_BASE) + msg_panic("%s: bad base: %d", myname, base); + + /* + * One-time initialization. Assume 8-bit bytes. + */ + if (char_map == 0) { + char_map = (unsigned char *) mymalloc(256); + for (char_val = 0; char_val < 256; char_val++) + char_map[char_val] = SAFE_MAX_BASE; + for (char_val = 0; char_val < SAFE_MAX_BASE; char_val++) + char_map[safe_chars[char_val]] = char_val; + } + + /* + * Per-call initialization. + */ + sum = 0; + div_limit = ULONG_MAX / base; + mod_limit = ULONG_MAX % base; + + /* + * Skip leading whitespace. We don't implement sign/base prefixes. + */ + while (ISSPACE(*start)) + ++start; + + /* + * Start the conversion. + */ + for (cp = (unsigned char *) start; *cp; cp++) { + /* Return (0, EINVAL) if no conversion was made. */ + if ((char_val = char_map[*cp]) >= base) { + if (cp == (unsigned char *) start) + errno = EINVAL; + break; + } + /* Return (ULONG_MAX, ERANGE) if the result is too large. */ + if (sum > div_limit + || (sum == div_limit && char_val > mod_limit)) { + sum = ULONG_MAX; + errno = ERANGE; + /* Skip "valid" characters, per the strtoul() spec. */ + while (char_map[*++cp] < base) + /* void */ ; + break; + } + sum = sum * base + char_val; + } + if (end) + *end = (char *) cp; + return (sum); +} + +#ifdef TEST + + /* + * Proof-of-concept test program. Read a number from stdin, convert to + * string, and print the result. + */ +#include /* sscanf */ +#include +#include + +int main(int unused_argc, char **unused_argv) +{ + VSTRING *buf = vstring_alloc(100); + char *junk; + unsigned long ulval; + int base; + char ch; + unsigned long ulval2; + +#ifdef MISSING_STRTOUL +#define strtoul strtol +#endif + + while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) { + ch = 0; + if (sscanf(STR(buf), "%lu %d%c", &ulval, &base, &ch) != 2 || ch) { + msg_warn("bad input %s", STR(buf)); + } else { + (void) safe_ultostr(buf, ulval, base, 5, '0'); + vstream_printf("%lu = %s\n", ulval, STR(buf)); + errno = 0; + ulval2 = safe_strtoul(STR(buf), &junk, base); + if (*junk || (ulval2 == ULONG_MAX && errno == ERANGE)) + msg_warn("%s: %m", STR(buf)); + if (ulval2 != ulval) + msg_warn("%lu != %lu", ulval2, ulval); + } + vstream_fflush(VSTREAM_OUT); + } + vstring_free(buf); + return (0); +} + +#endif diff --git a/postfix/src/global/safe_ultostr.h b/postfix/src/global/safe_ultostr.h new file mode 100644 index 000000000..2d88f5445 --- /dev/null +++ b/postfix/src/global/safe_ultostr.h @@ -0,0 +1,36 @@ +#ifndef _SAFE_ULTOSTR_H_INCLUDED_ +#define _SAFE_ULTOSTR_H_INCLUDED_ + +/*++ +/* NAME +/* safe_ultostr 3h +/* SUMMARY +/* convert unsigned long to safe string +/* SYNOPSIS +/* #include +/* DESCRIPTION +/* .nf + + /* + * Utility library. + */ +#include + + /* + * External interface. + */ +extern char *safe_ultostr(VSTRING *, unsigned long, int, int, int); +extern unsigned long safe_strtoul(char *, char **, int); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +#endif diff --git a/postfix/src/postsuper/Makefile.in b/postfix/src/postsuper/Makefile.in index 0df70b1ad..7367d601f 100644 --- a/postfix/src/postsuper/Makefile.in +++ b/postfix/src/postsuper/Makefile.in @@ -58,6 +58,7 @@ depend: $(MAKES) # do not edit below this line - it is generated by 'make depend' postsuper.o: ../../include/argv.h +postsuper.o: ../../include/file_id.h postsuper.o: ../../include/mail_conf.h postsuper.o: ../../include/mail_open_ok.h postsuper.o: ../../include/mail_params.h @@ -68,7 +69,9 @@ postsuper.o: ../../include/msg.h postsuper.o: ../../include/msg_syslog.h postsuper.o: ../../include/msg_vstream.h postsuper.o: ../../include/mymalloc.h +postsuper.o: ../../include/myrand.h postsuper.o: ../../include/safe.h +postsuper.o: ../../include/safe_ultostr.h postsuper.o: ../../include/sane_fsops.h postsuper.o: ../../include/scan_dir.h postsuper.o: ../../include/set_ugid.h diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c index 7b6ea74f5..ea513ddf9 100644 --- a/postfix/src/postsuper/postsuper.c +++ b/postfix/src/postsuper/postsuper.c @@ -5,7 +5,7 @@ /* Postfix superintendent /* SYNOPSIS /* .fi -/* \fBpostsuper\fR [\fB-psv\fR] +/* \fBpostsuper\fR [\fB-psSv\fR] /* [\fB-c \fIconfig_dir\fR] [\fB-d \fIqueue_id\fR] /* [\fB-h \fIqueue_id\fR] [\fB-H \fIqueue_id\fR] /* [\fB-r \fIqueue_id\fR] [\fIdirectory ...\fR] @@ -160,15 +160,36 @@ /* .RS /* .IP \(bu /* Rename files whose name does not match the message file inode -/* number. This operation is necessary after restoring a mail queue -/* from a different machine, or from backup media. +/* number. This operation is necessary after restoring a mail +/* queue from a different machine or from backup, when queue +/* files were created with Postfix <= 2.8 or with +/* "enable_long_queue_ids = no". /* .IP \(bu /* Move queue files that are in the wrong place in the file system /* hierarchy and remove subdirectories that are no longer needed. /* File position rearrangements are necessary after a change in the /* \fBhash_queue_names\fR and/or \fBhash_queue_depth\fR /* configuration parameters. +/* .IP \(bu +/* Rename queue files created with "enable_long_queue_ids = +/* yes" to short names, for migration to Postfix <= 2.8. The +/* procedure is as follows: +/* .sp +/* .nf +/* .na +/* # postfix stop +/* # postconf enable_long_queue_ids=no +/* # postsuper +/* .ad +/* .fi +/* .sp +/* Run \fBpostsuper\fR(1) repeatedly until it stops reporting +/* file name changes. /* .RE +/* .IP \fB-S\fR +/* A redundant version of \fB-s\fR that requires that long +/* file names also match the message file inode number. This +/* option exists for testing purposes. /* .IP \fB-v\fR /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR /* options make the software increasingly verbose. @@ -211,6 +232,10 @@ /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR" /* The mail system name that is prepended to the process name in syslog /* records, so that "smtpd" becomes, for example, "postfix/smtpd". +/* .PP +/* Available in Postfix version 2.9 and later: +/* .IP "\fBenable_long_queue_ids (no)\fR" +/* Enable long, non-repeating, queue IDs (queue file names). /* SEE ALSO /* sendmail(1), Sendmail-compatible user interface /* postqueue(1), unprivileged queue operations @@ -251,6 +276,7 @@ #include #include #include +#include /* Global library. */ @@ -258,8 +284,10 @@ #include #include #include +#define MAIL_QUEUE_INTERNAL #include #include +#include /* Application-specific. */ @@ -276,6 +304,7 @@ #define ACTION_HOLD_ALL (1<<7) /* put all messages on hold */ #define ACTION_RELEASE_ONE (1<<8) /* release named queue file(s) */ #define ACTION_RELEASE_ALL (1<<9) /* release all "on hold" mail */ +#define ACTION_STRUCT_RED (1<<10) /* fix long queue ID inode fields */ #define ACTION_DEFAULT (ACTION_STRUCT | ACTION_PURGE) @@ -629,12 +658,13 @@ static int operate_stream(VSTREAM *fp, /* fix_queue_id - make message queue ID match inode number */ static int fix_queue_id(const char *actual_path, const char *actual_queue, - const char *actual_id, ino_t inum) + const char *actual_id, struct stat * st) { VSTRING *old_path = vstring_alloc(10); VSTRING *new_path = vstring_alloc(10); VSTRING *new_id = vstring_alloc(10); const char **log_qpp; + char *cp; int ret; /* @@ -643,7 +673,15 @@ static int fix_queue_id(const char *actual_path, const char *actual_queue, * be deterministic so that we can recover even when the renaming * operation is interrupted in the middle. */ - vstring_sprintf(new_id, "%.5s%lX", actual_id, (unsigned long) inum); + if (MQID_FIND_LG_INUM_SEPARATOR(cp, actual_id) && var_long_queue_ids) { + vstring_sprintf(new_id, "%.*s%c%s", + (int) (cp - actual_id), actual_id, MQID_LG_INUM_SEP, + get_file_id_st(st, 1)); + } else { + vstring_sprintf(new_id, "%0*X%s", + MQID_SH_USEC_PAD, myrand() % 1000000, + get_file_id_st(st, 0)); + } /* * Rename logfiles before renaming the message file, so that we can @@ -690,6 +728,8 @@ static void super(const char **queues, int action) char **cpp; struct queue_info *qp; unsigned long inum; + int long_name; + int error; /* * Make sure every file is in the right place, clean out stale files, and @@ -827,7 +867,8 @@ static void super(const char **queues, int action) continue; } if (MESSAGE_QUEUE(qp)) { - if (sscanf(path + 5, "%lx", &inum) != 1) { + MQID_GET_INUM(path, inum, long_name, error); + if (error) { msg_warn("bogus file name: %s", STR(actual_path)); continue; } @@ -869,16 +910,24 @@ static void super(const char **queues, int action) * have to be handled properly. XXX This option cannot use * mail_queue_rename(), because the queue file name violates * normal queue file syntax. + * + * By design there is no need to "fix" non-repeating names. What + * follows is applicable only when reverting from long names to + * short names, or when migrating short names from one queue to + * another. */ if ((action & ACTION_STRUCT) != 0 && MESSAGE_QUEUE(qp)) { - if (sscanf(path + 5, "%lx", &inum) != 1) { + MQID_GET_INUM(path, inum, long_name, error); + if (error) { msg_warn("bogus file name: %s", STR(actual_path)); continue; } - if (inum != (unsigned long) st.st_ino) { + if ((long_name != 0 && var_long_queue_ids == 0) + || (inum != (unsigned long) st.st_ino + && (long_name == 0 || (action & ACTION_STRUCT_RED)))) { inode_mismatch++; /* before we fix */ action &= ~ACTIONS_AFTER_INUM_FIX; - fix_queue_id(STR(actual_path), queue_name, path, st.st_ino); + fix_queue_id(STR(actual_path), queue_name, path, &st); /* At this point, path and actual_path are invalidated. */ continue; } @@ -1094,7 +1143,7 @@ int main(int argc, char **argv) /* * Parse JCL. */ - while ((c = GETOPT(argc, argv, "c:d:h:H:pr:sv")) > 0) { + while ((c = GETOPT(argc, argv, "c:d:h:H:pr:sSv")) > 0) { switch (c) { default: msg_fatal("usage: %s " @@ -1102,8 +1151,8 @@ int main(int argc, char **argv) "[-d queue_id (delete)] " "[-h queue_id (hold)] [-H queue_id (un-hold)] " "[-p (purge temporary files)] [-r queue_id (requeue)] " - "[-s (structure fix)] [-v (verbose)] " - "[queue...]", argv[0]); + "[-s (structure fix)] [-S (redundant structure fix)]" + "[-v (verbose)] [queue...]", argv[0]); case 'c': if (*optarg != '/') msg_fatal("-c requires absolute pathname"); @@ -1141,6 +1190,9 @@ int main(int argc, char **argv) action |= (strcmp(optarg, "ALL") == 0 ? ACTION_REQUEUE_ALL : ACTION_REQUEUE_ONE); break; + case 'S': + action |= ACTION_STRUCT_RED; + /* FALLTHROUGH */ case 's': action |= ACTION_STRUCT; break; diff --git a/postfix/src/showq/showq.c b/postfix/src/showq/showq.c index ff23d337b..9f1980816 100644 --- a/postfix/src/showq/showq.c +++ b/postfix/src/showq/showq.c @@ -67,6 +67,10 @@ /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR" /* The mail system name that is prepended to the process name in syslog /* records, so that "smtpd" becomes, for example, "postfix/smtpd". +/* .PP +/* Available in Postfix version 2.9 and later: +/* .IP "\fBenable_long_queue_ids (no)\fR" +/* Enable long, non-repeating, queue IDs (queue file names). /* FILES /* /var/spool/postfix, queue directories /* SEE ALSO @@ -136,9 +140,17 @@ int var_dup_filter_limit; char *var_empty_addr; -#define STRING_FORMAT "%-10s %8s %-20s %s\n" -#define SENDER_FORMAT "%-11s %7ld %20.20s %s\n" -#define DROP_FORMAT "%-10s%c %7ld %20.20s (maildrop queue, sender UID %u)\n" +#define S_STRING_FORMAT "%-10s %8s %-20s %s\n" +#define S_SENDER_FORMAT "%-11s %7ld %20.20s %s\n" +#define S_DROP_FORMAT "%-10s%c %7ld %20.20s (maildrop queue, sender UID %u)\n" +#define S_HEADINGS "-Queue ID-", "--Size--", \ + "----Arrival Time----", "-Sender/Recipient-------" + +#define L_STRING_FORMAT "%-17s %8s %-19s %s\n" +#define L_SENDER_FORMAT "%-17s %8ld %19.19s %s\n" +#define L_DROP_FORMAT "%-16s%c %8ld %19.19s (maildrop queue, sender UID %u)\n" +#define L_HEADINGS "----Queue ID-----", "--Size--", \ + "---Arrival Time----", "--Sender/Recipient------" static void showq_reasons(VSTREAM *, BOUNCE_LOG *, RCPT_BUF *, DSN_BUF *, HTABLE *); @@ -198,7 +210,8 @@ static void showq_report(VSTREAM *client, char *queue, char *id, printable(STR(printable_quoted_addr), '?'); /* quote_822_local() saves buf, so we can reuse its space. */ vstring_sprintf(buf, "%s%c", id, status); - vstream_fprintf(client, SENDER_FORMAT, STR(buf), + vstream_fprintf(client, var_long_queue_ids ? + L_SENDER_FORMAT : S_SENDER_FORMAT, STR(buf), msg_size > 0 ? msg_size : size, arrival_time > 0 ? asctime(localtime(&arrival_time)) : asctime(localtime(&mtime)), @@ -211,7 +224,8 @@ static void showq_report(VSTREAM *client, char *queue, char *id, printable(STR(printable_quoted_addr), '?'); if (dup_filter == 0 || htable_locate(dup_filter, STR(printable_quoted_addr)) == 0) - vstream_fprintf(client, STRING_FORMAT, + vstream_fprintf(client, var_long_queue_ids ? + L_STRING_FORMAT : S_STRING_FORMAT, "", "", "", STR(printable_quoted_addr)); break; case REC_TYPE_MESG: @@ -287,7 +301,8 @@ static void showq_reasons(VSTREAM *client, BOUNCE_LOG *bp, RCPT_BUF *rcpt_buf, padding = 0; vstream_fprintf(client, "%*s(%s)\n", padding, "", saved_reason); } - vstream_fprintf(client, STRING_FORMAT, "", "", "", rcpt->address); + vstream_fprintf(client, var_long_queue_ids ? L_STRING_FORMAT : + S_STRING_FORMAT, "", "", "", rcpt->address); } if (saved_reason) myfree(saved_reason); @@ -353,12 +368,12 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv) saved_id = mystrdup(id); status = mail_open_ok(qp->name, id, &st, &path); if (status == MAIL_OPEN_YES) { - if (file_count == 0) - vstream_fprintf(client, STRING_FORMAT, - "-Queue ID-", "--Size--", - "----Arrival Time----", - "-Sender/Recipient-------"); - else + if (file_count == 0) { + if (var_long_queue_ids) + vstream_fprintf(client, L_STRING_FORMAT, L_HEADINGS); + else + vstream_fprintf(client, S_STRING_FORMAT, S_HEADINGS); + } else vstream_fprintf(client, "\n"); if ((qfile = mail_queue_open(qp->name, id, O_RDONLY, 0)) != 0) { queue_size += st.st_size; @@ -368,7 +383,8 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv) 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, DROP_FORMAT, id, ' ', + vstream_fprintf(client, var_long_queue_ids ? + L_DROP_FORMAT : S_DROP_FORMAT, id, ' ', (long) st.st_size, asctime(localtime(&st.st_mtime)), (unsigned) st.st_uid);