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,
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.

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_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

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
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
==============================================

View File

@ -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

View File

@ -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

View File

@ -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 \

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>
<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>
@ -333,6 +336,9 @@ default</th> </tr>
</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>
<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
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
manager.
manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b>
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
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
manager.
manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b>
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>
</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>
<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>
<p>
The lookup tables that the <a href="proxymap.8.html">proxymap(8)</a> server is allowed to
access for the read-write service.
The lookup tables that the <a href="proxymap.8.html">proxymap(8)</a> 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
<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.
</p>

View File

@ -173,6 +173,12 @@ 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:
<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:
<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.
<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
(lookup failed because the key was not found), BAD (mal-
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-
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>
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:
<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>
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.

View File

@ -363,9 +363,10 @@ SENDMAIL(1) SENDMAIL(1)
The maximal number of Received: 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
manager.
manager; prior to Postfix 2.4 the default value was
1000s.
<b>FAST FLUSH CONTROLS</b>
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,
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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -123,6 +123,7 @@ while (<>) {
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;\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;\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;

View File

@ -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" \

View File

@ -308,6 +308,9 @@ default</th> </tr>
<tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td>
<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>
@ -333,6 +336,9 @@ default</th> </tr>
</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>
<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
<p>
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.
</p>
@ -11030,3 +11032,12 @@ parameter value, where <i>transport</i> is the master.cf name of
the message delivery transport. </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 {
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,
@ -201,21 +204,86 @@ static void dict_proxy_update(DICT *dict, const char *key, const char *value)
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,
*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 */
}
}

View File

@ -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 */

View File

@ -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,

View File

@ -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.
*/

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 {

View File

@ -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 */

View File

@ -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.