mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
postfix-2.0.0-20030104
This commit is contained in:
parent
55978ec179
commit
1eed3b4cde
@ -7630,11 +7630,8 @@ Apologies for any names omitted.
|
||||
|
||||
20030102
|
||||
|
||||
Workaround: use different client instances when the same
|
||||
map is opened with different flags. This silences warnings
|
||||
from maps_append() when the same map is opened by
|
||||
virtual_alias_maps and by virtual_mailbox_maps. File:
|
||||
global/maps.c.
|
||||
Cleanup: use different client instances when the same map
|
||||
is opened with different flags. File: global/maps.c.
|
||||
|
||||
Feature: proxymap server for Postfix table lookups. This
|
||||
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
|
||||
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:
|
||||
|
||||
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
|
||||
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
|
||||
================================================================
|
||||
|
||||
|
@ -175,18 +175,20 @@ mail_owner = postfix
|
||||
# For example, you define $mydestination domain recipients in
|
||||
# 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"
|
||||
# feature of the Postfix local delivery agent (see sample-local.cf).
|
||||
#
|
||||
# Beware: if the Postfix SMTP server runs chrooted, you probably have
|
||||
# to copy the passwd (not shadow) database into the jail, and perhaps
|
||||
# other files. This is system dependent.
|
||||
# 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 = unix:passwd.byname $alias_maps
|
||||
#local_recipient_maps = proxy:passwd.byname $alias_maps
|
||||
#local_recipient_maps =
|
||||
|
||||
# The unknown_local_recipient_reject_code specifies the SMTP server
|
||||
|
@ -11,6 +11,10 @@
|
||||
# precedence, from highest to lowest priority: mailbox_transport,
|
||||
# mailbox_command_maps, mailbox_command, home_mailbox.
|
||||
|
||||
#
|
||||
# MISCELLANEOUS PARAMETERS
|
||||
#
|
||||
|
||||
# The biff parameter specifies whether or not to contact the biff
|
||||
# server. This server sends "new mail" notifications to users who
|
||||
# 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
|
||||
# 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,
|
||||
# the SMTP server rejects mail for recipients not listed with the
|
||||
# local_recipient_maps parameter.
|
||||
|
@ -4,6 +4,65 @@
|
||||
# This file contains example settings of Postfix configuration parameters
|
||||
# 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
|
||||
#
|
||||
|
@ -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
|
||||
with undeliverable mail from spammers).
|
||||
|
||||
<p.
|
||||
<p>
|
||||
|
||||
Specify <tt>local_recipient_maps =</tt> if maintaining recipient
|
||||
information is not practical.
|
||||
@ -2090,7 +2090,7 @@ you use the default Postfix local delivery agent:
|
||||
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
local_recipient_maps = $alias_maps, unix:passwd.byname
|
||||
local_recipient_maps = $alias_maps, proxy:unix:passwd.byname
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@ -2107,10 +2107,12 @@ To stop Postfix from rejecting local mail incorrectly:
|
||||
|
||||
<ul>
|
||||
|
||||
<li> If you run the Postfix SMTP server chrooted, it may be necessary
|
||||
to place a copy of the passwd file inside the chroot jail (typically:
|
||||
in <b>/var/spool/postfix/etc</b>). This is system dependent. The
|
||||
only way to find out is to try.
|
||||
<li> If you run the Postfix SMTP server chrooted, you need to access
|
||||
the system password database through the Postfix <a href="proxymap.8.html">
|
||||
proxymap</a> service, as shown in the above example. The alternative
|
||||
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>
|
||||
|
||||
@ -2313,21 +2315,30 @@ database" mean?</h3></a>
|
||||
This message is logged when, for example, the Postfix SMTP server
|
||||
is unable to access the UNIX password database.
|
||||
|
||||
<p>
|
||||
|
||||
<ul>
|
||||
|
||||
<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
|
||||
perhaps a bunch of other files into the Postfix queue directory; a
|
||||
typical destination would be <b>/var/spool/postfix/etc</b>. See also
|
||||
the chroot setup scripts in the <b>examples</b> directory of the
|
||||
Postfix source code distribution.
|
||||
<b>master.cf</b>) then you need to access the system password
|
||||
database through the Postfix <a href="proxymap.8.html">proxymap</a>
|
||||
service. The alternative is not practical: copying the password
|
||||
file and perhaps a bunch of other system dependent files into the
|
||||
Postfix queue directory.
|
||||
|
||||
<p>
|
||||
|
||||
<li> 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>).
|
||||
<pre>
|
||||
/etc/postfix/main.cf:
|
||||
local_recipient_maps = proxy:unix:passwd.byname $alias_maps ...
|
||||
</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>
|
||||
|
||||
|
@ -91,7 +91,7 @@ POSTCONF(1) POSTCONF(1)
|
||||
|
||||
<b>proxy</b> (read-only)
|
||||
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>.
|
||||
|
||||
<b>regexp</b> (read-only)
|
||||
|
@ -15,34 +15,39 @@ PROXYMAP(8) PROXYMAP(8)
|
||||
<b>o</b> To overcome chroot restrictions. For example, a
|
||||
chrooted SMTP server needs access to the system
|
||||
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 =
|
||||
proxy:unix:passwd.byname $alias_maps
|
||||
|
||||
<b>o</b> To consolidate the number of open lookup tables by
|
||||
sharing one open table among multiple processes.
|
||||
For example, to avoid problems due to "too many
|
||||
connections" to, e.g., mysql servers, specify:
|
||||
For example, making mysql connections from every
|
||||
Postfix daemon process results in "too many connec-
|
||||
tions" errors. The solution:
|
||||
|
||||
virtual_alias_maps =
|
||||
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:
|
||||
|
||||
<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>,
|
||||
as controlled by <i>flags</i>. The reply is the request
|
||||
completion status code and the map type dependent
|
||||
flags.
|
||||
completion status code (below) and the map type
|
||||
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>
|
||||
Look up the data stored under the requested key.
|
||||
The reply is the request completion status code and
|
||||
the lookup result value. The <i>maptype:mapname</i> and
|
||||
<i>flags</i> are the same as with the <b>PROXY</b><i>_</i><b>REQ</b><i>_</i><b>OPEN</b>
|
||||
request.
|
||||
The reply is the request completion status code
|
||||
(below) and the lookup result value. The <i>map-</i>
|
||||
<i>type:mapname</i> and <i>flags</i> are the same as with the
|
||||
<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
|
||||
because tables are meant to be shared among client pro-
|
||||
@ -51,52 +56,63 @@ PROXYMAP(8) PROXYMAP(8)
|
||||
The request completion status code is one of:
|
||||
|
||||
<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>
|
||||
The requested table or lookup key does not exist.
|
||||
<b>PROXY</b><i>_</i><b>STAT</b><i>_</i><b>NOKEY</b>
|
||||
The requested table entry was not found.
|
||||
|
||||
<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).
|
||||
|
||||
<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-
|
||||
ter server. Each server can handle multiple simultaneous
|
||||
connections. When all servers are busy while a client
|
||||
connects, the master creates a new proxymap server pro-
|
||||
cess, provided that the proxymap server process limit is
|
||||
not exceeded. Each proxymap server terminates after serv-
|
||||
ing <b>$max</b><i>_</i><b>use</b> clients or after <b>$max</b><i>_</i><b>idle</b> seconds of idle
|
||||
time.
|
||||
not exceeded. Each proxymap server stops accepting new
|
||||
connections after serving <b>$max</b><i>_</i><b>use</b> clients or terminates
|
||||
after <b>$max</b><i>_</i><b>idle</b> seconds of idle time.
|
||||
|
||||
<b>SECURITY</b>
|
||||
The proxymap server is not security-sensitive. It opens
|
||||
only tables that are approved via the <b>proxymap</b><i>_</i><b>filter</b> con-
|
||||
figuration parameter, does not talk to users, and can run
|
||||
at fixed low privilege, chrooted or not.
|
||||
The proxymap server opens only tables that are approved
|
||||
via the <b>proxy</b><i>_</i><b>read</b><i>_</i><b>maps</b> configuration parameter, does not
|
||||
talk to users, and 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 exter-
|
||||
nal commands.
|
||||
|
||||
<b>DIAGNOSTICS</b>
|
||||
Problems and transactions are logged to <b>syslogd</b>(8).
|
||||
|
||||
<b>BUGS</b>
|
||||
The proxymap server provides service to multiple clients,
|
||||
and must therefore not be used for tables that have high-
|
||||
The proxymap server provides service to multiple clients,
|
||||
and must therefore not be used for tables that have high-
|
||||
latency lookups.
|
||||
|
||||
<b>CONFIGURATION</b> <b>PARAMETERS</b>
|
||||
The following main.cf parameters are especially relevant
|
||||
to this program. Use the <b>postfix</b> <b>reload</b> command after a
|
||||
The following main.cf parameters are especially relevant
|
||||
to this program. Use the <b>postfix</b> <b>reload</b> command after a
|
||||
configuration change.
|
||||
|
||||
<b>proxymap</b><i>_</i><b>filter</b>
|
||||
A list of zero or more parameter values that may
|
||||
contain Postfix lookup table references. Only table
|
||||
references that begin with <b>proxy:</b> are approved for
|
||||
access via the proxymap server.
|
||||
<b>proxy</b><i>_</i><b>read</b><i>_</i><b>maps</b>
|
||||
A list of zero or more parameter values that may
|
||||
contain references to Postfix lookup tables. Only
|
||||
table references that begin with <b>proxy:</b> are
|
||||
approved for read-only access via the proxymap
|
||||
server.
|
||||
|
||||
<b>SEE</b> <b>ALSO</b>
|
||||
dict_proxy(3) proxy map client
|
||||
|
@ -37,14 +37,6 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
The envelope recipient address that is
|
||||
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>
|
||||
By default, Postfix uses one of the following delivery
|
||||
methods. This may be overruled with the optional <a href="transport.5.html">trans-</a>
|
||||
@ -83,14 +75,24 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
<b>$relayhost</b>. The default nexthop is the recipient
|
||||
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>
|
||||
None. The command does not interact with the outside
|
||||
None. The command does not interact with the outside
|
||||
world.
|
||||
|
||||
<b>SECURITY</b>
|
||||
The <b>trivial-rewrite</b> daemon is not security sensitive. By
|
||||
default, this daemon does not talk to remote or local
|
||||
users. It can run at a fixed low privilege in a chrooted
|
||||
The <b>trivial-rewrite</b> daemon is not security sensitive. By
|
||||
default, this daemon does not talk to remote or local
|
||||
users. It can run at a fixed low privilege in a chrooted
|
||||
environment.
|
||||
|
||||
<b>DIAGNOSTICS</b>
|
||||
@ -98,21 +100,21 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
|
||||
<b>BUGS</b>
|
||||
<b>CONFIGURATION</b> <b>PARAMETERS</b>
|
||||
The following <b>main.cf</b> parameters are especially relevant
|
||||
to this program. See the Postfix <b>main.cf</b> file for syntax
|
||||
details and for default values. Use the <b>postfix</b> <b>reload</b>
|
||||
The following <b>main.cf</b> parameters are especially relevant
|
||||
to this program. See the Postfix <b>main.cf</b> file for syntax
|
||||
details and for default values. Use the <b>postfix</b> <b>reload</b>
|
||||
command after a configuration change.
|
||||
|
||||
<b>Miscellaneous</b>
|
||||
<b>empty</b><i>_</i><b>address</b><i>_</i><b>recipient</b>
|
||||
The recipient that is substituted for the null
|
||||
The recipient that is substituted for the null
|
||||
address.
|
||||
|
||||
<b>inet</b><i>_</i><b>interfaces</b>
|
||||
The network interfaces that this mail system
|
||||
receives mail on. This information is used to
|
||||
determine if <i>user</i>@[<i>net.work.addr.ess</i>] is local or
|
||||
remote. Mail for local users is given to the
|
||||
The network interfaces that this mail system
|
||||
receives mail on. This information is used to
|
||||
determine if <i>user</i>@[<i>net.work.addr.ess</i>] is local or
|
||||
remote. Mail for local users is given to the
|
||||
<b>$local</b><i>_</i><b>transport</b>.
|
||||
|
||||
<b>mydestination</b>
|
||||
@ -121,7 +123,7 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
|
||||
<b>virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>
|
||||
List of simulated virtual domains (domains with all
|
||||
recipients aliased to some other local or remote
|
||||
recipients aliased to some other local or remote
|
||||
domain).
|
||||
|
||||
<b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>
|
||||
@ -134,10 +136,10 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
|
||||
<b>resolve</b><i>_</i><b>unquoted</b><i>_</i><b>address</b>
|
||||
When resolving an address, do not quote the address
|
||||
localpart as per <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a>, so that additional <b>@</b>, <b>%</b>
|
||||
or <b>!</b> characters remain visible. This is techni-
|
||||
localpart as per <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a>, so that additional <b>@</b>, <b>%</b>
|
||||
or <b>!</b> characters remain visible. This is techni-
|
||||
cally incorrect, but allows us to stop relay
|
||||
attacks when forwarding mail to a Sendmail primary
|
||||
attacks when forwarding mail to a Sendmail primary
|
||||
MX host.
|
||||
|
||||
<b>relocated</b><i>_</i><b>maps</b>
|
||||
@ -163,50 +165,50 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
|
||||
<b>Routing</b>
|
||||
<b>local</b><i>_</i><b>transport</b>
|
||||
Where to deliver mail for destinations that match
|
||||
<b>$mydestination</b> or <b>$inet</b><i>_</i><b>interfaces</b>. The default
|
||||
Where to deliver mail for destinations that match
|
||||
<b>$mydestination</b> or <b>$inet</b><i>_</i><b>interfaces</b>. The default
|
||||
transport is <b>local:$myhostname</b>.
|
||||
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
details. The :<i>nexthop</i> part is optional.
|
||||
|
||||
<b>virtual</b><i>_</i><b>transport</b>
|
||||
Where to deliver mail for non-local domains that
|
||||
match <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>. The default trans-
|
||||
port is <b>virtual</b>.
|
||||
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
details. The :<i>nexthop</i> part is optional.
|
||||
|
||||
<b>virtual</b><i>_</i><b>transport</b>
|
||||
Where to deliver mail for non-local domains that
|
||||
match <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>. The default trans-
|
||||
port is <b>virtual</b>.
|
||||
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
details. The :<i>nexthop</i> part is optional.
|
||||
|
||||
<b>relay</b><i>_</i><b>transport</b>
|
||||
Where to deliver mail for non-local domains that
|
||||
match <b>$relay</b><i>_</i><b>domains</b>. The default transport is
|
||||
Where to deliver mail for non-local domains that
|
||||
match <b>$relay</b><i>_</i><b>domains</b>. The default transport is
|
||||
<b>relay</b> (which normally is a clone of the <b>smtp</b> trans-
|
||||
port).
|
||||
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
details. The :<i>nexthop</i> part is optional.
|
||||
|
||||
<b>default</b><i>_</i><b>transport</b>
|
||||
Where to deliver all other non-local mail. The
|
||||
Where to deliver all other non-local mail. The
|
||||
default transport is <b>smtp</b>.
|
||||
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
|
||||
details. The :<i>nexthop</i> part is optional.
|
||||
|
||||
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
|
||||
List of Postfix features that use <i>domain.tld</i> pat-
|
||||
terns to match <i>sub.domain.tld</i> (as opposed to
|
||||
List of Postfix features that use <i>domain.tld</i> pat-
|
||||
terns to match <i>sub.domain.tld</i> (as opposed to
|
||||
requiring <i>.domain.tld</i> patterns).
|
||||
|
||||
<b>relayhost</b>
|
||||
The default host to send non-local mail to when no
|
||||
host is specified with <b>$relay</b><i>_</i><b>transport</b> or
|
||||
<b>$default</b><i>_</i><b>transport</b>, and when the recipient address
|
||||
The default host to send non-local mail to when no
|
||||
host is specified with <b>$relay</b><i>_</i><b>transport</b> or
|
||||
<b>$default</b><i>_</i><b>transport</b>, and when the recipient address
|
||||
does not match the optional the <a href="transport.5.html"><b>transport</b>(5)</a> table.
|
||||
|
||||
<b>transport</b><i>_</i><b>maps</b>
|
||||
List of tables with <i>recipient</i> or <i>domain</i> to (<i>trans-</i>
|
||||
List of tables with <i>recipient</i> or <i>domain</i> to (<i>trans-</i>
|
||||
<i>port,</i> <i>nexthop</i>) mappings.
|
||||
|
||||
<b>SEE</b> <b>ALSO</b>
|
||||
@ -216,7 +218,7 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
<a href="relocated.5.html">relocated(5)</a> format of the "user has moved" table
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
|
@ -18,35 +18,35 @@ of the service is:
|
||||
.IP \(bu
|
||||
To overcome chroot restrictions. For example, a chrooted SMTP
|
||||
server needs access to the system passwd file in order to
|
||||
reject mail for non-existent local addresses.
|
||||
The solution is to specify:
|
||||
reject mail for non-existent local addresses, but it is not
|
||||
practical to maintain a copy of the passwd file in the chroot
|
||||
jail. The solution:
|
||||
.sp
|
||||
local_recipient_maps =
|
||||
.ti +4
|
||||
proxy:unix:passwd.byname $alias_maps
|
||||
.IP \(bu
|
||||
To consolidate the number of open lookup tables by sharing
|
||||
one open table among multiple processes. For example, to avoid
|
||||
problems due to "too many connections" to, e.g., mysql servers,
|
||||
specify:
|
||||
one open table among multiple processes. For example, making
|
||||
mysql connections from every Postfix daemon process results
|
||||
in "too many connections" errors. The solution:
|
||||
.sp
|
||||
virtual_alias_maps =
|
||||
.ti +4
|
||||
proxy:mysql:/etc/postfix/virtual.cf
|
||||
.SH PROXYMAP SERVICES
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
.sp
|
||||
The total number of connections is limited by the number of
|
||||
proxymap server server processes.
|
||||
.PP
|
||||
The proxymap server implements the following requests:
|
||||
.IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
||||
Open the table with type \fImaptype\fR and name \fImapname\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.
|
||||
.IP "\fBPROXY_REQ_LOOKUP\fI maptype:mapname flags key\fR"
|
||||
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 \fImaptype:mapname\fR and \fIflags\fR are the same
|
||||
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:
|
||||
.IP \fBPROXY_STAT_OK\fR
|
||||
The requested table or lookup key was found.
|
||||
.IP \fBPROXY_STAT_FAIL\fR
|
||||
The requested table or lookup key does not exist.
|
||||
The specified table was opened, or the requested entry was found.
|
||||
.IP \fBPROXY_STAT_NOKEY\fR
|
||||
The requested table entry was not found.
|
||||
.IP \fBPROXY_STAT_BAD\fR
|
||||
The request was rejected (bad request parameter value).
|
||||
.IP \fBPROXY_STAT_RETRY\fR
|
||||
The request was not completed.
|
||||
.SH MASTER INTERFACE
|
||||
The lookup request could not be completed.
|
||||
.IP \fBPROXY_STAT_DENY\fR
|
||||
The specified table was not approved for access via the
|
||||
proxymap service.
|
||||
.SH SERVER PROCESS MANAGEMENT
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
@ -73,17 +76,21 @@ server. Each server can handle multiple simultaneous connections.
|
||||
When all servers are busy while a client connects, the master
|
||||
creates a new proxymap server process, provided that the proxymap
|
||||
server process limit is not exceeded.
|
||||
Each proxymap server terminates after serving \fB$max_use\fR clients
|
||||
or after \fB$max_idle\fR seconds of idle time.
|
||||
Each proxymap server stops accepting new connections after serving
|
||||
\fB$max_use\fR clients or terminates after \fB$max_idle\fR seconds
|
||||
of idle time.
|
||||
.SH SECURITY
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
The proxymap server is not security-sensitive. It opens only
|
||||
tables that are approved via the \fBproxymap_filter\fR
|
||||
configuration parameter, does not talk to users, and
|
||||
can run at fixed low privilege, chrooted or not.
|
||||
The proxymap server opens only tables that are approved via the
|
||||
\fBproxy_read_maps\fR configuration parameter, does not talk to
|
||||
users, and 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
|
||||
.ad
|
||||
.fi
|
||||
@ -102,11 +109,11 @@ lookups.
|
||||
The following main.cf parameters are especially relevant
|
||||
to this program. Use the \fBpostfix reload\fR command
|
||||
after a configuration change.
|
||||
.IP \fBproxymap_filter\fR
|
||||
.IP \fBproxy_read_maps\fR
|
||||
A list of zero or more parameter values that may contain
|
||||
Postfix lookup table references. Only table references that
|
||||
begin with \fBproxy:\fR are approved for access via the
|
||||
proxymap server.
|
||||
references to Postfix lookup tables. Only table references
|
||||
that begin with \fBproxy:\fR are approved for read-only
|
||||
access via the proxymap server.
|
||||
.SH SEE ALSO
|
||||
.na
|
||||
.nf
|
||||
|
@ -32,14 +32,6 @@ The host to send to and optional delivery method information.
|
||||
.IP \fIrecipient\fR
|
||||
The envelope recipient address that is passed on to \fInexthop\fR.
|
||||
.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
|
||||
.na
|
||||
.nf
|
||||
@ -73,6 +65,19 @@ The transport and optional nexthop are specified with
|
||||
This overrides the optional nexthop information that is specified
|
||||
with \fB$relayhost\fR.
|
||||
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
|
||||
.na
|
||||
.nf
|
||||
|
@ -44,7 +44,7 @@ exec sed '
|
||||
s/[<bB>]*canonical[</bB>]*(5)/<a href="canonical.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>]*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>]*relocated[</bB>]*(5)/<a href="relocated.5.html">&<\/a>/
|
||||
s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
|
||||
|
@ -48,7 +48,7 @@
|
||||
/* .IP timeout
|
||||
/* Idle time after which the client disconnects.
|
||||
/* .IP ttl
|
||||
/* Time to live after which the client disconnects.
|
||||
/* Upper bound on the time that a connection is allowed to persist.
|
||||
/* DIAGNOSTICS
|
||||
/* Warnings: communication failure. Fatal error: mail system is down,
|
||||
/* 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()
|
||||
* function cannot distinguish requests with the same callback routine.
|
||||
* The fix is obvious: specify a request ID along with the callback
|
||||
* routine, but there is too much code that would have to be changed.
|
||||
* XXX This function is needed only because event_request_timer() cannot
|
||||
* distinguish between requests that specify the same call-back routine
|
||||
* and call-back context. The fix is obvious: specify a request ID along
|
||||
* 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);
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
/* The \fIopen_flags\fR argument must specify O_RDONLY.
|
||||
/*
|
||||
/* 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
|
||||
/* The proxy map server is not meant to be a trusted process. Proxy
|
||||
/* maps must not be used to look up security sensitive information
|
||||
@ -27,7 +28,7 @@
|
||||
/* clnt_stream(3) client endpoint connection management
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal errors: out of memory, unimplemented operation,
|
||||
/* bad request parameter.
|
||||
/* bad request parameter, map not approved for proxy access.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -78,8 +79,7 @@ typedef struct {
|
||||
#define VSTREQ(v,s) (strcmp(STR(v),s) == 0)
|
||||
|
||||
/*
|
||||
* All proxied maps within the same process share the same query/reply
|
||||
* socket.
|
||||
* All proxied maps within a process share the same query/reply socket.
|
||||
*/
|
||||
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_END) != 2) {
|
||||
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 {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: table=%s flags=0%o key=%s -> status=%d result=%s",
|
||||
myname, dict->name, dict_proxy->in_flags, key,
|
||||
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));
|
||||
} else if (status == PROXY_STAT_FAIL) {
|
||||
case PROXY_STAT_NOKEY:
|
||||
return (0);
|
||||
} else if (status == PROXY_STAT_RETRY) {
|
||||
case PROXY_STAT_RETRY:
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
} else if (status == PROXY_STAT_BAD) {
|
||||
msg_fatal("%s: %s lookup %s failed: bad request",
|
||||
myname, dict->name, key);
|
||||
} else {
|
||||
msg_warn("%s: %s lookup %s failed with unknown status %d",
|
||||
myname, dict->name, key, status);
|
||||
default:
|
||||
msg_warn("%s lookup failed for table \"%s\" key \"%s\": "
|
||||
"unexpected reply status %d",
|
||||
MAIL_SERVICE_PROXYMAP, dict->name, key, status);
|
||||
}
|
||||
}
|
||||
clnt_stream_recover(proxy_stream);
|
||||
@ -166,10 +172,10 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
||||
/*
|
||||
* 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)
|
||||
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.
|
||||
@ -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 (;;) {
|
||||
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) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: service %s: %m", VSTREAM_PATH(stream), myname);
|
||||
} else if (status == PROXY_STAT_OK) {
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: connect to map=%s status=%d server_flags=0%o",
|
||||
myname, dict_proxy->dict.name, status, server_flags);
|
||||
dict_proxy->dict.flags = dict_proxy->in_flags | server_flags;
|
||||
break;
|
||||
} else if (status == PROXY_STAT_BAD) {
|
||||
msg_fatal("%s: %s connection request failed: bad request",
|
||||
myname, dict_proxy->dict.name);
|
||||
} else {
|
||||
msg_warn("%s: %s connection request failed with status %d",
|
||||
myname, dict_proxy->dict.name, status);
|
||||
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;
|
||||
return (DICT_DEBUG (&dict_proxy->dict));
|
||||
default:
|
||||
msg_warn("%s open failed for table \"%s\": unexpected status %d",
|
||||
MAIL_SERVICE_PROXYMAP, dict_proxy->dict.name, status);
|
||||
}
|
||||
}
|
||||
clnt_stream_recover(proxy_stream);
|
||||
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_LOOKUP "lookup"
|
||||
|
||||
#define PROXY_STAT_OK 0
|
||||
#define PROXY_STAT_FAIL 1
|
||||
#define PROXY_STAT_BAD 2
|
||||
#define PROXY_STAT_RETRY 3
|
||||
#define PROXY_STAT_OK 0 /* operation succeeded */
|
||||
#define PROXY_STAT_NOKEY 1 /* requested key not found */
|
||||
#define PROXY_STAT_RETRY 2 /* try lookup again later */
|
||||
#define PROXY_STAT_BAD 3 /* invalid request parameter */
|
||||
#define PROXY_STAT_DENY 4 /* table not approved for proxying */
|
||||
|
||||
/* LICENSE
|
||||
/* .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.
|
||||
*/
|
||||
#define VAR_PROXYMAP_FILTER "proxymap_filter"
|
||||
#define DEF_PROXYMAP_FILTER "$" VAR_LOCAL_RCPT_MAPS \
|
||||
#define VAR_PROXY_READ_MAPS "proxy_read_maps"
|
||||
#define DEF_PROXY_READ_MAPS "$" VAR_LOCAL_RCPT_MAPS \
|
||||
" $" VAR_MYDEST \
|
||||
" $" VAR_VIRT_ALIAS_MAPS \
|
||||
" $" VAR_VIRT_ALIAS_DOMS \
|
||||
@ -1346,7 +1346,7 @@ extern int var_local_rcpt_code;
|
||||
" $" VAR_RCPT_CANON_MAPS \
|
||||
" $" VAR_RELOCATED_MAPS \
|
||||
" $" VAR_TRANSPORT_MAPS
|
||||
extern char *var_proxymap_filter;
|
||||
extern char *var_proxy_read_maps;
|
||||
|
||||
/*
|
||||
* Other.
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change the patchlevel and the release date. Snapshots change the
|
||||
* 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 DEF_MAIL_VERSION "2.0.0-" MAIL_RELEASE_DATE
|
||||
|
@ -184,22 +184,20 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
||||
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, RESOLVE_ADDR,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||
ATTR_TYPE_END)
|
||||
|| vstream_fflush(stream)) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: bad write: %m", myname);
|
||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_END) != 0
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_TRANSPORT, reply->transport,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
|
||||
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &reply->flags,
|
||||
ATTR_TYPE_END) != 4) {
|
||||
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &reply->flags,
|
||||
ATTR_TYPE_END) != 4) {
|
||||
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 {
|
||||
if (msg_verbose)
|
||||
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
|
||||
break;
|
||||
}
|
||||
sleep(10); /* XXX make configurable */
|
||||
sleep(1); /* XXX make configurable */
|
||||
clnt_stream_recover(rewrite_clnt_stream);
|
||||
}
|
||||
|
||||
|
@ -125,26 +125,25 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||
ATTR_TYPE_END),
|
||||
vstream_fflush(stream)) {
|
||||
ATTR_TYPE_END) != 0
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
|
||||
ATTR_TYPE_END) != 1) {
|
||||
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_END) != 1) {
|
||||
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 {
|
||||
if (msg_verbose)
|
||||
msg_info("rewrite_clnt: %s: %s -> %s",
|
||||
rule, addr, vstring_str(result));
|
||||
break;
|
||||
}
|
||||
sleep(10); /* XXX make configurable */
|
||||
sleep(1); /* XXX make configurable */
|
||||
clnt_stream_recover(rewrite_clnt_stream);
|
||||
}
|
||||
|
||||
|
@ -117,24 +117,19 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
|
||||
*/
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(vrfy_clnt);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)) {
|
||||
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_ADDR_STATUS, addr_status,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
|
||||
ATTR_TYPE_END) != 3) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
||||
msg_warn("service %s: bad read: %m", var_verify_service);
|
||||
sleep(10); /* XXX make configurable */
|
||||
}
|
||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
|
||||
ATTR_TYPE_END) != 3) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("problem talking to service %s: %m",
|
||||
var_verify_service);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -181,25 +176,19 @@ int verify_clnt_vupdate(const char *addr, int addr_status,
|
||||
vstring_vsprintf(text, format, ap);
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(vrfy_clnt);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_UPDATE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_ADDR_STATUS, addr_status,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(text),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)) {
|
||||
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_END) != 1) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT)) {
|
||||
msg_warn("service %s: bad read: %m", var_verify_service);
|
||||
sleep(10); /* XXX make configurable */
|
||||
}
|
||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &request_status,
|
||||
ATTR_TYPE_END) != 1) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("problem talking to service %s: %m",
|
||||
var_verify_service);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -28,11 +28,7 @@
|
||||
/* named dictionaries.
|
||||
/* The result is a handle that must be specified along with all
|
||||
/* other virtual8_maps_xxx() operations.
|
||||
/* See dict_open(3) for a description of flags. virtual8_maps_create()
|
||||
/* 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.
|
||||
/* See dict_open(3) for a description of flags.
|
||||
/*
|
||||
/* virtual8_maps_find() searches the specified list of dictionaries
|
||||
/* in the specified order for the named key. The result is in
|
||||
|
@ -20,8 +20,7 @@
|
||||
* External interface.
|
||||
*/
|
||||
#define virtual8_maps_create(title, map_names, flags) \
|
||||
maps_create((title), (map_names), \
|
||||
(flags) | DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY)
|
||||
maps_create((title), (map_names), (flags))
|
||||
extern const char *virtual8_maps_find(MAPS *, const char *);
|
||||
#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);
|
||||
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,
|
||||
DICT_FLAG_LOCK | INSECURE_DICT_FLAGS);
|
||||
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||
}
|
||||
|
||||
/* main - pass control to the single-threaded skeleton */
|
||||
|
@ -12,33 +12,35 @@
|
||||
/* .IP \(bu
|
||||
/* To overcome chroot restrictions. For example, a chrooted SMTP
|
||||
/* server needs access to the system passwd file in order to
|
||||
/* reject mail for non-existent local addresses.
|
||||
/* The solution is to specify:
|
||||
/* reject mail for non-existent local addresses, but it is not
|
||||
/* practical to maintain a copy of the passwd file in the chroot
|
||||
/* jail. The solution:
|
||||
/* .sp
|
||||
/* local_recipient_maps =
|
||||
/* .ti +4
|
||||
/* proxy:unix:passwd.byname $alias_maps
|
||||
/* .IP \(bu
|
||||
/* To consolidate the number of open lookup tables by sharing
|
||||
/* one open table among multiple processes. For example, to avoid
|
||||
/* problems due to "too many connections" to, e.g., mysql servers,
|
||||
/* specify:
|
||||
/* one open table among multiple processes. For example, making
|
||||
/* mysql connections from every Postfix daemon process results
|
||||
/* in "too many connections" errors. The solution:
|
||||
/* .sp
|
||||
/* virtual_alias_maps =
|
||||
/* .ti +4
|
||||
/* proxy:mysql:/etc/postfix/virtual.cf
|
||||
/* PROXYMAP SERVICES
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* .sp
|
||||
/* The total number of connections is limited by the number of
|
||||
/* proxymap server server processes.
|
||||
/* .PP
|
||||
/* The proxymap server implements the following requests:
|
||||
/* .IP "\fBPROXY_REQ_OPEN\fI maptype:mapname flags\fR"
|
||||
/* Open the table with type \fImaptype\fR and name \fImapname\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.
|
||||
/* .IP "\fBPROXY_REQ_LOOKUP\fI maptype:mapname flags key\fR"
|
||||
/* 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 \fImaptype:mapname\fR and \fIflags\fR are the same
|
||||
/* as with the \fBPROXY_REQ_OPEN\fR request.
|
||||
@ -48,30 +50,37 @@
|
||||
/*
|
||||
/* The request completion status code is one of:
|
||||
/* .IP \fBPROXY_STAT_OK\fR
|
||||
/* The requested table or lookup key was found.
|
||||
/* .IP \fBPROXY_STAT_FAIL\fR
|
||||
/* The requested table or lookup key does not exist.
|
||||
/* The specified table was opened, or the requested entry was found.
|
||||
/* .IP \fBPROXY_STAT_NOKEY\fR
|
||||
/* The requested table entry was not found.
|
||||
/* .IP \fBPROXY_STAT_BAD\fR
|
||||
/* The request was rejected (bad request parameter value).
|
||||
/* .IP \fBPROXY_STAT_RETRY\fR
|
||||
/* The request was not completed.
|
||||
/* MASTER INTERFACE
|
||||
/* The lookup request could not be completed.
|
||||
/* .IP \fBPROXY_STAT_DENY\fR
|
||||
/* The specified table was not approved for access via the
|
||||
/* proxymap service.
|
||||
/* SERVER PROCESS MANAGEMENT
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The proxymap 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 proxymap server process, provided that the proxymap
|
||||
/* creates a new proxymap server process, provided that the proxymap
|
||||
/* server process limit is not exceeded.
|
||||
/* Each proxymap server terminates after serving \fB$max_use\fR clients
|
||||
/* or after \fB$max_idle\fR seconds of idle time.
|
||||
/* Each proxymap server stops accepting new connections after serving
|
||||
/* \fB$max_use\fR clients or terminates after \fB$max_idle\fR seconds
|
||||
/* of idle time.
|
||||
/* SECURITY
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The proxymap server is not security-sensitive. It opens only
|
||||
/* tables that are approved via the \fBproxymap_filter\fR
|
||||
/* configuration parameter, does not talk to users, and
|
||||
/* can run at fixed low privilege, chrooted or not.
|
||||
/* The proxymap server opens only tables that are approved via the
|
||||
/* \fBproxy_read_maps\fR configuration parameter, does not talk to
|
||||
/* users, and 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
|
||||
/* Problems and transactions are logged to \fBsyslogd\fR(8).
|
||||
/* BUGS
|
||||
@ -84,11 +93,11 @@
|
||||
/* The following main.cf parameters are especially relevant
|
||||
/* to this program. Use the \fBpostfix reload\fR command
|
||||
/* after a configuration change.
|
||||
/* .IP \fBproxymap_filter\fR
|
||||
/* .IP \fBproxy_read_maps\fR
|
||||
/* A list of zero or more parameter values that may contain
|
||||
/* Postfix lookup table references. Only table references that
|
||||
/* begin with \fBproxy:\fR are approved for access via the
|
||||
/* proxymap server.
|
||||
/* references to Postfix lookup tables. Only table references
|
||||
/* that begin with \fBproxy:\fR are approved for read-only
|
||||
/* access via the proxymap server.
|
||||
/* SEE ALSO
|
||||
/* dict_proxy(3) proxy map client
|
||||
/* LICENSE
|
||||
@ -148,20 +157,20 @@ char *var_send_canon_maps;
|
||||
char *var_rcpt_canon_maps;
|
||||
char *var_relocatedmaps;
|
||||
char *var_transport_maps;
|
||||
char *var_proxymap_filter;
|
||||
char *var_proxy_read_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.
|
||||
*/
|
||||
static VSTRING *request;
|
||||
static VSTRING *request_map;
|
||||
static VSTRING *request_key;
|
||||
static VSTRING *map_type_name_flags;
|
||||
static VSTRING *map_type_name;
|
||||
static VSTRING *key;
|
||||
|
||||
/*
|
||||
* Silly little macros.
|
||||
@ -171,13 +180,13 @@ static VSTRING *key;
|
||||
|
||||
/* 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;
|
||||
|
||||
#define PROXY_COLON DICT_TYPE_PROXY ":"
|
||||
#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,
|
||||
@ -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)
|
||||
map_type_name += PROXY_COLON_LEN;
|
||||
if (htable_locate(proxymap_filter, map_type_name) == 0) {
|
||||
msg_warn("request for unapproved map: %s", map_type_name);
|
||||
if (htable_locate(proxy_read_maps, map_type_name) == 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
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)
|
||||
dict = dict_open(map_type_name, OPEN_FLAGS, dict_flags);
|
||||
dict = dict_open(map_type_name, READ_OPEN_FLAGS, request_flags);
|
||||
if (dict == 0)
|
||||
msg_panic("proxy_map_find: dict_open null result");
|
||||
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)
|
||||
{
|
||||
int status = PROXY_STAT_BAD;
|
||||
int request_flags;
|
||||
DICT *dict;
|
||||
const char *value = "";
|
||||
int dict_flags;
|
||||
const char *reply_value;
|
||||
int reply_status;
|
||||
|
||||
/*
|
||||
* Process the request.
|
||||
*/
|
||||
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, map_type_name,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &dict_flags,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_KEY, key,
|
||||
ATTR_TYPE_END) == 3
|
||||
&& (dict = proxy_map_find(STR(map_type_name), dict_flags)) != 0) {
|
||||
|
||||
if ((value = dict_get(dict, STR(key))) != 0) {
|
||||
status = PROXY_STAT_OK;
|
||||
} else if (dict_errno == 0) {
|
||||
status = PROXY_STAT_FAIL;
|
||||
value = "";
|
||||
} else {
|
||||
status = PROXY_STAT_RETRY;
|
||||
value = "";
|
||||
}
|
||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, request_map,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request_flags,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_KEY, request_key,
|
||||
ATTR_TYPE_END) != 3) {
|
||||
reply_status = PROXY_STAT_BAD;
|
||||
reply_value = "";
|
||||
} else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
|
||||
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) {
|
||||
reply_status = PROXY_STAT_NOKEY;
|
||||
reply_value = "";
|
||||
} else {
|
||||
reply_status = PROXY_STAT_RETRY;
|
||||
reply_value = "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Respond to the client.
|
||||
*/
|
||||
attr_print(client_stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, status,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_VALUE, value,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, reply_status,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_VALUE, reply_value,
|
||||
ATTR_TYPE_END);
|
||||
}
|
||||
|
||||
@ -243,27 +259,34 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
|
||||
|
||||
static void proxymap_open_service(VSTREAM *client_stream)
|
||||
{
|
||||
int dict_flags;
|
||||
int request_flags;
|
||||
DICT *dict;
|
||||
int status = PROXY_STAT_BAD;
|
||||
int flags = 0;
|
||||
int reply_status;
|
||||
int reply_flags;
|
||||
|
||||
/*
|
||||
* Process the request.
|
||||
*/
|
||||
if (attr_scan(client_stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, map_type_name,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &dict_flags,
|
||||
ATTR_TYPE_END) == 2
|
||||
&& (dict = proxy_map_find(STR(map_type_name), dict_flags)) != 0) {
|
||||
|
||||
status = PROXY_STAT_OK;
|
||||
flags = dict->flags;
|
||||
ATTR_TYPE_STR, MAIL_ATTR_TABLE, request_map,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request_flags,
|
||||
ATTR_TYPE_END) != 2) {
|
||||
reply_status = PROXY_STAT_BAD;
|
||||
reply_flags = 0;
|
||||
} else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
|
||||
reply_status = PROXY_STAT_DENY;
|
||||
reply_flags = 0;
|
||||
} else {
|
||||
reply_status = PROXY_STAT_OK;
|
||||
reply_flags = dict->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Respond to the client.
|
||||
*/
|
||||
attr_print(client_stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, status,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, reply_status,
|
||||
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, reply_flags,
|
||||
ATTR_TYPE_END);
|
||||
}
|
||||
|
||||
@ -311,28 +334,41 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
||||
char *bp;
|
||||
char *type_name;
|
||||
|
||||
/*
|
||||
* Pre-allocate buffers.
|
||||
*/
|
||||
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);
|
||||
key = vstring_alloc(10);
|
||||
|
||||
/*
|
||||
* Prepare the pre-approved list of proxied tables.
|
||||
*/
|
||||
saved_filter = bp = mystrdup(var_proxymap_filter);
|
||||
proxymap_filter = htable_create(13);
|
||||
saved_filter = bp = mystrdup(var_proxy_read_maps);
|
||||
proxy_read_maps = htable_create(13);
|
||||
while ((type_name = mystrtok(&bp, sep)) != 0) {
|
||||
if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN))
|
||||
continue;
|
||||
do {
|
||||
type_name += PROXY_COLON_LEN;
|
||||
} while (!strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN));
|
||||
if (htable_find(proxymap_filter, type_name) == 0)
|
||||
(void) htable_enter(proxymap_filter, type_name, (char *) 0);
|
||||
if (htable_locate(proxy_read_maps, type_name) == 0)
|
||||
(void) htable_enter(proxy_read_maps, type_name, (char *) 0);
|
||||
}
|
||||
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 */
|
||||
|
||||
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_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocatedmaps, 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,
|
||||
};
|
||||
|
||||
multi_server_main(argc, argv, proxymap_service,
|
||||
MAIL_SERVER_STR_TABLE, str_table,
|
||||
MAIL_SERVER_POST_INIT, post_jail_init,
|
||||
MAIL_SERVER_PRE_ACCEPT, pre_accept,
|
||||
0);
|
||||
}
|
||||
|
@ -26,14 +26,6 @@
|
||||
/* .IP \fIrecipient\fR
|
||||
/* The envelope recipient address that is passed on to \fInexthop\fR.
|
||||
/* .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
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -65,6 +57,17 @@
|
||||
/* This overrides the optional nexthop information that is specified
|
||||
/* with \fB$relayhost\fR.
|
||||
/* 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
|
||||
/* .ad
|
||||
/* .fi
|
||||
|
@ -58,10 +58,11 @@ extern DICT *dict_debug(DICT *);
|
||||
#define DICT_FLAG_SYNC_UPDATE (1<<8) /* if file, sync updates */
|
||||
#define DICT_FLAG_DEBUG (1<<9) /* log access */
|
||||
#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_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_errno;
|
||||
|
||||
|
@ -84,6 +84,11 @@
|
||||
/* .IP DICT_FLAG_NO_REGSUB
|
||||
/* Disallow regular expression substitution from left-hand side data
|
||||
/* 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
|
||||
/* 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
|
||||
* buffering policy.
|
||||
*/
|
||||
if (bp->data == 0)
|
||||
if (bp->data == 0) {
|
||||
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,
|
||||
@ -724,6 +727,8 @@ static int vstream_buf_put_ready(VBUF *bp)
|
||||
*/
|
||||
if (bp->data == 0) {
|
||||
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) {
|
||||
if (VSTREAM_FFLUSH_SOME(stream))
|
||||
return (VSTREAM_EOF);
|
||||
|
@ -413,15 +413,15 @@ static void post_init(char *unused_name, char **unused_argv)
|
||||
|
||||
virtual_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 =
|
||||
virtual8_maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps,
|
||||
DICT_FLAG_LOCK);
|
||||
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
|
||||
|
||||
virtual_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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user