mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-01 14:45:32 +00:00
postfix-2.5-20071203
This commit is contained in:
committed by
Viktor Dukhovni
parent
93d0a26a92
commit
a98fc88914
@@ -13878,3 +13878,22 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Bugfix: don't update the back-to-back delivery time stamp
|
Bugfix: don't update the back-to-back delivery time stamp
|
||||||
while deferring mail. File: *qmgr/qmgr_entry.c.
|
while deferring mail. File: *qmgr/qmgr_entry.c.
|
||||||
|
|
||||||
|
20071203
|
||||||
|
|
||||||
|
Feature: support for read-write tables in the proxymap
|
||||||
|
service. This is implemented with a separate master.cf entry
|
||||||
|
named "proxywrite" that should run with process limit of 1
|
||||||
|
if you want to update Berkeley DB like tables. This feature
|
||||||
|
requires that tables be authorized with the proxy_write_maps
|
||||||
|
configuration parameter. Files: global/dict_procy.[hc],
|
||||||
|
proxymap/proxymap.c.
|
||||||
|
|
||||||
|
Human factors: the postmap and postalias commands now produce
|
||||||
|
nicer diagnostics when asked to do something with a proxied
|
||||||
|
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.
|
||||||
|
@@ -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.
|
||||||
|
|
||||||
|
Incompatibility with Postfix snapshot 20071203
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
The "make upgrade" procedure adds a new service "proxywrite" to the
|
||||||
|
master.cf file, for read/write lookup table access. If you copy
|
||||||
|
your old configuration file over the updated one, you will have
|
||||||
|
to run "postfix upgrade-configuration" again.
|
||||||
|
|
||||||
Major changes with Postfix snapshot 20071202
|
Major changes with Postfix snapshot 20071202
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
|
@@ -659,6 +659,15 @@ retry unix - - n - - error
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add missing proxywrite service to master.cf.
|
||||||
|
|
||||||
|
grep '^proxywrite.*proxymap' $config_directory/master.cf >/dev/null || {
|
||||||
|
echo Editing $config_directory/master.cf, adding missing entry for proxywrite service
|
||||||
|
cat >>$config_directory/master.cf <<EOF || exit 1
|
||||||
|
proxywrite unix - - n - 1 proxymap
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
# Report (but do not remove) obsolete files.
|
# Report (but do not remove) obsolete files.
|
||||||
|
|
||||||
test -n "$obsolete" && {
|
test -n "$obsolete" && {
|
||||||
|
@@ -6152,9 +6152,9 @@ Example:
|
|||||||
(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 access.
|
The lookup tables that the <a href="proxymap.8.html">proxymap(8)</a> server is allowed to
|
||||||
Table references that don't begin with <a href="proxymap.8.html">proxy</a>: are ignored. The
|
access for the read-only service.
|
||||||
<a href="proxymap.8.html">proxymap(8)</a> table accesses are read-only.
|
Table references that don't begin with <a href="proxymap.8.html">proxy</a>: are ignored.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -6162,6 +6162,22 @@ This feature is available in Postfix 2.0 and later.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</DD>
|
||||||
|
|
||||||
|
<DT><b><a name="proxy_write_maps">proxy_write_maps</a>
|
||||||
|
(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.
|
||||||
|
Table references that don't begin with <a href="proxymap.8.html">proxy</a>: are ignored.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This feature is available in Postfix 2.5 and later.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DT><b><a name="qmgr_clog_warn_time">qmgr_clog_warn_time</a>
|
<DT><b><a name="qmgr_clog_warn_time">qmgr_clog_warn_time</a>
|
||||||
|
@@ -13,8 +13,10 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
<b>proxymap</b> [generic Postfix daemon options]
|
<b>proxymap</b> [generic Postfix daemon options]
|
||||||
|
|
||||||
<b>DESCRIPTION</b>
|
<b>DESCRIPTION</b>
|
||||||
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server provides read-only table lookup
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server provides read-only or read-write
|
||||||
service to Postfix processes. The purpose of the service
|
table lookup service to Postfix processes. These services
|
||||||
|
are implemented with distinct service names: <b>proxymap</b> and
|
||||||
|
<b>proxywrite</b>, respectively. The purpose of these services
|
||||||
is:
|
is:
|
||||||
|
|
||||||
<b>o</b> To overcome chroot restrictions. For example, a
|
<b>o</b> To overcome chroot restrictions. For example, a
|
||||||
@@ -39,6 +41,10 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
The total number of connections is limited by the
|
The total number of connections is limited by the
|
||||||
number of proxymap server processes.
|
number of proxymap server processes.
|
||||||
|
|
||||||
|
<b>o</b> To provide single-updater functionality for lookup
|
||||||
|
tables that do not reliably support multiple writ-
|
||||||
|
ers (i.e. all file-based tables).
|
||||||
|
|
||||||
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server implements the following requests:
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server implements the following requests:
|
||||||
|
|
||||||
<b>open</b> <i>maptype:mapname flags</i>
|
<b>open</b> <i>maptype:mapname flags</i>
|
||||||
@@ -49,10 +55,26 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
|
|
||||||
<b>lookup</b> <i>maptype:mapname flags key</i>
|
<b>lookup</b> <i>maptype:mapname flags key</i>
|
||||||
Look up the data stored under the requested key.
|
Look up the data stored under the requested key.
|
||||||
The reply is the request completion status code
|
The reply is the request completion status code and
|
||||||
(below) and the lookup result value. The <i>map-</i>
|
the lookup result value. The <i>maptype:mapname</i> and
|
||||||
<i>type:mapname</i> and <i>flags</i> are the same as with the
|
<i>flags</i> are the same as with the <b>open</b> request.
|
||||||
<b>open</b> request.
|
|
||||||
|
<b>update</b> <i>maptype:mapname flags key value</i>
|
||||||
|
Update 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.
|
||||||
|
|
||||||
|
To implement single-updater maps, specify a process
|
||||||
|
limit of 1 in the <a href="master.5.html">master.cf</a> file entry for the
|
||||||
|
proxywrite service.
|
||||||
|
|
||||||
|
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
|
||||||
|
proxy read or update access).
|
||||||
|
|
||||||
There is no <b>close</b> command, nor are tables implicitly
|
There is no <b>close</b> command, nor are tables implicitly
|
||||||
closed when a client disconnects. The purpose is to share
|
closed when a client disconnects. The purpose is to share
|
||||||
@@ -69,11 +91,11 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
|
|
||||||
<b>SECURITY</b>
|
<b>SECURITY</b>
|
||||||
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server opens only tables that are approved
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server opens only tables that are approved
|
||||||
via the <b><a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a></b> configuration parameter, does not
|
via the <b><a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a></b> or <b><a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a></b> configuration
|
||||||
talk to users, and can run at fixed low privilege,
|
parameters, does not talk to users, and can run at fixed
|
||||||
chrooted or not. However, running the proxymap server
|
low privilege, chrooted or not. However, running the
|
||||||
chrooted severely limits usability, because it can open
|
proxymap server chrooted severely limits usability,
|
||||||
only chrooted tables.
|
because it can open only chrooted tables.
|
||||||
|
|
||||||
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is not a trusted daemon process,
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is not a trusted daemon process,
|
||||||
and must not be used to look up sensitive information such
|
and must not be used to look up sensitive information such
|
||||||
@@ -94,6 +116,16 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
clients, and must therefore not be used for tables that
|
clients, and must therefore not be used for tables that
|
||||||
have high-latency lookups.
|
have high-latency lookups.
|
||||||
|
|
||||||
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> read-write service does not explicitly
|
||||||
|
close lookup tables (even if it did, this could not be
|
||||||
|
relied on, because the process may be terminated between
|
||||||
|
table updates). The read-write service should therefore
|
||||||
|
not be used with tables that leave persistent storage in
|
||||||
|
an inconsistent state between updates (for example, CDB).
|
||||||
|
Tables that support "sync on update" should be safe (for
|
||||||
|
example, Berkeley DB) as should tables that are imple-
|
||||||
|
mented by a real DBMS.
|
||||||
|
|
||||||
<b>CONFIGURATION PARAMETERS</b>
|
<b>CONFIGURATION PARAMETERS</b>
|
||||||
On busy mail systems a long time may pass before <a href="proxymap.8.html"><b>prox-</b></a>
|
On busy mail systems a long time may pass before <a href="proxymap.8.html"><b>prox-</b></a>
|
||||||
<a href="proxymap.8.html"><b>ymap</b>(8)</a> relevant changes to <a href="postconf.5.html"><b>main.cf</b></a> are picked up. Use the
|
<a href="proxymap.8.html"><b>ymap</b>(8)</a> relevant changes to <a href="postconf.5.html"><b>main.cf</b></a> are picked up. Use the
|
||||||
@@ -135,7 +167,13 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
|
|
||||||
<b><a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a> (see 'postconf -d' output)</b>
|
<b><a href="postconf.5.html#proxy_read_maps">proxy_read_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.
|
allowed to access for the read-only service.
|
||||||
|
|
||||||
|
Available in Postfix 2.5 and later:
|
||||||
|
|
||||||
|
<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.
|
||||||
|
|
||||||
<b>SEE ALSO</b>
|
<b>SEE ALSO</b>
|
||||||
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
|
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
|
||||||
@@ -145,7 +183,7 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
|
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
|
||||||
|
|
||||||
<b>LICENSE</b>
|
<b>LICENSE</b>
|
||||||
The Secure Mailer license must be distributed with this
|
The Secure Mailer license must be distributed with this
|
||||||
software.
|
software.
|
||||||
|
|
||||||
<b>HISTORY</b>
|
<b>HISTORY</b>
|
||||||
|
@@ -3423,11 +3423,17 @@ proxy_interfaces = 1.2.3.4
|
|||||||
.ad
|
.ad
|
||||||
.ft R
|
.ft R
|
||||||
.SH proxy_read_maps (default: see "postconf -d" output)
|
.SH proxy_read_maps (default: see "postconf -d" output)
|
||||||
The lookup tables that the \fBproxymap\fR(8) server is allowed to access.
|
The lookup tables that the \fBproxymap\fR(8) server is allowed to
|
||||||
Table references that don't begin with proxy: are ignored. The
|
access for the read-only service.
|
||||||
\fBproxymap\fR(8) table accesses are read-only.
|
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)
|
||||||
|
The lookup tables that the \fBproxymap\fR(8) server is allowed to
|
||||||
|
access for the read-write service.
|
||||||
|
Table references that don't begin with proxy: are ignored.
|
||||||
|
.PP
|
||||||
|
This feature is available in Postfix 2.5 and later.
|
||||||
.SH qmgr_clog_warn_time (default: 300s)
|
.SH qmgr_clog_warn_time (default: 300s)
|
||||||
The minimal delay between warnings that a specific destination is
|
The minimal delay between warnings that a specific destination is
|
||||||
clogging up the Postfix active queue. Specify 0 to disable.
|
clogging up the Postfix active queue. Specify 0 to disable.
|
||||||
|
@@ -12,9 +12,10 @@ Postfix lookup table proxy server
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
The \fBproxymap\fR(8) server provides read-only table
|
The \fBproxymap\fR(8) server provides read-only or read-write
|
||||||
lookup service to Postfix processes. The purpose
|
table lookup service to Postfix processes. These services are
|
||||||
of the service is:
|
implemented with distinct service names: \fBproxymap\fR and
|
||||||
|
\fBproxywrite\fR, respectively. The purpose of these services is:
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
To overcome chroot restrictions. For example, a chrooted SMTP
|
To overcome chroot restrictions. For example, a chrooted SMTP
|
||||||
server needs access to the system passwd file in order to
|
server needs access to the system passwd file in order to
|
||||||
@@ -39,6 +40,10 @@ virtual_alias_maps =
|
|||||||
.sp
|
.sp
|
||||||
The total number of connections is limited by the number of
|
The total number of connections is limited by the number of
|
||||||
proxymap server processes.
|
proxymap server processes.
|
||||||
|
.IP \(bu
|
||||||
|
To provide single-updater functionality for lookup tables
|
||||||
|
that do not reliably support multiple writers (i.e. all
|
||||||
|
file-based tables).
|
||||||
.PP
|
.PP
|
||||||
The \fBproxymap\fR(8) server implements the following requests:
|
The \fBproxymap\fR(8) server implements the following requests:
|
||||||
.IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
.IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
||||||
@@ -48,11 +53,26 @@ dependent flags (to distinguish a fixed string table from a regular
|
|||||||
expression table).
|
expression table).
|
||||||
.IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
.IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
||||||
Look up the data stored under the requested key.
|
Look up the data stored under the requested key.
|
||||||
The reply is the request completion status code (below) and
|
The reply is the request completion status code and
|
||||||
the lookup result value.
|
the lookup result value.
|
||||||
The \fImaptype:mapname\fR and \fIflags\fR are the same
|
The \fImaptype:mapname\fR and \fIflags\fR are the same
|
||||||
as with the \fBopen\fR request.
|
as with the \fBopen\fR request.
|
||||||
|
.IP "\fBupdate\fR \fImaptype:mapname flags key value\fR"
|
||||||
|
Update 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
|
||||||
|
To implement single-updater maps, specify a process limit
|
||||||
|
of 1 in the master.cf file entry for the proxywrite service.
|
||||||
|
.sp
|
||||||
|
This request is supported in Postfix 2.5 and later.
|
||||||
.PP
|
.PP
|
||||||
|
The request completion status is one of OK, RETRY, NOKEY
|
||||||
|
(lookup failed because the key was not found), BAD (malformed
|
||||||
|
request) or DENY (the table is not approved for proxy read
|
||||||
|
or update access).
|
||||||
|
|
||||||
There is no \fBclose\fR command, nor are tables implicitly closed
|
There is no \fBclose\fR command, nor are tables implicitly closed
|
||||||
when a client disconnects. The purpose is to share tables among
|
when a client disconnects. The purpose is to share tables among
|
||||||
multiple client processes.
|
multiple client processes.
|
||||||
@@ -74,8 +94,9 @@ or after \fB$max_idle\fR seconds of idle time.
|
|||||||
.nf
|
.nf
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
The \fBproxymap\fR(8) server opens only tables that are approved via the
|
The \fBproxymap\fR(8) server opens only tables that are
|
||||||
\fBproxy_read_maps\fR configuration parameter, does not talk to
|
approved via the \fBproxy_read_maps\fR or \fBproxy_write_maps\fR
|
||||||
|
configuration parameters, does not talk to
|
||||||
users, and can run at fixed low privilege, chrooted or not.
|
users, and can run at fixed low privilege, chrooted or not.
|
||||||
However, running the proxymap server chrooted severely limits
|
However, running the proxymap server chrooted severely limits
|
||||||
usability, because it can open only chrooted tables.
|
usability, because it can open only chrooted tables.
|
||||||
@@ -98,6 +119,15 @@ Problems and transactions are logged to \fBsyslogd\fR(8).
|
|||||||
The \fBproxymap\fR(8) server provides service to multiple clients,
|
The \fBproxymap\fR(8) server provides service to multiple clients,
|
||||||
and must therefore not be used for tables that have high-latency
|
and must therefore not be used for tables that have high-latency
|
||||||
lookups.
|
lookups.
|
||||||
|
|
||||||
|
The \fBproxymap\fR(8) read-write service does not explicitly
|
||||||
|
close lookup tables (even if it did, this could not be relied on,
|
||||||
|
because the process may be terminated between table updates).
|
||||||
|
The read-write service should therefore not be used with tables that
|
||||||
|
leave persistent storage in an inconsistent state between
|
||||||
|
updates (for example, CDB). Tables that support "sync on
|
||||||
|
update" should be safe (for example, Berkeley DB) as should
|
||||||
|
tables that are implemented by a real DBMS.
|
||||||
.SH "CONFIGURATION PARAMETERS"
|
.SH "CONFIGURATION PARAMETERS"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
@@ -130,7 +160,13 @@ The process ID of a Postfix command or daemon process.
|
|||||||
.IP "\fBprocess_name (read-only)\fR"
|
.IP "\fBprocess_name (read-only)\fR"
|
||||||
The process name of a Postfix command or daemon process.
|
The process name of a Postfix command or daemon process.
|
||||||
.IP "\fBproxy_read_maps (see 'postconf -d' output)\fR"
|
.IP "\fBproxy_read_maps (see 'postconf -d' output)\fR"
|
||||||
The lookup tables that the \fBproxymap\fR(8) server is allowed to access.
|
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 "\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.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@@ -328,6 +328,7 @@ while (<>) {
|
|||||||
s;\bpropagate_unmatched_extensions\b;<a href="postconf.5.html#propagate_unmatched_extensions">$&</a>;g;
|
s;\bpropagate_unmatched_extensions\b;<a href="postconf.5.html#propagate_unmatched_extensions">$&</a>;g;
|
||||||
s;\bproxy_inter[-</bB>]*\n* *[<bB>]*faces\b;<a href="postconf.5.html#proxy_interfaces">$&</a>;g;
|
s;\bproxy_inter[-</bB>]*\n* *[<bB>]*faces\b;<a href="postconf.5.html#proxy_interfaces">$&</a>;g;
|
||||||
s;\bproxy_read_maps\b;<a href="postconf.5.html#proxy_read_maps">$&</a>;g;
|
s;\bproxy_read_maps\b;<a href="postconf.5.html#proxy_read_maps">$&</a>;g;
|
||||||
|
s;\bproxy_write_maps\b;<a href="postconf.5.html#proxy_write_maps">$&</a>;g;
|
||||||
s;\bqmgr_clog_warn_time\b;<a href="postconf.5.html#qmgr_clog_warn_time">$&</a>;g;
|
s;\bqmgr_clog_warn_time\b;<a href="postconf.5.html#qmgr_clog_warn_time">$&</a>;g;
|
||||||
s;\bqmgr_fudge_factor\b;<a href="postconf.5.html#qmgr_fudge_factor">$&</a>;g;
|
s;\bqmgr_fudge_factor\b;<a href="postconf.5.html#qmgr_fudge_factor">$&</a>;g;
|
||||||
s;\bqmgr_message_active_limit\b;<a href="postconf.5.html#qmgr_message_active_limit">$&</a>;g;
|
s;\bqmgr_message_active_limit\b;<a href="postconf.5.html#qmgr_message_active_limit">$&</a>;g;
|
||||||
|
@@ -7204,15 +7204,27 @@ This is a read-only parameter.
|
|||||||
%PARAM proxy_read_maps see "postconf -d" output
|
%PARAM proxy_read_maps see "postconf -d" output
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The lookup tables that the proxymap(8) server is allowed to access.
|
The lookup tables that the proxymap(8) server is allowed to
|
||||||
Table references that don't begin with proxy: are ignored. The
|
access for the read-only service.
|
||||||
proxymap(8) table accesses are read-only.
|
Table references that don't begin with proxy: are ignored.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This feature is available in Postfix 2.0 and later.
|
This feature is available in Postfix 2.0 and later.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
%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.
|
||||||
|
Table references that don't begin with proxy: are ignored.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This feature is available in Postfix 2.5 and later.
|
||||||
|
</p>
|
||||||
|
|
||||||
%PARAM qmgr_clog_warn_time 300s
|
%PARAM qmgr_clog_warn_time 300s
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@@ -28,7 +28,7 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
|
|||||||
tok822_resolve.c tok822_rewrite.c tok822_tree.c trace.c \
|
tok822_resolve.c tok822_rewrite.c tok822_tree.c trace.c \
|
||||||
user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \
|
user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \
|
||||||
verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
|
verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
|
||||||
fold_addr.c header_body_checks.c
|
fold_addr.c header_body_checks.c mkmap_proxy.c
|
||||||
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
|
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
|
||||||
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
|
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
|
||||||
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
|
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
|
||||||
@@ -58,7 +58,7 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
|
|||||||
tok822_resolve.o tok822_rewrite.o tok822_tree.o trace.o \
|
tok822_resolve.o tok822_rewrite.o tok822_tree.o trace.o \
|
||||||
user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \
|
user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \
|
||||||
verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
|
verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
|
||||||
fold_addr.o header_body_checks.o
|
fold_addr.o header_body_checks.o mkmap_proxy.o
|
||||||
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
|
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
|
||||||
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
|
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
|
||||||
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
|
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
|
||||||
@@ -1451,8 +1451,19 @@ mkmap_open.o: ../../include/sys_defs.h
|
|||||||
mkmap_open.o: ../../include/vbuf.h
|
mkmap_open.o: ../../include/vbuf.h
|
||||||
mkmap_open.o: ../../include/vstream.h
|
mkmap_open.o: ../../include/vstream.h
|
||||||
mkmap_open.o: ../../include/vstring.h
|
mkmap_open.o: ../../include/vstring.h
|
||||||
|
mkmap_open.o: dict_proxy.h
|
||||||
mkmap_open.o: mkmap.h
|
mkmap_open.o: mkmap.h
|
||||||
mkmap_open.o: mkmap_open.c
|
mkmap_open.o: mkmap_open.c
|
||||||
|
mkmap_proxy.o: ../../include/argv.h
|
||||||
|
mkmap_proxy.o: ../../include/dict.h
|
||||||
|
mkmap_proxy.o: ../../include/mymalloc.h
|
||||||
|
mkmap_proxy.o: ../../include/sys_defs.h
|
||||||
|
mkmap_proxy.o: ../../include/vbuf.h
|
||||||
|
mkmap_proxy.o: ../../include/vstream.h
|
||||||
|
mkmap_proxy.o: ../../include/vstring.h
|
||||||
|
mkmap_proxy.o: dict_proxy.h
|
||||||
|
mkmap_proxy.o: mkmap.h
|
||||||
|
mkmap_proxy.o: mkmap_proxy.c
|
||||||
mkmap_sdbm.o: ../../include/argv.h
|
mkmap_sdbm.o: ../../include/argv.h
|
||||||
mkmap_sdbm.o: ../../include/dict.h
|
mkmap_sdbm.o: ../../include/dict.h
|
||||||
mkmap_sdbm.o: ../../include/dict_sdbm.h
|
mkmap_sdbm.o: ../../include/dict_sdbm.h
|
||||||
|
@@ -14,7 +14,10 @@
|
|||||||
/* dict_proxy_open() relays read-only operations through
|
/* dict_proxy_open() relays read-only operations through
|
||||||
/* the Postfix proxymap server.
|
/* the Postfix proxymap server.
|
||||||
/*
|
/*
|
||||||
/* The \fIopen_flags\fR argument must specify O_RDONLY.
|
/* The \fIopen_flags\fR argument must specify O_RDONLY
|
||||||
|
/* or O_RDWR|O_CREAT. Depending on this, the client
|
||||||
|
/* connects to the proxymap multiserver or to the
|
||||||
|
/* proxywrite single updater.
|
||||||
/*
|
/*
|
||||||
/* The connection to the Postfix proxymap server is automatically
|
/* The connection to the Postfix proxymap server is automatically
|
||||||
/* closed after $ipc_idle seconds of idle time, or after $ipc_ttl
|
/* closed after $ipc_idle seconds of idle time, or after $ipc_ttl
|
||||||
@@ -154,6 +157,69 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dict_proxy_update - update table entry */
|
||||||
|
|
||||||
|
static void dict_proxy_update(DICT *dict, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
const char *myname = "dict_proxy_update";
|
||||||
|
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(proxy_stream);
|
||||||
|
errno = 0;
|
||||||
|
count += 1;
|
||||||
|
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_UPDATE,
|
||||||
|
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_STR, MAIL_ATTR_VALUE, value,
|
||||||
|
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 value=%s -> status=%d",
|
||||||
|
myname, dict->name, dict_flags_str(request_flags),
|
||||||
|
key, value, status);
|
||||||
|
switch (status) {
|
||||||
|
case PROXY_STAT_BAD:
|
||||||
|
msg_fatal("%s lookup failed for table \"%s\" key \"%s\": "
|
||||||
|
"invalid request",
|
||||||
|
MAIL_SERVICE_PROXYMAP, dict->name, key);
|
||||||
|
case PROXY_STAT_DENY:
|
||||||
|
msg_fatal("%s update access is not configured for table \"%s\"",
|
||||||
|
MAIL_SERVICE_PROXYMAP, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clnt_stream_recover(proxy_stream);
|
||||||
|
sleep(1); /* XXX make configurable */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* dict_proxy_close - disconnect */
|
/* dict_proxy_close - disconnect */
|
||||||
|
|
||||||
static void dict_proxy_close(DICT *dict)
|
static void dict_proxy_close(DICT *dict)
|
||||||
@@ -178,9 +244,14 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity checks.
|
* Sanity checks.
|
||||||
|
*
|
||||||
|
* XXX A complete implementation would also allow O_RDWR without O_CREAT.
|
||||||
|
* But we must not pass on every possible set of flags to the proxy
|
||||||
|
* 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)
|
if (open_flags != O_RDONLY && open_flags != (O_RDWR | O_CREAT))
|
||||||
msg_fatal("%s: %s map open requires O_RDONLY access mode",
|
msg_fatal("%s: %s map open requires O_RDONLY or O_RDWR|O_CREAT mode",
|
||||||
map, DICT_TYPE_PROXY);
|
map, DICT_TYPE_PROXY);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -197,6 +268,7 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
dict_proxy = (DICT_PROXY *)
|
dict_proxy = (DICT_PROXY *)
|
||||||
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.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);
|
||||||
@@ -207,13 +279,18 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
* 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 (proxy_stream == 0) {
|
||||||
if (access(MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP, F_OK) == 0)
|
if (access(open_flags == O_RDONLY ?
|
||||||
|
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,
|
proxy_stream = clnt_stream_create(prefix,
|
||||||
MAIL_SERVICE_PROXYMAP,
|
open_flags == O_RDONLY ?
|
||||||
|
MAIL_SERVICE_PROXYMAP :
|
||||||
|
MAIL_SERVICE_PROXYWRITE,
|
||||||
var_ipc_idle_limit,
|
var_ipc_idle_limit,
|
||||||
var_ipc_ttl_limit);
|
var_ipc_ttl_limit);
|
||||||
if (kludge)
|
if (kludge)
|
||||||
|
@@ -28,6 +28,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_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 */
|
||||||
|
@@ -2014,6 +2014,10 @@ extern int var_local_rcpt_code;
|
|||||||
" $" VAR_MYNETWORKS
|
" $" VAR_MYNETWORKS
|
||||||
extern char *var_proxy_read_maps;
|
extern char *var_proxy_read_maps;
|
||||||
|
|
||||||
|
#define VAR_PROXY_WRITE_MAPS "proxy_write_maps"
|
||||||
|
#define DEF_PROXY_WRITE_MAPS "" /* Add here: "$" VAR_AUTH_FAIL_MAP */
|
||||||
|
extern char *var_proxy_write_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other.
|
* Other.
|
||||||
*/
|
*/
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
#define MAIL_SERVICE_TRACE "trace"
|
#define MAIL_SERVICE_TRACE "trace"
|
||||||
#define MAIL_SERVICE_RELAY "relay"
|
#define MAIL_SERVICE_RELAY "relay"
|
||||||
#define MAIL_SERVICE_PROXYMAP "proxymap"
|
#define MAIL_SERVICE_PROXYMAP "proxymap"
|
||||||
|
#define MAIL_SERVICE_PROXYWRITE "proxywrite"
|
||||||
#define MAIL_SERVICE_SCACHE "scache"
|
#define MAIL_SERVICE_SCACHE "scache"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -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 "20071130"
|
#define MAIL_RELEASE_DATE "2007111203"
|
||||||
#define MAIL_VERSION_NUMBER "2.5"
|
#define MAIL_VERSION_NUMBER "2.5"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@@ -40,6 +40,7 @@ extern MKMAP *mkmap_cdb_open(const char *);
|
|||||||
extern MKMAP *mkmap_hash_open(const char *);
|
extern MKMAP *mkmap_hash_open(const char *);
|
||||||
extern MKMAP *mkmap_btree_open(const char *);
|
extern MKMAP *mkmap_btree_open(const char *);
|
||||||
extern MKMAP *mkmap_sdbm_open(const char *);
|
extern MKMAP *mkmap_sdbm_open(const char *);
|
||||||
|
extern MKMAP *mkmap_proxy_open(const char *);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
#include <dict_cdb.h>
|
#include <dict_cdb.h>
|
||||||
#include <dict_dbm.h>
|
#include <dict_dbm.h>
|
||||||
#include <dict_sdbm.h>
|
#include <dict_sdbm.h>
|
||||||
|
#include <dict_proxy.h>
|
||||||
#include <sigdelay.h>
|
#include <sigdelay.h>
|
||||||
#include <mymalloc.h>
|
#include <mymalloc.h>
|
||||||
|
|
||||||
@@ -83,6 +84,7 @@ typedef struct {
|
|||||||
} MKMAP_OPEN_INFO;
|
} MKMAP_OPEN_INFO;
|
||||||
|
|
||||||
MKMAP_OPEN_INFO mkmap_types[] = {
|
MKMAP_OPEN_INFO mkmap_types[] = {
|
||||||
|
DICT_TYPE_PROXY, mkmap_proxy_open,
|
||||||
#ifdef HAS_CDB
|
#ifdef HAS_CDB
|
||||||
DICT_TYPE_CDB, mkmap_cdb_open,
|
DICT_TYPE_CDB, mkmap_cdb_open,
|
||||||
#endif
|
#endif
|
||||||
|
58
postfix/src/global/mkmap_proxy.c
Normal file
58
postfix/src/global/mkmap_proxy.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* mkmap_proxy 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* create or proxied database
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <mkmap.h>
|
||||||
|
/*
|
||||||
|
/* MKMAP *mkmap_proxy_open(path)
|
||||||
|
/* const char *path;
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* This module implements support for updating proxy databases.
|
||||||
|
/*
|
||||||
|
/* mkmap_proxy_open() is a proxymap-specific helper for the
|
||||||
|
/* more general mkmap_open() routine.
|
||||||
|
/*
|
||||||
|
/* All errors are fatal.
|
||||||
|
/* SEE ALSO
|
||||||
|
/* dict_proxy(3), proxy client interface.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/* System library. */
|
||||||
|
|
||||||
|
#include <sys_defs.h>
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <dict_proxy.h>
|
||||||
|
|
||||||
|
/* Application-specific. */
|
||||||
|
|
||||||
|
#include "mkmap.h"
|
||||||
|
|
||||||
|
/* mkmap_proxy_open - create or open database */
|
||||||
|
|
||||||
|
MKMAP *mkmap_proxy_open(const char *unused_path)
|
||||||
|
{
|
||||||
|
MKMAP *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the generic members.
|
||||||
|
*/
|
||||||
|
mkmap->open = dict_proxy_open;
|
||||||
|
mkmap->after_open = 0;
|
||||||
|
mkmap->after_close = 0;
|
||||||
|
|
||||||
|
return (mkmap);
|
||||||
|
}
|
@@ -304,7 +304,7 @@ void qmgr_queue_throttle(QMGR_QUEUE *queue, DSN *dsn)
|
|||||||
queue->fail_cohorts += 1.0 / queue->window;
|
queue->fail_cohorts += 1.0 / queue->window;
|
||||||
if (transport->fail_cohort_limit > 0
|
if (transport->fail_cohort_limit > 0
|
||||||
&& queue->fail_cohorts >= transport->fail_cohort_limit)
|
&& queue->fail_cohorts >= transport->fail_cohort_limit)
|
||||||
queue->window = 0;
|
queue->window = QMGR_QUEUE_STAT_THROTTLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -83,6 +83,7 @@ depend: $(MAKES)
|
|||||||
# do not edit below this line - it is generated by 'make depend'
|
# do not edit below this line - it is generated by 'make depend'
|
||||||
postalias.o: ../../include/argv.h
|
postalias.o: ../../include/argv.h
|
||||||
postalias.o: ../../include/dict.h
|
postalias.o: ../../include/dict.h
|
||||||
|
postalias.o: ../../include/dict_proxy.h
|
||||||
postalias.o: ../../include/mail_conf.h
|
postalias.o: ../../include/mail_conf.h
|
||||||
postalias.o: ../../include/mail_dict.h
|
postalias.o: ../../include/mail_dict.h
|
||||||
postalias.o: ../../include/mail_params.h
|
postalias.o: ../../include/mail_params.h
|
||||||
|
@@ -239,6 +239,7 @@
|
|||||||
#include <mail_version.h>
|
#include <mail_version.h>
|
||||||
#include <mkmap.h>
|
#include <mkmap.h>
|
||||||
#include <mail_task.h>
|
#include <mail_task.h>
|
||||||
|
#include <dict_proxy.h>
|
||||||
|
|
||||||
/* Application-specific. */
|
/* Application-specific. */
|
||||||
|
|
||||||
@@ -275,6 +276,8 @@ static void postalias(char *map_type, char *path_name, int postalias_flags,
|
|||||||
if ((open_flags & O_TRUNC) == 0) {
|
if ((open_flags & O_TRUNC) == 0) {
|
||||||
source_fp = VSTREAM_IN;
|
source_fp = VSTREAM_IN;
|
||||||
vstream_control(source_fp, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
|
vstream_control(source_fp, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
|
||||||
|
} else if (strcmp(map_type, DICT_TYPE_PROXY) == 0) {
|
||||||
|
msg_fatal("can't create maps via the proxy service");
|
||||||
} else if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0) {
|
} else if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0) {
|
||||||
msg_fatal("open %s: %m", path_name);
|
msg_fatal("open %s: %m", path_name);
|
||||||
}
|
}
|
||||||
@@ -524,10 +527,14 @@ static int postalias_deletes(VSTREAM *in, char **maps, const int map_count,
|
|||||||
* Open maps ahead of time.
|
* Open maps ahead of time.
|
||||||
*/
|
*/
|
||||||
dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
|
dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
|
||||||
for (n = 0; n < map_count; n++)
|
for (n = 0; n < map_count; n++) {
|
||||||
dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
|
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");
|
||||||
|
dicts[n] = (map_name != 0 ?
|
||||||
dict_open3(maps[n], map_name, O_RDWR, dict_flags) :
|
dict_open3(maps[n], map_name, O_RDWR, dict_flags) :
|
||||||
dict_open3(var_db_type, maps[n], O_RDWR, dict_flags));
|
dict_open3(var_db_type, maps[n], O_RDWR, dict_flags));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform all requests.
|
* Perform all requests.
|
||||||
@@ -556,6 +563,8 @@ static int postalias_delete(const char *map_type, const char *map_name,
|
|||||||
DICT *dict;
|
DICT *dict;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
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);
|
dict = dict_open3(map_type, map_name, O_RDWR, dict_flags);
|
||||||
status = dict_del(dict, key);
|
status = dict_del(dict, key);
|
||||||
dict_close(dict);
|
dict_close(dict);
|
||||||
@@ -572,6 +581,8 @@ static void postalias_seq(const char *map_type, const char *map_name,
|
|||||||
const char *value;
|
const char *value;
|
||||||
int func;
|
int func;
|
||||||
|
|
||||||
|
if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
|
||||||
|
msg_fatal("can't sequence maps via the proxy service");
|
||||||
dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
|
dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
|
||||||
for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
|
for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
|
||||||
if (dict_seq(dict, func, &key, &value) != 0)
|
if (dict_seq(dict, func, &key, &value) != 0)
|
||||||
|
@@ -83,6 +83,7 @@ depend: $(MAKES)
|
|||||||
# do not edit below this line - it is generated by 'make depend'
|
# do not edit below this line - it is generated by 'make depend'
|
||||||
postmap.o: ../../include/argv.h
|
postmap.o: ../../include/argv.h
|
||||||
postmap.o: ../../include/dict.h
|
postmap.o: ../../include/dict.h
|
||||||
|
postmap.o: ../../include/dict_proxy.h
|
||||||
postmap.o: ../../include/mail_conf.h
|
postmap.o: ../../include/mail_conf.h
|
||||||
postmap.o: ../../include/mail_dict.h
|
postmap.o: ../../include/mail_dict.h
|
||||||
postmap.o: ../../include/mail_params.h
|
postmap.o: ../../include/mail_params.h
|
||||||
|
@@ -250,6 +250,7 @@
|
|||||||
#include <mail_version.h>
|
#include <mail_version.h>
|
||||||
#include <mkmap.h>
|
#include <mkmap.h>
|
||||||
#include <mail_task.h>
|
#include <mail_task.h>
|
||||||
|
#include <dict_proxy.h>
|
||||||
|
|
||||||
/* Application-specific. */
|
/* Application-specific. */
|
||||||
|
|
||||||
@@ -279,6 +280,8 @@ static void postmap(char *map_type, char *path_name, int postmap_flags,
|
|||||||
if ((open_flags & O_TRUNC) == 0) {
|
if ((open_flags & O_TRUNC) == 0) {
|
||||||
source_fp = VSTREAM_IN;
|
source_fp = VSTREAM_IN;
|
||||||
vstream_control(source_fp, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
|
vstream_control(source_fp, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
|
||||||
|
} else if (strcmp(map_type, DICT_TYPE_PROXY) == 0) {
|
||||||
|
msg_fatal("can't create maps via the proxy service");
|
||||||
} else if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0) {
|
} else if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0) {
|
||||||
msg_fatal("open %s: %m", path_name);
|
msg_fatal("open %s: %m", path_name);
|
||||||
}
|
}
|
||||||
@@ -471,10 +474,14 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count,
|
|||||||
* Open maps ahead of time.
|
* Open maps ahead of time.
|
||||||
*/
|
*/
|
||||||
dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
|
dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
|
||||||
for (n = 0; n < map_count; n++)
|
for (n = 0; n < map_count; n++) {
|
||||||
dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
|
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");
|
||||||
|
dicts[n] = (map_name != 0 ?
|
||||||
dict_open3(maps[n], map_name, O_RDWR, dict_flags) :
|
dict_open3(maps[n], map_name, O_RDWR, dict_flags) :
|
||||||
dict_open3(var_db_type, maps[n], O_RDWR, dict_flags));
|
dict_open3(var_db_type, maps[n], O_RDWR, dict_flags));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform all requests.
|
* Perform all requests.
|
||||||
@@ -503,6 +510,8 @@ static int postmap_delete(const char *map_type, const char *map_name,
|
|||||||
DICT *dict;
|
DICT *dict;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
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);
|
dict = dict_open3(map_type, map_name, O_RDWR, dict_flags);
|
||||||
status = dict_del(dict, key);
|
status = dict_del(dict, key);
|
||||||
dict_close(dict);
|
dict_close(dict);
|
||||||
@@ -519,6 +528,8 @@ static void postmap_seq(const char *map_type, const char *map_name,
|
|||||||
const char *value;
|
const char *value;
|
||||||
int func;
|
int func;
|
||||||
|
|
||||||
|
if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
|
||||||
|
msg_fatal("can't sequence maps via the proxy service");
|
||||||
dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
|
dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
|
||||||
for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
|
for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
|
||||||
if (dict_seq(dict, func, &key, &value) != 0)
|
if (dict_seq(dict, func, &key, &value) != 0)
|
||||||
|
@@ -6,9 +6,10 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* \fBproxymap\fR [generic Postfix daemon options]
|
/* \fBproxymap\fR [generic Postfix daemon options]
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* The \fBproxymap\fR(8) server provides read-only table
|
/* The \fBproxymap\fR(8) server provides read-only or read-write
|
||||||
/* lookup service to Postfix processes. The purpose
|
/* table lookup service to Postfix processes. These services are
|
||||||
/* of the service is:
|
/* implemented with distinct service names: \fBproxymap\fR and
|
||||||
|
/* \fBproxywrite\fR, respectively. The purpose of these services is:
|
||||||
/* .IP \(bu
|
/* .IP \(bu
|
||||||
/* To overcome chroot restrictions. For example, a chrooted SMTP
|
/* To overcome chroot restrictions. For example, a chrooted SMTP
|
||||||
/* server needs access to the system passwd file in order to
|
/* server needs access to the system passwd file in order to
|
||||||
@@ -33,6 +34,10 @@
|
|||||||
/* .sp
|
/* .sp
|
||||||
/* The total number of connections is limited by the number of
|
/* The total number of connections is limited by the number of
|
||||||
/* proxymap server processes.
|
/* proxymap server processes.
|
||||||
|
/* .IP \(bu
|
||||||
|
/* To provide single-updater functionality for lookup tables
|
||||||
|
/* that do not reliably support multiple writers (i.e. all
|
||||||
|
/* file-based tables).
|
||||||
/* .PP
|
/* .PP
|
||||||
/* The \fBproxymap\fR(8) server implements the following requests:
|
/* The \fBproxymap\fR(8) server implements the following requests:
|
||||||
/* .IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
/* .IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
||||||
@@ -42,11 +47,26 @@
|
|||||||
/* expression table).
|
/* expression table).
|
||||||
/* .IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
/* .IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
||||||
/* Look up the data stored under the requested key.
|
/* Look up the data stored under the requested key.
|
||||||
/* The reply is the request completion status code (below) and
|
/* The reply is the request completion status code and
|
||||||
/* the lookup result value.
|
/* the lookup result value.
|
||||||
/* The \fImaptype:mapname\fR and \fIflags\fR are the same
|
/* The \fImaptype:mapname\fR and \fIflags\fR are the same
|
||||||
/* as with the \fBopen\fR request.
|
/* as with the \fBopen\fR request.
|
||||||
|
/* .IP "\fBupdate\fR \fImaptype:mapname flags key value\fR"
|
||||||
|
/* Update 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
|
||||||
|
/* To implement single-updater maps, specify a process limit
|
||||||
|
/* of 1 in the master.cf file entry for the proxywrite service.
|
||||||
|
/* .sp
|
||||||
|
/* This request is supported in Postfix 2.5 and later.
|
||||||
/* .PP
|
/* .PP
|
||||||
|
/* The request completion status is one of OK, RETRY, NOKEY
|
||||||
|
/* (lookup failed because the key was not found), BAD (malformed
|
||||||
|
/* request) or DENY (the table is not approved for proxy read
|
||||||
|
/* or update access).
|
||||||
|
/*
|
||||||
/* There is no \fBclose\fR command, nor are tables implicitly closed
|
/* There is no \fBclose\fR command, nor are tables implicitly closed
|
||||||
/* when a client disconnects. The purpose is to share tables among
|
/* when a client disconnects. The purpose is to share tables among
|
||||||
/* multiple client processes.
|
/* multiple client processes.
|
||||||
@@ -64,8 +84,9 @@
|
|||||||
/* SECURITY
|
/* SECURITY
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
/* The \fBproxymap\fR(8) server opens only tables that are approved via the
|
/* The \fBproxymap\fR(8) server opens only tables that are
|
||||||
/* \fBproxy_read_maps\fR configuration parameter, does not talk to
|
/* approved via the \fBproxy_read_maps\fR or \fBproxy_write_maps\fR
|
||||||
|
/* configuration parameters, does not talk to
|
||||||
/* users, and can run at fixed low privilege, chrooted or not.
|
/* users, and can run at fixed low privilege, chrooted or not.
|
||||||
/* However, running the proxymap server chrooted severely limits
|
/* However, running the proxymap server chrooted severely limits
|
||||||
/* usability, because it can open only chrooted tables.
|
/* usability, because it can open only chrooted tables.
|
||||||
@@ -84,6 +105,15 @@
|
|||||||
/* The \fBproxymap\fR(8) server provides service to multiple clients,
|
/* The \fBproxymap\fR(8) server provides service to multiple clients,
|
||||||
/* and must therefore not be used for tables that have high-latency
|
/* and must therefore not be used for tables that have high-latency
|
||||||
/* lookups.
|
/* lookups.
|
||||||
|
/*
|
||||||
|
/* The \fBproxymap\fR(8) read-write service does not explicitly
|
||||||
|
/* close lookup tables (even if it did, this could not be relied on,
|
||||||
|
/* because the process may be terminated between table updates).
|
||||||
|
/* The read-write service should therefore not be used with tables that
|
||||||
|
/* leave persistent storage in an inconsistent state between
|
||||||
|
/* updates (for example, CDB). Tables that support "sync on
|
||||||
|
/* update" should be safe (for example, Berkeley DB) as should
|
||||||
|
/* tables that are implemented by a real DBMS.
|
||||||
/* CONFIGURATION PARAMETERS
|
/* CONFIGURATION PARAMETERS
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@@ -114,7 +144,13 @@
|
|||||||
/* .IP "\fBprocess_name (read-only)\fR"
|
/* .IP "\fBprocess_name (read-only)\fR"
|
||||||
/* The process name of a Postfix command or daemon process.
|
/* The process name of a Postfix command or daemon process.
|
||||||
/* .IP "\fBproxy_read_maps (see 'postconf -d' output)\fR"
|
/* .IP "\fBproxy_read_maps (see 'postconf -d' output)\fR"
|
||||||
/* The lookup tables that the \fBproxymap\fR(8) server is allowed to access.
|
/* 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 "\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.
|
||||||
/* SEE ALSO
|
/* SEE ALSO
|
||||||
/* postconf(5), configuration parameters
|
/* postconf(5), configuration parameters
|
||||||
/* master(5), generic daemon options
|
/* master(5), generic daemon options
|
||||||
@@ -189,11 +225,12 @@ char *var_rcpt_canon_maps;
|
|||||||
char *var_relocated_maps;
|
char *var_relocated_maps;
|
||||||
char *var_transport_maps;
|
char *var_transport_maps;
|
||||||
char *var_proxy_read_maps;
|
char *var_proxy_read_maps;
|
||||||
|
char *var_proxy_write_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The pre-approved, pre-parsed list of maps.
|
* The pre-approved, pre-parsed list of maps.
|
||||||
*/
|
*/
|
||||||
static HTABLE *proxy_read_maps;
|
static HTABLE *proxy_auth_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shared and static to reduce memory allocation overhead.
|
* Shared and static to reduce memory allocation overhead.
|
||||||
@@ -201,8 +238,14 @@ static HTABLE *proxy_read_maps;
|
|||||||
static VSTRING *request;
|
static VSTRING *request;
|
||||||
static VSTRING *request_map;
|
static VSTRING *request_map;
|
||||||
static VSTRING *request_key;
|
static VSTRING *request_key;
|
||||||
|
static VSTRING *request_value;
|
||||||
static VSTRING *map_type_name_flags;
|
static VSTRING *map_type_name_flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Are we a proxy writer or not?
|
||||||
|
*/
|
||||||
|
static int proxy_writer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Silly little macros.
|
* Silly little macros.
|
||||||
*/
|
*/
|
||||||
@@ -219,6 +262,7 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
|
|||||||
#define PROXY_COLON DICT_TYPE_PROXY ":"
|
#define PROXY_COLON DICT_TYPE_PROXY ":"
|
||||||
#define PROXY_COLON_LEN (sizeof(PROXY_COLON) - 1)
|
#define PROXY_COLON_LEN (sizeof(PROXY_COLON) - 1)
|
||||||
#define READ_OPEN_FLAGS O_RDONLY
|
#define READ_OPEN_FLAGS O_RDONLY
|
||||||
|
#define WRITE_OPEN_FLAGS (O_RDWR | O_CREAT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Canonicalize the map name. If the map is not on the approved list,
|
* Canonicalize the map name. If the map is not on the approved list,
|
||||||
@@ -230,11 +274,13 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
|
|||||||
map_type_name += PROXY_COLON_LEN;
|
map_type_name += PROXY_COLON_LEN;
|
||||||
if (strchr(map_type_name, ':') == 0)
|
if (strchr(map_type_name, ':') == 0)
|
||||||
PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_BAD);
|
PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_BAD);
|
||||||
if (htable_locate(proxy_read_maps, map_type_name) == 0) {
|
if (htable_locate(proxy_auth_maps, map_type_name) == 0) {
|
||||||
msg_warn("request for unapproved table: \"%s\"", map_type_name);
|
msg_warn("request for unapproved table: \"%s\"", map_type_name);
|
||||||
msg_warn("to approve this table for %s access, list %s:%s in %s:%s",
|
msg_warn("to approve this table for %s access, list %s:%s in %s:%s",
|
||||||
MAIL_SERVICE_PROXYMAP, DICT_TYPE_PROXY, map_type_name,
|
proxy_writer == 0 ? "read-only" : "read-write",
|
||||||
MAIN_CONF_FILE, VAR_PROXY_READ_MAPS);
|
DICT_TYPE_PROXY, map_type_name, MAIN_CONF_FILE,
|
||||||
|
proxy_writer == 0 ? VAR_PROXY_READ_MAPS :
|
||||||
|
VAR_PROXY_WRITE_MAPS);
|
||||||
PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_DENY);
|
PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_DENY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,13 +289,21 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
|
|||||||
*
|
*
|
||||||
* Assume that a map instance can be shared among clients with different
|
* Assume that a map instance can be shared among clients with different
|
||||||
* paranoia flag settings and with different map lookup flag settings.
|
* paranoia flag settings and with different map lookup flag settings.
|
||||||
|
*
|
||||||
|
* XXX The open() flags are passed implicitly, via the selection of the
|
||||||
|
* service name. For a more sophisticated interface, appropriate subsets
|
||||||
|
* of open() flags should be received directly from the client.
|
||||||
*/
|
*/
|
||||||
vstring_sprintf(map_type_name_flags, "%s:%s", map_type_name,
|
vstring_sprintf(map_type_name_flags, "%s:%s", map_type_name,
|
||||||
dict_flags_str(request_flags & DICT_FLAG_NP_INST_MASK));
|
dict_flags_str(request_flags & DICT_FLAG_NP_INST_MASK));
|
||||||
if ((dict = dict_handle(STR(map_type_name_flags))) == 0)
|
if ((dict = dict_handle(STR(map_type_name_flags))) == 0)
|
||||||
dict = dict_open(map_type_name, READ_OPEN_FLAGS, request_flags);
|
dict = dict_open(map_type_name, proxy_writer ?
|
||||||
|
WRITE_OPEN_FLAGS : READ_OPEN_FLAGS,
|
||||||
|
request_flags);
|
||||||
if (dict == 0)
|
if (dict == 0)
|
||||||
msg_panic("proxy_map_find: dict_open null result");
|
msg_panic("proxy_map_find: dict_open null result");
|
||||||
|
if (proxy_writer)
|
||||||
|
dict->flags |= DICT_FLAG_SYNC_UPDATE;
|
||||||
dict_register(STR(map_type_name_flags), dict);
|
dict_register(STR(map_type_name_flags), dict);
|
||||||
return (dict);
|
return (dict);
|
||||||
}
|
}
|
||||||
@@ -297,6 +351,46 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
|
|||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* proxymap_update_service - remote update service */
|
||||||
|
|
||||||
|
static void proxymap_update_service(VSTREAM *client_stream)
|
||||||
|
{
|
||||||
|
int request_flags;
|
||||||
|
DICT *dict;
|
||||||
|
int reply_status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the request.
|
||||||
|
*/
|
||||||
|
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_STR, MAIL_ATTR_VALUE, request_value,
|
||||||
|
ATTR_TYPE_END) != 4) {
|
||||||
|
reply_status = PROXY_STAT_BAD;
|
||||||
|
} else if (proxy_writer == 0) {
|
||||||
|
msg_warn("refusing %s update 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_put(dict, STR(request_key), STR(request_value));
|
||||||
|
reply_status = PROXY_STAT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
@@ -355,6 +449,8 @@ static void proxymap_service(VSTREAM *client_stream, char *unused_service,
|
|||||||
ATTR_TYPE_END) == 1) {
|
ATTR_TYPE_END) == 1) {
|
||||||
if (VSTREQ(request, PROXY_REQ_LOOKUP)) {
|
if (VSTREQ(request, PROXY_REQ_LOOKUP)) {
|
||||||
proxymap_lookup_service(client_stream);
|
proxymap_lookup_service(client_stream);
|
||||||
|
} else if (VSTREQ(request, PROXY_REQ_UPDATE)) {
|
||||||
|
proxymap_update_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 {
|
||||||
@@ -381,26 +477,37 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
|
|
||||||
/* post_jail_init - initialization after privilege drop */
|
/* post_jail_init - initialization after privilege drop */
|
||||||
|
|
||||||
static void post_jail_init(char *unused_name, char **unused_argv)
|
static void post_jail_init(char *service_name, char **unused_argv)
|
||||||
{
|
{
|
||||||
const char *sep = ", \t\r\n";
|
const char *sep = ", \t\r\n";
|
||||||
char *saved_filter;
|
char *saved_filter;
|
||||||
char *bp;
|
char *bp;
|
||||||
char *type_name;
|
char *type_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Are we proxy writer?
|
||||||
|
*/
|
||||||
|
if (strcmp(service_name, MAIL_SERVICE_PROXYWRITE) == 0)
|
||||||
|
proxy_writer = 1;
|
||||||
|
else if (strcmp(service_name, MAIL_SERVICE_PROXYMAP) != 0)
|
||||||
|
msg_fatal("service name must be one of %s or %s",
|
||||||
|
MAIL_SERVICE_PROXYMAP, MAIL_SERVICE_PROXYMAP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pre-allocate buffers.
|
* Pre-allocate buffers.
|
||||||
*/
|
*/
|
||||||
request = vstring_alloc(10);
|
request = vstring_alloc(10);
|
||||||
request_map = vstring_alloc(10);
|
request_map = vstring_alloc(10);
|
||||||
request_key = vstring_alloc(10);
|
request_key = vstring_alloc(10);
|
||||||
|
request_value = vstring_alloc(10);
|
||||||
map_type_name_flags = vstring_alloc(10);
|
map_type_name_flags = vstring_alloc(10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the pre-approved list of proxied tables.
|
* Prepare the pre-approved list of proxied tables.
|
||||||
*/
|
*/
|
||||||
saved_filter = bp = mystrdup(var_proxy_read_maps);
|
saved_filter = bp = mystrdup(proxy_writer ? var_proxy_write_maps :
|
||||||
proxy_read_maps = htable_create(13);
|
var_proxy_read_maps);
|
||||||
|
proxy_auth_maps = htable_create(13);
|
||||||
while ((type_name = mystrtok(&bp, sep)) != 0) {
|
while ((type_name = mystrtok(&bp, sep)) != 0) {
|
||||||
if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN))
|
if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN))
|
||||||
continue;
|
continue;
|
||||||
@@ -408,8 +515,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
|||||||
type_name += PROXY_COLON_LEN;
|
type_name += PROXY_COLON_LEN;
|
||||||
} while (!strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN));
|
} while (!strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN));
|
||||||
if (strchr(type_name, ':') != 0
|
if (strchr(type_name, ':') != 0
|
||||||
&& htable_locate(proxy_read_maps, type_name) == 0)
|
&& htable_locate(proxy_auth_maps, type_name) == 0)
|
||||||
(void) htable_enter(proxy_read_maps, type_name, (char *) 0);
|
(void) htable_enter(proxy_auth_maps, type_name, (char *) 0);
|
||||||
}
|
}
|
||||||
myfree(saved_filter);
|
myfree(saved_filter);
|
||||||
|
|
||||||
@@ -418,6 +525,13 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
|||||||
* time, so we don't have to do it another time.
|
* time, so we don't have to do it another time.
|
||||||
*/
|
*/
|
||||||
var_idle_limit = 1;
|
var_idle_limit = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Never, ever, get killed by a master signal, as that could corrupt a
|
||||||
|
* persistent database when we're in the middle of an update.
|
||||||
|
*/
|
||||||
|
if (proxy_writer != 0)
|
||||||
|
setsid();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pre_accept - see if tables have changed */
|
/* pre_accept - see if tables have changed */
|
||||||
@@ -426,7 +540,7 @@ static void pre_accept(char *unused_name, char **unused_argv)
|
|||||||
{
|
{
|
||||||
const char *table;
|
const char *table;
|
||||||
|
|
||||||
if ((table = dict_changed_name()) != 0) {
|
if (proxy_writer == 0 && (table = dict_changed_name()) != 0) {
|
||||||
msg_info("table %s has changed -- restarting", table);
|
msg_info("table %s has changed -- restarting", table);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@@ -452,6 +566,7 @@ int main(int argc, char **argv)
|
|||||||
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
|
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
|
||||||
VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0,
|
VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0,
|
||||||
VAR_PROXY_READ_MAPS, DEF_PROXY_READ_MAPS, &var_proxy_read_maps, 0, 0,
|
VAR_PROXY_READ_MAPS, DEF_PROXY_READ_MAPS, &var_proxy_read_maps, 0, 0,
|
||||||
|
VAR_PROXY_WRITE_MAPS, DEF_PROXY_WRITE_MAPS, &var_proxy_write_maps, 0, 0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -464,5 +579,6 @@ int main(int argc, char **argv)
|
|||||||
MAIL_SERVER_STR_TABLE, str_table,
|
MAIL_SERVER_STR_TABLE, str_table,
|
||||||
MAIL_SERVER_POST_INIT, post_jail_init,
|
MAIL_SERVER_POST_INIT, post_jail_init,
|
||||||
MAIL_SERVER_PRE_ACCEPT, pre_accept,
|
MAIL_SERVER_PRE_ACCEPT, pre_accept,
|
||||||
|
/* XXX MAIL_SERVER_SOLITARY if proxywrite */
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
@@ -306,7 +306,7 @@ void qmgr_queue_throttle(QMGR_QUEUE *queue, DSN *dsn)
|
|||||||
queue->fail_cohorts += 1.0 / queue->window;
|
queue->fail_cohorts += 1.0 / queue->window;
|
||||||
if (transport->fail_cohort_limit > 0
|
if (transport->fail_cohort_limit > 0
|
||||||
&& queue->fail_cohorts >= transport->fail_cohort_limit)
|
&& queue->fail_cohorts >= transport->fail_cohort_limit)
|
||||||
queue->window = 0;
|
queue->window = QMGR_QUEUE_STAT_THROTTLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -95,7 +95,9 @@ extern DICT *dict_debug(DICT *);
|
|||||||
#define DICT_FLAG_PARANOID \
|
#define DICT_FLAG_PARANOID \
|
||||||
(DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
|
(DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
|
||||||
#define DICT_FLAG_IMPL_MASK (DICT_FLAG_FIXED | DICT_FLAG_PATTERN)
|
#define DICT_FLAG_IMPL_MASK (DICT_FLAG_FIXED | DICT_FLAG_PATTERN)
|
||||||
#define DICT_FLAG_RQST_MASK DICT_FLAG_FOLD_ANY
|
#define DICT_FLAG_RQST_MASK (DICT_FLAG_FOLD_ANY | DICT_FLAG_LOCK | \
|
||||||
|
DICT_FLAG_DUP_REPLACE | DICT_FLAG_DUP_WARN | \
|
||||||
|
DICT_FLAG_SYNC_UPDATE)
|
||||||
#define DICT_FLAG_NP_INST_MASK ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
|
#define DICT_FLAG_NP_INST_MASK ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
|
||||||
#define DICT_FLAG_INST_MASK (DICT_FLAG_NP_INST_MASK | DICT_FLAG_PARANOID)
|
#define DICT_FLAG_INST_MASK (DICT_FLAG_NP_INST_MASK | DICT_FLAG_PARANOID)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user