mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 14:17:41 +00:00
postfix-2.0.0-20030104
This commit is contained in:
committed by
Viktor Dukhovni
parent
55978ec179
commit
1eed3b4cde
@@ -7630,11 +7630,8 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
20030102
|
20030102
|
||||||
|
|
||||||
Workaround: use different client instances when the same
|
Cleanup: use different client instances when the same map
|
||||||
map is opened with different flags. This silences warnings
|
is opened with different flags. File: global/maps.c.
|
||||||
from maps_append() when the same map is opened by
|
|
||||||
virtual_alias_maps and by virtual_mailbox_maps. File:
|
|
||||||
global/maps.c.
|
|
||||||
|
|
||||||
Feature: proxymap server for Postfix table lookups. This
|
Feature: proxymap server for Postfix table lookups. This
|
||||||
helps to consolidate the number of open lookup tables (such
|
helps to consolidate the number of open lookup tables (such
|
||||||
@@ -7649,6 +7646,25 @@ Apologies for any names omitted.
|
|||||||
after the limit is reached. Based on a patch by Victor
|
after the limit is reached. Based on a patch by Victor
|
||||||
Duchovni, Morgan Stanley. File: master/multi_server.c.
|
Duchovni, Morgan Stanley. File: master/multi_server.c.
|
||||||
|
|
||||||
|
20030103
|
||||||
|
|
||||||
|
Cleanup: client stream endpoints not only have an idle time
|
||||||
|
limit ($ipc_idle) before a connection is closed, they now
|
||||||
|
also have a time to live ($ipc_ttl) to prevent connections
|
||||||
|
from becoming too persistent. This allows multi-servers
|
||||||
|
such as trivial-rewrite or the proxymap server to refresh
|
||||||
|
more frequently on busy systems. File: global/clnt_stream.c.
|
||||||
|
|
||||||
|
20030104
|
||||||
|
|
||||||
|
Cleanup: avoid warnings about flag mismatches when the same
|
||||||
|
lookup table is listed under both virtual_alias_maps and
|
||||||
|
virtual_mailbox_maps. Files: global/virtual8.h, virtual/virtual.c.
|
||||||
|
|
||||||
|
Bugfix: an obscure memory leak that puzzled me for more
|
||||||
|
than a year until I found out how to reproduce it. File:
|
||||||
|
util/vstream.c.
|
||||||
|
|
||||||
Open problems:
|
Open problems:
|
||||||
|
|
||||||
Med: do not postpone rejected "MAIL FROM" size information,
|
Med: do not postpone rejected "MAIL FROM" size information,
|
||||||
|
@@ -22,6 +22,37 @@ snapshot release). Patches change the patchlevel and the release
|
|||||||
date. Snapshots change only the release date, unless they include
|
date. Snapshots change only the release date, unless they include
|
||||||
the same bugfixes as a patch release.
|
the same bugfixes as a patch release.
|
||||||
|
|
||||||
|
Incompatible changes with Postfix snapshot 2.0.0-20030104
|
||||||
|
=========================================================
|
||||||
|
|
||||||
|
This release adds the new proxymap service (table lookup via a
|
||||||
|
proxy process) to the the master.cf file. If you get warnings about
|
||||||
|
problems connecting to the proxymap service, then you did not
|
||||||
|
properly upgrade Postfix.
|
||||||
|
|
||||||
|
Major changes with Postfix snapshot 2.0.0-20030104
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
This release introduces the proxymap service for Postfix lookup
|
||||||
|
table access. This can be used to overcome chroot restrictions in
|
||||||
|
the Postfix SMTP server (specify proxy:unix:passwd.byname for
|
||||||
|
password file lookup through the proxymap server) and can be used
|
||||||
|
to consolidate the number of open tables by sharing one open table
|
||||||
|
among multiple processes (specify proxy:mysql:/file/name to avoid
|
||||||
|
"too many connections" conditions). The proxy_read_maps parameter
|
||||||
|
specifies what maps are approved for access via the proxy service
|
||||||
|
(only map references starting with "proxy:" are considered approved).
|
||||||
|
|
||||||
|
Multi-server daemons (servers that accept simultaneous connections
|
||||||
|
from multiple clients) will now stop accepting new connections
|
||||||
|
after serving $max_use clients. This allows multi-server daemons
|
||||||
|
to automatically restart even on busy mail systems.
|
||||||
|
|
||||||
|
Clients of multi-server daemons such as trivial-rewrite and the
|
||||||
|
new proxymap service now automatically disconnect after $ipc_ttl
|
||||||
|
seconds of activity (default: 1000s). This allows multi-server
|
||||||
|
daemons to automatically restart even on busy mail mail systems.
|
||||||
|
|
||||||
Incompatible changes with Postfix snapshot 1.1.11-trace-20021119
|
Incompatible changes with Postfix snapshot 1.1.11-trace-20021119
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
|
@@ -175,18 +175,20 @@ mail_owner = postfix
|
|||||||
# For example, you define $mydestination domain recipients in
|
# For example, you define $mydestination domain recipients in
|
||||||
# the $virtual_mailbox_maps files.
|
# the $virtual_mailbox_maps files.
|
||||||
#
|
#
|
||||||
# - You redefined the local delivery agent in master.cf.
|
# - You redefine the local delivery agent in master.cf.
|
||||||
#
|
#
|
||||||
# - You redefined the "local_transport" setting in main.cf.
|
# - You redefine the "local_transport" setting in main.cf.
|
||||||
#
|
#
|
||||||
# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
|
# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
|
||||||
# feature of the Postfix local delivery agent (see sample-local.cf).
|
# feature of the Postfix local delivery agent (see sample-local.cf).
|
||||||
#
|
#
|
||||||
# Beware: if the Postfix SMTP server runs chrooted, you probably have
|
# Beware: if the Postfix SMTP server runs chrooted, you probably have
|
||||||
# to copy the passwd (not shadow) database into the jail, and perhaps
|
# to access the passwd file via the proxymap service, in order to
|
||||||
# other files. This is system dependent.
|
# overcome chroot restrictions. The alternative, having a copy of
|
||||||
|
# the system passwd file in the chroot jail is just not practical.
|
||||||
#
|
#
|
||||||
#local_recipient_maps = unix:passwd.byname $alias_maps
|
#local_recipient_maps = unix:passwd.byname $alias_maps
|
||||||
|
#local_recipient_maps = proxy:passwd.byname $alias_maps
|
||||||
#local_recipient_maps =
|
#local_recipient_maps =
|
||||||
|
|
||||||
# The unknown_local_recipient_reject_code specifies the SMTP server
|
# The unknown_local_recipient_reject_code specifies the SMTP server
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
# precedence, from highest to lowest priority: mailbox_transport,
|
# precedence, from highest to lowest priority: mailbox_transport,
|
||||||
# mailbox_command_maps, mailbox_command, home_mailbox.
|
# mailbox_command_maps, mailbox_command, home_mailbox.
|
||||||
|
|
||||||
|
#
|
||||||
|
# MISCELLANEOUS PARAMETERS
|
||||||
|
#
|
||||||
|
|
||||||
# The biff parameter specifies whether or not to contact the biff
|
# The biff parameter specifies whether or not to contact the biff
|
||||||
# server. This server sends "new mail" notifications to users who
|
# server. This server sends "new mail" notifications to users who
|
||||||
# have requested new mail notification with "biff y".
|
# have requested new mail notification with "biff y".
|
||||||
|
@@ -236,7 +236,7 @@ max_use = 100
|
|||||||
# a name matches a lookup key. Continue long lines by starting the
|
# a name matches a lookup key. Continue long lines by starting the
|
||||||
# next line with whitespace.
|
# next line with whitespace.
|
||||||
#
|
#
|
||||||
# See sample-local.cf for a description of the local_recipient_maps
|
# See sample-smtpd.cf for a description of the local_recipient_maps
|
||||||
# and unknown_local_recipient_reject_code parameters. By default,
|
# and unknown_local_recipient_reject_code parameters. By default,
|
||||||
# the SMTP server rejects mail for recipients not listed with the
|
# the SMTP server rejects mail for recipients not listed with the
|
||||||
# local_recipient_maps parameter.
|
# local_recipient_maps parameter.
|
||||||
|
@@ -4,6 +4,65 @@
|
|||||||
# This file contains example settings of Postfix configuration parameters
|
# This file contains example settings of Postfix configuration parameters
|
||||||
# that control the SMTP server program.
|
# that control the SMTP server program.
|
||||||
|
|
||||||
|
# REJECTING MAIL FOR UNKNOWN LOCAL USERS
|
||||||
|
#
|
||||||
|
# The local_recipient_maps parameter specifies optional lookup tables
|
||||||
|
# with all names or addresses of users that are local with respect
|
||||||
|
# to $mydestination and $inet_interfaces.
|
||||||
|
#
|
||||||
|
# If this parameter is defined, then the SMTP server will reject
|
||||||
|
# mail for unknown local users. This parameter is defined by default.
|
||||||
|
#
|
||||||
|
# To turn off local recipient checking in the SMTP server, specify
|
||||||
|
# local_recipient_maps = (i.e. empty).
|
||||||
|
#
|
||||||
|
# The default setting assumes that you use the default Postfix local
|
||||||
|
# delivery agent for local delivery. You need to update the
|
||||||
|
# local_recipient_maps setting if:
|
||||||
|
#
|
||||||
|
# - You define $mydestination domain recipients in files other than
|
||||||
|
# /etc/passwd, /etc/aliases, or the $virtual_alias_maps files.
|
||||||
|
# For example, you define $mydestination domain recipients in
|
||||||
|
# the $virtual_mailbox_maps files.
|
||||||
|
#
|
||||||
|
# - You redefine the local delivery agent in master.cf.
|
||||||
|
#
|
||||||
|
# - You redefine the "local_transport" setting in main.cf.
|
||||||
|
#
|
||||||
|
# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
|
||||||
|
# feature of the Postfix local delivery agent (see sample-local.cf).
|
||||||
|
#
|
||||||
|
# Beware: if the Postfix SMTP server runs chrooted, you probably have
|
||||||
|
# to access the passwd file via the proxymap service, in order to
|
||||||
|
# overcome chroot restrictions. The alternative, having a copy of
|
||||||
|
# the system passwd file in the chroot jail is just not practical.
|
||||||
|
#
|
||||||
|
#local_recipient_maps =
|
||||||
|
#local_recipient_maps = unix:passwd.byname $alias_maps
|
||||||
|
local_recipient_maps = proxy:passwd.byname $alias_maps
|
||||||
|
|
||||||
|
# The unknown_local_recipient_reject_code specifies the SMTP server
|
||||||
|
# response code when a recipient domain matches $mydestination or
|
||||||
|
# $inet_interfaces, while $local_recipient_maps is non-empty and the
|
||||||
|
# recipient address or address local-part is not found.
|
||||||
|
#
|
||||||
|
# The default setting is 550 (reject mail) but it is safer to start
|
||||||
|
# with 450 (try again later) until you are certain that your
|
||||||
|
# local_recipient_maps settings are OK.
|
||||||
|
#
|
||||||
|
#unknown_local_recipient_reject_code = 450
|
||||||
|
unknown_local_recipient_reject_code = 550
|
||||||
|
|
||||||
|
# REJECTING UNKNOWN RELAY USERS
|
||||||
|
#
|
||||||
|
# The relay_recipient_maps parameter specifies optional lookup tables
|
||||||
|
# with all addresses in the domains that match $relay_domains.
|
||||||
|
#
|
||||||
|
# If this parameter is defined, then the SMTP server will reject
|
||||||
|
# mail for unknown relay users. This feature is off by default.
|
||||||
|
#
|
||||||
|
#relay_recipient_maps = hash:/etc/postfix/relay_recipients
|
||||||
|
|
||||||
#
|
#
|
||||||
# SENDER ANTI-SPOOFING
|
# SENDER ANTI-SPOOFING
|
||||||
#
|
#
|
||||||
|
@@ -674,7 +674,7 @@ to send mail only to <i>user@domain.com</i>.
|
|||||||
Specify what recipients exist (so that your queue does not fill up
|
Specify what recipients exist (so that your queue does not fill up
|
||||||
with undeliverable mail from spammers).
|
with undeliverable mail from spammers).
|
||||||
|
|
||||||
<p.
|
<p>
|
||||||
|
|
||||||
Specify <tt>local_recipient_maps =</tt> if maintaining recipient
|
Specify <tt>local_recipient_maps =</tt> if maintaining recipient
|
||||||
information is not practical.
|
information is not practical.
|
||||||
@@ -2090,7 +2090,7 @@ you use the default Postfix local delivery agent:
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/main.cf:
|
||||||
local_recipient_maps = $alias_maps, unix:passwd.byname
|
local_recipient_maps = $alias_maps, proxy:unix:passwd.byname
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -2107,10 +2107,12 @@ To stop Postfix from rejecting local mail incorrectly:
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li> If you run the Postfix SMTP server chrooted, it may be necessary
|
<li> If you run the Postfix SMTP server chrooted, you need to access
|
||||||
to place a copy of the passwd file inside the chroot jail (typically:
|
the system password database through the Postfix <a href="proxymap.8.html">
|
||||||
in <b>/var/spool/postfix/etc</b>). This is system dependent. The
|
proxymap</a> service, as shown in the above example. The alternative
|
||||||
only way to find out is to try.
|
is simply not practical: placing a copy of the passwd file inside
|
||||||
|
the chroot jail (typically: in <b>/var/spool/postfix/etc</b>)
|
||||||
|
together with a list of system dependent files.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
@@ -2313,21 +2315,30 @@ database" mean?</h3></a>
|
|||||||
This message is logged when, for example, the Postfix SMTP server
|
This message is logged when, for example, the Postfix SMTP server
|
||||||
is unable to access the UNIX password database.
|
is unable to access the UNIX password database.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li> If you're running the Postfix SMTP server chrooted (see
|
<li> If you're running the Postfix SMTP server chrooted (see
|
||||||
<b>master.cf</b>) then you may have to copy the password file and
|
<b>master.cf</b>) then you need to access the system password
|
||||||
perhaps a bunch of other files into the Postfix queue directory; a
|
database through the Postfix <a href="proxymap.8.html">proxymap</a>
|
||||||
typical destination would be <b>/var/spool/postfix/etc</b>. See also
|
service. The alternative is not practical: copying the password
|
||||||
the chroot setup scripts in the <b>examples</b> directory of the
|
file and perhaps a bunch of other system dependent files into the
|
||||||
Postfix source code distribution.
|
Postfix queue directory.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
<li> Be sure that you have world execute permissions on directories
|
<pre>
|
||||||
and world read permission on the passwd file and any auxiliary
|
/etc/postfix/main.cf:
|
||||||
files that may be needed (such as <b>/etc/nsswitch.conf</b> and
|
local_recipient_maps = proxy:unix:passwd.byname $alias_maps ...
|
||||||
<b>libnss*.so*</b> files referenced by <b>/etc/nsswitch.conf</b>).
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<li> Chrooted or not, be sure that you have world execute permissions
|
||||||
|
on directories and world read permission on the passwd file and
|
||||||
|
any auxiliary files that may be needed (such as <b>/etc/nsswitch.conf</b>
|
||||||
|
and <b>libnss*.so*</b> files referenced by <b>/etc/nsswitch.conf</b>).
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@@ -91,7 +91,7 @@ POSTCONF(1) POSTCONF(1)
|
|||||||
|
|
||||||
<b>proxy</b> (read-only)
|
<b>proxy</b> (read-only)
|
||||||
A lookup table that is implemented via the
|
A lookup table that is implemented via the
|
||||||
Postfix <a href="verify.8.html"><b>proxymap</b>(8)</a> service. The table name
|
Postfix <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table name
|
||||||
syntax is <i>type</i><b>:</b><i>name</i>.
|
syntax is <i>type</i><b>:</b><i>name</i>.
|
||||||
|
|
||||||
<b>regexp</b> (read-only)
|
<b>regexp</b> (read-only)
|
||||||
|
@@ -15,34 +15,39 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
<b>o</b> To overcome chroot restrictions. For example, a
|
<b>o</b> To overcome chroot restrictions. For example, a
|
||||||
chrooted SMTP server needs access to the system
|
chrooted SMTP server needs access to the system
|
||||||
passwd file in order to reject mail for non-exis-
|
passwd file in order to reject mail for non-exis-
|
||||||
tent local addresses. The solution is to specify:
|
tent local addresses, but it is not practical to
|
||||||
|
maintain a copy of the passwd file in the chroot
|
||||||
|
jail. The solution:
|
||||||
|
|
||||||
local_recipient_maps =
|
local_recipient_maps =
|
||||||
proxy:unix:passwd.byname $alias_maps
|
proxy:unix:passwd.byname $alias_maps
|
||||||
|
|
||||||
<b>o</b> To consolidate the number of open lookup tables by
|
<b>o</b> To consolidate the number of open lookup tables by
|
||||||
sharing one open table among multiple processes.
|
sharing one open table among multiple processes.
|
||||||
For example, to avoid problems due to "too many
|
For example, making mysql connections from every
|
||||||
connections" to, e.g., mysql servers, specify:
|
Postfix daemon process results in "too many connec-
|
||||||
|
tions" errors. The solution:
|
||||||
|
|
||||||
virtual_alias_maps =
|
virtual_alias_maps =
|
||||||
proxy:mysql:/etc/postfix/virtual.cf
|
proxy:mysql:/etc/postfix/virtual.cf
|
||||||
|
|
||||||
<b>PROXYMAP</b> <b>SERVICES</b>
|
The total number of connections is limited by the
|
||||||
|
number of proxymap server server processes.
|
||||||
|
|
||||||
The proxymap server implements the following requests:
|
The proxymap server implements the following requests:
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>OPEN</b> <i>maptype:mapname</i> <i>flags</i>
|
<b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>OPEN</b> <i>maptype:mapname</i> <i>flags</i>
|
||||||
Open the table with type <i>maptype</i> and name <i>mapname</i>,
|
Open the table with type <i>maptype</i> and name <i>mapname</i>,
|
||||||
as controlled by <i>flags</i>. The reply is the request
|
as controlled by <i>flags</i>. The reply is the request
|
||||||
completion status code and the map type dependent
|
completion status code (below) and the map type
|
||||||
flags.
|
dependent flags.
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>LOOKUP</b> <i>maptype:mapname</i> <i>flags</i> <i>key</i>
|
<b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>LOOKUP</b> <i>maptype:mapname</i> <i>flags</i> <i>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 and
|
The reply is the request completion status code
|
||||||
the lookup result value. The <i>maptype:mapname</i> and
|
(below) and the lookup result value. The <i>map-</i>
|
||||||
<i>flags</i> are the same as with the <b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>OPEN</b>
|
<i>type:mapname</i> and <i>flags</i> are the same as with the
|
||||||
request.
|
<b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>OPEN</b> request.
|
||||||
|
|
||||||
There is no close command. This does not seem to be useful
|
There is no close command. This does not seem to be useful
|
||||||
because tables are meant to be shared among client pro-
|
because tables are meant to be shared among client pro-
|
||||||
@@ -51,33 +56,43 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
The request completion status code is one of:
|
The request completion status code is one of:
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>OK</b>
|
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>OK</b>
|
||||||
The requested table or lookup key was found.
|
The specified table was opened, or the requested
|
||||||
|
entry was found.
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>FAIL</b>
|
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>NOKEY</b>
|
||||||
The requested table or lookup key does not exist.
|
The requested table entry was not found.
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>BAD</b>
|
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>BAD</b>
|
||||||
The request was rejected (bad request parameter
|
The request was rejected (bad request parameter
|
||||||
value).
|
value).
|
||||||
|
|
||||||
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>RETRY</b>
|
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>RETRY</b>
|
||||||
The request was not completed.
|
The lookup request could not be completed.
|
||||||
|
|
||||||
<b>MASTER</b> <b>INTERFACE</b>
|
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>DENY</b>
|
||||||
|
The specified table was not approved for access via
|
||||||
|
the proxymap service.
|
||||||
|
|
||||||
|
<b>SERVER</b> <b>PROCESS</b> <b>MANAGEMENT</b>
|
||||||
The proxymap servers run under control by the Postfix mas-
|
The proxymap servers run under control by the Postfix mas-
|
||||||
ter server. Each server can handle multiple simultaneous
|
ter server. Each server can handle multiple simultaneous
|
||||||
connections. When all servers are busy while a client
|
connections. When all servers are busy while a client
|
||||||
connects, the master creates a new proxymap server pro-
|
connects, the master creates a new proxymap server pro-
|
||||||
cess, provided that the proxymap server process limit is
|
cess, provided that the proxymap server process limit is
|
||||||
not exceeded. Each proxymap server terminates after serv-
|
not exceeded. Each proxymap server stops accepting new
|
||||||
ing <b>$max</b><i>_</i><b>use</b> clients or after <b>$max</b><i>_</i><b>idle</b> seconds of idle
|
connections after serving <b>$max</b><i>_</i><b>use</b> clients or terminates
|
||||||
time.
|
after <b>$max</b><i>_</i><b>idle</b> seconds of idle time.
|
||||||
|
|
||||||
<b>SECURITY</b>
|
<b>SECURITY</b>
|
||||||
The proxymap server is not security-sensitive. It opens
|
The proxymap server opens only tables that are approved
|
||||||
only tables that are approved via the <b>proxymap</b><i>_</i><b>filter</b> con-
|
via the <b>proxy</b><i>_</i><b>read</b><i>_</i><b>maps</b> configuration parameter, does not
|
||||||
figuration parameter, does not talk to users, and can run
|
talk to users, and can run at fixed low privilege,
|
||||||
at fixed low privilege, chrooted or not.
|
chrooted or not.
|
||||||
|
|
||||||
|
The proxymap server is not a trusted daemon process, and
|
||||||
|
must not be used to look up sensitive information such as
|
||||||
|
user or group IDs, mailbox file/directory names or exter-
|
||||||
|
nal commands.
|
||||||
|
|
||||||
<b>DIAGNOSTICS</b>
|
<b>DIAGNOSTICS</b>
|
||||||
Problems and transactions are logged to <b>syslogd</b>(8).
|
Problems and transactions are logged to <b>syslogd</b>(8).
|
||||||
@@ -92,11 +107,12 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
to this program. Use the <b>postfix</b> <b>reload</b> command after a
|
to this program. Use the <b>postfix</b> <b>reload</b> command after a
|
||||||
configuration change.
|
configuration change.
|
||||||
|
|
||||||
<b>proxymap</b><i>_</i><b>filter</b>
|
<b>proxy</b><i>_</i><b>read</b><i>_</i><b>maps</b>
|
||||||
A list of zero or more parameter values that may
|
A list of zero or more parameter values that may
|
||||||
contain Postfix lookup table references. Only table
|
contain references to Postfix lookup tables. Only
|
||||||
references that begin with <b>proxy:</b> are approved for
|
table references that begin with <b>proxy:</b> are
|
||||||
access via the proxymap server.
|
approved for read-only access via the proxymap
|
||||||
|
server.
|
||||||
|
|
||||||
<b>SEE</b> <b>ALSO</b>
|
<b>SEE</b> <b>ALSO</b>
|
||||||
dict_proxy(3) proxy map client
|
dict_proxy(3) proxy map client
|
||||||
|
@@ -37,14 +37,6 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
|||||||
The envelope recipient address that is
|
The envelope recipient address that is
|
||||||
passed on to <i>nexthop</i>.
|
passed on to <i>nexthop</i>.
|
||||||
|
|
||||||
<b>trivial-rewrite</b> servers run under control by the Postfix
|
|
||||||
master server. Each server can handle multiple simultane-
|
|
||||||
ous connections. When all servers are busy while a client
|
|
||||||
connects, a new server process is created, provided that
|
|
||||||
the trivial-rewrite server process limit is not exceeded.
|
|
||||||
Each server terminates after serving <b>$max</b><i>_</i><b>use</b> clients or
|
|
||||||
after <b>$max</b><i>_</i><b>idle</b> seconds of idle time.
|
|
||||||
|
|
||||||
<b>DEFAULT</b> <b>DELIVERY</b> <b>METHODS</b>
|
<b>DEFAULT</b> <b>DELIVERY</b> <b>METHODS</b>
|
||||||
By default, Postfix uses one of the following delivery
|
By default, Postfix uses one of the following delivery
|
||||||
methods. This may be overruled with the optional <a href="transport.5.html">trans-</a>
|
methods. This may be overruled with the optional <a href="transport.5.html">trans-</a>
|
||||||
@@ -83,6 +75,16 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
|||||||
<b>$relayhost</b>. The default nexthop is the recipient
|
<b>$relayhost</b>. The default nexthop is the recipient
|
||||||
domain.
|
domain.
|
||||||
|
|
||||||
|
<b>SERVER</b> <b>PROCESS</b> <b>MANAGEMENT</b>
|
||||||
|
The trivial-rewrite servers run under control by the Post-
|
||||||
|
fix master server. Each server can handle multiple simul-
|
||||||
|
taneous connections. When all servers are busy while a
|
||||||
|
client connects, the master creates a new server process,
|
||||||
|
provided that the trivial-rewrite server process limit is
|
||||||
|
not exceeded. Each trivial-rewrite server stops accepting
|
||||||
|
new connections after serving <b>$max</b><i>_</i><b>use</b> clients or termi-
|
||||||
|
nates after <b>$max</b><i>_</i><b>idle</b> seconds of idle time.
|
||||||
|
|
||||||
<b>STANDARDS</b>
|
<b>STANDARDS</b>
|
||||||
None. The command does not interact with the outside
|
None. The command does not interact with the outside
|
||||||
world.
|
world.
|
||||||
|
@@ -18,35 +18,35 @@ of the service 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
|
||||||
reject mail for non-existent local addresses.
|
reject mail for non-existent local addresses, but it is not
|
||||||
The solution is to specify:
|
practical to maintain a copy of the passwd file in the chroot
|
||||||
|
jail. The solution:
|
||||||
.sp
|
.sp
|
||||||
local_recipient_maps =
|
local_recipient_maps =
|
||||||
.ti +4
|
.ti +4
|
||||||
proxy:unix:passwd.byname $alias_maps
|
proxy:unix:passwd.byname $alias_maps
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
To consolidate the number of open lookup tables by sharing
|
To consolidate the number of open lookup tables by sharing
|
||||||
one open table among multiple processes. For example, to avoid
|
one open table among multiple processes. For example, making
|
||||||
problems due to "too many connections" to, e.g., mysql servers,
|
mysql connections from every Postfix daemon process results
|
||||||
specify:
|
in "too many connections" errors. The solution:
|
||||||
.sp
|
.sp
|
||||||
virtual_alias_maps =
|
virtual_alias_maps =
|
||||||
.ti +4
|
.ti +4
|
||||||
proxy:mysql:/etc/postfix/virtual.cf
|
proxy:mysql:/etc/postfix/virtual.cf
|
||||||
.SH PROXYMAP SERVICES
|
.sp
|
||||||
.na
|
The total number of connections is limited by the number of
|
||||||
.nf
|
proxymap server server processes.
|
||||||
.ad
|
.PP
|
||||||
.fi
|
|
||||||
The proxymap server implements the following requests:
|
The proxymap server implements the following requests:
|
||||||
.IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
.IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
||||||
Open the table with type \fImaptype\fR and name \fImapname\fR,
|
Open the table with type \fImaptype\fR and name \fImapname\fR,
|
||||||
as controlled by \fIflags\fR.
|
as controlled by \fIflags\fR.
|
||||||
The reply is the request completion status code and the
|
The reply is the request completion status code (below) and the
|
||||||
map type dependent flags.
|
map type dependent flags.
|
||||||
.IP "\fBPROXY_REQ_LOOKUP\fI maptype:mapname flags key\fR"
|
.IP "\fBPROXY_REQ_LOOKUP\fI maptype: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 and
|
The reply is the request completion status code (below) 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 \fBPROXY_REQ_OPEN\fR request.
|
as with the \fBPROXY_REQ_OPEN\fR request.
|
||||||
@@ -56,14 +56,17 @@ because tables are meant to be shared among client processes.
|
|||||||
|
|
||||||
The request completion status code is one of:
|
The request completion status code is one of:
|
||||||
.IP \fBPROXY_STAT_OK\fR
|
.IP \fBPROXY_STAT_OK\fR
|
||||||
The requested table or lookup key was found.
|
The specified table was opened, or the requested entry was found.
|
||||||
.IP \fBPROXY_STAT_FAIL\fR
|
.IP \fBPROXY_STAT_NOKEY\fR
|
||||||
The requested table or lookup key does not exist.
|
The requested table entry was not found.
|
||||||
.IP \fBPROXY_STAT_BAD\fR
|
.IP \fBPROXY_STAT_BAD\fR
|
||||||
The request was rejected (bad request parameter value).
|
The request was rejected (bad request parameter value).
|
||||||
.IP \fBPROXY_STAT_RETRY\fR
|
.IP \fBPROXY_STAT_RETRY\fR
|
||||||
The request was not completed.
|
The lookup request could not be completed.
|
||||||
.SH MASTER INTERFACE
|
.IP \fBPROXY_STAT_DENY\fR
|
||||||
|
The specified table was not approved for access via the
|
||||||
|
proxymap service.
|
||||||
|
.SH SERVER PROCESS MANAGEMENT
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
.ad
|
.ad
|
||||||
@@ -73,17 +76,21 @@ server. Each server can handle multiple simultaneous connections.
|
|||||||
When all servers are busy while a client connects, the master
|
When all servers are busy while a client connects, the master
|
||||||
creates a new proxymap server process, provided that the proxymap
|
creates a new proxymap server process, provided that the proxymap
|
||||||
server process limit is not exceeded.
|
server process limit is not exceeded.
|
||||||
Each proxymap server terminates after serving \fB$max_use\fR clients
|
Each proxymap server stops accepting new connections after serving
|
||||||
or after \fB$max_idle\fR seconds of idle time.
|
\fB$max_use\fR clients or terminates after \fB$max_idle\fR seconds
|
||||||
|
of idle time.
|
||||||
.SH SECURITY
|
.SH SECURITY
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
The proxymap server is not security-sensitive. It opens only
|
The proxymap server opens only tables that are approved via the
|
||||||
tables that are approved via the \fBproxymap_filter\fR
|
\fBproxy_read_maps\fR configuration parameter, does not talk to
|
||||||
configuration parameter, does not talk to users, and
|
users, and can run at fixed low privilege, chrooted or not.
|
||||||
can run at fixed low privilege, chrooted or not.
|
|
||||||
|
The proxymap server is not a trusted daemon process, and must
|
||||||
|
not be used to look up sensitive information such as user or
|
||||||
|
group IDs, mailbox file/directory names or external commands.
|
||||||
.SH DIAGNOSTICS
|
.SH DIAGNOSTICS
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
@@ -102,11 +109,11 @@ lookups.
|
|||||||
The following main.cf parameters are especially relevant
|
The following main.cf parameters are especially relevant
|
||||||
to this program. Use the \fBpostfix reload\fR command
|
to this program. Use the \fBpostfix reload\fR command
|
||||||
after a configuration change.
|
after a configuration change.
|
||||||
.IP \fBproxymap_filter\fR
|
.IP \fBproxy_read_maps\fR
|
||||||
A list of zero or more parameter values that may contain
|
A list of zero or more parameter values that may contain
|
||||||
Postfix lookup table references. Only table references that
|
references to Postfix lookup tables. Only table references
|
||||||
begin with \fBproxy:\fR are approved for access via the
|
that begin with \fBproxy:\fR are approved for read-only
|
||||||
proxymap server.
|
access via the proxymap server.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@@ -32,14 +32,6 @@ The host to send to and optional delivery method information.
|
|||||||
.IP \fIrecipient\fR
|
.IP \fIrecipient\fR
|
||||||
The envelope recipient address that is passed on to \fInexthop\fR.
|
The envelope recipient address that is passed on to \fInexthop\fR.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
|
||||||
\fBtrivial-rewrite\fR servers run under control by the Postfix master
|
|
||||||
server. Each server can handle multiple simultaneous connections.
|
|
||||||
When all servers are busy while a client connects, a new server
|
|
||||||
process is created, provided that the trivial-rewrite server
|
|
||||||
process limit is not exceeded.
|
|
||||||
Each server terminates after serving \fB$max_use\fR clients
|
|
||||||
or after \fB$max_idle\fR seconds of idle time.
|
|
||||||
.SH DEFAULT DELIVERY METHODS
|
.SH DEFAULT DELIVERY METHODS
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
@@ -73,6 +65,19 @@ The transport and optional nexthop are specified with
|
|||||||
This overrides the optional nexthop information that is specified
|
This overrides the optional nexthop information that is specified
|
||||||
with \fB$relayhost\fR.
|
with \fB$relayhost\fR.
|
||||||
The default nexthop is the recipient domain.
|
The default nexthop is the recipient domain.
|
||||||
|
.SH SERVER PROCESS MANAGEMENT
|
||||||
|
.na
|
||||||
|
.nf
|
||||||
|
.ad
|
||||||
|
.fi
|
||||||
|
The trivial-rewrite servers run under control by the Postfix master
|
||||||
|
server. Each server can handle multiple simultaneous connections.
|
||||||
|
When all servers are busy while a client connects, the master
|
||||||
|
creates a new server process, provided that the trivial-rewrite
|
||||||
|
server process limit is not exceeded.
|
||||||
|
Each trivial-rewrite server stops accepting new connections after
|
||||||
|
serving \fB$max_use\fR clients or terminates after \fB$max_idle\fR
|
||||||
|
seconds of idle time.
|
||||||
.SH STANDARDS
|
.SH STANDARDS
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@@ -44,7 +44,7 @@ exec sed '
|
|||||||
s/[<bB>]*canonical[</bB>]*(5)/<a href="canonical.5.html">&<\/a>/
|
s/[<bB>]*canonical[</bB>]*(5)/<a href="canonical.5.html">&<\/a>/
|
||||||
s/[<bB>]*etrn[</bB>]*(5)/<a href="etrn.5.html">&<\/a>/
|
s/[<bB>]*etrn[</bB>]*(5)/<a href="etrn.5.html">&<\/a>/
|
||||||
s/[<bB>]*pcre[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="pcre_table.5.html">&<\/a>/
|
s/[<bB>]*pcre[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="pcre_table.5.html">&<\/a>/
|
||||||
s/[<bB>]*proxymap[</bB>]*(8)/<a href="verify.8.html">&<\/a>/
|
s/[<bB>]*proxymap[</bB>]*(8)/<a href="proxymap.8.html">&<\/a>/
|
||||||
s/[<bB>]*reg[-</bB>]*\n*[ <bB>]*exp[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="regexp_table.5.html">&<\/a>/
|
s/[<bB>]*reg[-</bB>]*\n*[ <bB>]*exp[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="regexp_table.5.html">&<\/a>/
|
||||||
s/[<bB>]*relocated[</bB>]*(5)/<a href="relocated.5.html">&<\/a>/
|
s/[<bB>]*relocated[</bB>]*(5)/<a href="relocated.5.html">&<\/a>/
|
||||||
s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
|
s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
/* .IP timeout
|
/* .IP timeout
|
||||||
/* Idle time after which the client disconnects.
|
/* Idle time after which the client disconnects.
|
||||||
/* .IP ttl
|
/* .IP ttl
|
||||||
/* Time to live after which the client disconnects.
|
/* Upper bound on the time that a connection is allowed to persist.
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Warnings: communication failure. Fatal error: mail system is down,
|
/* Warnings: communication failure. Fatal error: mail system is down,
|
||||||
/* out of memory.
|
/* out of memory.
|
||||||
@@ -121,10 +121,16 @@ static void clnt_stream_ttl_event(int event, char *context)
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX This function is needed only because the event_request_timer()
|
* XXX This function is needed only because event_request_timer() cannot
|
||||||
* function cannot distinguish requests with the same callback routine.
|
* distinguish between requests that specify the same call-back routine
|
||||||
* The fix is obvious: specify a request ID along with the callback
|
* and call-back context. The fix is obvious: specify a request ID along
|
||||||
* routine, but there is too much code that would have to be changed.
|
* with the call-back routine, but there is too much code that would have
|
||||||
|
* to be changed.
|
||||||
|
*
|
||||||
|
* XXX Should we be concerned that an overly agressive optimizer will
|
||||||
|
* eliminate this function and replace calls to clnt_stream_ttl_event()
|
||||||
|
* by direct calls to clnt_stream_event()? It should not, because there
|
||||||
|
* exists code that takes the address of both functions.
|
||||||
*/
|
*/
|
||||||
clnt_stream_event(event, context);
|
clnt_stream_event(event, context);
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,8 @@
|
|||||||
/* The \fIopen_flags\fR argument must specify O_RDONLY.
|
/* The \fIopen_flags\fR argument must specify O_RDONLY.
|
||||||
/*
|
/*
|
||||||
/* 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.
|
/* closed after $ipc_idle seconds of idle time, or after $ipc_ttl
|
||||||
|
/* seconds of activity.
|
||||||
/* SECURITY
|
/* SECURITY
|
||||||
/* The proxy map server is not meant to be a trusted process. Proxy
|
/* The proxy map server is not meant to be a trusted process. Proxy
|
||||||
/* maps must not be used to look up security sensitive information
|
/* maps must not be used to look up security sensitive information
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
/* clnt_stream(3) client endpoint connection management
|
/* clnt_stream(3) client endpoint connection management
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Fatal errors: out of memory, unimplemented operation,
|
/* Fatal errors: out of memory, unimplemented operation,
|
||||||
/* bad request parameter.
|
/* bad request parameter, map not approved for proxy access.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@@ -78,8 +79,7 @@ typedef struct {
|
|||||||
#define VSTREQ(v,s) (strcmp(STR(v),s) == 0)
|
#define VSTREQ(v,s) (strcmp(STR(v),s) == 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All proxied maps within the same process share the same query/reply
|
* All proxied maps within a process share the same query/reply socket.
|
||||||
* socket.
|
|
||||||
*/
|
*/
|
||||||
static CLNT_STREAM *proxy_stream;
|
static CLNT_STREAM *proxy_stream;
|
||||||
|
|
||||||
@@ -115,25 +115,31 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
|
|||||||
ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result,
|
ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result,
|
||||||
ATTR_TYPE_END) != 2) {
|
ATTR_TYPE_END) != 2) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("%s: service %s: %m", VSTREAM_PATH(stream), myname);
|
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: table=%s flags=0%o key=%s -> status=%d result=%s",
|
msg_info("%s: table=%s flags=0%o key=%s -> status=%d result=%s",
|
||||||
myname, dict->name, dict_proxy->in_flags, key,
|
myname, dict->name, dict_proxy->in_flags, key,
|
||||||
status, STR(dict_proxy->result));
|
status, STR(dict_proxy->result));
|
||||||
if (status == PROXY_STAT_OK) {
|
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 service is not configured for table \"%s\"",
|
||||||
|
MAIL_SERVICE_PROXYMAP, dict->name);
|
||||||
|
case PROXY_STAT_OK:
|
||||||
return (STR(dict_proxy->result));
|
return (STR(dict_proxy->result));
|
||||||
} else if (status == PROXY_STAT_FAIL) {
|
case PROXY_STAT_NOKEY:
|
||||||
return (0);
|
return (0);
|
||||||
} else if (status == PROXY_STAT_RETRY) {
|
case PROXY_STAT_RETRY:
|
||||||
dict_errno = DICT_ERR_RETRY;
|
dict_errno = DICT_ERR_RETRY;
|
||||||
return (0);
|
return (0);
|
||||||
} else if (status == PROXY_STAT_BAD) {
|
default:
|
||||||
msg_fatal("%s: %s lookup %s failed: bad request",
|
msg_warn("%s lookup failed for table \"%s\" key \"%s\": "
|
||||||
myname, dict->name, key);
|
"unexpected reply status %d",
|
||||||
} else {
|
MAIL_SERVICE_PROXYMAP, dict->name, key, status);
|
||||||
msg_warn("%s: %s lookup %s failed with unknown status %d",
|
|
||||||
myname, dict->name, key, status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clnt_stream_recover(proxy_stream);
|
clnt_stream_recover(proxy_stream);
|
||||||
@@ -166,10 +172,10 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
/*
|
/*
|
||||||
* Sanity checks.
|
* Sanity checks.
|
||||||
*/
|
*/
|
||||||
|
if (dict_flags & DICT_FLAG_NO_PROXY)
|
||||||
|
msg_fatal("%s: proxy map must not be used with this map type", map);
|
||||||
if (open_flags != O_RDONLY)
|
if (open_flags != O_RDONLY)
|
||||||
msg_fatal("%s: proxy map open requires O_RDONLY access mode", map);
|
msg_fatal("%s: proxy map open requires O_RDONLY access mode", map);
|
||||||
if (dict_flags & DICT_FLAG_NO_PROXY)
|
|
||||||
msg_fatal("%s: proxy map is not allowed for this map type", map);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local initialization.
|
* Local initialization.
|
||||||
@@ -201,7 +207,9 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Establish initial contact and finalize the flags.
|
* Establish initial contact and get the map type specific flags.
|
||||||
|
*
|
||||||
|
* XXX Should retrieve flags from local instance.
|
||||||
*/
|
*/
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(proxy_stream);
|
stream = clnt_stream_access(proxy_stream);
|
||||||
@@ -217,21 +225,26 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
ATTR_TYPE_END) != 2) {
|
ATTR_TYPE_END) != 2) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("%s: service %s: %m", VSTREAM_PATH(stream), myname);
|
msg_warn("%s: service %s: %m", VSTREAM_PATH(stream), myname);
|
||||||
} else if (status == PROXY_STAT_OK) {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: connect to map=%s status=%d server_flags=0%o",
|
msg_info("%s: connect to map=%s status=%d server_flags=0%o",
|
||||||
myname, dict_proxy->dict.name, status, server_flags);
|
myname, dict_proxy->dict.name, status, server_flags);
|
||||||
|
switch (status) {
|
||||||
|
case PROXY_STAT_BAD:
|
||||||
|
msg_fatal("%s open failed for table \"%s\": invalid request",
|
||||||
|
MAIL_SERVICE_PROXYMAP, 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);
|
||||||
|
case PROXY_STAT_OK:
|
||||||
dict_proxy->dict.flags = dict_proxy->in_flags | server_flags;
|
dict_proxy->dict.flags = dict_proxy->in_flags | server_flags;
|
||||||
break;
|
return (DICT_DEBUG (&dict_proxy->dict));
|
||||||
} else if (status == PROXY_STAT_BAD) {
|
default:
|
||||||
msg_fatal("%s: %s connection request failed: bad request",
|
msg_warn("%s open failed for table \"%s\": unexpected status %d",
|
||||||
myname, dict_proxy->dict.name);
|
MAIL_SERVICE_PROXYMAP, dict_proxy->dict.name, status);
|
||||||
} else {
|
}
|
||||||
msg_warn("%s: %s connection request failed with status %d",
|
|
||||||
myname, dict_proxy->dict.name, status);
|
|
||||||
}
|
}
|
||||||
clnt_stream_recover(proxy_stream);
|
clnt_stream_recover(proxy_stream);
|
||||||
sleep(1); /* XXX make configurable */
|
sleep(1); /* XXX make configurable */
|
||||||
}
|
}
|
||||||
return (DICT_DEBUG (&dict_proxy->dict));
|
|
||||||
}
|
}
|
||||||
|
@@ -29,10 +29,11 @@ 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_STAT_OK 0
|
#define PROXY_STAT_OK 0 /* operation succeeded */
|
||||||
#define PROXY_STAT_FAIL 1
|
#define PROXY_STAT_NOKEY 1 /* requested key not found */
|
||||||
#define PROXY_STAT_BAD 2
|
#define PROXY_STAT_RETRY 2 /* try lookup again later */
|
||||||
#define PROXY_STAT_RETRY 3
|
#define PROXY_STAT_BAD 3 /* invalid request parameter */
|
||||||
|
#define PROXY_STAT_DENY 4 /* table not approved for proxying */
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@@ -1332,8 +1332,8 @@ extern int var_local_rcpt_code;
|
|||||||
/*
|
/*
|
||||||
* List of pre-approved maps that are OK to open with the proxymap service.
|
* List of pre-approved maps that are OK to open with the proxymap service.
|
||||||
*/
|
*/
|
||||||
#define VAR_PROXYMAP_FILTER "proxymap_filter"
|
#define VAR_PROXY_READ_MAPS "proxy_read_maps"
|
||||||
#define DEF_PROXYMAP_FILTER "$" VAR_LOCAL_RCPT_MAPS \
|
#define DEF_PROXY_READ_MAPS "$" VAR_LOCAL_RCPT_MAPS \
|
||||||
" $" VAR_MYDEST \
|
" $" VAR_MYDEST \
|
||||||
" $" VAR_VIRT_ALIAS_MAPS \
|
" $" VAR_VIRT_ALIAS_MAPS \
|
||||||
" $" VAR_VIRT_ALIAS_DOMS \
|
" $" VAR_VIRT_ALIAS_DOMS \
|
||||||
@@ -1346,7 +1346,7 @@ extern int var_local_rcpt_code;
|
|||||||
" $" VAR_RCPT_CANON_MAPS \
|
" $" VAR_RCPT_CANON_MAPS \
|
||||||
" $" VAR_RELOCATED_MAPS \
|
" $" VAR_RELOCATED_MAPS \
|
||||||
" $" VAR_TRANSPORT_MAPS
|
" $" VAR_TRANSPORT_MAPS
|
||||||
extern char *var_proxymap_filter;
|
extern char *var_proxy_read_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other.
|
* Other.
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change the patchlevel and the release date. Snapshots change the
|
* Patches change the patchlevel and the release date. Snapshots change the
|
||||||
* release date only, unless they include the same bugfix as a patch release.
|
* release date only, unless they include the same bugfix as a patch release.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20030103"
|
#define MAIL_RELEASE_DATE "20030104"
|
||||||
|
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "2.0.0-" MAIL_RELEASE_DATE
|
#define DEF_MAIL_VERSION "2.0.0-" MAIL_RELEASE_DATE
|
||||||
|
@@ -184,22 +184,20 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||||
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, RESOLVE_ADDR,
|
ATTR_TYPE_STR, MAIL_ATTR_REQ, RESOLVE_ADDR,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||||
ATTR_TYPE_END)
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)) {
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
|
||||||
msg_warn("%s: bad write: %m", myname);
|
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_TRANSPORT, reply->transport,
|
ATTR_TYPE_STR, MAIL_ATTR_TRANSPORT, reply->transport,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
|
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
|
||||||
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
|
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &reply->flags,
|
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &reply->flags,
|
||||||
ATTR_TYPE_END) != 4) {
|
ATTR_TYPE_END) != 4) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("%s: bad read: %m", myname);
|
msg_warn("problem talking to service %s: %m",
|
||||||
|
var_rewrite_service);
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: `%s' -> t=`%s' h=`%s' r=`%s'",
|
msg_info("%s: `%s' -> t=`%s' h=`%s' r=`%s'",
|
||||||
@@ -212,7 +210,7 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(10); /* XXX make configurable */
|
sleep(1); /* XXX make configurable */
|
||||||
clnt_stream_recover(rewrite_clnt_stream);
|
clnt_stream_recover(rewrite_clnt_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -125,26 +125,25 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||||
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
|
ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
|
ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||||
ATTR_TYPE_END),
|
ATTR_TYPE_END) != 0
|
||||||
vstream_fflush(stream)) {
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
|
||||||
msg_warn("%s: bad write: %m", myname);
|
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
|
ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 1) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("%s: bad read: %m", myname);
|
msg_warn("problem talking to service %s: %m",
|
||||||
|
var_rewrite_service);
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("rewrite_clnt: %s: %s -> %s",
|
msg_info("rewrite_clnt: %s: %s -> %s",
|
||||||
rule, addr, vstring_str(result));
|
rule, addr, vstring_str(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(10); /* XXX make configurable */
|
sleep(1); /* XXX make configurable */
|
||||||
clnt_stream_recover(rewrite_clnt_stream);
|
clnt_stream_recover(rewrite_clnt_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -117,24 +117,19 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
|
|||||||
*/
|
*/
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(vrfy_clnt);
|
stream = clnt_stream_access(vrfy_clnt);
|
||||||
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
|
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||||
ATTR_TYPE_END) != 0
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)) {
|
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
|
||||||
msg_warn("service %s: bad write: %m", var_verify_service);
|
|
||||||
sleep(10); /* XXX make configurable */
|
|
||||||
}
|
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_MISSING,
|
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
|
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
|
||||||
ATTR_TYPE_END) != 3) {
|
ATTR_TYPE_END) != 3) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("service %s: bad read: %m", var_verify_service);
|
msg_warn("problem talking to service %s: %m",
|
||||||
sleep(10); /* XXX make configurable */
|
var_verify_service);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -181,25 +176,19 @@ int verify_clnt_vupdate(const char *addr, int addr_status,
|
|||||||
vstring_vsprintf(text, format, ap);
|
vstring_vsprintf(text, format, ap);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(vrfy_clnt);
|
stream = clnt_stream_access(vrfy_clnt);
|
||||||
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_UPDATE,
|
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_UPDATE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(text),
|
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(text),
|
||||||
ATTR_TYPE_END) != 0
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)) {
|
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
|
||||||
msg_warn("service %s: bad write: %m", var_verify_service);
|
|
||||||
msg_warn("service %s: bad write: %m", var_verify_service);
|
|
||||||
sleep(10); /* XXX make configurable */
|
|
||||||
}
|
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_MISSING,
|
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 1) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||||
msg_warn("service %s: bad read: %m", var_verify_service);
|
msg_warn("problem talking to service %s: %m",
|
||||||
sleep(10); /* XXX make configurable */
|
var_verify_service);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -28,11 +28,7 @@
|
|||||||
/* named dictionaries.
|
/* named dictionaries.
|
||||||
/* The result is a handle that must be specified along with all
|
/* The result is a handle that must be specified along with all
|
||||||
/* other virtual8_maps_xxx() operations.
|
/* other virtual8_maps_xxx() operations.
|
||||||
/* See dict_open(3) for a description of flags. virtual8_maps_create()
|
/* See dict_open(3) for a description of flags.
|
||||||
/* implicitly sets the DICT_FLAG_NO_REGSUB flag in order to disable
|
|
||||||
/* regular expression substitution into the lookup result, and
|
|
||||||
/* implicitly sets the DICT_FLAG_NO_PROXY flag in order to disable
|
|
||||||
/* lookup of sensitive information via an untrusted process.
|
|
||||||
/*
|
/*
|
||||||
/* virtual8_maps_find() searches the specified list of dictionaries
|
/* virtual8_maps_find() searches the specified list of dictionaries
|
||||||
/* in the specified order for the named key. The result is in
|
/* in the specified order for the named key. The result is in
|
||||||
|
@@ -20,8 +20,7 @@
|
|||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
#define virtual8_maps_create(title, map_names, flags) \
|
#define virtual8_maps_create(title, map_names, flags) \
|
||||||
maps_create((title), (map_names), \
|
maps_create((title), (map_names), (flags))
|
||||||
(flags) | DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY)
|
|
||||||
extern const char *virtual8_maps_find(MAPS *, const char *);
|
extern const char *virtual8_maps_find(MAPS *, const char *);
|
||||||
#define virtual8_maps_free(maps) maps_free((maps))
|
#define virtual8_maps_free(maps) maps_free((maps))
|
||||||
|
|
||||||
|
@@ -696,10 +696,8 @@ static void pre_init(char *unused_name, char **unused_argv)
|
|||||||
VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
|
VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
|
||||||
set_file_limit(var_mailbox_limit);
|
set_file_limit(var_mailbox_limit);
|
||||||
}
|
}
|
||||||
#define INSECURE_DICT_FLAGS (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY)
|
|
||||||
|
|
||||||
alias_maps = maps_create("aliases", var_alias_maps,
|
alias_maps = maps_create("aliases", var_alias_maps,
|
||||||
DICT_FLAG_LOCK | INSECURE_DICT_FLAGS);
|
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* main - pass control to the single-threaded skeleton */
|
/* main - pass control to the single-threaded skeleton */
|
||||||
|
@@ -12,33 +12,35 @@
|
|||||||
/* .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
|
||||||
/* reject mail for non-existent local addresses.
|
/* reject mail for non-existent local addresses, but it is not
|
||||||
/* The solution is to specify:
|
/* practical to maintain a copy of the passwd file in the chroot
|
||||||
|
/* jail. The solution:
|
||||||
/* .sp
|
/* .sp
|
||||||
/* local_recipient_maps =
|
/* local_recipient_maps =
|
||||||
/* .ti +4
|
/* .ti +4
|
||||||
/* proxy:unix:passwd.byname $alias_maps
|
/* proxy:unix:passwd.byname $alias_maps
|
||||||
/* .IP \(bu
|
/* .IP \(bu
|
||||||
/* To consolidate the number of open lookup tables by sharing
|
/* To consolidate the number of open lookup tables by sharing
|
||||||
/* one open table among multiple processes. For example, to avoid
|
/* one open table among multiple processes. For example, making
|
||||||
/* problems due to "too many connections" to, e.g., mysql servers,
|
/* mysql connections from every Postfix daemon process results
|
||||||
/* specify:
|
/* in "too many connections" errors. The solution:
|
||||||
/* .sp
|
/* .sp
|
||||||
/* virtual_alias_maps =
|
/* virtual_alias_maps =
|
||||||
/* .ti +4
|
/* .ti +4
|
||||||
/* proxy:mysql:/etc/postfix/virtual.cf
|
/* proxy:mysql:/etc/postfix/virtual.cf
|
||||||
/* PROXYMAP SERVICES
|
/* .sp
|
||||||
/* .ad
|
/* The total number of connections is limited by the number of
|
||||||
/* .fi
|
/* proxymap server server processes.
|
||||||
|
/* .PP
|
||||||
/* The proxymap server implements the following requests:
|
/* The proxymap server implements the following requests:
|
||||||
/* .IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
/* .IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
||||||
/* Open the table with type \fImaptype\fR and name \fImapname\fR,
|
/* Open the table with type \fImaptype\fR and name \fImapname\fR,
|
||||||
/* as controlled by \fIflags\fR.
|
/* as controlled by \fIflags\fR.
|
||||||
/* The reply is the request completion status code and the
|
/* The reply is the request completion status code (below) and the
|
||||||
/* map type dependent flags.
|
/* map type dependent flags.
|
||||||
/* .IP "\fBPROXY_REQ_LOOKUP\fI maptype:mapname flags key\fR"
|
/* .IP "\fBPROXY_REQ_LOOKUP\fI maptype: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 and
|
/* The reply is the request completion status code (below) 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 \fBPROXY_REQ_OPEN\fR request.
|
/* as with the \fBPROXY_REQ_OPEN\fR request.
|
||||||
@@ -48,14 +50,17 @@
|
|||||||
/*
|
/*
|
||||||
/* The request completion status code is one of:
|
/* The request completion status code is one of:
|
||||||
/* .IP \fBPROXY_STAT_OK\fR
|
/* .IP \fBPROXY_STAT_OK\fR
|
||||||
/* The requested table or lookup key was found.
|
/* The specified table was opened, or the requested entry was found.
|
||||||
/* .IP \fBPROXY_STAT_FAIL\fR
|
/* .IP \fBPROXY_STAT_NOKEY\fR
|
||||||
/* The requested table or lookup key does not exist.
|
/* The requested table entry was not found.
|
||||||
/* .IP \fBPROXY_STAT_BAD\fR
|
/* .IP \fBPROXY_STAT_BAD\fR
|
||||||
/* The request was rejected (bad request parameter value).
|
/* The request was rejected (bad request parameter value).
|
||||||
/* .IP \fBPROXY_STAT_RETRY\fR
|
/* .IP \fBPROXY_STAT_RETRY\fR
|
||||||
/* The request was not completed.
|
/* The lookup request could not be completed.
|
||||||
/* MASTER INTERFACE
|
/* .IP \fBPROXY_STAT_DENY\fR
|
||||||
|
/* The specified table was not approved for access via the
|
||||||
|
/* proxymap service.
|
||||||
|
/* SERVER PROCESS MANAGEMENT
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
/* The proxymap servers run under control by the Postfix master
|
/* The proxymap servers run under control by the Postfix master
|
||||||
@@ -63,15 +68,19 @@
|
|||||||
/* When all servers are busy while a client connects, the master
|
/* When all servers are busy while a client connects, the master
|
||||||
/* creates a new proxymap server process, provided that the proxymap
|
/* creates a new proxymap server process, provided that the proxymap
|
||||||
/* server process limit is not exceeded.
|
/* server process limit is not exceeded.
|
||||||
/* Each proxymap server terminates after serving \fB$max_use\fR clients
|
/* Each proxymap server stops accepting new connections after serving
|
||||||
/* or after \fB$max_idle\fR seconds of idle time.
|
/* \fB$max_use\fR clients or terminates after \fB$max_idle\fR seconds
|
||||||
|
/* of idle time.
|
||||||
/* SECURITY
|
/* SECURITY
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
/* The proxymap server is not security-sensitive. It opens only
|
/* The proxymap server opens only tables that are approved via the
|
||||||
/* tables that are approved via the \fBproxymap_filter\fR
|
/* \fBproxy_read_maps\fR configuration parameter, does not talk to
|
||||||
/* configuration parameter, does not talk to users, and
|
/* users, and can run at fixed low privilege, chrooted or not.
|
||||||
/* can run at fixed low privilege, chrooted or not.
|
/*
|
||||||
|
/* The proxymap server is not a trusted daemon process, and must
|
||||||
|
/* not be used to look up sensitive information such as user or
|
||||||
|
/* group IDs, mailbox file/directory names or external commands.
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Problems and transactions are logged to \fBsyslogd\fR(8).
|
/* Problems and transactions are logged to \fBsyslogd\fR(8).
|
||||||
/* BUGS
|
/* BUGS
|
||||||
@@ -84,11 +93,11 @@
|
|||||||
/* The following main.cf parameters are especially relevant
|
/* The following main.cf parameters are especially relevant
|
||||||
/* to this program. Use the \fBpostfix reload\fR command
|
/* to this program. Use the \fBpostfix reload\fR command
|
||||||
/* after a configuration change.
|
/* after a configuration change.
|
||||||
/* .IP \fBproxymap_filter\fR
|
/* .IP \fBproxy_read_maps\fR
|
||||||
/* A list of zero or more parameter values that may contain
|
/* A list of zero or more parameter values that may contain
|
||||||
/* Postfix lookup table references. Only table references that
|
/* references to Postfix lookup tables. Only table references
|
||||||
/* begin with \fBproxy:\fR are approved for access via the
|
/* that begin with \fBproxy:\fR are approved for read-only
|
||||||
/* proxymap server.
|
/* access via the proxymap server.
|
||||||
/* SEE ALSO
|
/* SEE ALSO
|
||||||
/* dict_proxy(3) proxy map client
|
/* dict_proxy(3) proxy map client
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
@@ -148,20 +157,20 @@ char *var_send_canon_maps;
|
|||||||
char *var_rcpt_canon_maps;
|
char *var_rcpt_canon_maps;
|
||||||
char *var_relocatedmaps;
|
char *var_relocatedmaps;
|
||||||
char *var_transport_maps;
|
char *var_transport_maps;
|
||||||
char *var_proxymap_filter;
|
char *var_proxy_read_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The pre-approved, pre-parsed list of maps.
|
* The pre-approved, pre-parsed list of maps.
|
||||||
*/
|
*/
|
||||||
static HTABLE *proxymap_filter;
|
static HTABLE *proxy_read_maps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shared and static to reduce memory allocation overhead.
|
* Shared and static to reduce memory allocation overhead.
|
||||||
*/
|
*/
|
||||||
static VSTRING *request;
|
static VSTRING *request;
|
||||||
|
static VSTRING *request_map;
|
||||||
|
static VSTRING *request_key;
|
||||||
static VSTRING *map_type_name_flags;
|
static VSTRING *map_type_name_flags;
|
||||||
static VSTRING *map_type_name;
|
|
||||||
static VSTRING *key;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Silly little macros.
|
* Silly little macros.
|
||||||
@@ -171,13 +180,13 @@ static VSTRING *key;
|
|||||||
|
|
||||||
/* proxy_map_find - look up or open table */
|
/* proxy_map_find - look up or open table */
|
||||||
|
|
||||||
static DICT *proxy_map_find(const char *map_type_name, int dict_flags)
|
static DICT *proxy_map_find(const char *map_type_name, int request_flags)
|
||||||
{
|
{
|
||||||
DICT *dict;
|
DICT *dict;
|
||||||
|
|
||||||
#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 OPEN_FLAGS O_RDONLY
|
#define READ_OPEN_FLAGS O_RDONLY
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,
|
||||||
@@ -185,8 +194,10 @@ static DICT *proxy_map_find(const char *map_type_name, int dict_flags)
|
|||||||
*/
|
*/
|
||||||
while (strncmp(map_type_name, PROXY_COLON, PROXY_COLON_LEN) == 0)
|
while (strncmp(map_type_name, PROXY_COLON, PROXY_COLON_LEN) == 0)
|
||||||
map_type_name += PROXY_COLON_LEN;
|
map_type_name += PROXY_COLON_LEN;
|
||||||
if (htable_locate(proxymap_filter, map_type_name) == 0) {
|
if (htable_locate(proxy_read_maps, map_type_name) == 0) {
|
||||||
msg_warn("request for unapproved map: %s", map_type_name);
|
msg_warn("request for unapproved table: \"%s\"", map_type_name);
|
||||||
|
msg_warn("to approve a table for %s access, specify it in %s with %s",
|
||||||
|
MAIL_SERVICE_PROXYMAP, MAIN_CONF_FILE, VAR_PROXY_READ_MAPS);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +205,9 @@ static DICT *proxy_map_find(const char *map_type_name, int dict_flags)
|
|||||||
* Open one instance of a map for each combination of name+flags.
|
* Open one instance of a map for each combination of name+flags.
|
||||||
*/
|
*/
|
||||||
vstring_sprintf(map_type_name_flags, "%s:%o",
|
vstring_sprintf(map_type_name_flags, "%s:%o",
|
||||||
map_type_name, dict_flags);
|
map_type_name, request_flags);
|
||||||
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, OPEN_FLAGS, dict_flags);
|
dict = dict_open(map_type_name, 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");
|
||||||
dict_register(STR(map_type_name_flags), dict);
|
dict_register(STR(map_type_name_flags), dict);
|
||||||
@@ -207,35 +218,40 @@ static DICT *proxy_map_find(const char *map_type_name, int dict_flags)
|
|||||||
|
|
||||||
static void proxymap_lookup_service(VSTREAM *client_stream)
|
static void proxymap_lookup_service(VSTREAM *client_stream)
|
||||||
{
|
{
|
||||||
int status = PROXY_STAT_BAD;
|
int request_flags;
|
||||||
DICT *dict;
|
DICT *dict;
|
||||||
const char *value = "";
|
const char *reply_value;
|
||||||
int dict_flags;
|
int reply_status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the request.
|
||||||
|
*/
|
||||||
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, map_type_name,
|
ATTR_TYPE_STR, MAIL_ATTR_TABLE, request_map,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &dict_flags,
|
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request_flags,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_KEY, key,
|
ATTR_TYPE_STR, MAIL_ATTR_KEY, request_key,
|
||||||
ATTR_TYPE_END) == 3
|
ATTR_TYPE_END) != 3) {
|
||||||
&& (dict = proxy_map_find(STR(map_type_name), dict_flags)) != 0) {
|
reply_status = PROXY_STAT_BAD;
|
||||||
|
reply_value = "";
|
||||||
if ((value = dict_get(dict, STR(key))) != 0) {
|
} else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
|
||||||
status = PROXY_STAT_OK;
|
reply_status = PROXY_STAT_DENY;
|
||||||
|
reply_value = "";
|
||||||
|
} else if ((reply_value = dict_get(dict, STR(request_key))) != 0) {
|
||||||
|
reply_status = PROXY_STAT_OK;
|
||||||
} else if (dict_errno == 0) {
|
} else if (dict_errno == 0) {
|
||||||
status = PROXY_STAT_FAIL;
|
reply_status = PROXY_STAT_NOKEY;
|
||||||
value = "";
|
reply_value = "";
|
||||||
} else {
|
} else {
|
||||||
status = PROXY_STAT_RETRY;
|
reply_status = PROXY_STAT_RETRY;
|
||||||
value = "";
|
reply_value = "";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Respond to the client.
|
* Respond to the client.
|
||||||
*/
|
*/
|
||||||
attr_print(client_stream, ATTR_FLAG_NONE,
|
attr_print(client_stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, status,
|
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, reply_status,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_VALUE, value,
|
ATTR_TYPE_STR, MAIL_ATTR_VALUE, reply_value,
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,27 +259,34 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
|
|||||||
|
|
||||||
static void proxymap_open_service(VSTREAM *client_stream)
|
static void proxymap_open_service(VSTREAM *client_stream)
|
||||||
{
|
{
|
||||||
int dict_flags;
|
int request_flags;
|
||||||
DICT *dict;
|
DICT *dict;
|
||||||
int status = PROXY_STAT_BAD;
|
int reply_status;
|
||||||
int flags = 0;
|
int reply_flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the request.
|
||||||
|
*/
|
||||||
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, map_type_name,
|
ATTR_TYPE_STR, MAIL_ATTR_TABLE, request_map,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &dict_flags,
|
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request_flags,
|
||||||
ATTR_TYPE_END) == 2
|
ATTR_TYPE_END) != 2) {
|
||||||
&& (dict = proxy_map_find(STR(map_type_name), dict_flags)) != 0) {
|
reply_status = PROXY_STAT_BAD;
|
||||||
|
reply_flags = 0;
|
||||||
status = PROXY_STAT_OK;
|
} else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
|
||||||
flags = dict->flags;
|
reply_status = PROXY_STAT_DENY;
|
||||||
|
reply_flags = 0;
|
||||||
|
} else {
|
||||||
|
reply_status = PROXY_STAT_OK;
|
||||||
|
reply_flags = dict->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Respond to the client.
|
* Respond to the client.
|
||||||
*/
|
*/
|
||||||
attr_print(client_stream, ATTR_FLAG_NONE,
|
attr_print(client_stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, status,
|
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, reply_status,
|
||||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
|
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, reply_flags,
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,28 +334,41 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
|||||||
char *bp;
|
char *bp;
|
||||||
char *type_name;
|
char *type_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pre-allocate buffers.
|
||||||
|
*/
|
||||||
request = vstring_alloc(10);
|
request = vstring_alloc(10);
|
||||||
map_type_name = vstring_alloc(10);
|
request_map = vstring_alloc(10);
|
||||||
|
request_key = vstring_alloc(10);
|
||||||
map_type_name_flags = vstring_alloc(10);
|
map_type_name_flags = vstring_alloc(10);
|
||||||
key = vstring_alloc(10);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the pre-approved list of proxied tables.
|
* Prepare the pre-approved list of proxied tables.
|
||||||
*/
|
*/
|
||||||
saved_filter = bp = mystrdup(var_proxymap_filter);
|
saved_filter = bp = mystrdup(var_proxy_read_maps);
|
||||||
proxymap_filter = htable_create(13);
|
proxy_read_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;
|
||||||
do {
|
do {
|
||||||
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 (htable_find(proxymap_filter, type_name) == 0)
|
if (htable_locate(proxy_read_maps, type_name) == 0)
|
||||||
(void) htable_enter(proxymap_filter, type_name, (char *) 0);
|
(void) htable_enter(proxy_read_maps, type_name, (char *) 0);
|
||||||
}
|
}
|
||||||
myfree(saved_filter);
|
myfree(saved_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pre_accept - see if tables have changed */
|
||||||
|
|
||||||
|
static void pre_accept(char *unused_name, char **unused_argv)
|
||||||
|
{
|
||||||
|
if (dict_changed()) {
|
||||||
|
msg_info("some lookup table has changed -- restarting");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* main - pass control to the multi-threaded skeleton */
|
/* main - pass control to the multi-threaded skeleton */
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -350,12 +386,13 @@ int main(int argc, char **argv)
|
|||||||
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
|
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
|
||||||
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocatedmaps, 0, 0,
|
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocatedmaps, 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_PROXYMAP_FILTER, DEF_PROXYMAP_FILTER, &var_proxymap_filter, 0, 0,
|
VAR_PROXY_READ_MAPS, DEF_PROXY_READ_MAPS, &var_proxy_read_maps, 0, 0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
multi_server_main(argc, argv, proxymap_service,
|
multi_server_main(argc, argv, proxymap_service,
|
||||||
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,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
@@ -26,14 +26,6 @@
|
|||||||
/* .IP \fIrecipient\fR
|
/* .IP \fIrecipient\fR
|
||||||
/* The envelope recipient address that is passed on to \fInexthop\fR.
|
/* The envelope recipient address that is passed on to \fInexthop\fR.
|
||||||
/* .RE
|
/* .RE
|
||||||
/* .PP
|
|
||||||
/* \fBtrivial-rewrite\fR servers run under control by the Postfix master
|
|
||||||
/* server. Each server can handle multiple simultaneous connections.
|
|
||||||
/* When all servers are busy while a client connects, a new server
|
|
||||||
/* process is created, provided that the trivial-rewrite server
|
|
||||||
/* process limit is not exceeded.
|
|
||||||
/* Each server terminates after serving \fB$max_use\fR clients
|
|
||||||
/* or after \fB$max_idle\fR seconds of idle time.
|
|
||||||
/* DEFAULT DELIVERY METHODS
|
/* DEFAULT DELIVERY METHODS
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@@ -65,6 +57,17 @@
|
|||||||
/* This overrides the optional nexthop information that is specified
|
/* This overrides the optional nexthop information that is specified
|
||||||
/* with \fB$relayhost\fR.
|
/* with \fB$relayhost\fR.
|
||||||
/* The default nexthop is the recipient domain.
|
/* The default nexthop is the recipient domain.
|
||||||
|
/* SERVER PROCESS MANAGEMENT
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The trivial-rewrite servers run under control by the Postfix master
|
||||||
|
/* server. Each server can handle multiple simultaneous connections.
|
||||||
|
/* When all servers are busy while a client connects, the master
|
||||||
|
/* creates a new server process, provided that the trivial-rewrite
|
||||||
|
/* server process limit is not exceeded.
|
||||||
|
/* Each trivial-rewrite server stops accepting new connections after
|
||||||
|
/* serving \fB$max_use\fR clients or terminates after \fB$max_idle\fR
|
||||||
|
/* seconds of idle time.
|
||||||
/* STANDARDS
|
/* STANDARDS
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
|
@@ -58,10 +58,11 @@ extern DICT *dict_debug(DICT *);
|
|||||||
#define DICT_FLAG_SYNC_UPDATE (1<<8) /* if file, sync updates */
|
#define DICT_FLAG_SYNC_UPDATE (1<<8) /* if file, sync updates */
|
||||||
#define DICT_FLAG_DEBUG (1<<9) /* log access */
|
#define DICT_FLAG_DEBUG (1<<9) /* log access */
|
||||||
#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
|
#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
|
||||||
|
|
||||||
#define DICT_FLAG_NO_REGSUB (1<<11) /* no lhs->rhs regexp substitution */
|
#define DICT_FLAG_NO_REGSUB (1<<11) /* no lhs->rhs regexp substitution */
|
||||||
#define DICT_FLAG_NO_PROXY (1<<12) /* no proxy mapping */
|
#define DICT_FLAG_NO_PROXY (1<<12) /* no proxy mapping */
|
||||||
|
|
||||||
|
#define DICT_FLAG_PARANOID (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY)
|
||||||
|
|
||||||
extern int dict_unknown_allowed;
|
extern int dict_unknown_allowed;
|
||||||
extern int dict_errno;
|
extern int dict_errno;
|
||||||
|
|
||||||
|
@@ -84,6 +84,11 @@
|
|||||||
/* .IP DICT_FLAG_NO_REGSUB
|
/* .IP DICT_FLAG_NO_REGSUB
|
||||||
/* Disallow regular expression substitution from left-hand side data
|
/* Disallow regular expression substitution from left-hand side data
|
||||||
/* into the right-hand side.
|
/* into the right-hand side.
|
||||||
|
/* .IP DICT_FLAG_NO_PROXY
|
||||||
|
/* Disallow access through the \fBproxymap\fR service.
|
||||||
|
/* .IP DICT_FLAG_PARANOID
|
||||||
|
/* A combination of all the paranoia flags: DICT_FLAG_NO_REGSUB
|
||||||
|
/* and DICT_FLAG_NO_PROXY.
|
||||||
/* .PP
|
/* .PP
|
||||||
/* Specify DICT_FLAG_NONE for no special processing.
|
/* Specify DICT_FLAG_NONE for no special processing.
|
||||||
/*
|
/*
|
||||||
|
@@ -640,8 +640,11 @@ static int vstream_buf_get_ready(VBUF *bp)
|
|||||||
* allocation gives the application a chance to override the default
|
* allocation gives the application a chance to override the default
|
||||||
* buffering policy.
|
* buffering policy.
|
||||||
*/
|
*/
|
||||||
if (bp->data == 0)
|
if (bp->data == 0) {
|
||||||
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
|
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
|
||||||
|
if (bp->flags & VSTREAM_FLAG_DOUBLE)
|
||||||
|
VSTREAM_SAVE_STATE(stream, read_buf, read_fd);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the stream is double-buffered and the write buffer is not empty,
|
* If the stream is double-buffered and the write buffer is not empty,
|
||||||
@@ -724,6 +727,8 @@ static int vstream_buf_put_ready(VBUF *bp)
|
|||||||
*/
|
*/
|
||||||
if (bp->data == 0) {
|
if (bp->data == 0) {
|
||||||
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
|
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
|
||||||
|
if (bp->flags & VSTREAM_FLAG_DOUBLE)
|
||||||
|
VSTREAM_SAVE_STATE(stream, write_buf, write_fd);
|
||||||
} else if (bp->cnt <= 0) {
|
} else if (bp->cnt <= 0) {
|
||||||
if (VSTREAM_FFLUSH_SOME(stream))
|
if (VSTREAM_FFLUSH_SOME(stream))
|
||||||
return (VSTREAM_EOF);
|
return (VSTREAM_EOF);
|
||||||
|
@@ -413,15 +413,15 @@ static void post_init(char *unused_name, char **unused_argv)
|
|||||||
|
|
||||||
virtual_mailbox_maps =
|
virtual_mailbox_maps =
|
||||||
virtual8_maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps,
|
virtual8_maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps,
|
||||||
DICT_FLAG_LOCK);
|
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||||
|
|
||||||
virtual_uid_maps =
|
virtual_uid_maps =
|
||||||
virtual8_maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps,
|
virtual8_maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps,
|
||||||
DICT_FLAG_LOCK);
|
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||||
|
|
||||||
virtual_gid_maps =
|
virtual_gid_maps =
|
||||||
virtual8_maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps,
|
virtual8_maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps,
|
||||||
DICT_FLAG_LOCK);
|
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||||
|
|
||||||
virtual_mbox_lock_mask = mbox_lock_mask(var_virt_mailbox_lock);
|
virtual_mbox_lock_mask = mbox_lock_mask(var_virt_mailbox_lock);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user