2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

postfix-2.5-20071205

This commit is contained in:
Wietse Venema 2033-08-08 05:53:25 -05:00 committed by Viktor Dukhovni
parent 063ff5ac81
commit d510de3fec
33 changed files with 515 additions and 175 deletions

View File

@ -13894,10 +13894,32 @@ Apologies for any names omitted.
map that they can't do. Files: postmap/postmap.c, map that they can't do. Files: postmap/postmap.c,
postalias/postalias.c. postalias/postalias.c.
Bugfix: the proxymap client didn't properly propagate the Bugfix: the proxymap client didn't properly propagate user
postmap (postalias) -r and -w options to the proxymap server. options options to the proxymap server. File: util/dict.h.
File: util/dict.h.
Workaround: force synchronous updates in the proxymap server Workaround: force synchronous updates in the proxymap server
so that maps will be in a consistent state between updates. so that maps will be in a consistent state between updates.
File: proxymap/proxymap.c. 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.

View File

@ -201,6 +201,8 @@ Parameters whose defaults can be specified in this way are:
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|DEF_DAEMON_DIR |daemon_directory |/usr/libexec/postfix| |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_MAILQ_PATH |mailq_path |/usr/bin/mailq |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|DEF_HTML_DIR |html_directory |no | |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 | |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 44..55 -- SSuuppppoorrtt ffoorr tthhoouussaannddss ooff pprroocceesssseess
The number of connections that Postfix can manage simultaneously is limited by The number of connections that Postfix can manage simultaneously is limited by

View File

@ -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 If you upgrade from Postfix 2.3 or earlier, read RELEASE_NOTES-2.4
before proceeding. 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 Incompatibility with Postfix snapshot 20071203
============================================== ==============================================

View File

@ -41,6 +41,12 @@ command_directory = /usr/sbin
# #
daemon_directory = /usr/libexec/postfix 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 # QUEUE AND PROCESS OWNERSHIP
# #
# The mail_owner parameter specifies the owner of the Postfix queue # The mail_owner parameter specifies the owner of the Postfix queue

View File

@ -42,6 +42,7 @@
# permissions, so that running "make install" fixes any glitches. # permissions, so that running "make install" fixes any glitches.
# #
$config_directory:d:root:-:755:u $config_directory:d:root:-:755:u
$data_directory:d:$mail_owner:-:700:u
$daemon_directory:d:root:-:755:u $daemon_directory:d:root:-:755:u
$queue_directory:d:root:-:755:uc $queue_directory:d:root:-:755:uc
$sample_directory:d:root:-:755:o $sample_directory:d:root:-:755:o

View File

@ -228,6 +228,9 @@ check-warn)
\( -perm -020 -o -perm -002 \) -type f \ \( -perm -020 -o -perm -002 \) -type f \
-exec $WARN group or other writable: {} \; -exec $WARN group or other writable: {} \;
find $data_directory/. ! -user $mail_owner \
-exec $WARN not owned by $mail_owner: {} \;
find `ls -d $queue_directory/* | \ find `ls -d $queue_directory/* | \
egrep '/(incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \ egrep '/(incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
! \( -type p -o -type s \) ! -user $mail_owner \ ! \( -type p -o -type s \) ! -user $mail_owner \

View File

@ -308,6 +308,9 @@ default</th> </tr>
<tr> <td>DEF_DAEMON_DIR</td> <td><a href="postconf.5.html#daemon_directory">daemon_directory</a></td> <tr> <td>DEF_DAEMON_DIR</td> <td><a href="postconf.5.html#daemon_directory">daemon_directory</a></td>
<td>/usr/libexec/postfix</td> </tr> <td>/usr/libexec/postfix</td> </tr>
<tr> <td>DEF_DATA_DIR</td> <td><a href="postconf.5.html#data_directory">data_directory</a></td>
<td>/var/lib/postfix</td> </tr>
<tr> <td>DEF_MAILQ_PATH</td> <td><a href="postconf.5.html#mailq_path">mailq_path</a></td> <td>/usr/bin/mailq</td> <tr> <td>DEF_MAILQ_PATH</td> <td><a href="postconf.5.html#mailq_path">mailq_path</a></td> <td>/usr/bin/mailq</td>
</tr> </tr>
@ -333,6 +336,9 @@ default</th> </tr>
</blockquote> </blockquote>
<p> Note: the <a href="postconf.5.html#data_directory">data_directory</a> parameter (for caches and pseudo-random
numbers) was introduced with Postfix version 2.5. </p>
<h3>4.5 - Support for thousands of processes</h3> <h3>4.5 - Support for thousands of processes</h3>
<p> The number of connections that Postfix can manage simultaneously <p> The number of connections that Postfix can manage simultaneously

View File

@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1)
The maximal number of Received: message headers The maximal number of Received: message headers
that is allowed in the primary message headers. that is allowed in the primary message headers.
<b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (version dependent)</b> <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (300s)</b>
The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue
manager. manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b> <b>FAST FLUSH CONTROLS</b>
The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation

View File

@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1)
The maximal number of Received: message headers The maximal number of Received: message headers
that is allowed in the primary message headers. that is allowed in the primary message headers.
<b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (version dependent)</b> <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (300s)</b>
The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue
manager. manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b> <b>FAST FLUSH CONTROLS</b>
The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation

View File

@ -1500,6 +1500,19 @@ The default time unit is s (seconds).
</p> </p>
</DD>
<DT><b><a name="data_directory">data_directory</a>
(default: see "postconf -d" output)</b></DT><DD>
<p> The directory with Postfix-writable data files (for example:
caches, pseudo-random numbers). This directory must be owned by
the <a href="postconf.5.html#mail_owner">mail_owner</a> account, and must not be shared with non-Postfix
software. </p>
<p> This feature is available in Postfix 2.5 and later. </p>
</DD> </DD>
<DT><b><a name="debug_peer_level">debug_peer_level</a> <DT><b><a name="debug_peer_level">debug_peer_level</a>
@ -6168,8 +6181,10 @@ This feature is available in Postfix 2.0 and later.
(default: see "postconf -d" output)</b></DT><DD> (default: see "postconf -d" output)</b></DT><DD>
<p> <p>
The lookup tables that the <a href="proxymap.8.html">proxymap(8)</a> server is allowed to The lookup tables that the <a href="proxymap.8.html">proxymap(8)</a> server is allowed to access
access for the read-write service. for the read-write service. If implemented with local files, these
tables are preferably stored under the location specified with the
<a href="postconf.5.html#data_directory">data_directory</a> configuration parameter.
Table references that don't begin with <a href="proxymap.8.html">proxy</a>: are ignored. Table references that don't begin with <a href="proxymap.8.html">proxy</a>: are ignored.
</p> </p>

View File

@ -173,6 +173,12 @@ POSTFIX(1) POSTFIX(1)
how to build, configure or operate a specific Post- how to build, configure or operate a specific Post-
fix subsystem or feature. fix subsystem or feature.
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#data_directory">data_directory</a> (see 'postconf -d' output)</b>
The directory with Postfix-writable data files (for
example: caches, pseudo-random numbers).
Other configuration parameters: Other configuration parameters:
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b> <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>

View File

@ -71,6 +71,14 @@ PROXYMAP(8) PROXYMAP(8)
This request is supported in Postfix 2.5 and later. This request is supported in Postfix 2.5 and later.
<b>delete</b> <i>maptype:mapname flags key</i>
Delete the data stored under the requested key.
The reply is the request completion status code.
The <i>maptype:mapname</i> and <i>flags</i> are the same as with
the <b>open</b> request.
This request is supported in Postfix 2.5 and later.
The request completion status is one of OK, RETRY, NOKEY The request completion status is one of OK, RETRY, NOKEY
(lookup failed because the key was not found), BAD (mal- (lookup failed because the key was not found), BAD (mal-
formed request) or DENY (the table is not approved for formed request) or DENY (the table is not approved for
@ -108,6 +116,15 @@ PROXYMAP(8) PROXYMAP(8)
same <a href="postconf.5.html">main.cf</a> setting to be used by sensitive and non-sen- same <a href="postconf.5.html">main.cf</a> setting to be used by sensitive and non-sen-
sitive processes. sitive processes.
Postfix-writable data files should be stored under a dedi-
cated directory that is writable only by the $<b><a href="postconf.5.html#mail_owner">mail_owner</a></b>
account, such as the $<b><a href="postconf.5.html#data_directory">data_directory</a></b> 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).
<b>DIAGNOSTICS</b> <b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Problems and transactions are logged to <b>syslogd</b>(8).
@ -171,6 +188,10 @@ PROXYMAP(8) PROXYMAP(8)
Available in Postfix 2.5 and later: Available in Postfix 2.5 and later:
<b><a href="postconf.5.html#data_directory">data_directory</a> (see 'postconf -d' output)</b>
The directory with Postfix-writable data files (for
example: caches, pseudo-random numbers).
<b><a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a> (see 'postconf -d' output)</b> <b><a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a> (see 'postconf -d' output)</b>
The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is
allowed to access for the read-write service. allowed to access for the read-write service.

View File

@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1)
The maximal number of Received: message headers The maximal number of Received: message headers
that is allowed in the primary message headers. that is allowed in the primary message headers.
<b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (version dependent)</b> <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a> (300s)</b>
The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue The time between <a href="QSHAPE_README.html#deferred_queue">deferred queue</a> scans by the queue
manager. manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b> <b>FAST FLUSH CONTROLS</b>
The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation The <a href="ETRN_README.html">ETRN_README</a> file describes configuration and operation

View File

@ -142,6 +142,11 @@ Where the Postfix manual pages are installed.
The location of Postfix README files that describe how to build, The location of Postfix README files that describe how to build,
configure or operate a specific Postfix subsystem or feature. configure or operate a specific Postfix subsystem or feature.
.PP .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: Other configuration parameters:
.IP "\fBconfig_directory (see 'postconf -d' output)\fR" .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
The default location of the Postfix main.cf and master.cf The default location of the Postfix main.cf and master.cf

View File

@ -308,8 +308,9 @@ The delay between attempts to fork() a child process.
.IP "\fBhopcount_limit (50)\fR" .IP "\fBhopcount_limit (50)\fR"
The maximal number of Received: message headers that is allowed The maximal number of Received: message headers that is allowed
in the primary message headers. in the primary message headers.
.IP "\fBqueue_run_delay (version dependent)\fR" .IP "\fBqueue_run_delay (300s)\fR"
The time between deferred queue scans by the queue manager. The time between deferred queue scans by the queue manager;
prior to Postfix 2.4 the default value was 1000s.
.SH "FAST FLUSH CONTROLS" .SH "FAST FLUSH CONTROLS"
.na .na
.nf .nf

View File

@ -817,6 +817,13 @@ request before it is terminated by a built-in watchdog timer.
.PP .PP
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
The default time unit is s (seconds). 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) .SH debug_peer_level (default: 2)
The increment in verbose logging level when a remote client or The increment in verbose logging level when a remote client or
server matches a pattern in the debug_peer_list parameter. 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 .PP
This feature is available in Postfix 2.0 and later. This feature is available in Postfix 2.0 and later.
.SH proxy_write_maps (default: see "postconf -d" output) .SH proxy_write_maps (default: see "postconf -d" output)
The lookup tables that the \fBproxymap\fR(8) server is allowed to The lookup tables that the \fBproxymap\fR(8) server is allowed to access
access for the read-write service. 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. Table references that don't begin with proxy: are ignored.
.PP .PP
This feature is available in Postfix 2.5 and later. This feature is available in Postfix 2.5 and later.

View File

@ -68,6 +68,13 @@ of 1 in the master.cf file entry for the \fBproxywrite\fR
service. service.
.sp .sp
This request is supported in Postfix 2.5 and later. 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 .PP
The request completion status is one of OK, RETRY, NOKEY The request completion status is one of OK, RETRY, NOKEY
(lookup failed because the key was not found), BAD (malformed (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, requests to access a table for security-sensitive purposes,
and opens the table directly. This allows the same main.cf and opens the table directly. This allows the same main.cf
setting to be used by sensitive and non-sensitive processes. 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 .SH DIAGNOSTICS
.ad .ad
.fi .fi
@ -165,9 +181,12 @@ The lookup tables that the \fBproxymap\fR(8) server is allowed to
access for the read-only service. access for the read-only service.
.PP .PP
Available in Postfix 2.5 and later: 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" .IP "\fBproxy_write_maps (see 'postconf -d' output)\fR"
The lookup tables that the \fBproxymap\fR(8) server is allowed to The lookup tables that the \fBproxymap\fR(8) server is allowed to access
access for the read-write service. for the read-write service.
.SH "SEE ALSO" .SH "SEE ALSO"
.na .na
.nf .nf

View File

@ -123,6 +123,7 @@ while (<>) {
s;\bcommand_time_limit\b;<a href="postconf.5.html#command_time_limit">$&</a>;g; s;\bcommand_time_limit\b;<a href="postconf.5.html#command_time_limit">$&</a>;g;
s;\bconfig_direc[-</bB>]*\n*[ <bB>]*tory\b;<a href="postconf.5.html#config_directory">$&</a>;g; s;\bconfig_direc[-</bB>]*\n*[ <bB>]*tory\b;<a href="postconf.5.html#config_directory">$&</a>;g;
s;\bcon[-</bB>]*\n*[ <bB>]*tent_filter\b;<a href="postconf.5.html#content_filter">$&</a>;g; s;\bcon[-</bB>]*\n*[ <bB>]*tent_filter\b;<a href="postconf.5.html#content_filter">$&</a>;g;
s;\bdata_directory\b;<a href="postconf.5.html#data_directory">$&</a>;g;
s;\bdae[-</bB>]*\n*[ <bB>]*mon_directory\b;<a href="postconf.5.html#daemon_directory">$&</a>;g; s;\bdae[-</bB>]*\n*[ <bB>]*mon_directory\b;<a href="postconf.5.html#daemon_directory">$&</a>;g;
s;\bdaemon_timeout\b;<a href="postconf.5.html#daemon_timeout">$&</a>;g; s;\bdaemon_timeout\b;<a href="postconf.5.html#daemon_timeout">$&</a>;g;
s;\bdebug_peer_level\b;<a href="postconf.5.html#debug_peer_level">$&</a>;g; s;\bdebug_peer_level\b;<a href="postconf.5.html#debug_peer_level">$&</a>;g;

View File

@ -88,6 +88,11 @@
# The built-in default directory name is /etc/postfix. # The built-in default directory name is /etc/postfix.
# This parameter setting is not recorded in the installed main.cf file # This parameter setting is not recorded in the installed main.cf file
# and can be changed only by recompiling Postfix. # 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 # .IP daemon_directory
# The final destination directory for Postfix daemon programs. This # The final destination directory for Postfix daemon programs. This
# directory should not be in the command search path of any users. # 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 config_directory_prompt="the final destination directory for
installed Postfix configuration files." 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 daemon_directory_prompt="the final destination directory for
installed Postfix daemon programs. This directory should not be installed Postfix daemon programs. This directory should not be
in the command search path of any users." 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 manpage_directory_prompt="the destination directory for the Postfix on-line
manual pages. You can no longer specify \"no\" here." 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_directory_prompt="the destination directory for the Postfix
README files. Specify \"no\" if you do not want to install these files." 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. # Extract parameter settings from the installed main.cf file.
test -f $CONFIG_DIRECTORY/main.cf && { test -f $CONFIG_DIRECTORY/main.cf && {
for name in daemon_directory command_directory queue_directory mail_owner \ for name in $CONFIG_PARAMS sample_directory
setgid_group sendmail_path newaliases_path mailq_path manpage_directory \
sample_directory html_directory readme_directory
do do
eval junk=\$$name eval junk=\$$name
case "$junk" in case "$junk" in
@ -432,9 +440,7 @@ test -f $CONFIG_DIRECTORY/main.cf && {
# Use built-in defaults as the final source of parameter settings. # Use built-in defaults as the final source of parameter settings.
for name in daemon_directory command_directory queue_directory mail_owner \ for name in $CONFIG_PARAMS sample_directory
setgid_group sendmail_path newaliases_path mailq_path manpage_directory \
sample_directory html_directory readme_directory
do do
eval junk=\$$name eval junk=\$$name
case "$junk" in case "$junk" in
@ -445,9 +451,7 @@ done
# Override settings manually. # Override settings manually.
test -z "$non_interactive" && for name in daemon_directory command_directory \ test -z "$non_interactive" && for name in $CONFIG_PARAMS
queue_directory sendmail_path newaliases_path mailq_path mail_owner \
setgid_group html_directory manpage_directory readme_directory
do do
while : while :
do do
@ -490,7 +494,7 @@ do
esac esac
done 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" "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
do do
case "$path" in case "$path" in
@ -507,7 +511,7 @@ do
} }
done 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 manpage_directory queue_directory html_directory readme_directory
do do
eval test -f $install_root\$$path && { eval test -f $install_root\$$path && {
@ -559,7 +563,6 @@ QUEUE_DIRECTORY=$install_root$queue_directory
SENDMAIL_PATH=$install_root$sendmail_path SENDMAIL_PATH=$install_root$sendmail_path
HTML_DIRECTORY=$install_root$html_directory HTML_DIRECTORY=$install_root$html_directory
MANPAGE_DIRECTORY=$install_root$manpage_directory MANPAGE_DIRECTORY=$install_root$manpage_directory
SAMPLE_DIRECTORY=$install_root$sample_directory
README_DIRECTORY=$install_root$readme_directory README_DIRECTORY=$install_root$readme_directory
# Avoid repeated tests for existence of these; default permissions suffice. # Avoid repeated tests for existence of these; default permissions suffice.
@ -723,6 +726,7 @@ do
bin/postconf -c $CONFIG_DIRECTORY -e \ bin/postconf -c $CONFIG_DIRECTORY -e \
"daemon_directory = $daemon_directory" \ "daemon_directory = $daemon_directory" \
"data_directory = $data_directory" \
"command_directory = $command_directory" \ "command_directory = $command_directory" \
"queue_directory = $queue_directory" \ "queue_directory = $queue_directory" \
"mail_owner = $mail_owner" \ "mail_owner = $mail_owner" \

View File

@ -308,6 +308,9 @@ default</th> </tr>
<tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td> <tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td>
<td>/usr/libexec/postfix</td> </tr> <td>/usr/libexec/postfix</td> </tr>
<tr> <td>DEF_DATA_DIR</td> <td>data_directory</td>
<td>/var/lib/postfix</td> </tr>
<tr> <td>DEF_MAILQ_PATH</td> <td>mailq_path</td> <td>/usr/bin/mailq</td> <tr> <td>DEF_MAILQ_PATH</td> <td>mailq_path</td> <td>/usr/bin/mailq</td>
</tr> </tr>
@ -333,6 +336,9 @@ default</th> </tr>
</blockquote> </blockquote>
<p> Note: the data_directory parameter (for caches and pseudo-random
numbers) was introduced with Postfix version 2.5. </p>
<h3>4.5 - Support for thousands of processes</h3> <h3>4.5 - Support for thousands of processes</h3>
<p> The number of connections that Postfix can manage simultaneously <p> The number of connections that Postfix can manage simultaneously

View File

@ -7216,8 +7216,10 @@ This feature is available in Postfix 2.0 and later.
%PARAM proxy_write_maps see "postconf -d" output %PARAM proxy_write_maps see "postconf -d" output
<p> <p>
The lookup tables that the proxymap(8) server is allowed to The lookup tables that the proxymap(8) server is allowed to access
access for the read-write service. 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. Table references that don't begin with proxy: are ignored.
</p> </p>
@ -11030,3 +11032,12 @@ parameter value, where <i>transport</i> is the master.cf name of
the message delivery transport. </p> the message delivery transport. </p>
<p> This feature is available in Postfix 2.5 and later. </p> <p> This feature is available in Postfix 2.5 and later. </p>
%PARAM data_directory see "postconf -d" output
<p> 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. </p>
<p> This feature is available in Postfix 2.5 and later. </p>

View File

@ -70,6 +70,8 @@
typedef struct { typedef struct {
DICT dict; /* generic members */ DICT dict; /* generic members */
CLNT_STREAM *clnt; /* client handle (shared) */
const char *service; /* service name */
int in_flags; /* caller-specified flags */ int in_flags; /* caller-specified flags */
VSTRING *result; /* storage */ VSTRING *result; /* storage */
} DICT_PROXY; } DICT_PROXY;
@ -81,9 +83,10 @@ typedef struct {
#define VSTREQ(v,s) (strcmp(STR(v),s) == 0) #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 */ /* 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) request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
| (dict->flags & DICT_FLAG_RQST_MASK); | (dict->flags & DICT_FLAG_RQST_MASK);
for (;;) { for (;;) {
stream = clnt_stream_access(proxy_stream); stream = clnt_stream_access(dict_proxy->clnt);
errno = 0; errno = 0;
count += 1; count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, 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: case PROXY_STAT_BAD:
msg_fatal("%s lookup failed for table \"%s\" key \"%s\": " msg_fatal("%s lookup failed for table \"%s\" key \"%s\": "
"invalid request", "invalid request",
MAIL_SERVICE_PROXYMAP, dict->name, key); dict_proxy->service, dict->name, key);
case PROXY_STAT_DENY: case PROXY_STAT_DENY:
msg_fatal("%s service is not configured for table \"%s\"", msg_fatal("%s service is not configured for table \"%s\"",
MAIL_SERVICE_PROXYMAP, dict->name); dict_proxy->service, dict->name);
case PROXY_STAT_OK: case PROXY_STAT_OK:
return (STR(dict_proxy->result)); return (STR(dict_proxy->result));
case PROXY_STAT_NOKEY: case PROXY_STAT_NOKEY:
@ -149,10 +152,10 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
default: default:
msg_warn("%s lookup failed for table \"%s\" key \"%s\": " msg_warn("%s lookup failed for table \"%s\" key \"%s\": "
"unexpected reply status %d", "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 */ 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) request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
| (dict->flags & DICT_FLAG_RQST_MASK); | (dict->flags & DICT_FLAG_RQST_MASK);
for (;;) { for (;;) {
stream = clnt_stream_access(proxy_stream); stream = clnt_stream_access(dict_proxy->clnt);
errno = 0; errno = 0;
count += 1; count += 1;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
@ -201,21 +204,86 @@ static void dict_proxy_update(DICT *dict, const char *key, const char *value)
key, value, status); key, value, status);
switch (status) { switch (status) {
case PROXY_STAT_BAD: 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", "invalid request",
MAIL_SERVICE_PROXYMAP, dict->name, key); dict_proxy->service, dict->name, key);
case PROXY_STAT_DENY: case PROXY_STAT_DENY:
msg_fatal("%s update access is not configured for table \"%s\"", 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: case PROXY_STAT_OK:
return; return;
default: default:
msg_warn("%s update failed for table \"%s\" key \"%s\": " msg_warn("%s update failed for table \"%s\" key \"%s\": "
"unexpected reply status %d", "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 */ sleep(1); /* XXX make configurable */
} }
} }
@ -239,8 +307,11 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
VSTREAM *stream; VSTREAM *stream;
int server_flags; int server_flags;
int status; int status;
const char *service;
const char *relative_path;
char *kludge = 0; char *kludge = 0;
char *prefix; char *prefix;
CLNT_STREAM **pstream;
/* /*
* Sanity checks. * 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 * server; only sets that make sense. For now, the flags are passed
* implicitly by choosing between the proxymap or proxywrite service. * 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", msg_fatal("%s: %s map open requires O_RDONLY or O_RDWR|O_CREAT mode",
map, DICT_TYPE_PROXY); 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_alloc(DICT_TYPE_PROXY, map, sizeof(*dict_proxy));
dict_proxy->dict.lookup = dict_proxy_lookup; dict_proxy->dict.lookup = dict_proxy_lookup;
dict_proxy->dict.update = dict_proxy_update; dict_proxy->dict.update = dict_proxy_update;
dict_proxy->dict.delete = dict_proxy_delete;
dict_proxy->dict.close = dict_proxy_close; dict_proxy->dict.close = dict_proxy_close;
dict_proxy->in_flags = dict_flags; dict_proxy->in_flags = dict_flags;
dict_proxy->result = vstring_alloc(10); 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. * XXX Use absolute pathname to make this work from non-daemon processes.
*/ */
if (proxy_stream == 0) { if (*pstream == 0) {
if (access(open_flags == O_RDONLY ? if (access(relative_path, F_OK) == 0)
MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP :
MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYWRITE,
F_OK) == 0)
prefix = MAIL_CLASS_PRIVATE; prefix = MAIL_CLASS_PRIVATE;
else else
prefix = kludge = concatenate(var_queue_dir, "/", prefix = kludge = concatenate(var_queue_dir, "/",
MAIL_CLASS_PRIVATE, (char *) 0); MAIL_CLASS_PRIVATE, (char *) 0);
proxy_stream = clnt_stream_create(prefix, *pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
open_flags == O_RDONLY ?
MAIL_SERVICE_PROXYMAP :
MAIL_SERVICE_PROXYWRITE,
var_ipc_idle_limit,
var_ipc_ttl_limit); var_ipc_ttl_limit);
if (kludge) if (kludge)
myfree(kludge); myfree(kludge);
} }
dict_proxy->clnt = *pstream;
dict_proxy->service = service;
/* /*
* Establish initial contact and get the map type specific flags. * 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. * XXX Should retrieve flags from local instance.
*/ */
for (;;) { for (;;) {
stream = clnt_stream_access(proxy_stream); stream = clnt_stream_access(dict_proxy->clnt);
errno = 0; errno = 0;
if (attr_print(stream, ATTR_FLAG_NONE, if (attr_print(stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_OPEN, 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) { switch (status) {
case PROXY_STAT_BAD: case PROXY_STAT_BAD:
msg_fatal("%s open failed for table \"%s\": invalid request", 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: case PROXY_STAT_DENY:
msg_fatal("%s service is not configured for table \"%s\"", 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: case PROXY_STAT_OK:
dict_proxy->dict.flags = dict_proxy->in_flags dict_proxy->dict.flags = dict_proxy->in_flags
| (server_flags & DICT_FLAG_IMPL_MASK); | (server_flags & DICT_FLAG_IMPL_MASK);
return (DICT_DEBUG (&dict_proxy->dict)); return (DICT_DEBUG (&dict_proxy->dict));
default: default:
msg_warn("%s open failed for table \"%s\": unexpected status %d", 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 */ sleep(1); /* XXX make configurable */
} }
} }

View File

@ -29,6 +29,7 @@ extern DICT *dict_proxy_open(const char *, int, int);
#define PROXY_REQ_OPEN "open" #define PROXY_REQ_OPEN "open"
#define PROXY_REQ_LOOKUP "lookup" #define PROXY_REQ_LOOKUP "lookup"
#define PROXY_REQ_UPDATE "update" #define PROXY_REQ_UPDATE "update"
#define PROXY_REQ_DELETE "delete"
#define PROXY_STAT_OK 0 /* operation succeeded */ #define PROXY_STAT_OK 0 /* operation succeeded */
#define PROXY_STAT_NOKEY 1 /* requested key not found */ #define PROXY_STAT_NOKEY 1 /* requested key not found */

View File

@ -26,6 +26,7 @@
/* gid_t var_default_gid; /* gid_t var_default_gid;
/* char *var_config_dir; /* char *var_config_dir;
/* char *var_daemon_dir; /* char *var_daemon_dir;
/* char *var_data_dir;
/* char *var_command_dir; /* char *var_command_dir;
/* char *var_queue_dir; /* char *var_queue_dir;
/* int var_use_limit; /* int var_use_limit;
@ -200,6 +201,7 @@ uid_t var_default_uid;
gid_t var_default_gid; gid_t var_default_gid;
char *var_config_dir; char *var_config_dir;
char *var_daemon_dir; char *var_daemon_dir;
char *var_data_dir;
char *var_command_dir; char *var_command_dir;
char *var_queue_dir; char *var_queue_dir;
int var_use_limit; int var_use_limit;
@ -504,6 +506,7 @@ void mail_params_init()
VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0, VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0,
VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0, VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0,
VAR_DAEMON_DIR, DEF_DAEMON_DIR, &var_daemon_dir, 1, 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_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0,
VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_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, VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0,

View File

@ -260,6 +260,15 @@ extern char *var_command_dir;
#endif #endif
extern char *var_pid_dir; 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. * Program startup time.
*/ */

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "2007111204" #define MAIL_RELEASE_DATE "2007111205"
#define MAIL_VERSION_NUMBER "2.5" #define MAIL_VERSION_NUMBER "2.5"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -148,6 +148,13 @@ static void qmgr_queue_resume(int event, char *context)
queue->window = 1; queue->window = 1;
if (queue->todo_refcount > 0) if (queue->todo_refcount > 0)
qmgr_active_drain(); 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 */ /* qmgr_queue_suspend - briefly suspend a destination */

View File

@ -516,6 +516,7 @@ static int postalias_deletes(VSTREAM *in, char **maps, const int map_count,
DICT **dicts; DICT **dicts;
const char *map_name; const char *map_name;
int n; int n;
int open_flags;
/* /*
* Sanity check. * 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++) { for (n = 0; n < map_count; n++) {
map_name = split_at(maps[n], ':'); map_name = split_at(maps[n], ':');
if (map_name && strcmp(maps[n], DICT_TYPE_PROXY) == 0) 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 ? dicts[n] = (map_name != 0 ?
dict_open3(maps[n], map_name, O_RDWR, dict_flags) : dict_open3(maps[n], map_name, open_flags, dict_flags) :
dict_open3(var_db_type, maps[n], O_RDWR, 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; DICT *dict;
int status; int status;
int open_flags;
if (strcmp(map_type, DICT_TYPE_PROXY) == 0) if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
msg_fatal("can't delete map entries via the proxy service"); open_flags = O_RDWR | O_CREAT; /* XXX */
dict = dict_open3(map_type, map_name, O_RDWR, dict_flags); else
open_flags = O_RDWR;
dict = dict_open3(map_type, map_name, open_flags, dict_flags);
status = dict_del(dict, key); status = dict_del(dict, key);
dict_close(dict); dict_close(dict);
return (status == 0); return (status == 0);

View File

@ -132,6 +132,11 @@
/* The location of Postfix README files that describe how to build, /* The location of Postfix README files that describe how to build,
/* configure or operate a specific Postfix subsystem or feature. /* configure or operate a specific Postfix subsystem or feature.
/* .PP /* .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: /* Other configuration parameters:
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
/* The default location of the Postfix main.cf and master.cf /* 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_COMMAND_DIR, var_command_dir); /* main.cf */
check_setenv(VAR_DAEMON_DIR, var_daemon_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_QUEUE_DIR, var_queue_dir); /* main.cf */
check_setenv(VAR_CONFIG_DIR, var_config_dir); /* main.cf */ check_setenv(VAR_CONFIG_DIR, var_config_dir); /* main.cf */

View File

@ -463,6 +463,7 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count,
DICT **dicts; DICT **dicts;
const char *map_name; const char *map_name;
int n; int n;
int open_flags;
/* /*
* Sanity check. * 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++) { for (n = 0; n < map_count; n++) {
map_name = split_at(maps[n], ':'); map_name = split_at(maps[n], ':');
if (map_name && strcmp(maps[n], DICT_TYPE_PROXY) == 0) 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 ? dicts[n] = (map_name != 0 ?
dict_open3(maps[n], map_name, O_RDWR, dict_flags) : dict_open3(maps[n], map_name, open_flags, dict_flags) :
dict_open3(var_db_type, maps[n], O_RDWR, 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; DICT *dict;
int status; int status;
int open_flags;
if (strcmp(map_type, DICT_TYPE_PROXY) == 0) if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
msg_fatal("can't delete map entries via the proxy service"); open_flags = O_RDWR | O_CREAT; /* XXX */
dict = dict_open3(map_type, map_name, O_RDWR, dict_flags); else
open_flags = O_RDWR;
dict = dict_open3(map_type, map_name, open_flags, dict_flags);
status = dict_del(dict, key); status = dict_del(dict, key);
dict_close(dict); dict_close(dict);
return (status == 0); return (status == 0);

View File

@ -62,6 +62,13 @@
/* service. /* service.
/* .sp /* .sp
/* This request is supported in Postfix 2.5 and later. /* 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 /* .PP
/* The request completion status is one of OK, RETRY, NOKEY /* The request completion status is one of OK, RETRY, NOKEY
/* (lookup failed because the key was not found), BAD (malformed /* (lookup failed because the key was not found), BAD (malformed
@ -100,6 +107,15 @@
/* requests to access a table for security-sensitive purposes, /* requests to access a table for security-sensitive purposes,
/* and opens the table directly. This allows the same main.cf /* and opens the table directly. This allows the same main.cf
/* setting to be used by sensitive and non-sensitive processes. /* 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 /* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8). /* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS /* BUGS
@ -149,9 +165,12 @@
/* access for the read-only service. /* access for the read-only service.
/* .PP /* .PP
/* Available in Postfix 2.5 and later: /* 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" /* .IP "\fBproxy_write_maps (see 'postconf -d' output)\fR"
/* The lookup tables that the \fBproxymap\fR(8) server is allowed to /* The lookup tables that the \fBproxymap\fR(8) server is allowed to access
/* access for the read-write service. /* for the read-write service.
/* SEE ALSO /* SEE ALSO
/* postconf(5), configuration parameters /* postconf(5), configuration parameters
/* master(5), generic daemon options /* master(5), generic daemon options
@ -397,6 +416,49 @@ static void proxymap_update_service(VSTREAM *client_stream)
ATTR_TYPE_END); 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 */ /* proxymap_open_service - open remote lookup table */
static void proxymap_open_service(VSTREAM *client_stream) 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); proxymap_lookup_service(client_stream);
} else if (VSTREQ(request, PROXY_REQ_UPDATE)) { } else if (VSTREQ(request, PROXY_REQ_UPDATE)) {
proxymap_update_service(client_stream); proxymap_update_service(client_stream);
} else if (VSTREQ(request, PROXY_REQ_DELETE)) {
proxymap_delete_service(client_stream);
} else if (VSTREQ(request, PROXY_REQ_OPEN)) { } else if (VSTREQ(request, PROXY_REQ_OPEN)) {
proxymap_open_service(client_stream); proxymap_open_service(client_stream);
} else { } else {

View File

@ -150,6 +150,13 @@ static void qmgr_queue_resume(int event, char *context)
queue->window = 1; queue->window = 1;
if (queue->todo_refcount > 0) if (queue->todo_refcount > 0)
qmgr_active_drain(); 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 */ /* qmgr_queue_suspend - briefly suspend a destination */

View File

@ -288,8 +288,9 @@
/* .IP "\fBhopcount_limit (50)\fR" /* .IP "\fBhopcount_limit (50)\fR"
/* The maximal number of Received: message headers that is allowed /* The maximal number of Received: message headers that is allowed
/* in the primary message headers. /* in the primary message headers.
/* .IP "\fBqueue_run_delay (version dependent)\fR" /* .IP "\fBqueue_run_delay (300s)\fR"
/* The time between deferred queue scans by the queue manager. /* The time between deferred queue scans by the queue manager;
/* prior to Postfix 2.4 the default value was 1000s.
/* FAST FLUSH CONTROLS /* FAST FLUSH CONTROLS
/* .ad /* .ad
/* .fi /* .fi
@ -687,7 +688,8 @@ static void enqueue(const int flags, const char *encoding,
rec_fputs(dst, REC_TYPE_FROM, saved_sender); rec_fputs(dst, REC_TYPE_FROM, saved_sender);
if (verp_delims && *saved_sender == 0) if (verp_delims && *saved_sender == 0)
msg_fatal_status(EX_USAGE, 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) if (encoding)
rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding); rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding);
if (DEL_REQ_TRACE_FLAGS(flags)) 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, ""); rec_fputs(dst, REC_TYPE_MESG, "");
if (DEL_REQ_TRACE_ONLY(flags) != 0) { if (DEL_REQ_TRACE_ONLY(flags) != 0) {
if (flags & SM_FLAG_XRCPT) 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) if (*saved_sender)
rec_fprintf(dst, REC_TYPE_NORM, "From: %s", saved_sender); rec_fprintf(dst, REC_TYPE_NORM, "From: %s", saved_sender);
rec_fprintf(dst, REC_TYPE_NORM, "Subject: probe"); 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) if (rcpt_count == 0)
msg_fatal_status(EX_USAGE, (flags & SM_FLAG_XRCPT) ? 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" "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. * Identify the end of the queue file.