From d510de3fec1abedbc7af638559dab3ef7e26d10e Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Mon, 8 Aug 2033 05:53:25 -0500 Subject: [PATCH] postfix-2.5-20071205 --- postfix/HISTORY | 28 +++++- postfix/README_FILES/INSTALL | 5 ++ postfix/RELEASE_NOTES | 8 ++ postfix/conf/main.cf | 6 ++ postfix/conf/postfix-files | 1 + postfix/conf/postfix-script | 3 + postfix/html/INSTALL.html | 6 ++ postfix/html/mailq.1.html | 47 +++++----- postfix/html/newaliases.1.html | 47 +++++----- postfix/html/postconf.5.html | 19 +++- postfix/html/postfix.1.html | 16 ++-- postfix/html/proxymap.8.html | 65 +++++++++----- postfix/html/sendmail.1.html | 47 +++++----- postfix/man/man1/postfix.1 | 5 ++ postfix/man/man1/sendmail.1 | 5 +- postfix/man/man5/postconf.5 | 13 ++- postfix/man/man8/proxymap.8 | 23 ++++- postfix/mantools/postlink | 1 + postfix/postfix-install | 34 ++++---- postfix/proto/INSTALL.html | 6 ++ postfix/proto/postconf.proto | 15 +++- postfix/src/global/dict_proxy.c | 139 +++++++++++++++++++++++------- postfix/src/global/dict_proxy.h | 1 + postfix/src/global/mail_params.c | 3 + postfix/src/global/mail_params.h | 9 ++ postfix/src/global/mail_version.h | 2 +- postfix/src/oqmgr/qmgr_queue.c | 7 ++ postfix/src/postalias/postalias.c | 16 ++-- postfix/src/postfix/postfix.c | 6 ++ postfix/src/postmap/postmap.c | 16 ++-- postfix/src/proxymap/proxymap.c | 68 ++++++++++++++- postfix/src/qmgr/qmgr_queue.c | 7 ++ postfix/src/sendmail/sendmail.c | 16 ++-- 33 files changed, 515 insertions(+), 175 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index c82088f23..b419c7f81 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -13894,10 +13894,32 @@ Apologies for any names omitted. map that they can't do. Files: postmap/postmap.c, postalias/postalias.c. - Bugfix: the proxymap client didn't properly propagate the - postmap (postalias) -r and -w options to the proxymap server. - File: util/dict.h. + Bugfix: the proxymap client didn't properly propagate user + options options to the proxymap server. File: util/dict.h. Workaround: force synchronous updates in the proxymap server so that maps will be in a consistent state between updates. File: proxymap/proxymap.c. + + Bugfix: an empty rate-limited queue wasn't removed after + timer expiry. Files: *qmgr/qmgr_queue.c. + +20071204 + + Use different sockets for proxymap (read-only) and proxywrite + (read-write) services in the proxy: client. Victor Duchovni. + File: global/dict_proxy.c. + + Feature: proxymap delete support by Victor Duchovni. Files: + global/dict_proxy.c, proxymap/proxymap.c. + + Feature: proxymap delete support. Files: postmap/postmap.c + postalias/postalias.c. + + Cleanup: the Postfix sendmail command did not include the + user (name/uid) information in all error messages. File: + sendmail/sendmail.c. + + Feature: data_directory configuration parameter for + Postfix-writable data such as caches and random numbers. + Files: postfix-install, conf/postfix-files. diff --git a/postfix/README_FILES/INSTALL b/postfix/README_FILES/INSTALL index b8f51e698..28bd4635b 100644 --- a/postfix/README_FILES/INSTALL +++ b/postfix/README_FILES/INSTALL @@ -201,6 +201,8 @@ Parameters whose defaults can be specified in this way are: |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |DEF_DAEMON_DIR |daemon_directory |/usr/libexec/postfix| |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |DEF_DATA_DIR |data_directory |/var/lib/postfix | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |DEF_MAILQ_PATH |mailq_path |/usr/bin/mailq | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |DEF_HTML_DIR |html_directory |no | @@ -216,6 +218,9 @@ Parameters whose defaults can be specified in this way are: |DEF_SENDMAIL_PATH|sendmail_path |/usr/sbin/sendmail | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | +Note: the data_directory parameter (for caches and pseudo-random numbers) was +introduced with Postfix version 2.5. + 44..55 -- SSuuppppoorrtt ffoorr tthhoouussaannddss ooff pprroocceesssseess The number of connections that Postfix can manage simultaneously is limited by diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index ff9099f94..da2fd5d40 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -17,6 +17,14 @@ Incompatibility with Postfix 2.3 and earlier If you upgrade from Postfix 2.3 or earlier, read RELEASE_NOTES-2.4 before proceeding. +Major changes with Postfix snapshot 20071205 +============================================ + +The "make install" and "make upgrade" procedures now create a +postfix-owned directory for Postfix-writable data files such as +caches and random numbers. The location is specified with the +"data_directory" variable (default: "/var/lib/postfix"). + Incompatibility with Postfix snapshot 20071203 ============================================== diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index f321730a3..41f5fa798 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -41,6 +41,12 @@ command_directory = /usr/sbin # daemon_directory = /usr/libexec/postfix +# The data_directory parameter specifies the location of Postfix-writable +# data files (caches, random numbers). This directory must be owned +# by the mail_owner account (see below). +# +data_directory = /var/lib/postfix + # QUEUE AND PROCESS OWNERSHIP # # The mail_owner parameter specifies the owner of the Postfix queue diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files index b63de9a35..7690afc90 100644 --- a/postfix/conf/postfix-files +++ b/postfix/conf/postfix-files @@ -42,6 +42,7 @@ # permissions, so that running "make install" fixes any glitches. # $config_directory:d:root:-:755:u +$data_directory:d:$mail_owner:-:700:u $daemon_directory:d:root:-:755:u $queue_directory:d:root:-:755:uc $sample_directory:d:root:-:755:o diff --git a/postfix/conf/postfix-script b/postfix/conf/postfix-script index 6e3b607c8..8c1efd789 100644 --- a/postfix/conf/postfix-script +++ b/postfix/conf/postfix-script @@ -228,6 +228,9 @@ check-warn) \( -perm -020 -o -perm -002 \) -type f \ -exec $WARN group or other writable: {} \; + find $data_directory/. ! -user $mail_owner \ + -exec $WARN not owned by $mail_owner: {} \; + find `ls -d $queue_directory/* | \ egrep '/(incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \ ! \( -type p -o -type s \) ! -user $mail_owner \ diff --git a/postfix/html/INSTALL.html b/postfix/html/INSTALL.html index ee09a25c2..6d0f6e4f5 100644 --- a/postfix/html/INSTALL.html +++ b/postfix/html/INSTALL.html @@ -308,6 +308,9 @@ default DEF_DAEMON_DIR daemon_directory /usr/libexec/postfix + DEF_DATA_DIR data_directory +/var/lib/postfix + DEF_MAILQ_PATH mailq_path /usr/bin/mailq @@ -333,6 +336,9 @@ default +

Note: the data_directory parameter (for caches and pseudo-random +numbers) was introduced with Postfix version 2.5.

+

4.5 - Support for thousands of processes

The number of connections that Postfix can manage simultaneously diff --git a/postfix/html/mailq.1.html b/postfix/html/mailq.1.html index 52a9a8645..15009baf5 100644 --- a/postfix/html/mailq.1.html +++ b/postfix/html/mailq.1.html @@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1) The maximal number of Received: message headers that is allowed in the primary message headers. - queue_run_delay (version dependent) + queue_run_delay (300s) The time between deferred queue scans by the queue - manager. + manager; prior to Postfix 2.4 the default value was + 1000s. FAST FLUSH CONTROLS The ETRN_README file describes configuration and operation @@ -373,37 +374,37 @@ SENDMAIL(1) SENDMAIL(1) fast_flush_domains ($relay_domains) Optional list of destinations that are eligible for - per-destination logfiles with mail that is queued + per-destination logfiles with mail that is queued to those destinations. VERP CONTROLS The VERP_README file describes configuration and operation - details of Postfix support for variable envelope return + details of Postfix support for variable envelope return path addresses. default_verp_delimiters (+=) The two default VERP delimiter characters. verp_delimiter_filter (-=+) - The characters Postfix accepts as VERP delimiter - characters on the Postfix sendmail(1) command line + The characters Postfix accepts as VERP delimiter + characters on the Postfix sendmail(1) command line and in SMTP commands. MISCELLANEOUS CONTROLS alias_database (see 'postconf -d' output) - The alias databases for local(8) delivery that are + The alias databases for local(8) delivery that are updated with "newaliases" or with "sendmail -bi". command_directory (see 'postconf -d' output) - The location of all postfix administrative com- + The location of all postfix administrative com- mands. 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_directory (see 'postconf -d' output) - The directory with Postfix support programs and + The directory with Postfix support programs and daemon programs. default_database_type (see 'postconf -d' output) @@ -411,16 +412,16 @@ SENDMAIL(1) SENDMAIL(1) postalias(1) and postmap(1) commands. 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. enable_errors_to (no) - Report mail delivery errors to the address speci- - fied with the 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 ver- + Report mail delivery errors to the address speci- + fied with the 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 ver- sions). mail_owner (postfix) @@ -428,21 +429,21 @@ SENDMAIL(1) SENDMAIL(1) and most Postfix daemon processes. 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. 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. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - 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". FILES @@ -467,7 +468,7 @@ SENDMAIL(1) SENDMAIL(1) VERP_README, Postfix VERP howto 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/newaliases.1.html b/postfix/html/newaliases.1.html index 52a9a8645..15009baf5 100644 --- a/postfix/html/newaliases.1.html +++ b/postfix/html/newaliases.1.html @@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1) The maximal number of Received: message headers that is allowed in the primary message headers. - queue_run_delay (version dependent) + queue_run_delay (300s) The time between deferred queue scans by the queue - manager. + manager; prior to Postfix 2.4 the default value was + 1000s. FAST FLUSH CONTROLS The ETRN_README file describes configuration and operation @@ -373,37 +374,37 @@ SENDMAIL(1) SENDMAIL(1) fast_flush_domains ($relay_domains) Optional list of destinations that are eligible for - per-destination logfiles with mail that is queued + per-destination logfiles with mail that is queued to those destinations. VERP CONTROLS The VERP_README file describes configuration and operation - details of Postfix support for variable envelope return + details of Postfix support for variable envelope return path addresses. default_verp_delimiters (+=) The two default VERP delimiter characters. verp_delimiter_filter (-=+) - The characters Postfix accepts as VERP delimiter - characters on the Postfix sendmail(1) command line + The characters Postfix accepts as VERP delimiter + characters on the Postfix sendmail(1) command line and in SMTP commands. MISCELLANEOUS CONTROLS alias_database (see 'postconf -d' output) - The alias databases for local(8) delivery that are + The alias databases for local(8) delivery that are updated with "newaliases" or with "sendmail -bi". command_directory (see 'postconf -d' output) - The location of all postfix administrative com- + The location of all postfix administrative com- mands. 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_directory (see 'postconf -d' output) - The directory with Postfix support programs and + The directory with Postfix support programs and daemon programs. default_database_type (see 'postconf -d' output) @@ -411,16 +412,16 @@ SENDMAIL(1) SENDMAIL(1) postalias(1) and postmap(1) commands. 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. enable_errors_to (no) - Report mail delivery errors to the address speci- - fied with the 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 ver- + Report mail delivery errors to the address speci- + fied with the 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 ver- sions). mail_owner (postfix) @@ -428,21 +429,21 @@ SENDMAIL(1) SENDMAIL(1) and most Postfix daemon processes. 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. 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. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - 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". FILES @@ -467,7 +468,7 @@ SENDMAIL(1) SENDMAIL(1) VERP_README, Postfix VERP howto 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 cc7f6d06d..7d364d855 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -1500,6 +1500,19 @@ The default time unit is s (seconds).

+ + +
data_directory +(default: see "postconf -d" output)
+ +

The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). This directory must be owned by +the mail_owner account, and must not be shared with non-Postfix +software.

+ +

This feature is available in Postfix 2.5 and later.

+ +
debug_peer_level @@ -6168,8 +6181,10 @@ This feature is available in Postfix 2.0 and later. (default: see "postconf -d" output)

-The lookup tables that the proxymap(8) server is allowed to -access for the read-write service. +The lookup tables that the proxymap(8) server is allowed to access +for the read-write service. If implemented with local files, these +tables are preferably stored under the location specified with the +data_directory configuration parameter. Table references that don't begin with proxy: are ignored.

diff --git a/postfix/html/postfix.1.html b/postfix/html/postfix.1.html index 56c38c773..cd1f1e3de 100644 --- a/postfix/html/postfix.1.html +++ b/postfix/html/postfix.1.html @@ -173,14 +173,20 @@ POSTFIX(1) POSTFIX(1) how to build, configure or operate a specific Post- fix subsystem or feature. + Available in Postfix version 2.5 and later: + + data_directory (see 'postconf -d' output) + The directory with Postfix-writable data files (for + example: caches, pseudo-random numbers). + Other configuration parameters: 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. import_environment (see 'postconf -d' output) - The list of environment parameters that a Postfix + The list of environment parameters that a Postfix process will import from a non-Postfix parent process. @@ -188,8 +194,8 @@ POSTFIX(1) POSTFIX(1) The syslog facility of Postfix logging. syslog_name (postfix) - 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". FILES @@ -277,7 +283,7 @@ POSTFIX(1) POSTFIX(1) QSHAPE_README, Postfix queue analysis 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/proxymap.8.html b/postfix/html/proxymap.8.html index 39a39c760..48100fe83 100644 --- a/postfix/html/proxymap.8.html +++ b/postfix/html/proxymap.8.html @@ -71,6 +71,14 @@ PROXYMAP(8) PROXYMAP(8) This request is supported in Postfix 2.5 and later. + delete maptype:mapname flags key + Delete the data stored under the requested key. + The reply is the request completion status code. + The maptype:mapname and flags are the same as with + the open request. + + This request is supported in Postfix 2.5 and later. + The request completion status is one of OK, RETRY, NOKEY (lookup failed because the key was not found), BAD (mal- formed request) or DENY (the table is not approved for @@ -108,39 +116,48 @@ PROXYMAP(8) PROXYMAP(8) same main.cf setting to be used by sensitive and non-sen- sitive processes. + Postfix-writable data files should be stored under a dedi- + cated directory that is writable only by the $mail_owner + account, such as the $data_directory directory. + + In particular, Postfix-writable files should never exist + in root-owned directories. That would open up a particular + type of security hole where ownership (root) does not + match content provenance (Postfix). + DIAGNOSTICS Problems and transactions are logged to syslogd(8). BUGS - The proxymap(8) server provides service to multiple - clients, and must therefore not be used for tables that + The proxymap(8) server provides service to multiple + clients, and must therefore not be used for tables that have high-latency lookups. - The proxymap(8) read-write service does not explicitly - close lookup tables (even if it did, this could not be - relied on, because the process may be terminated between - table updates). The read-write service should therefore - not be used with tables that leave persistent storage in - an inconsistent state between updates (for example, CDB). - Tables that support "sync on update" should be safe (for - example, Berkeley DB) as should tables that are imple- + The proxymap(8) read-write service does not explicitly + close lookup tables (even if it did, this could not be + relied on, because the process may be terminated between + table updates). The read-write service should therefore + not be used with tables that leave persistent storage in + an inconsistent state between updates (for example, CDB). + Tables that support "sync on update" should be safe (for + example, Berkeley DB) as should tables that are imple- mented by a real DBMS. CONFIGURATION PARAMETERS - On busy mail systems a long time may pass before prox- + On busy mail systems a long time may pass before prox- ymap(8) relevant changes to main.cf are picked up. Use the command "postfix reload" to speed up a change. - The text below provides only a parameter summary. See + The text below provides only a parameter summary. See postconf(5) for more details including examples. 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. ipc_timeout (3600s) @@ -148,29 +165,33 @@ PROXYMAP(8) PROXYMAP(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. 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. proxy_read_maps (see 'postconf -d' output) - The lookup tables that the proxymap(8) server is + The lookup tables that the proxymap(8) server is allowed to access for the read-only service. Available in Postfix 2.5 and later: + data_directory (see 'postconf -d' output) + The directory with Postfix-writable data files (for + example: caches, pseudo-random numbers). + proxy_write_maps (see 'postconf -d' output) The lookup tables that the proxymap(8) server is allowed to access for the read-write service. diff --git a/postfix/html/sendmail.1.html b/postfix/html/sendmail.1.html index 52a9a8645..15009baf5 100644 --- a/postfix/html/sendmail.1.html +++ b/postfix/html/sendmail.1.html @@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1) The maximal number of Received: message headers that is allowed in the primary message headers. - queue_run_delay (version dependent) + queue_run_delay (300s) The time between deferred queue scans by the queue - manager. + manager; prior to Postfix 2.4 the default value was + 1000s. FAST FLUSH CONTROLS The ETRN_README file describes configuration and operation @@ -373,37 +374,37 @@ SENDMAIL(1) SENDMAIL(1) fast_flush_domains ($relay_domains) Optional list of destinations that are eligible for - per-destination logfiles with mail that is queued + per-destination logfiles with mail that is queued to those destinations. VERP CONTROLS The VERP_README file describes configuration and operation - details of Postfix support for variable envelope return + details of Postfix support for variable envelope return path addresses. default_verp_delimiters (+=) The two default VERP delimiter characters. verp_delimiter_filter (-=+) - The characters Postfix accepts as VERP delimiter - characters on the Postfix sendmail(1) command line + The characters Postfix accepts as VERP delimiter + characters on the Postfix sendmail(1) command line and in SMTP commands. MISCELLANEOUS CONTROLS alias_database (see 'postconf -d' output) - The alias databases for local(8) delivery that are + The alias databases for local(8) delivery that are updated with "newaliases" or with "sendmail -bi". command_directory (see 'postconf -d' output) - The location of all postfix administrative com- + The location of all postfix administrative com- mands. 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_directory (see 'postconf -d' output) - The directory with Postfix support programs and + The directory with Postfix support programs and daemon programs. default_database_type (see 'postconf -d' output) @@ -411,16 +412,16 @@ SENDMAIL(1) SENDMAIL(1) postalias(1) and postmap(1) commands. 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. enable_errors_to (no) - Report mail delivery errors to the address speci- - fied with the 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 ver- + Report mail delivery errors to the address speci- + fied with the 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 ver- sions). mail_owner (postfix) @@ -428,21 +429,21 @@ SENDMAIL(1) SENDMAIL(1) and most Postfix daemon processes. 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. 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. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - 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". FILES @@ -467,7 +468,7 @@ SENDMAIL(1) SENDMAIL(1) VERP_README, Postfix VERP howto 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/postfix.1 b/postfix/man/man1/postfix.1 index 5a2087f8a..4d46606e9 100644 --- a/postfix/man/man1/postfix.1 +++ b/postfix/man/man1/postfix.1 @@ -142,6 +142,11 @@ Where the Postfix manual pages are installed. The location of Postfix README files that describe how to build, configure or operate a specific Postfix subsystem or feature. .PP +Available in Postfix version 2.5 and later: +.IP "\fBdata_directory (see 'postconf -d' output)\fR" +The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). +.PP Other configuration parameters: .IP "\fBconfig_directory (see 'postconf -d' output)\fR" The default location of the Postfix main.cf and master.cf diff --git a/postfix/man/man1/sendmail.1 b/postfix/man/man1/sendmail.1 index 04ba044f9..c3873cd7c 100644 --- a/postfix/man/man1/sendmail.1 +++ b/postfix/man/man1/sendmail.1 @@ -308,8 +308,9 @@ The delay between attempts to fork() a child process. .IP "\fBhopcount_limit (50)\fR" The maximal number of Received: message headers that is allowed in the primary message headers. -.IP "\fBqueue_run_delay (version dependent)\fR" -The time between deferred queue scans by the queue manager. +.IP "\fBqueue_run_delay (300s)\fR" +The time between deferred queue scans by the queue manager; +prior to Postfix 2.4 the default value was 1000s. .SH "FAST FLUSH CONTROLS" .na .nf diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index c14d6a850..e204a342a 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -817,6 +817,13 @@ request before it is terminated by a built-in watchdog timer. .PP Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). The default time unit is s (seconds). +.SH data_directory (default: see "postconf -d" output) +The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). This directory must be owned by +the mail_owner account, and must not be shared with non-Postfix +software. +.PP +This feature is available in Postfix 2.5 and later. .SH debug_peer_level (default: 2) The increment in verbose logging level when a remote client or server matches a pattern in the debug_peer_list parameter. @@ -3429,8 +3436,10 @@ Table references that don't begin with proxy: are ignored. .PP This feature is available in Postfix 2.0 and later. .SH proxy_write_maps (default: see "postconf -d" output) -The lookup tables that the \fBproxymap\fR(8) server is allowed to -access for the read-write service. +The lookup tables that the \fBproxymap\fR(8) server is allowed to access +for the read-write service. If implemented with local files, these +tables are preferably stored under the location specified with the +data_directory configuration parameter. Table references that don't begin with proxy: are ignored. .PP This feature is available in Postfix 2.5 and later. diff --git a/postfix/man/man8/proxymap.8 b/postfix/man/man8/proxymap.8 index 205e967c4..6d6aa619d 100644 --- a/postfix/man/man8/proxymap.8 +++ b/postfix/man/man8/proxymap.8 @@ -68,6 +68,13 @@ of 1 in the master.cf file entry for the \fBproxywrite\fR service. .sp This request is supported in Postfix 2.5 and later. +.IP "\fBdelete\fR \fImaptype:mapname flags key\fR" +Delete the data stored under the requested key. +The reply is the request completion status code. +The \fImaptype:mapname\fR and \fIflags\fR are the same +as with the \fBopen\fR request. +.sp +This request is supported in Postfix 2.5 and later. .PP The request completion status is one of OK, RETRY, NOKEY (lookup failed because the key was not found), BAD (malformed @@ -110,6 +117,15 @@ In Postfix version 2.2 and later, the proxymap client recognizes requests to access a table for security-sensitive purposes, and opens the table directly. This allows the same main.cf setting to be used by sensitive and non-sensitive processes. + +Postfix-writable data files should be stored under a dedicated +directory that is writable only by the $\fBmail_owner\fR +account, such as the $\fBdata_directory\fR directory. + +In particular, Postfix-writable files should never exist +in root-owned directories. That would open up a particular +type of security hole where ownership (root) does not match +content provenance (Postfix). .SH DIAGNOSTICS .ad .fi @@ -165,9 +181,12 @@ The lookup tables that the \fBproxymap\fR(8) server is allowed to access for the read-only service. .PP Available in Postfix 2.5 and later: +.IP "\fBdata_directory (see 'postconf -d' output)\fR" +The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). .IP "\fBproxy_write_maps (see 'postconf -d' output)\fR" -The lookup tables that the \fBproxymap\fR(8) server is allowed to -access for the read-write service. +The lookup tables that the \fBproxymap\fR(8) server is allowed to access +for the read-write service. .SH "SEE ALSO" .na .nf diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 1812212c3..b555db6a2 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -123,6 +123,7 @@ while (<>) { s;\bcommand_time_limit\b;$&;g; s;\bconfig_direc[-]*\n*[ ]*tory\b;$&;g; s;\bcon[-]*\n*[ ]*tent_filter\b;$&;g; + s;\bdata_directory\b;$&;g; s;\bdae[-]*\n*[ ]*mon_directory\b;$&;g; s;\bdaemon_timeout\b;$&;g; s;\bdebug_peer_level\b;$&;g; diff --git a/postfix/postfix-install b/postfix/postfix-install index 28258ea5d..b8286a5d4 100644 --- a/postfix/postfix-install +++ b/postfix/postfix-install @@ -88,6 +88,11 @@ # The built-in default directory name is /etc/postfix. # This parameter setting is not recorded in the installed main.cf file # and can be changed only by recompiling Postfix. +# .IP data_directory +# The final destination directory for Postfix-writable data files such +# as caches. This directory should not be shared with non-Postfix +# software. The built-in default directory name is /var/lib/postfix. +# This parameter setting is recorded in the installed main.cf file. # .IP daemon_directory # The final destination directory for Postfix daemon programs. This # directory should not be in the command search path of any users. @@ -308,6 +313,10 @@ Postfix. You must have write permission in this directory." config_directory_prompt="the final destination directory for installed Postfix configuration files." +data_directory_prompt="the final destination directory for +Postfix-writable data files such as caches or random numbers. This +directory should not be shared with non-Postfix software." + daemon_directory_prompt="the final destination directory for installed Postfix daemon programs. This directory should not be in the command search path of any users." @@ -344,9 +353,6 @@ mail_owner account. You can no longer specify \"no\" here." manpage_directory_prompt="the destination directory for the Postfix on-line manual pages. You can no longer specify \"no\" here." -sample_directory_prompt="the destination directory for the Postfix -sample configuration files." - readme_directory_prompt="the destination directory for the Postfix README files. Specify \"no\" if you do not want to install these files." @@ -414,12 +420,14 @@ grep setgid_group $CONFIG_DIRECTORY/main.cf >/dev/null 2>&1 || { } } +CONFIG_PARAMS="command_directory daemon_directory data_directory \ +html_directory mail_owner mailq_path manpage_directory newaliases_path \ +queue_directory readme_directory sendmail_path setgid_group" + # Extract parameter settings from the installed main.cf file. test -f $CONFIG_DIRECTORY/main.cf && { - for name in daemon_directory command_directory queue_directory mail_owner \ - setgid_group sendmail_path newaliases_path mailq_path manpage_directory \ - sample_directory html_directory readme_directory + for name in $CONFIG_PARAMS sample_directory do eval junk=\$$name case "$junk" in @@ -432,9 +440,7 @@ test -f $CONFIG_DIRECTORY/main.cf && { # Use built-in defaults as the final source of parameter settings. -for name in daemon_directory command_directory queue_directory mail_owner \ - setgid_group sendmail_path newaliases_path mailq_path manpage_directory \ - sample_directory html_directory readme_directory +for name in $CONFIG_PARAMS sample_directory do eval junk=\$$name case "$junk" in @@ -445,9 +451,7 @@ done # Override settings manually. -test -z "$non_interactive" && for name in daemon_directory command_directory \ - queue_directory sendmail_path newaliases_path mailq_path mail_owner \ - setgid_group html_directory manpage_directory readme_directory +test -z "$non_interactive" && for name in $CONFIG_PARAMS do while : do @@ -490,7 +494,7 @@ do esac done -for path in "$daemon_directory" "$command_directory" "$queue_directory" \ +for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \ "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" do case "$path" in @@ -507,7 +511,7 @@ do } done -for path in command_directory config_directory daemon_directory \ +for path in command_directory config_directory daemon_directory data_directory \ manpage_directory queue_directory html_directory readme_directory do eval test -f $install_root\$$path && { @@ -559,7 +563,6 @@ QUEUE_DIRECTORY=$install_root$queue_directory SENDMAIL_PATH=$install_root$sendmail_path HTML_DIRECTORY=$install_root$html_directory MANPAGE_DIRECTORY=$install_root$manpage_directory -SAMPLE_DIRECTORY=$install_root$sample_directory README_DIRECTORY=$install_root$readme_directory # Avoid repeated tests for existence of these; default permissions suffice. @@ -723,6 +726,7 @@ do bin/postconf -c $CONFIG_DIRECTORY -e \ "daemon_directory = $daemon_directory" \ + "data_directory = $data_directory" \ "command_directory = $command_directory" \ "queue_directory = $queue_directory" \ "mail_owner = $mail_owner" \ diff --git a/postfix/proto/INSTALL.html b/postfix/proto/INSTALL.html index c689b001e..74a8653c8 100644 --- a/postfix/proto/INSTALL.html +++ b/postfix/proto/INSTALL.html @@ -308,6 +308,9 @@ default DEF_DAEMON_DIR daemon_directory /usr/libexec/postfix + DEF_DATA_DIR data_directory +/var/lib/postfix + DEF_MAILQ_PATH mailq_path /usr/bin/mailq @@ -333,6 +336,9 @@ default +

Note: the data_directory parameter (for caches and pseudo-random +numbers) was introduced with Postfix version 2.5.

+

4.5 - Support for thousands of processes

The number of connections that Postfix can manage simultaneously diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index d5002584f..8a1889615 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -7216,8 +7216,10 @@ This feature is available in Postfix 2.0 and later. %PARAM proxy_write_maps see "postconf -d" output

-The lookup tables that the proxymap(8) server is allowed to -access for the read-write service. +The lookup tables that the proxymap(8) server is allowed to access +for the read-write service. If implemented with local files, these +tables are preferably stored under the location specified with the +data_directory configuration parameter. Table references that don't begin with proxy: are ignored.

@@ -11030,3 +11032,12 @@ parameter value, where transport is the master.cf name of the message delivery transport.

This feature is available in Postfix 2.5 and later.

+ +%PARAM data_directory see "postconf -d" output + +

The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). This directory must be owned by +the mail_owner account, and must not be shared with non-Postfix +software.

+ +

This feature is available in Postfix 2.5 and later.

diff --git a/postfix/src/global/dict_proxy.c b/postfix/src/global/dict_proxy.c index e4f788473..8005c8d36 100644 --- a/postfix/src/global/dict_proxy.c +++ b/postfix/src/global/dict_proxy.c @@ -70,6 +70,8 @@ typedef struct { DICT dict; /* generic members */ + CLNT_STREAM *clnt; /* client handle (shared) */ + const char *service; /* service name */ int in_flags; /* caller-specified flags */ VSTRING *result; /* storage */ } DICT_PROXY; @@ -81,9 +83,10 @@ typedef struct { #define VSTREQ(v,s) (strcmp(STR(v),s) == 0) /* - * All proxied maps within a process share the same query/reply socket. + * All proxied maps of the same type share the same query/reply socket. */ -static CLNT_STREAM *proxy_stream; +static CLNT_STREAM *proxymap_stream; /* read-only maps */ +static CLNT_STREAM *proxywrite_stream; /* read-write maps */ /* dict_proxy_lookup - find table entry */ @@ -108,7 +111,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK) | (dict->flags & DICT_FLAG_RQST_MASK); for (;;) { - stream = clnt_stream_access(proxy_stream); + stream = clnt_stream_access(dict_proxy->clnt); errno = 0; count += 1; if (attr_print(stream, ATTR_FLAG_NONE, @@ -134,10 +137,10 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) case PROXY_STAT_BAD: msg_fatal("%s lookup failed for table \"%s\" key \"%s\": " "invalid request", - MAIL_SERVICE_PROXYMAP, dict->name, key); + dict_proxy->service, dict->name, key); case PROXY_STAT_DENY: msg_fatal("%s service is not configured for table \"%s\"", - MAIL_SERVICE_PROXYMAP, dict->name); + dict_proxy->service, dict->name); case PROXY_STAT_OK: return (STR(dict_proxy->result)); case PROXY_STAT_NOKEY: @@ -149,10 +152,10 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) default: msg_warn("%s lookup failed for table \"%s\" key \"%s\": " "unexpected reply status %d", - MAIL_SERVICE_PROXYMAP, dict->name, key, status); + dict_proxy->service, dict->name, key, status); } } - clnt_stream_recover(proxy_stream); + clnt_stream_recover(dict_proxy->clnt); sleep(1); /* XXX make configurable */ } } @@ -178,7 +181,7 @@ static void dict_proxy_update(DICT *dict, const char *key, const char *value) request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK) | (dict->flags & DICT_FLAG_RQST_MASK); for (;;) { - stream = clnt_stream_access(proxy_stream); + stream = clnt_stream_access(dict_proxy->clnt); errno = 0; count += 1; if (attr_print(stream, ATTR_FLAG_NONE, @@ -197,25 +200,90 @@ static void dict_proxy_update(DICT *dict, const char *key, const char *value) } else { if (msg_verbose) msg_info("%s: table=%s flags=%s key=%s value=%s -> status=%d", - myname, dict->name, dict_flags_str(request_flags), + myname, dict->name, dict_flags_str(request_flags), key, value, status); switch (status) { case PROXY_STAT_BAD: - msg_fatal("%s lookup failed for table \"%s\" key \"%s\": " + msg_fatal("%s update failed for table \"%s\" key \"%s\": " "invalid request", - MAIL_SERVICE_PROXYMAP, dict->name, key); + dict_proxy->service, dict->name, key); case PROXY_STAT_DENY: msg_fatal("%s update access is not configured for table \"%s\"", - MAIL_SERVICE_PROXYMAP, dict->name); + dict_proxy->service, dict->name); case PROXY_STAT_OK: return; default: msg_warn("%s update failed for table \"%s\" key \"%s\": " "unexpected reply status %d", - MAIL_SERVICE_PROXYMAP, dict->name, key, status); + dict_proxy->service, dict->name, key, status); } } - clnt_stream_recover(proxy_stream); + clnt_stream_recover(dict_proxy->clnt); + sleep(1); /* XXX make configurable */ + } +} + +/* dict_proxy_delete - delete table entry */ + +static int dict_proxy_delete(DICT *dict, const char *key) +{ + const char *myname = "dict_proxy_delete"; + DICT_PROXY *dict_proxy = (DICT_PROXY *) dict; + VSTREAM *stream; + int status; + int count = 0; + int request_flags; + + /* + * The client and server live in separate processes that may start and + * terminate independently. We cannot rely on a persistent connection, + * let alone on persistent state (such as a specific open table) that is + * associated with a specific connection. Each lookup needs to specify + * the table and the flags that were specified to dict_proxy_open(). + */ + request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK) + | (dict->flags & DICT_FLAG_RQST_MASK); + for (;;) { + stream = clnt_stream_access(dict_proxy->clnt); + errno = 0; + count += 1; + if (attr_print(stream, ATTR_FLAG_NONE, + ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_DELETE, + ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name, + ATTR_TYPE_INT, MAIL_ATTR_FLAGS, request_flags, + ATTR_TYPE_STR, MAIL_ATTR_KEY, key, + ATTR_TYPE_END) != 0 + || vstream_fflush(stream) + || attr_scan(stream, ATTR_FLAG_STRICT, + ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, + ATTR_TYPE_END) != 1) { + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != + ENOENT)) + msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream)); + } else { + if (msg_verbose) + msg_info("%s: table=%s flags=%s key=%s -> status=%d", + myname, dict->name, dict_flags_str(request_flags), + key, status); + switch (status) { + case PROXY_STAT_BAD: + msg_fatal("%s delete failed for table \"%s\" key \"%s\": " + "invalid request", + dict_proxy->service, dict->name, key); + case PROXY_STAT_DENY: + msg_fatal("%s update access is not configured for table \"%s\"", + dict_proxy->service, dict->name); + case PROXY_STAT_OK: + return 0; + case PROXY_STAT_NOKEY: + return 1; + default: + msg_warn("%s delete failed for table \"%s\" key \"%s\": " + "unexpected reply status %d", + dict_proxy->service, dict->name, key, status); + } + } + clnt_stream_recover(dict_proxy->clnt); sleep(1); /* XXX make configurable */ } } @@ -239,8 +307,11 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) VSTREAM *stream; int server_flags; int status; + const char *service; + const char *relative_path; char *kludge = 0; char *prefix; + CLNT_STREAM **pstream; /* * Sanity checks. @@ -250,7 +321,15 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) * server; only sets that make sense. For now, the flags are passed * implicitly by choosing between the proxymap or proxywrite service. */ - if (open_flags != O_RDONLY && open_flags != (O_RDWR | O_CREAT)) + if (open_flags == O_RDONLY) { + pstream = &proxymap_stream; + service = MAIL_SERVICE_PROXYMAP; + relative_path = MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP; + } else if (open_flags == (O_RDWR | O_CREAT)) { + pstream = &proxywrite_stream; + service = MAIL_SERVICE_PROXYWRITE; + relative_path = MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYWRITE; + } else msg_fatal("%s: %s map open requires O_RDONLY or O_RDWR|O_CREAT mode", map, DICT_TYPE_PROXY); @@ -269,33 +348,29 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) dict_alloc(DICT_TYPE_PROXY, map, sizeof(*dict_proxy)); dict_proxy->dict.lookup = dict_proxy_lookup; dict_proxy->dict.update = dict_proxy_update; + dict_proxy->dict.delete = dict_proxy_delete; dict_proxy->dict.close = dict_proxy_close; dict_proxy->in_flags = dict_flags; dict_proxy->result = vstring_alloc(10); /* - * Use a shared stream for all proxied table lookups. + * Use a shared stream for proxied table lookups of the same type. * * XXX Use absolute pathname to make this work from non-daemon processes. */ - if (proxy_stream == 0) { - if (access(open_flags == O_RDONLY ? - MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP : - MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYWRITE, - F_OK) == 0) + if (*pstream == 0) { + if (access(relative_path, F_OK) == 0) prefix = MAIL_CLASS_PRIVATE; else prefix = kludge = concatenate(var_queue_dir, "/", MAIL_CLASS_PRIVATE, (char *) 0); - proxy_stream = clnt_stream_create(prefix, - open_flags == O_RDONLY ? - MAIL_SERVICE_PROXYMAP : - MAIL_SERVICE_PROXYWRITE, - var_ipc_idle_limit, - var_ipc_ttl_limit); + *pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit, + var_ipc_ttl_limit); if (kludge) myfree(kludge); } + dict_proxy->clnt = *pstream; + dict_proxy->service = service; /* * Establish initial contact and get the map type specific flags. @@ -303,7 +378,7 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) * XXX Should retrieve flags from local instance. */ for (;;) { - stream = clnt_stream_access(proxy_stream); + stream = clnt_stream_access(dict_proxy->clnt); errno = 0; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_OPEN, @@ -325,20 +400,20 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) switch (status) { case PROXY_STAT_BAD: msg_fatal("%s open failed for table \"%s\": invalid request", - MAIL_SERVICE_PROXYMAP, dict_proxy->dict.name); + dict_proxy->service, dict_proxy->dict.name); case PROXY_STAT_DENY: msg_fatal("%s service is not configured for table \"%s\"", - MAIL_SERVICE_PROXYMAP, dict_proxy->dict.name); + dict_proxy->service, dict_proxy->dict.name); case PROXY_STAT_OK: dict_proxy->dict.flags = dict_proxy->in_flags | (server_flags & DICT_FLAG_IMPL_MASK); return (DICT_DEBUG (&dict_proxy->dict)); default: msg_warn("%s open failed for table \"%s\": unexpected status %d", - MAIL_SERVICE_PROXYMAP, dict_proxy->dict.name, status); + dict_proxy->service, dict_proxy->dict.name, status); } } - clnt_stream_recover(proxy_stream); + clnt_stream_recover(dict_proxy->clnt); sleep(1); /* XXX make configurable */ } } diff --git a/postfix/src/global/dict_proxy.h b/postfix/src/global/dict_proxy.h index 2a1e3fd21..6d55842d4 100644 --- a/postfix/src/global/dict_proxy.h +++ b/postfix/src/global/dict_proxy.h @@ -29,6 +29,7 @@ extern DICT *dict_proxy_open(const char *, int, int); #define PROXY_REQ_OPEN "open" #define PROXY_REQ_LOOKUP "lookup" #define PROXY_REQ_UPDATE "update" +#define PROXY_REQ_DELETE "delete" #define PROXY_STAT_OK 0 /* operation succeeded */ #define PROXY_STAT_NOKEY 1 /* requested key not found */ diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index d12e4bd90..54e48368f 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -26,6 +26,7 @@ /* gid_t var_default_gid; /* char *var_config_dir; /* char *var_daemon_dir; +/* char *var_data_dir; /* char *var_command_dir; /* char *var_queue_dir; /* int var_use_limit; @@ -200,6 +201,7 @@ uid_t var_default_uid; gid_t var_default_gid; char *var_config_dir; char *var_daemon_dir; +char *var_data_dir; char *var_command_dir; char *var_queue_dir; int var_use_limit; @@ -504,6 +506,7 @@ void mail_params_init() VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0, VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0, VAR_DAEMON_DIR, DEF_DAEMON_DIR, &var_daemon_dir, 1, 0, + VAR_DATA_DIR, DEF_DATA_DIR, &var_data_dir, 1, 0, VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0, VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0, VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0, diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index ca7679f47..aac05a6ba 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -260,6 +260,15 @@ extern char *var_command_dir; #endif extern char *var_pid_dir; + /* + * Location of writable data files. + */ +#define VAR_DATA_DIR "data_directory" +#ifndef DEF_DATA_DIR +#define DEF_DATA_DIR "/var/lib/postfix" +#endif +extern char *var_data_dir; + /* * Program startup time. */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 287cba84b..3e91849b7 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 "2007111204" +#define MAIL_RELEASE_DATE "2007111205" #define MAIL_VERSION_NUMBER "2.5" #ifdef SNAPSHOT diff --git a/postfix/src/oqmgr/qmgr_queue.c b/postfix/src/oqmgr/qmgr_queue.c index ae3de84c2..1cc8f50c9 100644 --- a/postfix/src/oqmgr/qmgr_queue.c +++ b/postfix/src/oqmgr/qmgr_queue.c @@ -148,6 +148,13 @@ static void qmgr_queue_resume(int event, char *context) queue->window = 1; if (queue->todo_refcount > 0) qmgr_active_drain(); + + /* + * Every event handler that leaves a queue in the "ready" state should + * remove the queue when it is empty. + */ + if (QMGR_QUEUE_READY(queue) && queue->todo.next == 0 && queue->busy.next == 0) + qmgr_queue_done(queue); } /* qmgr_queue_suspend - briefly suspend a destination */ diff --git a/postfix/src/postalias/postalias.c b/postfix/src/postalias/postalias.c index 186601f56..cd0569173 100644 --- a/postfix/src/postalias/postalias.c +++ b/postfix/src/postalias/postalias.c @@ -516,6 +516,7 @@ static int postalias_deletes(VSTREAM *in, char **maps, const int map_count, DICT **dicts; const char *map_name; int n; + int open_flags; /* * Sanity check. @@ -530,10 +531,12 @@ static int postalias_deletes(VSTREAM *in, char **maps, const int map_count, for (n = 0; n < map_count; n++) { map_name = split_at(maps[n], ':'); if (map_name && strcmp(maps[n], DICT_TYPE_PROXY) == 0) - msg_fatal("can't delete map entries via the proxy service"); + open_flags = O_RDWR | O_CREAT; /* XXX */ + else + open_flags = O_RDWR; dicts[n] = (map_name != 0 ? - dict_open3(maps[n], map_name, O_RDWR, dict_flags) : - dict_open3(var_db_type, maps[n], O_RDWR, dict_flags)); + dict_open3(maps[n], map_name, open_flags, dict_flags) : + dict_open3(var_db_type, maps[n], open_flags, dict_flags)); } /* @@ -562,10 +565,13 @@ static int postalias_delete(const char *map_type, const char *map_name, { DICT *dict; int status; + int open_flags; if (strcmp(map_type, DICT_TYPE_PROXY) == 0) - msg_fatal("can't delete map entries via the proxy service"); - dict = dict_open3(map_type, map_name, O_RDWR, dict_flags); + open_flags = O_RDWR | O_CREAT; /* XXX */ + else + open_flags = O_RDWR; + dict = dict_open3(map_type, map_name, open_flags, dict_flags); status = dict_del(dict, key); dict_close(dict); return (status == 0); diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index a0a4a9609..132aedd6f 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -132,6 +132,11 @@ /* The location of Postfix README files that describe how to build, /* configure or operate a specific Postfix subsystem or feature. /* .PP +/* Available in Postfix version 2.5 and later: +/* .IP "\fBdata_directory (see 'postconf -d' output)\fR" +/* The directory with Postfix-writable data files (for example: +/* caches, pseudo-random numbers). +/* .PP /* Other configuration parameters: /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" /* The default location of the Postfix main.cf and master.cf @@ -430,6 +435,7 @@ int main(int argc, char **argv) check_setenv(VAR_COMMAND_DIR, var_command_dir); /* main.cf */ check_setenv(VAR_DAEMON_DIR, var_daemon_dir); /* main.cf */ + check_setenv(VAR_DATA_DIR, var_data_dir); /* main.cf */ check_setenv(VAR_QUEUE_DIR, var_queue_dir); /* main.cf */ check_setenv(VAR_CONFIG_DIR, var_config_dir); /* main.cf */ diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c index 2631c7e45..f2f28e0b5 100644 --- a/postfix/src/postmap/postmap.c +++ b/postfix/src/postmap/postmap.c @@ -463,6 +463,7 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count, DICT **dicts; const char *map_name; int n; + int open_flags; /* * Sanity check. @@ -477,10 +478,12 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count, for (n = 0; n < map_count; n++) { map_name = split_at(maps[n], ':'); if (map_name && strcmp(maps[n], DICT_TYPE_PROXY) == 0) - msg_fatal("can't delete map entries via the proxy service"); + open_flags = O_RDWR | O_CREAT; /* XXX */ + else + open_flags = O_RDWR; dicts[n] = (map_name != 0 ? - dict_open3(maps[n], map_name, O_RDWR, dict_flags) : - dict_open3(var_db_type, maps[n], O_RDWR, dict_flags)); + dict_open3(maps[n], map_name, open_flags, dict_flags) : + dict_open3(var_db_type, maps[n], open_flags, dict_flags)); } /* @@ -509,10 +512,13 @@ static int postmap_delete(const char *map_type, const char *map_name, { DICT *dict; int status; + int open_flags; if (strcmp(map_type, DICT_TYPE_PROXY) == 0) - msg_fatal("can't delete map entries via the proxy service"); - dict = dict_open3(map_type, map_name, O_RDWR, dict_flags); + open_flags = O_RDWR | O_CREAT; /* XXX */ + else + open_flags = O_RDWR; + dict = dict_open3(map_type, map_name, open_flags, dict_flags); status = dict_del(dict, key); dict_close(dict); return (status == 0); diff --git a/postfix/src/proxymap/proxymap.c b/postfix/src/proxymap/proxymap.c index c3b5e23d4..2a3c392af 100644 --- a/postfix/src/proxymap/proxymap.c +++ b/postfix/src/proxymap/proxymap.c @@ -62,6 +62,13 @@ /* service. /* .sp /* This request is supported in Postfix 2.5 and later. +/* .IP "\fBdelete\fR \fImaptype:mapname flags key\fR" +/* Delete the data stored under the requested key. +/* The reply is the request completion status code. +/* The \fImaptype:mapname\fR and \fIflags\fR are the same +/* as with the \fBopen\fR request. +/* .sp +/* This request is supported in Postfix 2.5 and later. /* .PP /* The request completion status is one of OK, RETRY, NOKEY /* (lookup failed because the key was not found), BAD (malformed @@ -100,6 +107,15 @@ /* requests to access a table for security-sensitive purposes, /* and opens the table directly. This allows the same main.cf /* setting to be used by sensitive and non-sensitive processes. +/* +/* Postfix-writable data files should be stored under a dedicated +/* directory that is writable only by the $\fBmail_owner\fR +/* account, such as the $\fBdata_directory\fR directory. +/* +/* In particular, Postfix-writable files should never exist +/* in root-owned directories. That would open up a particular +/* type of security hole where ownership (root) does not match +/* content provenance (Postfix). /* DIAGNOSTICS /* Problems and transactions are logged to \fBsyslogd\fR(8). /* BUGS @@ -149,9 +165,12 @@ /* access for the read-only service. /* .PP /* Available in Postfix 2.5 and later: +/* .IP "\fBdata_directory (see 'postconf -d' output)\fR" +/* The directory with Postfix-writable data files (for example: +/* caches, pseudo-random numbers). /* .IP "\fBproxy_write_maps (see 'postconf -d' output)\fR" -/* The lookup tables that the \fBproxymap\fR(8) server is allowed to -/* access for the read-write service. +/* The lookup tables that the \fBproxymap\fR(8) server is allowed to access +/* for the read-write service. /* SEE ALSO /* postconf(5), configuration parameters /* master(5), generic daemon options @@ -397,6 +416,49 @@ static void proxymap_update_service(VSTREAM *client_stream) ATTR_TYPE_END); } +/* proxymap_delete_service - remote delete service */ + +static void proxymap_delete_service(VSTREAM *client_stream) +{ + int request_flags; + DICT *dict; + int reply_status; + + /* + * Process the request. + * + * XXX We don't close maps, so we must turn on synchronous update to ensure + * that the on-disk data is in a consistent state between updates. + */ + if (attr_scan(client_stream, ATTR_FLAG_STRICT, + ATTR_TYPE_STR, MAIL_ATTR_TABLE, request_map, + ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &request_flags, + ATTR_TYPE_STR, MAIL_ATTR_KEY, request_key, + ATTR_TYPE_END) != 3) { + reply_status = PROXY_STAT_BAD; + } else if (proxy_writer == 0) { + msg_warn("refusing %s delete request on non-%s service", + STR(request_map), MAIL_SERVICE_PROXYWRITE); + reply_status = PROXY_STAT_DENY; + } else if ((dict = proxy_map_find(STR(request_map), request_flags, + &reply_status)) == 0) { + /* void */ ; + } else { + dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK) + | (request_flags & DICT_FLAG_RQST_MASK) + | DICT_FLAG_SYNC_UPDATE); + reply_status = + dict_del(dict, STR(request_key)) ? PROXY_STAT_OK : PROXY_STAT_NOKEY; + } + + /* + * Respond to the client. + */ + attr_print(client_stream, ATTR_FLAG_NONE, + ATTR_TYPE_INT, MAIL_ATTR_STATUS, reply_status, + ATTR_TYPE_END); +} + /* proxymap_open_service - open remote lookup table */ static void proxymap_open_service(VSTREAM *client_stream) @@ -457,6 +519,8 @@ static void proxymap_service(VSTREAM *client_stream, char *unused_service, proxymap_lookup_service(client_stream); } else if (VSTREQ(request, PROXY_REQ_UPDATE)) { proxymap_update_service(client_stream); + } else if (VSTREQ(request, PROXY_REQ_DELETE)) { + proxymap_delete_service(client_stream); } else if (VSTREQ(request, PROXY_REQ_OPEN)) { proxymap_open_service(client_stream); } else { diff --git a/postfix/src/qmgr/qmgr_queue.c b/postfix/src/qmgr/qmgr_queue.c index 8d9a1528e..2a81740e9 100644 --- a/postfix/src/qmgr/qmgr_queue.c +++ b/postfix/src/qmgr/qmgr_queue.c @@ -150,6 +150,13 @@ static void qmgr_queue_resume(int event, char *context) queue->window = 1; if (queue->todo_refcount > 0) qmgr_active_drain(); + + /* + * Every event handler that leaves a queue in the "ready" state should + * remove the queue when it is empty. + */ + if (QMGR_QUEUE_READY(queue) && queue->todo.next == 0 && queue->busy.next == 0) + qmgr_queue_done(queue); } /* qmgr_queue_suspend - briefly suspend a destination */ diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index 30fef831e..e2da158ba 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -288,8 +288,9 @@ /* .IP "\fBhopcount_limit (50)\fR" /* The maximal number of Received: message headers that is allowed /* in the primary message headers. -/* .IP "\fBqueue_run_delay (version dependent)\fR" -/* The time between deferred queue scans by the queue manager. +/* .IP "\fBqueue_run_delay (300s)\fR" +/* The time between deferred queue scans by the queue manager; +/* prior to Postfix 2.4 the default value was 1000s. /* FAST FLUSH CONTROLS /* .ad /* .fi @@ -687,7 +688,8 @@ static void enqueue(const int flags, const char *encoding, rec_fputs(dst, REC_TYPE_FROM, saved_sender); if (verp_delims && *saved_sender == 0) msg_fatal_status(EX_USAGE, - "-V option requires non-null sender address"); + "%s(%ld): -V option requires non-null sender address", + saved_sender, (long) uid); if (encoding) rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding); if (DEL_REQ_TRACE_FLAGS(flags)) @@ -735,7 +737,8 @@ static void enqueue(const int flags, const char *encoding, rec_fputs(dst, REC_TYPE_MESG, ""); if (DEL_REQ_TRACE_ONLY(flags) != 0) { if (flags & SM_FLAG_XRCPT) - msg_fatal_status(EX_USAGE, "-t option cannot be used with -bv"); + msg_fatal_status(EX_USAGE, "%s(%ld): -t option cannot be used with -bv", + saved_sender, (long) uid); if (*saved_sender) rec_fprintf(dst, REC_TYPE_NORM, "From: %s", saved_sender); rec_fprintf(dst, REC_TYPE_NORM, "Subject: probe"); @@ -850,9 +853,10 @@ static void enqueue(const int flags, const char *encoding, } if (rcpt_count == 0) msg_fatal_status(EX_USAGE, (flags & SM_FLAG_XRCPT) ? - "No recipient addresses found in message header" : + "%s(%ld): No recipient addresses found in message header" : "Recipient addresses must be specified on" - " the command line or via the -t option"); + " the command line or via the -t option", + saved_sender, (long) uid); /* * Identify the end of the queue file.